Skip to content

Commit

Permalink
Merge pull request #206 from shobhit-pathak/dev
Browse files Browse the repository at this point in the history
v0.8.0
  • Loading branch information
shobhit-pathak authored Aug 17, 2024
2 parents a18840e + f83e2cc commit 3a846fc
Show file tree
Hide file tree
Showing 25 changed files with 720 additions and 249 deletions.
434 changes: 349 additions & 85 deletions BackupManagement.cs

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# MatchZy Changelog

# 0.8.0

#### August 17, 2024

- Improved backup and restore system. (Added matchzy_loadbackup and matchzy_loadbackup_url commands, now round backups will be stored in .json file in csgo/MatchZyDataBackup/ directory which will have valve backup and other match config data.)
- Added matchzy_listbackups which lists all the backups for the provided matchid. By default lists backups of the current match.
- Added matchzy_hostname_format for hostname formatting.
- Improved player color smokes in practice mode
- Fixed .last grenade's player rotation
- Added switching of maps without adding de_ prefix (using .map command)
- Marked the requestBody as required: true in event_schema.yml

# 0.7.13

#### July 07, 2024
Expand Down
41 changes: 41 additions & 0 deletions ConfigConvars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public partial class MatchZy

public FakeConVar<bool> showCreditsOnMatchStart = new("matchzy_show_credits_on_match_start", "Whether to show 'MatchZy Plugin by WD-' message on match start. Default: true", true);

public FakeConVar<string> hostnameFormat = new("matchzy_hostname_format", "The server hostname to use. Set to \"\" to disable/use existing. Default: MatchZy | {TEAM1} vs {TEAM2}", "MatchZy | {TEAM1} vs {TEAM2}");

[ConsoleCommand("matchzy_whitelist_enabled_default", "Whether Whitelist is enabled by default or not. Default value: false")]
public void MatchZyWLConvar(CCSPlayerController? player, CommandInfo command)
{
Expand Down Expand Up @@ -262,5 +264,44 @@ public void MatchZyMaxSavedLastGrenadesConvar(CCSPlayerController? player, Comma
ReplyToUserCommand(player, Localizer["matchzy.cc.usage", $"matchzy_max_saved_last_grenades <number>"]);
}
}

[ConsoleCommand("get5_remote_backup_url", "A URL to send backup files to over HTTP. Leave empty to disable.")]
[ConsoleCommand("matchzy_remote_backup_url", "A URL to send backup files to over HTTP. Leave empty to disable.")]
[CommandHelper(minArgs: 1, usage: "<remote_backup_upload_url>")]
public void MatchZyBackupUploadURL(CCSPlayerController? player, CommandInfo command)
{
if (player != null) return;
string url = command.ArgByIndex(1);
if (url.Trim() == "") return;
if (!IsValidUrl(url))
{
Log($"[MatchZyBackupUploadURL] Invalid URL: {url}. Please provide a valid URL for uploading the demo!");
return;
}
backupUploadURL = url;
}

[ConsoleCommand("get5_remote_backup_header_key", "If defined, a custom HTTP header with this name is added to the backup HTTP request.")]
[ConsoleCommand("matchzy_remote_backup_header_key", "If defined, a custom HTTP header with this name is added to the backup HTTP request.")]
[CommandHelper(minArgs: 1, usage: "<remote_backup_header_key>")]
public void BackupUploadHeaderKeyCommand(CCSPlayerController? player, CommandInfo command)
{
if (player != null) return;
string header = command.ArgByIndex(1).Trim();

if (header != "") backupUploadHeaderKey = header;
}

[ConsoleCommand("get5_remote_backup_header_value", "If defined, the value of the custom header added to the backup HTTP request.")]
[ConsoleCommand("matchzy_remote_backup_header_value", "If defined, the value of the custom header added to the backup HTTP request.")]
[CommandHelper(minArgs: 1, usage: "<remote_backup_header_value>")]
public void BackupUploadHeaderValueCommand(CCSPlayerController? player, CommandInfo command)
{
if (player != null) return;
string headerValue = command.ArgByIndex(1).Trim();

if (headerValue != "") backupUploadHeaderValue = headerValue;
}

}
}
97 changes: 10 additions & 87 deletions DemoManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ public partial class MatchZy

public void StartDemoRecording()
{

string demoFileName = FormatDemoName();
if (isDemoRecording)
{
Log("[StartDemoRecording] Demo recording is already in progress.");
return;
}
string demoFileName = FormatCvarValue(demoNameFormat.Replace(" ", "_")) + ".dem";
try
{
string? directoryPath = Path.GetDirectoryName(Path.Join(Server.GameDirectory + "/csgo/", demoPath));
Expand Down Expand Up @@ -55,17 +59,20 @@ public void StopDemoRecording(float delay, string activeDemoFile, long liveMatch
{
Log($"[StopDemoRecording] Going to stop demorecording in {delay}s");
string demoPath = Path.Join(Server.GameDirectory + "/csgo/", activeDemoFile);
(int t1score, int t2score) = GetTeamsScore();
int roundNumber = t1score + t2score;
AddTimer(delay, () =>
{
if (isDemoRecording)
{
Server.ExecuteCommand($"tv_stoprecord");
}
isDemoRecording = false;
AddTimer(15, () =>
{
Task.Run(async () =>
{
await UploadDemoAsync(demoPath, liveMatchId, currentMapNumber);
await UploadFileAsync(demoPath, demoUploadURL, demoUploadHeaderKey, demoUploadHeaderValue, liveMatchId, currentMapNumber, roundNumber);
});
});
});
Expand All @@ -86,90 +93,6 @@ public int GetTvDelay()
return tvDelay;
}

public async Task UploadDemoAsync(string? demoPath, long matchId, int mapNumber)
{
if (demoPath == null || demoUploadURL == "")
{
Log($"[UploadDemoAsync] Not able to upload demo, either demoPath or demoUploadURL is not set. demoPath: {demoPath} demoUploadURL: {demoUploadURL}");
return;
}

try
{
using var httpClient = new HttpClient();
Log($"[UploadDemoAsync] Going to upload demo on {demoUploadURL}. Complete path: {demoPath}");

if (!File.Exists(demoPath))
{
Log($"[UploadDemoAsync ERROR] File not found: {demoPath}");
return;
}

using FileStream fileStream = File.OpenRead(demoPath);

byte[] fileContent = new byte[fileStream.Length];
await fileStream.ReadAsync(fileContent, 0, (int)fileStream.Length);

using ByteArrayContent content = new ByteArrayContent(fileContent);
content.Headers.Add("Content-Type", "application/octet-stream");

content.Headers.Add("MatchZy-FileName", Path.GetFileName(demoPath));
content.Headers.Add("MatchZy-MatchId", matchId.ToString());
content.Headers.Add("MatchZy-MapNumber", mapNumber.ToString());

// For Get5 Panel
content.Headers.Add("Get5-FileName", Path.GetFileName(demoPath));
content.Headers.Add("Get5-MatchId", matchId.ToString());
content.Headers.Add("Get5-MapNumber", mapNumber.ToString());

if (!string.IsNullOrEmpty(demoUploadHeaderKey))
{
httpClient.DefaultRequestHeaders.Add(demoUploadHeaderKey, demoUploadHeaderValue);
}

HttpResponseMessage response = await httpClient.PostAsync(demoUploadURL, content);

if (response.IsSuccessStatusCode)
{
Log($"[UploadDemoAsync] File upload successful for matchId: {matchId} mapNumber: {mapNumber} fileName: {Path.GetFileName(demoPath)}.");
}
else
{
Log($"[UploadDemoAsync ERROR] Failed to upload file. Status code: {response.StatusCode} Response: {await response.Content.ReadAsStringAsync()}");
}

var demoUploadedEvent = new MatchZyDemoUploadedEvent
{
MatchId = matchId,
MapNumber = mapNumber,
FileName = Path.GetFileName(demoPath),
Success = response.IsSuccessStatusCode
};
await SendEventAsync(demoUploadedEvent);

}
catch (Exception e)
{
Log($"[UploadDemoAsync FATAL] An error occurred: {e.Message}");
}
}


private string FormatDemoName()
{
string formattedTime = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");

var demoName = demoNameFormat
.Replace("{TIME}", formattedTime)
.Replace("{MATCH_ID}", $"{liveMatchId}")
.Replace("{MAP}", Server.MapName)
.Replace("{MAPNUMBER}", matchConfig.CurrentMapNumber.ToString())
.Replace("{TEAM1}", matchzyTeam1.teamName)
.Replace("{TEAM2}", matchzyTeam2.teamName)
.Replace(" ", "_");
return $"{demoName}.dem";
}

[ConsoleCommand("get5_demo_upload_header_key", "If defined, a custom HTTP header with this name is added to the HTTP requests for demos")]
[ConsoleCommand("matchzy_demo_upload_header_key", "If defined, a custom HTTP header with this name is added to the HTTP requests for demos")]
public void DemoUploadHeaderKeyCommand(CCSPlayerController? player, CommandInfo command)
Expand Down
10 changes: 6 additions & 4 deletions EventHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public HookResult EventPlayerConnectFullHandler(EventPlayerConnectFull @event, G
if (!whiteList.Contains(steamId.ToString()))
{
Log($"[EventPlayerConnectFull] KICKING PLAYER STEAMID: {steamId}, Name: {player.PlayerName} (Not whitelisted!)");
PrintToAllChat($"Kicking player {player.PlayerName} - Not whitelisted.");
KickPlayer(player);

return HookResult.Continue;
Expand All @@ -50,6 +51,7 @@ public HookResult EventPlayerConnectFullHandler(EventPlayerConnectFull @event, G
if (team == CsTeam.None)
{
Log($"[EventPlayerConnectFull] KICKING PLAYER STEAMID: {steamId}, Name: {player.PlayerName} (NOT ALLOWED!)");
PrintToAllChat($"Kicking player {player.PlayerName} - Not a player in this game.");
KickPlayer(player);
return HookResult.Continue;
}
Expand Down Expand Up @@ -184,7 +186,7 @@ public void OnEntitySpawnedHandler(CEntityInstance entity)
{
try
{
if (entity == null || entity.Entity == null || !isPractice) return;
if (!isPractice || entity == null || entity.Entity == null) return;
if (!Constants.ProjectileTypeMap.ContainsKey(entity.Entity.DesignerName)) return;

Server.NextFrame(() => {
Expand Down Expand Up @@ -220,7 +222,7 @@ public void OnEntitySpawnedHandler(CEntityInstance entity)
angle,
velocity,
player.PlayerPawn.Value.CBodyComponent!.SceneNode!.AbsOrigin,
player.PlayerPawn.Value.CBodyComponent!.SceneNode!.AbsRotation,
player.PlayerPawn.Value.EyeAngles,
nadeType,
DateTime.Now
);
Expand All @@ -239,6 +241,7 @@ public void OnEntitySpawnedHandler(CEntityInstance entity)
CSmokeGrenadeProjectile smokeProjectile = new(entity.Handle);
smokeProjectile.SmokeColor.X = GetPlayerTeammateColor(player).R;
smokeProjectile.SmokeColor.Y = GetPlayerTeammateColor(player).G;
smokeProjectile.SmokeColor.Z = GetPlayerTeammateColor(player).B;
}
});
}
Expand Down Expand Up @@ -288,9 +291,8 @@ public HookResult EventRoundFreezeEndHandler(EventRoundFreezeEnd @event, GameEve

public HookResult EventSmokegrenadeDetonateHandler(EventSmokegrenadeDetonate @event, GameEventInfo info)
{
CCSPlayerController? player = @event.Userid;

if (!isPractice || isDryRun) return HookResult.Continue;
CCSPlayerController? player = @event.Userid;
if (!IsPlayerValid(player)) return HookResult.Continue;
if(lastGrenadeThrownTime.TryGetValue(@event.Entityid, out var thrownTime))
{
Expand Down
55 changes: 47 additions & 8 deletions MatchConfig.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.Json.Serialization;
using Newtonsoft.Json.Linq;


Expand All @@ -6,32 +7,70 @@ namespace MatchZy

public class MatchConfig
{
[JsonPropertyName("maplist")]
public List<string> Maplist { get; set; } = new List<string>();

[JsonPropertyName("maps_pool")]
public List<string> MapsPool { get; set; } = new List<string>();

[JsonPropertyName("maps_left_in_veto_pool")]
public List<string> MapsLeftInVetoPool { get; set; } = new List<string>();

[JsonPropertyName("map_ban_order")]
public List<string> MapBanOrder { get; set; } = new List<string>();
public bool SkipVeto = true;

[JsonPropertyName("skip_veto")]
public bool SkipVeto { get; set; } = true;

[JsonPropertyName("match_id")]
public long MatchId { get; set; }

[JsonPropertyName("num_maps")]
public int NumMaps { get; set; } = 1;

[JsonPropertyName("players_per_team")]
public int PlayersPerTeam { get; set; } = 5;

[JsonPropertyName("min_players_to_ready")]
public int MinPlayersToReady { get; set; } = 12;

[JsonPropertyName("min_spectators_to_ready")]
public int MinSpectatorsToReady { get; set; } = 0;
public int CurrentMapNumber = 0;

[JsonPropertyName("current_map_number")]
public int CurrentMapNumber { get; set; } = 0;

[JsonPropertyName("map_sides")]
public List<string> MapSides { get; set; } = new List<string>();

[JsonPropertyName("series_can_clinch")]
public bool SeriesCanClinch { get; set; } = true;

[JsonPropertyName("scrim")]
public bool Scrim { get; set; } = false;

[JsonPropertyName("wingman")]
public bool Wingman { get; set; } = false;

[JsonPropertyName("match_side_type")]
public string MatchSideType { get; set; } = "standard";

public Dictionary<string, string> ChangedCvars = new();
[JsonPropertyName("changed_cvars")]
public Dictionary<string, string> ChangedCvars { get; set; } = new();

[JsonPropertyName("original_cvars")]
public Dictionary<string, string> OriginalCvars { get; set; } = new();

[JsonPropertyName("spectators")]
public JToken Spectators { get; set; } = new JObject();

[JsonPropertyName("remote_log_url")]
public string RemoteLogURL { get; set; } = "";

[JsonPropertyName("remote_log_header_key")]
public string RemoteLogHeaderKey { get; set; } = "";

public Dictionary<string, string> OriginalCvars = new();
public JToken? Spectators;
public string RemoteLogURL = "";
public string RemoteLogHeaderKey = "";
public string RemoteLogHeaderValue = "";
[JsonPropertyName("remote_log_header_value")]
public string RemoteLogHeaderValue { get; set; } = "";
}
}
4 changes: 2 additions & 2 deletions MatchManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,8 @@ public bool LoadMatchFromJSON(string jsonData)
if(matchConfig.SkipVeto) SetMapSides();

SetTeamNames();

UpdatePlayersMap();
UpdateHostname();

var seriesStartedEvent = new MatchZySeriesStartedEvent
{
Expand Down Expand Up @@ -462,7 +462,7 @@ public void GetOptionalMatchValues(JObject jsonDataObject)
}
if (jsonDataObject["spectators"] != null && jsonDataObject["spectators"]!["players"] != null)
{
matchConfig.Spectators = jsonDataObject["spectators"]!["players"];
matchConfig.Spectators = jsonDataObject["spectators"]!["players"]!;
if (matchConfig.Spectators is JArray spectatorsArray && spectatorsArray.Count == 0)
{
// Convert the empty JArray to an empty JObject
Expand Down
6 changes: 4 additions & 2 deletions MatchZy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class MatchZy : BasePlugin
{

public override string ModuleName => "MatchZy";
public override string ModuleVersion => "0.7.13";
public override string ModuleVersion => "0.8.0";

public override string ModuleAuthor => "WD- (https://github.com/shobhit-pathak/)";

Expand Down Expand Up @@ -224,11 +224,13 @@ public override void Load(bool hotReload) {

RegisterEventHandler<EventPlayerTeam>((@event, info) =>
{
if (!isMatchSetup && !isVeto) return HookResult.Continue;
CCSPlayerController? player = @event.Userid;
if (!IsPlayerValid(player)) return HookResult.Continue;
if (player!.IsHLTV || player.IsBot || (!isMatchSetup && !isVeto))
if (player!.IsHLTV || player.IsBot)
{
return HookResult.Continue;
}
Expand Down
2 changes: 1 addition & 1 deletion MatchZy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.245">
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.253">
<PrivateAssets>none</PrivateAssets>
<ExcludeAssets>runtime</ExcludeAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading

0 comments on commit 3a846fc

Please sign in to comment.