summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/gokz-core/demofix.sp
blob: 84a930768e43fbd9dd560d26481f44801d9ad33d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
static ConVar CV_EnableDemofix;
static Handle H_DemofixTimer;
static bool mapRunning;

void OnPluginStart_Demofix()
{
	AddCommandListener(Command_Demorestart, "demorestart");
	CV_EnableDemofix = AutoExecConfig_CreateConVar("gokz_demofix", "1", "Whether GOKZ applies demo record fix to server. (0 = Disabled, 1 = Update warmup period once, 2 = Regularly reset warmup period)", _, true, 0.0, true, 2.0);
	CV_EnableDemofix.AddChangeHook(OnDemofixConVarChanged);
	// If the map is tweaking the warmup value, we need to rerun the fix again.
	FindConVar("mp_warmuptime").AddChangeHook(OnDemofixConVarChanged);
	// We assume that the map is already loaded on late load.
	if (gB_LateLoad)
	{
		mapRunning = true;
	}
}

void OnMapStart_Demofix()
{
	mapRunning = true;
}

void OnMapEnd_Demofix()
{
	mapRunning = false;
}

void OnRoundStart_Demofix()
{
	DoDemoFix();
}

public Action Command_Demorestart(int client, const char[] command, int argc)
{
	FixRecord(client);
	return Plugin_Continue;
}

static void FixRecord(int client)
{
	// For some reasons, demo playback speed is absolute trash without a round_start event.
	// So whenever the client starts recording a demo, we create the event and send it to them.
	Event e = CreateEvent("round_start", true);
	int timelimit = FindConVar("mp_timelimit").IntValue;
	e.SetInt("timelimit", timelimit);
	e.SetInt("fraglimit", 0);
	e.SetString("objective", "demofix");

	e.FireToClient(client);
	delete e;
}

public void OnDemofixConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
	DoDemoFix();
}

public Action Timer_EnableDemoRecord(Handle timer)
{
	EnableDemoRecord();
	return Plugin_Continue;
}

static void DoDemoFix()
{
	if (H_DemofixTimer != null)
	{
		delete H_DemofixTimer;
	}
	// Setting the cvar value to 1 can avoid clogging the demo file and slightly increase performance.
	switch (CV_EnableDemofix.IntValue)
	{
		case 0:
		{
			if (!mapRunning)
			{
				return;
			}

			GameRules_SetProp("m_bWarmupPeriod", 0);
		}
		case 1:
		{
			// Set warmup time to 2^31-1, effectively forever
			if (FindConVar("mp_warmuptime").IntValue != 2147483647)
			{
				FindConVar("mp_warmuptime").SetInt(2147483647);
			}
			EnableDemoRecord();
		}
		case 2:
		{
			H_DemofixTimer = CreateTimer(1.0, Timer_EnableDemoRecord, _, TIMER_REPEAT);
		}
	}
}

static void EnableDemoRecord()
{
	// Enable warmup to allow demo recording
	// m_fWarmupPeriodEnd is set in the past to hide the timer UI
	if (!mapRunning)
	{
		return;
	}
	GameRules_SetProp("m_bWarmupPeriod", 1);
	GameRules_SetPropFloat("m_fWarmupPeriodStart", GetGameTime() - 1.0);
	GameRules_SetPropFloat("m_fWarmupPeriodEnd", GetGameTime() - 1.0);
}