Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 2.4.0 #174

Merged
merged 10 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Resources/RetakesAllocator_gamedata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"GiveNamedItem2": {
"signatures": {
"library": "server",
"windows": "48 83 EC ? 48 C7 44 24 ? ? ? ? ? 45 33 C9 45 33 C0 C6 44 24 ? ? E8 ? ? ? ? 48 83 C4 ? C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC 48 83 EC",
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 48 83 EC ? 48 89 7D ? 44 89 45"
}
}
}
65 changes: 46 additions & 19 deletions RetakesAllocator/CustomGameData.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
using System.Runtime.InteropServices;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using RetakesAllocatorCore.Config;
using RetakesAllocatorCore;
using CounterStrikeSharp.API.Modules.Memory.DynamicFunctions;
using System.Text.Json;

namespace RetakesAllocator;

public class CustomGameData
{
private static Dictionary<string, Dictionary<OSPlatform, string>> _customGameData = new()
{
// Thank you to @Whaliin https://github.com/CS2Plugins/WeaponRestrict/blob/main/WeaponRestrict.json
{
"GiveNamedItem2",
new()
{
{
OSPlatform.Windows,
@"\x48\x83\xEC\x38\x48\xC7\x44\x24\x28\x00\x00\x00\x00\x45\x33\xC9\x45\x33\xC0\xC6\x44\x24\x20\x00\xE8\x2A\x2A\x2A\x2A\x48\x85"
},
{
OSPlatform.Linux,
@"\x55\x48\x89\xE5\x41\x57\x41\x56\x4D\x89\xC6\x41\x55\x49\x89\xD5\x41\x54\x49\x89\xF4"
},
}
}
};

public static Dictionary<string, Dictionary<OSPlatform, string>> _customGameData = new();
private readonly MemoryFunctionVoid<IntPtr, string, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr, IntPtr> GiveNamedItem2;

public readonly
Expand All @@ -36,8 +21,50 @@ public readonly

public CustomGameData()
{
LoadCustomGameDataFromJson();

GiveNamedItem2 = new(GetCustomGameDataKey("GiveNamedItem2"));
}
public void LoadCustomGameDataFromJson()
{
string jsonFilePath = $"{Configs.Shared.Module}/../../plugins/RetakesAllocator/gamedata/RetakesAllocator_gamedata.json";
if (!File.Exists(jsonFilePath))
{
Log.Debug($"JSON file does not exist at path: {jsonFilePath}. Returning without loading custom game data.");
return;
}

try
{
var jsonData = File.ReadAllText(jsonFilePath);
var jsonDocument = JsonDocument.Parse(jsonData);

foreach (var element in jsonDocument.RootElement.EnumerateObject())
{
string key = element.Name;

var platformData = new Dictionary<OSPlatform, string>();

if (element.Value.TryGetProperty("signatures", out var signatures))
{
if (signatures.TryGetProperty("windows", out var windows))
{
platformData[OSPlatform.Windows] = windows.GetString()!;
}

if (signatures.TryGetProperty("linux", out var linux))
{
platformData[OSPlatform.Linux] = linux.GetString()!;
}
}
_customGameData[key] = platformData;
}
}
catch (Exception ex)
{
Log.Debug($"Error loading custom game data: {ex.Message}");
}
}

private string GetCustomGameDataKey(string key)
{
Expand Down
88 changes: 88 additions & 0 deletions RetakesAllocator/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Utils;
using RetakesAllocatorCore.Config;
using RetakesAllocatorCore;

namespace RetakesAllocator;
Expand Down Expand Up @@ -201,4 +202,91 @@ public static bool IsWindows()
}

public static bool IsVip(CCSPlayerController player) => AdminManager.PlayerHasPermissions(player, "@css/vip");

public static async Task DownloadMissingFiles()
{
string baseFolderPath = Configs.Shared.Module!;

string gamedataFileName = "gamedata/RetakesAllocator_gamedata.json";
string gamedataGithubUrl = "https://raw.githubusercontent.com/yonilerner/cs2-retakes-allocator/main/Resources/RetakesAllocator_gamedata.json";
string gamedataFilePath = Path.Combine(baseFolderPath, gamedataFileName);
string gamedataDirectoryPath = Path.GetDirectoryName(gamedataFilePath)!;
await CheckAndDownloadFile(gamedataFilePath, gamedataGithubUrl, gamedataDirectoryPath);
}

public static async Task<bool> CheckAndDownloadFile(string filePath, string githubUrl, string directoryPath)
{
if (!File.Exists(filePath))
{
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
await DownloadFileFromGithub(githubUrl, filePath);
return true;
}
else
{
if (Configs.GetConfigData().AutoUpdateSignatures)
{
bool isFileDifferent = await IsFileDifferent(filePath, githubUrl);
if (isFileDifferent)
{
File.Delete(filePath);
await DownloadFileFromGithub(githubUrl, filePath);
return true;
}
}

}

return false;
}


public static async Task<bool> IsFileDifferent(string localFilePath, string githubUrl)
{
try
{
byte[] localFileBytes = await File.ReadAllBytesAsync(localFilePath);
string localFileHash = GetFileHash(localFileBytes);

using (HttpClient client = new HttpClient())
{
byte[] githubFileBytes = await client.GetByteArrayAsync(githubUrl);
string githubFileHash = GetFileHash(githubFileBytes);
return localFileHash != githubFileHash;
}
}
catch (Exception ex)
{
Log.Debug($"Error comparing files: {ex.Message}");
return false;
}
}

public static string GetFileHash(byte[] fileBytes)
{
using (var md5 = System.Security.Cryptography.MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(fileBytes);
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
}
}

public static async Task DownloadFileFromGithub(string url, string destinationPath)
{
using (HttpClient client = new HttpClient())
{
try
{
byte[] fileBytes = await client.GetByteArrayAsync(url);
await File.WriteAllBytesAsync(destinationPath, fileBytes);
}
catch (Exception ex)
{
Log.Debug($"Error downloading file: {ex.Message}");
}
}
}
}
18 changes: 16 additions & 2 deletions RetakesAllocator/RetakesAllocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class RetakesAllocator : BasePlugin

public override void Load(bool hotReload)
{
Configs.Shared.Module = ModuleDirectory;

Log.Debug($"Loaded. Hot reload: {hotReload}");
ResetState();
Batteries.Init();
Expand All @@ -60,6 +62,11 @@ public override void Load(bool hotReload)
RoundTypeManager.Instance.SetMap(mapName);
});

_ = Task.Run(async () =>
{
await Helpers.DownloadMissingFiles();
});

if (Configs.GetConfigData().UseOnTickFeatures)
{
RegisterListener<Listeners.OnTick>(OnTick);
Expand Down Expand Up @@ -949,7 +956,14 @@ private void AllocateItemsForPlayer(CCSPlayerController player, ICollection<CsIt
continue;
}

CustomFunctions?.PlayerGiveNamedItem(player, itemString);
if(Configs.GetConfigData().CapabilityWeaponPaints)
{
CustomFunctions?.PlayerGiveNamedItem(player, itemString);
}else
{
player.GiveNamedItem(itemString);
}

var slotType = WeaponHelpers.GetSlotTypeForItem(item);
if (slotType is not null)
{
Expand Down Expand Up @@ -987,4 +1001,4 @@ private void GiveDefuseKit(CCSPlayerController player)
}

#endregion
}
}
6 changes: 6 additions & 0 deletions RetakesAllocatorCore/Config/Configs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ namespace RetakesAllocatorCore.Config;

public static class Configs
{
public static class Shared
{
public static string? Module { get; set; }
}
private static readonly string ConfigDirectoryName = "config";
private static readonly string ConfigFileName = "config.json";

Expand Down Expand Up @@ -229,6 +233,7 @@ public Dictionary<
public bool ResetStateOnGameRestart { get; set; } = true;
public bool AllowAllocationAfterFreezeTime { get; set; } = true;
public bool UseOnTickFeatures { get; set; } = true;
public bool CapabilityWeaponPaints { get; set; } = true;
public bool EnableRoundTypeAnnouncement { get; set; } = true;
public bool EnableRoundTypeAnnouncementCenter { get; set; } = false;
public bool EnableBombSiteAnnouncementCenter { get; set; } = false;
Expand Down Expand Up @@ -270,6 +275,7 @@ public Dictionary<

public DatabaseProvider DatabaseProvider { get; set; } = DatabaseProvider.Sqlite;
public string DatabaseConnectionString { get; set; } = "Data Source=data.db; Pooling=False";
public bool AutoUpdateSignatures { get; set; } = true;

public IList<string> Validate()
{
Expand Down
2 changes: 1 addition & 1 deletion RetakesAllocatorCore/PluginInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace RetakesAllocatorCore;

public static class PluginInfo
{
public const string Version = "2.3.19";
public const string Version = "2.4.0";

public static readonly string LogPrefix = $"[RetakesAllocator {Version}] ";

Expand Down
Loading