Skip to content

Commit 01086a9

Browse files
0.5.0 | feat: json config and much more
1 parent 486ecad commit 01086a9

16 files changed

+1618
-519
lines changed

BackupManagement.cs

+18-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public partial class MatchZy
2323
};
2424

2525
public void SetupRoundBackupFile() {
26-
string backupFilePrefix = $"matchzy_{liveMatchId}";
26+
string backupFilePrefix = $"matchzy_{liveMatchId}_{matchConfig.CurrentMapNumber}";
2727
Server.ExecuteCommand($"mp_backup_round_file {backupFilePrefix}");
2828
}
2929
[ConsoleCommand("css_stop", "Marks the player ready")]
@@ -32,6 +32,11 @@ public void OnStopCommand(CCSPlayerController? player, CommandInfo? command) {
3232

3333
Log($"[!stop command] Sent by: {player.UserId}, TeamNum: {player.TeamNum}, connectedPlayers: {connectedPlayers}");
3434
if (isStopCommandAvailable && isMatchLive) {
35+
if (IsHalfTimePhase())
36+
{
37+
ReplyToUserCommand(player, "You cannot use this command during halftime.");
38+
return;
39+
}
3540
string stopTeamName = "";
3641
string remainingStopTeam = "";
3742
if (player.TeamNum == 2) {
@@ -89,7 +94,7 @@ private void HandleRestoreCommand(CCSPlayerController? player, string commandArg
8994
if (!string.IsNullOrWhiteSpace(commandArg)) {
9095
if (int.TryParse(commandArg, out int roundNumber) && roundNumber >= 0) {
9196
string round = roundNumber.ToString("D2");
92-
string requiredBackupFileName = $"matchzy_{liveMatchId}_round{round}.txt";
97+
string requiredBackupFileName = $"matchzy_{liveMatchId}_{matchConfig.CurrentMapNumber}_round{round}.txt";
9398
RestoreRoundBackup(player, requiredBackupFileName, round);
9499
}
95100
else {
@@ -102,6 +107,11 @@ private void HandleRestoreCommand(CCSPlayerController? player, string commandArg
102107
}
103108

104109
private void RestoreRoundBackup(CCSPlayerController? player, string fileName, string round="") {
110+
if (IsHalfTimePhase())
111+
{
112+
ReplyToUserCommand(player, "You cannot load a backup during halftime.");
113+
return;
114+
}
105115
if (!File.Exists(Path.Join(Server.GameDirectory + "/csgo/", fileName))) {
106116
ReplyToUserCommand(player, $"Backup file {fileName} does not exist, please make sure you are restoring a valid backup.");
107117
return;
@@ -114,7 +124,7 @@ private void RestoreRoundBackup(CCSPlayerController? player, string fileName, st
114124
round = (t1score + t2score).ToString("D2");
115125
}
116126

117-
string matchZyBackupFileName = $"matchzy_data_backup_{liveMatchId}_round_{round}.json";
127+
string matchZyBackupFileName = $"matchzy_data_backup_{liveMatchId}_{matchConfig.CurrentMapNumber}_round_{round}.json";
118128
string filePath = Server.GameDirectory + "/csgo/MatchZyDataBackup/" + matchZyBackupFileName;
119129

120130
if (File.Exists(filePath)) {
@@ -146,8 +156,8 @@ private void RestoreRoundBackup(CCSPlayerController? player, string fileName, st
146156
} else if (kvp.Value == "TERRORIST" && teamSides[matchzyTeam1] != "TERRORIST") {
147157
SwapSidesInTeamData(false);
148158
}
149-
Server.ExecuteCommand($"mp_teamname_1 {matchzyTeam1.teamName}");
150-
Server.ExecuteCommand($"mp_teamname_2 {matchzyTeam2.teamName}");
159+
// Server.ExecuteCommand($"mp_teamname_1 {matchzyTeam1.teamName}");
160+
// Server.ExecuteCommand($"mp_teamname_2 {matchzyTeam2.teamName}");
151161
}
152162
}
153163
}
@@ -179,7 +189,7 @@ public void CreateMatchZyRoundDataBackup()
179189
{
180190
(int t1score, int t2score) = GetTeamsScore();
181191
string round = (t1score + t2score).ToString("D2");
182-
string matchZyBackupFileName = $"matchzy_data_backup_{liveMatchId}_round_{round}.json";
192+
string matchZyBackupFileName = $"matchzy_data_backup_{liveMatchId}_{matchConfig.CurrentMapNumber}_round_{round}.json";
183193
string filePath = Server.GameDirectory + "/csgo/MatchZyDataBackup/" + matchZyBackupFileName;
184194
string? directoryPath = Path.GetDirectoryName(filePath);
185195
if (directoryPath != null)
@@ -192,6 +202,8 @@ public void CreateMatchZyRoundDataBackup()
192202

193203
Dictionary<string, string> roundData = new()
194204
{
205+
{ "matchid", liveMatchId.ToString() },
206+
{ "mapnumber", matchConfig.CurrentMapNumber.ToString() },
195207
{ "team1_name", matchzyTeam1.teamName },
196208
{ "team1_flag", matchzyTeam1.teamFlag },
197209
{ "team1_tag", matchzyTeam1.teamTag },

ConfigConvars.cs

+31
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ public void MatchZyPlayoutConvar(CCSPlayerController? player, CommandInfo comman
3737
isPlayOutEnabled = bool.TryParse(args, out bool isPlayOutEnabledValue) ? isPlayOutEnabledValue : args != "0" && isPlayOutEnabled;
3838
}
3939

40+
[ConsoleCommand("matchzy_match_mode_only", "Whether to keep server in match mode only. Default value: false")]
41+
public void MatchZyMatchModeOnlyConvar(CCSPlayerController? player, CommandInfo command)
42+
{
43+
if (player != null) return;
44+
string args = command.ArgString;
45+
46+
matchModeOnly = bool.TryParse(args, out bool matchModeOnlyValue) ? matchModeOnlyValue : args != "0" && matchModeOnly;
47+
}
48+
49+
[ConsoleCommand("matchzy_reset_cvars_on_series_end", "Whether parameters from the cvars section of a match configuration are restored to their original values when a series ends. Default value: true")]
50+
public void MatchZyResetCvarsOnSeriesEndConvar(CCSPlayerController? player, CommandInfo command)
51+
{
52+
if (player != null) return;
53+
string args = command.ArgString;
54+
55+
resetCvarsOnSeriesEnd = bool.TryParse(args, out bool resetCvarsOnSeriesEndValue) ? resetCvarsOnSeriesEndValue : args != "0" && resetCvarsOnSeriesEnd;
56+
}
57+
4058
[ConsoleCommand("matchzy_minimum_ready_required", "Minimum ready players required to start the match. Default: 1")]
4159
public void MatchZyMinimumReadyRequired(CCSPlayerController? player, CommandInfo command)
4260
{
@@ -63,6 +81,19 @@ public void MatchZyDemoPath(CCSPlayerController? player, CommandInfo command)
6381
}
6482
}
6583

84+
[ConsoleCommand("matchzy_demo_upload_url", "If defined, recorded demos will be uploaded to this URL once the map ends.")]
85+
public void MatchZyDemoUploadURL(CCSPlayerController? player, CommandInfo command)
86+
{
87+
if (player != null) return;
88+
string url = command.ArgByIndex(1);
89+
if (!IsValidUrl(url))
90+
{
91+
Log($"[MatchZyDemoUploadURL] Invalid URL: {url}. Please provide a valid URL for uploading the demo!");
92+
return;
93+
}
94+
demoUploadURL = url;
95+
}
96+
6697
[ConsoleCommand("matchzy_stop_command_available", "Whether .stop command is enabled or not (to restore the current round). Default value: false")]
6798
public void MatchZyStopCommandEnabled(CCSPlayerController? player, CommandInfo command)
6899
{

ConsoleCommands.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,12 @@ private void OnMapReloadCommand(CCSPlayerController? player, CommandInfo? comman
260260
return;
261261
}
262262
string currentMapName = Server.MapName;
263-
if (Server.IsMapValid(currentMapName)) {
263+
if (long.TryParse(currentMapName, out _)) { // Check if mapName is a long for workshop map ids
264+
Server.ExecuteCommand($"host_workshop_map \"{currentMapName}\"");
265+
} else if (Server.IsMapValid(currentMapName)) {
264266
Server.ExecuteCommand($"changelevel \"{currentMapName}\"");
265267
} else {
266-
player.PrintToChat($"{chatPrefix} Cant reload a workshop map!");
268+
player.PrintToChat($"{chatPrefix} Invalid map name!");
267269
}
268270
}
269271

DamageInfo.cs

+61-45
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ public partial class MatchZy
1212
private void InitPlayerDamageInfo()
1313
{
1414
foreach (var key in playerData.Keys) {
15+
if (!playerData[key].IsValid) continue;
1516
if (playerData[key].IsBot) continue;
1617
int attackerId = key;
1718
foreach (var key2 in playerData.Keys) {
1819
if (key == key2) continue;
19-
if (playerData[key2].IsBot) continue;
20+
if (!playerData[key2].IsValid || playerData[key2].IsBot) continue;
2021
if (playerData[key].TeamNum == playerData[key2].TeamNum) continue;
2122
if (playerData[key].TeamNum == 2) {
2223
if (playerData[key2].TeamNum != 3) continue;
@@ -54,50 +55,65 @@ private void UpdatePlayerDamageInfo(EventPlayerHurt @event, int targetId)
5455
}
5556

5657
private void ShowDamageInfo()
57-
{
58-
HashSet<(int, int)> processedPairs = new HashSet<(int, int)>();
59-
60-
foreach (var entry in playerDamageInfo)
61-
{
62-
int attackerId = entry.Key;
63-
foreach (var (targetId, targetEntry) in entry.Value)
64-
{
65-
if (processedPairs.Contains((attackerId, targetId)) || processedPairs.Contains((targetId, attackerId)))
66-
continue;
67-
68-
// Access and use the damage information as needed.
69-
int damageGiven = targetEntry.DamageHP;
70-
int hitsGiven = targetEntry.Hits;
71-
int damageTaken = 0;
72-
int hitsTaken = 0;
73-
74-
if (playerDamageInfo.TryGetValue(targetId, out var targetInfo) && targetInfo.TryGetValue(attackerId, out var takenInfo))
75-
{
76-
damageTaken = takenInfo.DamageHP;
77-
hitsTaken = takenInfo.Hits;
78-
}
79-
80-
var attackerController = Utilities.GetPlayerFromUserid(attackerId);
81-
var targetController = Utilities.GetPlayerFromUserid(targetId);
82-
83-
if (attackerController != null && targetController != null)
84-
{
85-
int attackerHP = attackerController.PlayerPawn.Value.Health < 0 ? 0 : attackerController.PlayerPawn.Value.Health;
86-
string attackerName = attackerController.PlayerName;
87-
88-
int targetHP = targetController.PlayerPawn.Value.Health < 0 ? 0 : targetController.PlayerPawn.Value.Health;
89-
string targetName = targetController.PlayerName;
90-
91-
attackerController.PrintToChat($"{chatPrefix} {ChatColors.Green}To: [{damageGiven} / {hitsGiven} hits] From: [{damageTaken} / {hitsTaken} hits] - {targetName} - ({targetHP} hp){ChatColors.Default}");
92-
targetController.PrintToChat($"{chatPrefix} {ChatColors.Green}To: [{damageTaken} / {hitsTaken} hits] From: [{damageGiven} / {hitsGiven} hits] - {attackerName} - ({attackerHP} hp){ChatColors.Default}");
93-
}
94-
95-
// Mark this pair as processed to avoid duplicates.
96-
processedPairs.Add((attackerId, targetId));
97-
}
98-
}
99-
playerDamageInfo.Clear();
100-
}
58+
{
59+
try
60+
{
61+
HashSet<(int, int)> processedPairs = new HashSet<(int, int)>();
62+
63+
foreach (var entry in playerDamageInfo)
64+
{
65+
int attackerId = entry.Key;
66+
foreach (var (targetId, targetEntry) in entry.Value)
67+
{
68+
if (processedPairs.Contains((attackerId, targetId)) || processedPairs.Contains((targetId, attackerId)))
69+
continue;
70+
71+
// Access and use the damage information as needed.
72+
int damageGiven = targetEntry.DamageHP;
73+
int hitsGiven = targetEntry.Hits;
74+
int damageTaken = 0;
75+
int hitsTaken = 0;
76+
77+
if (playerDamageInfo.TryGetValue(targetId, out var targetInfo) && targetInfo.TryGetValue(attackerId, out var takenInfo))
78+
{
79+
damageTaken = takenInfo.DamageHP;
80+
hitsTaken = takenInfo.Hits;
81+
}
82+
83+
if (!playerData.ContainsKey(attackerId) || !playerData.ContainsKey(targetId)) continue;
84+
85+
var attackerController = playerData[attackerId];
86+
var targetController = playerData[targetId];
87+
88+
if (attackerController != null && targetController != null)
89+
{
90+
if (!attackerController.IsValid || !targetController.IsValid) continue;
91+
if (attackerController.Connected != PlayerConnectedState.PlayerConnected) continue;
92+
if (targetController.Connected != PlayerConnectedState.PlayerConnected) continue;
93+
if (!attackerController.PlayerPawn.IsValid || !targetController.PlayerPawn.IsValid) continue;
94+
95+
int attackerHP = attackerController.PlayerPawn.Value.Health < 0 ? 0 : attackerController.PlayerPawn.Value.Health;
96+
string attackerName = attackerController.PlayerName;
97+
98+
int targetHP = targetController.PlayerPawn.Value.Health < 0 ? 0 : targetController.PlayerPawn.Value.Health;
99+
string targetName = targetController.PlayerName;
100+
101+
attackerController.PrintToChat($"{chatPrefix} {ChatColors.Green}To: [{damageGiven} / {hitsGiven} hits] From: [{damageTaken} / {hitsTaken} hits] - {targetName} - ({targetHP} hp){ChatColors.Default}");
102+
targetController.PrintToChat($"{chatPrefix} {ChatColors.Green}To: [{damageTaken} / {hitsTaken} hits] From: [{damageGiven} / {hitsGiven} hits] - {attackerName} - ({attackerHP} hp){ChatColors.Default}");
103+
}
104+
105+
// Mark this pair as processed to avoid duplicates.
106+
processedPairs.Add((attackerId, targetId));
107+
}
108+
}
109+
playerDamageInfo.Clear();
110+
}
111+
catch (Exception e)
112+
{
113+
Log($"[ShowDamageInfo FATAL] An error occurred: {e.Message}");
114+
}
115+
116+
}
101117
}
102118

103119
public class DamagePlayerInfo

0 commit comments

Comments
 (0)