mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-07 18:38:26 +00:00
Merge branch 'shavitush:master' into master
This commit is contained in:
commit
5f925bc26d
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -33,6 +33,12 @@ jobs:
|
|||||||
wget https://github.com/hermansimensen/eventqueue-fix/archive/refs/heads/main.tar.gz
|
wget https://github.com/hermansimensen/eventqueue-fix/archive/refs/heads/main.tar.gz
|
||||||
tar --strip-components=1 -xvzf main.tar.gz -C addons/sourcemod
|
tar --strip-components=1 -xvzf main.tar.gz -C addons/sourcemod
|
||||||
rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE
|
rm -rf *.zip *.tar.gz addons/sourcemod/.git* addons/sourcemod/LICENSE
|
||||||
|
wget https://github.com/srcwr/eventqueuefixfix/releases/download/v1.0.1/eventqueuefixfix-v1.0.1-def5b0e-windows-x32.zip
|
||||||
|
unzip eventqueuefixfix-v1.0.1-def5b0e-windows-x32.zip "addons/sourcemod/extensions/*"
|
||||||
|
rm "addons/sourcemod/extensions/eventqueuefixfix.pdb"
|
||||||
|
wget https://github.com/srcwr/srcwrfloppy/releases/download/v2.0.4/srcwrfloppy-v2.0.4.zip
|
||||||
|
unzip -qO UTF-8 srcwrfloppy-v2.0.4.zip "addons/sourcemod/extensions/*"
|
||||||
|
rm "addons/sourcemod/extensions/srcwr💾.pdb"
|
||||||
|
|
||||||
- name: Run compiler
|
- name: Run compiler
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@ -25,6 +25,10 @@ Includes a records system, map zones (start/end marks etc), bonuses, HUD with us
|
|||||||
* [eventqueuefix](https://github.com/hermansimensen/eventqueue-fix)
|
* [eventqueuefix](https://github.com/hermansimensen/eventqueue-fix)
|
||||||
* Allows for timescaling boosters and is used to fix some exploits. (Use this instead of `boosterfix`)
|
* Allows for timescaling boosters and is used to fix some exploits. (Use this instead of `boosterfix`)
|
||||||
* (included in bhoptimer release zips)
|
* (included in bhoptimer release zips)
|
||||||
|
* Along with using [eventqueuefixfix](https://github.com/srcwr/eventqueuefixfix) at the same time to fix eventqueuefix on Windows after the 2025-02-18 update.
|
||||||
|
* [srcwr💾](https://github.com/srcwr/srcwrfloppy)
|
||||||
|
* Saves replays asynchronously (read: doesn't lag the server when saving a replay).
|
||||||
|
* (included in bhoptimer release zips)
|
||||||
* [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556)
|
* [SteamWorks](https://forums.alliedmods.net/showthread.php?t=229556)
|
||||||
* Used to grab `{serverip}` in advertisements.
|
* Used to grab `{serverip}` in advertisements.
|
||||||
* [DynamicChannels](https://github.com/Vauff/DynamicChannels)
|
* [DynamicChannels](https://github.com/Vauff/DynamicChannels)
|
||||||
|
|||||||
@ -162,10 +162,13 @@
|
|||||||
}
|
}
|
||||||
// search "sv_maxusrcmdprocessticks_warning at server" to find CPlayerMove::RunCommand
|
// search "sv_maxusrcmdprocessticks_warning at server" to find CPlayerMove::RunCommand
|
||||||
// then sig the the `mov REG1,dword ptr [REG2 + OFFSET_TO_BUTTON_DISABLED_HERE]`
|
// then sig the the `mov REG1,dword ptr [REG2 + OFFSET_TO_BUTTON_DISABLED_HERE]`
|
||||||
|
// looks like these in decompiled form:
|
||||||
|
// (windows) `param_3[0xc] = param_3[0xc] & ~param_2[0x32b];`
|
||||||
|
// (linux) `*(uint *)(param_3 + 0x30) = uVar12 & ~param_2[0x331];`
|
||||||
"CBasePlayer->m_afButtonDisabled"
|
"CBasePlayer->m_afButtonDisabled"
|
||||||
{
|
{
|
||||||
"windows" "\x8B\x87\x2A\x2A\x2A\x2A\xF7\xD0\x21\x43"
|
"windows" "\x8B\x86\x2A\x2A\x2A\x2A\xF7\xD0\x21\x47"
|
||||||
"linux" "\x8B\x83\x2A\x2A\x2A\x2A\xF7\xD0"
|
"linux" "\x8b\x93\x2A\x2A\x2A\x2A\xF7\xD2\x21\xd0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -365,6 +365,35 @@ stock void WriteReplayHeader(File fFile, int style, int track, float time, int s
|
|||||||
fFile.WriteInt32(view_as<int>(fZoneOffset[1]));
|
fFile.WriteInt32(view_as<int>(fZoneOffset[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stock void cell2buf(char[] buf, int& pos, int cell)
|
||||||
|
{
|
||||||
|
buf[pos++] = cell & 0xFF;
|
||||||
|
buf[pos++] = (cell >> 8) & 0xFF;
|
||||||
|
buf[pos++] = (cell >> 16) & 0xFF;
|
||||||
|
buf[pos++] = (cell >> 24) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
stock int WriteReplayHeaderToBuffer(char[] buf, int style, int track, float time, int steamid, int preframes, int postframes, float fZoneOffset[2], int totalframes, float tickrate, const char[] sMap)
|
||||||
|
{
|
||||||
|
int pos = FormatEx(buf, 512, "%d:%s\n%s", REPLAY_FORMAT_SUBVERSION, REPLAY_FORMAT_FINAL, sMap);
|
||||||
|
pos += 1; // skip past NUL
|
||||||
|
buf[pos++] = style & 0xFF;
|
||||||
|
buf[pos++] = track & 0xFF;
|
||||||
|
cell2buf(buf, pos, preframes);
|
||||||
|
|
||||||
|
cell2buf(buf, pos, totalframes - preframes - postframes);
|
||||||
|
cell2buf(buf, pos, view_as<int>(time));
|
||||||
|
cell2buf(buf, pos, steamid);
|
||||||
|
|
||||||
|
cell2buf(buf, pos, postframes);
|
||||||
|
cell2buf(buf, pos, view_as<int>(tickrate));
|
||||||
|
|
||||||
|
cell2buf(buf, pos, view_as<int>(fZoneOffset[0]));
|
||||||
|
cell2buf(buf, pos, view_as<int>(fZoneOffset[1]));
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
// file_a is usually used as the wr replay file.
|
// file_a is usually used as the wr replay file.
|
||||||
// file_b is usually used as the duplicate/backup replay file.
|
// file_b is usually used as the duplicate/backup replay file.
|
||||||
stock void WriteReplayFrames(ArrayList playerrecording, int iSize, File file_a, File file_b)
|
stock void WriteReplayFrames(ArrayList playerrecording, int iSize, File file_a, File file_b)
|
||||||
|
|||||||
@ -48,8 +48,9 @@ forward Action Shavit_ShouldSaveReplayCopy(int client, int style, float time, in
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when either a WR replay or a copy of a replay has been saved.
|
* Called when either a WR replay or a copy of a replay has been saved.
|
||||||
|
* NOTE: Can be called with a delay after a run is finished due to asynchronous replay saving through extensions.
|
||||||
*
|
*
|
||||||
* @param client Client index.
|
* @param client Client index. Can be 0 if the replay was saved asynchronously & the client disconnected super duper quick...
|
||||||
* @param style Style the record was done on.
|
* @param style Style the record was done on.
|
||||||
* @param time Record time.
|
* @param time Record time.
|
||||||
* @param jumps Jumps amount.
|
* @param jumps Jumps amount.
|
||||||
|
|||||||
50
addons/sourcemod/scripting/include/srcwr/floppy.inc
Normal file
50
addons/sourcemod/scripting/include/srcwr/floppy.inc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
// Copyright 2025 rtldg <rtldg@protonmail.com>
|
||||||
|
|
||||||
|
#if defined _srcwrfloppy_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _srcwrfloppy_included
|
||||||
|
#pragma semicolon 1
|
||||||
|
|
||||||
|
|
||||||
|
typeset ReplaySavedCallback {
|
||||||
|
function void(bool saved, any value, char[] sPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Don't modify the `playerrecording` ArrayList until the ReplaySavedCallback is called... OR ELSE!!!!
|
||||||
|
native void SRCWRFloppy_AsyncSaveReplay(
|
||||||
|
ReplaySavedCallback callback // what to call when saved
|
||||||
|
, any value // what to pass along to the callback
|
||||||
|
, char[] wrpath
|
||||||
|
, char[] copypath
|
||||||
|
, char[] header
|
||||||
|
, int headersize
|
||||||
|
, ArrayList playerrecording
|
||||||
|
, int totalframes
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public Extension __ext_srcwrfloppy =
|
||||||
|
{
|
||||||
|
name = "srcwr💾",
|
||||||
|
file = "srcwr💾.ext",
|
||||||
|
#if defined AUTOLOAD_EXTENSIONS
|
||||||
|
autoload = 1,
|
||||||
|
#else
|
||||||
|
autoload = 0,
|
||||||
|
#endif
|
||||||
|
#if defined REQUIRE_EXTENSIONS
|
||||||
|
required = 1,
|
||||||
|
#else
|
||||||
|
required = 0,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined REQUIRE_EXTENSIONS
|
||||||
|
public void __ext_srcwrfloppy_SetNTVOptional()
|
||||||
|
{
|
||||||
|
MarkNativeAsOptional("SRCWRFloppy_AsyncSaveReplay");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -92,7 +92,8 @@ Handle gH_Forwards_OnProcessMovementPost = null;
|
|||||||
// player timer variables
|
// player timer variables
|
||||||
timer_snapshot_t gA_Timers[MAXPLAYERS+1];
|
timer_snapshot_t gA_Timers[MAXPLAYERS+1];
|
||||||
bool gB_Auto[MAXPLAYERS+1];
|
bool gB_Auto[MAXPLAYERS+1];
|
||||||
int gI_FirstTouchedGround[MAXPLAYERS+1];
|
// 0 is in air, 1 or greater is on ground, -1 means client was on ground with zero...ish... velocity
|
||||||
|
int gI_FirstTouchedGroundForStartTimer[MAXPLAYERS+1];
|
||||||
int gI_LastTickcount[MAXPLAYERS+1];
|
int gI_LastTickcount[MAXPLAYERS+1];
|
||||||
|
|
||||||
// these are here until the compiler bug is fixed
|
// these are here until the compiler bug is fixed
|
||||||
@ -2576,10 +2577,20 @@ bool CanStartTimer(int client, int track, bool skipGroundCheck)
|
|||||||
|
|
||||||
if (skipGroundTimer) return true;
|
if (skipGroundTimer) return true;
|
||||||
|
|
||||||
|
if (gI_FirstTouchedGroundForStartTimer[client] < 0)
|
||||||
|
{
|
||||||
|
// was on ground with zero...ish... velocity...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (gI_FirstTouchedGroundForStartTimer[client] > 0)
|
||||||
|
{
|
||||||
int halfSecOfTicks = RoundFloat(0.5 / GetTickInterval());
|
int halfSecOfTicks = RoundFloat(0.5 / GetTickInterval());
|
||||||
int onGroundTicks = gI_LastTickcount[client] - gI_FirstTouchedGround[client];
|
int onGroundTicks = gI_LastTickcount[client] - gI_FirstTouchedGroundForStartTimer[client];
|
||||||
|
|
||||||
return onGroundTicks >= halfSecOfTicks;
|
return onGroundTicks >= halfSecOfTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTimer(int client, int track, bool skipGroundCheck)
|
void StartTimer(int client, int track, bool skipGroundCheck)
|
||||||
@ -2771,7 +2782,7 @@ public void OnClientPutInServer(int client)
|
|||||||
gA_Timers[client].fNextFrameTime = 0.0;
|
gA_Timers[client].fNextFrameTime = 0.0;
|
||||||
gA_Timers[client].fplayer_speedmod = 1.0;
|
gA_Timers[client].fplayer_speedmod = 1.0;
|
||||||
gS_DeleteMap[client][0] = 0;
|
gS_DeleteMap[client][0] = 0;
|
||||||
gI_FirstTouchedGround[client] = 0;
|
gI_FirstTouchedGroundForStartTimer[client] = 0;
|
||||||
gI_LastTickcount[client] = 0;
|
gI_LastTickcount[client] = 0;
|
||||||
gI_HijackFrames[client] = 0;
|
gI_HijackFrames[client] = 0;
|
||||||
gI_LastPrintedSteamID[client] = 0;
|
gI_LastPrintedSteamID[client] = 0;
|
||||||
@ -3665,10 +3676,35 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3
|
|||||||
|
|
||||||
gI_LastTickcount[client] = tickcount;
|
gI_LastTickcount[client] = tickcount;
|
||||||
|
|
||||||
|
if (bOnGround)
|
||||||
|
{
|
||||||
|
if (gI_FirstTouchedGroundForStartTimer[client] == 0)
|
||||||
|
{
|
||||||
|
// just landed (or teleported to the ground or whatever)
|
||||||
|
gI_FirstTouchedGroundForStartTimer[client] = tickcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gI_FirstTouchedGroundForStartTimer[client] > 0)
|
||||||
|
{
|
||||||
|
float fSpeed[3];
|
||||||
|
GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed);
|
||||||
|
|
||||||
|
// zero...ish... velocity... (squared-ish (cubed?))
|
||||||
|
if (GetVectorLength(fSpeed, true) <= 1000.0)
|
||||||
|
{
|
||||||
|
gI_FirstTouchedGroundForStartTimer[client] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gI_FirstTouchedGroundForStartTimer[client] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(bOnGround && !gA_Timers[client].bOnGround)
|
if(bOnGround && !gA_Timers[client].bOnGround)
|
||||||
{
|
{
|
||||||
gA_Timers[client].iLandingTick = tickcount;
|
gA_Timers[client].iLandingTick = tickcount;
|
||||||
gI_FirstTouchedGround[client] = tickcount;
|
gI_FirstTouchedGroundForStartTimer[client] = tickcount;
|
||||||
|
|
||||||
if (gEV_Type != Engine_TF2 && GetStyleSettingBool(gA_Timers[client].bsStyle, "easybhop"))
|
if (gEV_Type != Engine_TF2 && GetStyleSettingBool(gA_Timers[client].bsStyle, "easybhop"))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1929,7 +1929,16 @@ bool Teleport(int client, int targetserial)
|
|||||||
float vecPosition[3];
|
float vecPosition[3];
|
||||||
GetClientAbsOrigin(iTarget, vecPosition);
|
GetClientAbsOrigin(iTarget, vecPosition);
|
||||||
|
|
||||||
|
if(Shavit_GetTimerStatus(client) == Timer_Running || !gCV_PauseMovement.BoolValue)
|
||||||
|
{
|
||||||
|
if(ShouldDisplayStopWarning(client))
|
||||||
|
{
|
||||||
|
gI_LastStopInfo[client] = targetserial;
|
||||||
|
OpenStopWarningMenu(client, DoTeleport);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Shavit_StopTimer(client);
|
Shavit_StopTimer(client);
|
||||||
|
}
|
||||||
|
|
||||||
TeleportEntity(client, vecPosition, NULL_VECTOR, NULL_VECTOR);
|
TeleportEntity(client, vecPosition, NULL_VECTOR, NULL_VECTOR);
|
||||||
|
|
||||||
@ -2040,6 +2049,12 @@ void DoStopTimer(int client)
|
|||||||
Shavit_StopTimer(client);
|
Shavit_StopTimer(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoTeleport(int client)
|
||||||
|
{
|
||||||
|
Shavit_StopTimer(client);
|
||||||
|
Teleport(client, gI_LastStopInfo[client]);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenStopWarningMenu(int client, StopTimerCallback after)
|
void OpenStopWarningMenu(int client, StopTimerCallback after)
|
||||||
{
|
{
|
||||||
gH_AfterWarningMenu[client] = after;
|
gH_AfterWarningMenu[client] = after;
|
||||||
|
|||||||
@ -3001,7 +3001,9 @@ public int DeleteConfirmation_Callback(Menu menu, MenuAction action, int param1,
|
|||||||
menu.GetItem(param2, sInfo, 4);
|
menu.GetItem(param2, sInfo, 4);
|
||||||
int style = StringToInt(sInfo);
|
int style = StringToInt(sInfo);
|
||||||
|
|
||||||
if (style != -1 && DeleteReplay(style, gI_MenuTrack[param1], 0, gS_Map))
|
if (style != -1)
|
||||||
|
{
|
||||||
|
if (DeleteReplay(style, gI_MenuTrack[param1], 0, gS_Map))
|
||||||
{
|
{
|
||||||
char sTrack[32];
|
char sTrack[32];
|
||||||
GetTrackName(param1, gI_MenuTrack[param1], sTrack, 32);
|
GetTrackName(param1, gI_MenuTrack[param1], sTrack, 32);
|
||||||
@ -3014,6 +3016,7 @@ public int DeleteConfirmation_Callback(Menu menu, MenuAction action, int param1,
|
|||||||
{
|
{
|
||||||
Shavit_PrintToChat(param1, "%T", "ReplayDeleteFailure", param1, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText);
|
Shavit_PrintToChat(param1, "%T", "ReplayDeleteFailure", param1, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Command_DeleteReplay(param1, 0);
|
Command_DeleteReplay(param1, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,10 @@
|
|||||||
#include <shavit/replay-file>
|
#include <shavit/replay-file>
|
||||||
#include <shavit/replay-stocks.sp>
|
#include <shavit/replay-stocks.sp>
|
||||||
|
|
||||||
|
#undef REQUIRE_EXTENSIONS
|
||||||
|
#include <srcwr/floppy>
|
||||||
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
public Plugin myinfo =
|
||||||
{
|
{
|
||||||
name = "[shavit] Replay Recorder",
|
name = "[shavit] Replay Recorder",
|
||||||
@ -94,6 +98,7 @@ float gF_HijackedAngles[MAXPLAYERS+1][2];
|
|||||||
bool gB_HijackFramesKeepOnStart[MAXPLAYERS+1];
|
bool gB_HijackFramesKeepOnStart[MAXPLAYERS+1];
|
||||||
|
|
||||||
bool gB_ReplayPlayback = false;
|
bool gB_ReplayPlayback = false;
|
||||||
|
bool gB_Floppy = false;
|
||||||
|
|
||||||
//#include <TickRateControl>
|
//#include <TickRateControl>
|
||||||
forward void TickRate_OnTickRateChanged(float fOld, float fNew);
|
forward void TickRate_OnTickRateChanged(float fOld, float fNew);
|
||||||
@ -142,13 +147,14 @@ public void OnPluginStart()
|
|||||||
gCV_PlaybackPostRunTime = new Convar("shavit_replay_postruntime", "1.5", "Time (in seconds) to record after a player enters the end zone.", 0, true, 0.0, true, 2.0);
|
gCV_PlaybackPostRunTime = new Convar("shavit_replay_postruntime", "1.5", "Time (in seconds) to record after a player enters the end zone.", 0, true, 0.0, true, 2.0);
|
||||||
gCV_PreRunAlways = new Convar("shavit_replay_prerun_always", "1", "Record prerun frames outside the start zone?", 0, true, 0.0, true, 1.0);
|
gCV_PreRunAlways = new Convar("shavit_replay_prerun_always", "1", "Record prerun frames outside the start zone?", 0, true, 0.0, true, 1.0);
|
||||||
gCV_PlaybackPreRunTime = new Convar("shavit_replay_preruntime", "1.5", "Time (in seconds) to record before a player leaves start zone.", 0, true, 0.0, true, 2.0);
|
gCV_PlaybackPreRunTime = new Convar("shavit_replay_preruntime", "1.5", "Time (in seconds) to record before a player leaves start zone.", 0, true, 0.0, true, 2.0);
|
||||||
gCV_TimeLimit = new Convar("shavit_replay_timelimit", "7200.0", "Maximum amount of time (in seconds) to allow saving to disk.\nDefault is 7200 (2 hours)\n0 - Disabled", 0, true, 0.0);
|
gCV_TimeLimit = new Convar("shavit_replay_timelimit", "7200.0", "Maximum amount of time (in seconds) to allow saving to disk.\nDefault is 7200 (2 hours)\n0 - Disabled (no replays will be recorded)", 0, true, 0.0);
|
||||||
|
|
||||||
Convar.AutoExecConfig();
|
Convar.AutoExecConfig();
|
||||||
|
|
||||||
gF_Tickrate = (1.0 / GetTickInterval());
|
gF_Tickrate = (1.0 / GetTickInterval());
|
||||||
|
|
||||||
gB_ReplayPlayback = LibraryExists("shavit-replay-playback");
|
gB_ReplayPlayback = LibraryExists("shavit-replay-playback");
|
||||||
|
gB_Floppy = LibraryExists("srcwr💾");
|
||||||
|
|
||||||
if (gB_Late)
|
if (gB_Late)
|
||||||
{
|
{
|
||||||
@ -170,6 +176,10 @@ public void OnLibraryAdded(const char[] name)
|
|||||||
{
|
{
|
||||||
gB_ReplayPlayback = true;
|
gB_ReplayPlayback = true;
|
||||||
}
|
}
|
||||||
|
else if (StrEqual(name, "srcwr💾"))
|
||||||
|
{
|
||||||
|
gB_Floppy = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLibraryRemoved(const char[] name)
|
public void OnLibraryRemoved(const char[] name)
|
||||||
@ -178,6 +188,10 @@ public void OnLibraryRemoved(const char[] name)
|
|||||||
{
|
{
|
||||||
gB_ReplayPlayback = false;
|
gB_ReplayPlayback = false;
|
||||||
}
|
}
|
||||||
|
else if (StrEqual(name, "srcwr💾"))
|
||||||
|
{
|
||||||
|
gB_Floppy = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnMapStart()
|
public void OnMapStart()
|
||||||
@ -378,13 +392,94 @@ void DoReplaySaverCallbacks(int iSteamID, int client, int style, float time, int
|
|||||||
|
|
||||||
int postframes = gI_PlayerFrames[client] - gI_PlayerFinishFrame[client];
|
int postframes = gI_PlayerFrames[client] - gI_PlayerFinishFrame[client];
|
||||||
|
|
||||||
|
ArrayList playerrecording = view_as<ArrayList>(CloneHandle(gA_PlayerFrames[client]));
|
||||||
|
|
||||||
|
DataPack dp = new DataPack();
|
||||||
|
dp.WriteCell(GetClientSerial(client));
|
||||||
|
dp.WriteCell(style);
|
||||||
|
dp.WriteCell(time);
|
||||||
|
dp.WriteCell(jumps);
|
||||||
|
dp.WriteCell(strafes);
|
||||||
|
dp.WriteCell(sync);
|
||||||
|
dp.WriteCell(track);
|
||||||
|
dp.WriteCell(oldtime);
|
||||||
|
dp.WriteCell(perfs);
|
||||||
|
dp.WriteCell(avgvel);
|
||||||
|
dp.WriteCell(maxvel);
|
||||||
|
dp.WriteCell(timestamp);
|
||||||
|
dp.WriteCell(isBestReplay);
|
||||||
|
dp.WriteCell(isTooLong);
|
||||||
|
dp.WriteCell(makeCopy);
|
||||||
|
dp.WriteCell(playerrecording);
|
||||||
|
dp.WriteCell(gI_PlayerPrerunFrames[client]);
|
||||||
|
dp.WriteCell(postframes);
|
||||||
|
dp.WriteString(sName);
|
||||||
|
|
||||||
|
if (gB_Floppy)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
int headersize = WriteReplayHeaderToBuffer(buf, style, track, time, iSteamID, gI_PlayerPrerunFrames[client], postframes, fZoneOffset, gI_PlayerFrames[client], gF_Tickrate, gS_Map);
|
||||||
|
|
||||||
|
char wrpath[PLATFORM_MAX_PATH], copypath[PLATFORM_MAX_PATH];
|
||||||
|
if (makeReplay)
|
||||||
|
FormatEx(wrpath, sizeof(wrpath),
|
||||||
|
track>0?"%s/%d/%s_%d.replay" : "%s/%d/%s.replay",
|
||||||
|
gS_ReplayFolder, style, gS_Map, track
|
||||||
|
);
|
||||||
|
if (makeCopy)
|
||||||
|
FormatEx(copypath, sizeof(copypath), "%s/copy/%d_%d_%s.replay", gS_ReplayFolder, timestamp, iSteamID, gS_Map);
|
||||||
|
|
||||||
|
SRCWRFloppy_AsyncSaveReplay(
|
||||||
|
FloppyAsynchronouslySavedMyReplayWhichWasNiceOfThem
|
||||||
|
, dp
|
||||||
|
, wrpath
|
||||||
|
, copypath
|
||||||
|
, buf
|
||||||
|
, headersize
|
||||||
|
, playerrecording
|
||||||
|
, gI_PlayerFrames[client]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char sPath[PLATFORM_MAX_PATH];
|
char sPath[PLATFORM_MAX_PATH];
|
||||||
bool saved = SaveReplay(style, track, time, iSteamID, gI_PlayerPrerunFrames[client], gA_PlayerFrames[client], gI_PlayerFrames[client], postframes, timestamp, fZoneOffset, makeCopy, makeReplay, sPath, sizeof(sPath));
|
bool saved = SaveReplay(style, track, time, iSteamID, gI_PlayerPrerunFrames[client], playerrecording, gI_PlayerFrames[client], postframes, timestamp, fZoneOffset, makeCopy, makeReplay, sPath, sizeof(sPath));
|
||||||
|
FloppyAsynchronouslySavedMyReplayWhichWasNiceOfThem(saved, dp, sPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearFrames(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FloppyAsynchronouslySavedMyReplayWhichWasNiceOfThem(bool saved, any value, char[] sPath)
|
||||||
|
{
|
||||||
|
DataPack dp = value;
|
||||||
|
dp.Reset();
|
||||||
|
|
||||||
|
int client = GetClientFromSerial(dp.ReadCell());
|
||||||
|
int style = dp.ReadCell();
|
||||||
|
float time = dp.ReadCell();
|
||||||
|
int jumps = dp.ReadCell();
|
||||||
|
int strafes = dp.ReadCell();
|
||||||
|
float sync = dp.ReadCell();
|
||||||
|
int track = dp.ReadCell();
|
||||||
|
float oldtime = dp.ReadCell();
|
||||||
|
float perfs = dp.ReadCell();
|
||||||
|
float avgvel = dp.ReadCell();
|
||||||
|
float maxvel = dp.ReadCell();
|
||||||
|
int timestamp = dp.ReadCell();
|
||||||
|
bool isBestReplay = dp.ReadCell();
|
||||||
|
bool isTooLong = dp.ReadCell();
|
||||||
|
bool makeCopy = dp.ReadCell();
|
||||||
|
ArrayList playerrecording = dp.ReadCell();
|
||||||
|
int preframes = dp.ReadCell();
|
||||||
|
int postframes = dp.ReadCell();
|
||||||
|
char sName[MAX_NAME_LENGTH];
|
||||||
|
dp.ReadString(sName, sizeof(sName));
|
||||||
|
|
||||||
if (!saved)
|
if (!saved)
|
||||||
{
|
{
|
||||||
LogError("SaveReplay() failed. Skipping OnReplaySaved")
|
LogError("Failed to save replay... Skipping OnReplaySaved");
|
||||||
ClearFrames(client);
|
delete playerrecording; // importante!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,13 +500,13 @@ void DoReplaySaverCallbacks(int iSteamID, int client, int style, float time, int
|
|||||||
Call_PushCell(isTooLong);
|
Call_PushCell(isTooLong);
|
||||||
Call_PushCell(makeCopy);
|
Call_PushCell(makeCopy);
|
||||||
Call_PushString(sPath);
|
Call_PushString(sPath);
|
||||||
Call_PushCell(gA_PlayerFrames[client]);
|
Call_PushCell(playerrecording);
|
||||||
Call_PushCell(gI_PlayerPrerunFrames[client]);
|
Call_PushCell(preframes);
|
||||||
Call_PushCell(postframes);
|
Call_PushCell(postframes);
|
||||||
Call_PushString(sName);
|
Call_PushString(sName);
|
||||||
Call_Finish();
|
Call_Finish();
|
||||||
|
|
||||||
ClearFrames(client);
|
delete playerrecording;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs, float avgvel, float maxvel, int timestamp)
|
public void Shavit_OnFinish(int client, int style, float time, int jumps, int strafes, float sync, int track, float oldtime, float perfs, float avgvel, float maxvel, int timestamp)
|
||||||
@ -469,16 +564,6 @@ bool SaveReplay(int style, int track, float time, int steamid, int preframes, Ar
|
|||||||
File fWR = null;
|
File fWR = null;
|
||||||
File fCopy = null;
|
File fCopy = null;
|
||||||
|
|
||||||
if (saveWR)
|
|
||||||
{
|
|
||||||
FormatEx(sPath, sPathLen, "%s/%d/%s%s.replay", gS_ReplayFolder, style, gS_Map, (track > 0)? sTrack:"");
|
|
||||||
|
|
||||||
if (!(fWR = OpenFile(sPath, "wb+")))
|
|
||||||
{
|
|
||||||
LogError("Failed to open WR replay file for writing. ('%s')", sPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saveCopy)
|
if (saveCopy)
|
||||||
{
|
{
|
||||||
FormatEx(sPath, sPathLen, "%s/copy/%d_%d_%s.replay", gS_ReplayFolder, timestamp, steamid, gS_Map);
|
FormatEx(sPath, sPathLen, "%s/copy/%d_%d_%s.replay", gS_ReplayFolder, timestamp, steamid, gS_Map);
|
||||||
@ -489,6 +574,16 @@ bool SaveReplay(int style, int track, float time, int steamid, int preframes, Ar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saveWR)
|
||||||
|
{
|
||||||
|
FormatEx(sPath, sPathLen, "%s/%d/%s%s.replay", gS_ReplayFolder, style, gS_Map, (track > 0)? sTrack:"");
|
||||||
|
|
||||||
|
if (!(fWR = OpenFile(sPath, "wb+")))
|
||||||
|
{
|
||||||
|
LogError("Failed to open WR replay file for writing. ('%s')", sPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!fWR && !fCopy)
|
if (!fWR && !fCopy)
|
||||||
{
|
{
|
||||||
// I want to try and salvage the replay file so let's write it out to a random
|
// I want to try and salvage the replay file so let's write it out to a random
|
||||||
|
|||||||
@ -5347,7 +5347,7 @@ public void StartTouchPost(int entity, int other)
|
|||||||
|
|
||||||
case Zone_Slay:
|
case Zone_Slay:
|
||||||
{
|
{
|
||||||
if (status != Timer_Stopped)
|
if (status == Timer_Running)
|
||||||
{
|
{
|
||||||
Shavit_StopTimer(other);
|
Shavit_StopTimer(other);
|
||||||
ACTUALLY_ForcePlayerSuicide(other);
|
ACTUALLY_ForcePlayerSuicide(other);
|
||||||
@ -5357,7 +5357,7 @@ public void StartTouchPost(int entity, int other)
|
|||||||
|
|
||||||
case Zone_Stop:
|
case Zone_Stop:
|
||||||
{
|
{
|
||||||
if(status != Timer_Stopped)
|
if(status == Timer_Running)
|
||||||
{
|
{
|
||||||
Shavit_StopTimer(other);
|
Shavit_StopTimer(other);
|
||||||
Shavit_PrintToChat(other, "%T", "ZoneStopEnter", other, gS_ChatStrings.sWarning, gS_ChatStrings.sVariable2, gS_ChatStrings.sWarning);
|
Shavit_PrintToChat(other, "%T", "ZoneStopEnter", other, gS_ChatStrings.sWarning, gS_ChatStrings.sVariable2, gS_ChatStrings.sWarning);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user