diff --git a/WolfKillCounter/Commands/Commands.cs b/WolfKillCounter/Commands/Commands.cs index 6ed96cb..27c3928 100644 --- a/WolfKillCounter/Commands/Commands.cs +++ b/WolfKillCounter/Commands/Commands.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Vintagestory.API.Common; using Vintagestory.API.Server; -using Vintagestory.Common; using WolfKillCounter.Config; namespace WolfKillCounter.Commands @@ -15,12 +11,11 @@ internal class Commands private static ICoreServerAPI sapi; public static void RegisterCommands(ICoreServerAPI api) { - + sapi = api; // List Leaderboard Command api.ChatCommands.Create("wkc") .WithDescription("Provides the Wolf Kill Counter commands") .RequiresPrivilege(Privilege.chat) - .HandleWith(args => HandleWKCCommand(args, api)) // List Wolf Kills Subcommand .BeginSubCommand("listWolfKills") .WithDescription("List the top 5 wolf killers") @@ -50,15 +45,9 @@ public static void RegisterCommands(ICoreServerAPI api) .EndSubCommand(); } - private static TextCommandResult HandleWKCCommand(TextCommandCallingArgs args, ICoreServerAPI api) - { - throw new NotImplementedException(); - } - // Command function to print the Wolf Kills Leaderboard private static TextCommandResult ListWolfKills(TextCommandCallingArgs args, ICoreServerAPI api) { - string playerName = args.Caller.Player.PlayerName; api.Logger.Notification($"{playerName}: Printing Wolf Kill List Top 5"); @@ -66,18 +55,18 @@ private static TextCommandResult ListWolfKills(TextCommandCallingArgs args, ICor } // Command function to reset the Wolf Kills Leaderboard - private static TextCommandResult ResetLeaderboardCommand(TextCommandCallingArgs args, ICoreServerAPI api) + private static TextCommandResult ResetLeaderboardCommand(TextCommandCallingArgs _, ICoreServerAPI api) { WolfKillCounterModSystem modSystem = api.ModLoader.GetModSystem(); modSystem.SetCurrentLeaderboard(new Dictionary()); - modSystem.GetConfig().SaveWolfKillData(api); + modSystem.GetConfig().SaveWolfKillData(); api.Logger.Notification("[WolfKillCounter] Resetting leaderboard."); return TextCommandResult.Success("Wolf kill leaderboard has been reset. Total kill count remains unchanged."); } - private static TextCommandResult DisplayServerGoal(TextCommandCallingArgs args, ICoreServerAPI api) + private static TextCommandResult DisplayServerGoal(TextCommandCallingArgs _, ICoreServerAPI api) { WolfKillCounterModSystem modSystem = api.ModLoader.GetModSystem(); @@ -96,7 +85,7 @@ private static TextCommandResult DisplayPlayerGoal(TextCommandCallingArgs args, if (wolfKillCount.ContainsKey(playerName)) { modSystem.AddPlayer(playerName, new KillCountData { Kills = 0, Goal = 50, Deaths = 0 }); - modSystem.GetConfig().SaveWolfKillData(api); + modSystem.GetConfig().SaveWolfKillData(); } return TextCommandResult.Success($"{playerName}'s Kill Goal: {modSystem.GetWolfKillCount()[playerName].Goal}.\n" + diff --git a/WolfKillCounter/Config/WolfKillCounterConfig.cs b/WolfKillCounter/Config/WolfKillCounterConfig.cs index 6c555cb..fbe413b 100644 --- a/WolfKillCounter/Config/WolfKillCounterConfig.cs +++ b/WolfKillCounter/Config/WolfKillCounterConfig.cs @@ -1,9 +1,6 @@ using ProtoBuf; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Vintagestory.API.Server; using Vintagestory.API.Util; @@ -25,11 +22,11 @@ public class KillCountData [ProtoContract] public class WolfKillData { - // Players and their wolf kill counts + // Players and their wolf kill counts (OUTDATED) [ProtoMember(1)] public Dictionary KillCounts { get; set; } = new Dictionary(); - // Old Dictionary format, REFORMAT USE ONLY + // New Format [ProtoMember(2)] public Dictionary NewKillCounts { get; set; } = new Dictionary(); @@ -44,118 +41,47 @@ public class WolfKillData [ProtoMember(5)] public int ServerKillGoal { get; set; } = 100; } - public class WolfKillCounterConfig + public class WolfKillCounterConfig(ICoreServerAPI api) { - ICoreServerAPI sapi; - - private string SaveFilePath => sapi.GetOrCreateDataPath("wolfkills.json"); + + //private string SaveFilePath => api.GetOrCreateDataPath("wolfkills.json"); // Load the saved data from the json file - public WolfKillData LoadWolfKillData(ICoreServerAPI api) + public void LoadWolfKillData(ref WolfKillData data) { - sapi = api; - - // If the old json file exists, get the data and switch to new saving format - if (api.LoadModConfig("wolfkills.json") != null) + // Create new data if none exists + if (api.WorldManager.SaveGame.GetData("wolfkilldata") is null) { - // Get Mod System - WolfKillCounterModSystem wolfKillCounter = api.ModLoader.GetModSystem(); - - // Get the file data - var data = api.LoadModConfig("wolfkills.json"); - - // Load Leaderboard and TotalKills - var currentLeaderboard = data.Leaderboard; - var totalWolfKillCount = data.TotalKills; - var serverKillGoal = wolfKillCounter.CalculateGoal(totalWolfKillCount); - - Dictionary wolfKillCount = new Dictionary(); - // Load KillCounts from the old format and convert it to the new format - if (data.KillCounts != null) - { - foreach (var kvp in data.KillCounts) - { - wolfKillCount.Add(kvp.Key, new KillCountData { Kills = kvp.Value, Goal = wolfKillCounter.CalculateGoal((int)kvp.Value), Deaths = 0 }); - } - } - - api.Logger.Notification("[WolfKillCounter]: KillCounts parsed and migrated if needed."); - - // Try to Delete the JSON file, otherwise Error. - try - { - System.IO.File.Delete(SaveFilePath); - api.Logger.Notification("[WolfKillCounter]: Deleted old json file for SaveData Migration."); - } - catch (Exception) - { - api.Logger.Error($"[WolfKillCounter] - Error: File not deleted! Make sure the JSON file is manually deleted.\n"); - } + // Fresh WolfKillData + data = new WolfKillData() { }; - WolfKillData loadData = new WolfKillData() - { - NewKillCounts = wolfKillCount, - Leaderboard = currentLeaderboard, - TotalKills = totalWolfKillCount, - ServerKillGoal = serverKillGoal - }; + // Store the fresh data + api.WorldManager.SaveGame.StoreData("wolfkilldata", data); + api.Logger.Notification("[WolfKillCounter]: Created new save data in SaveGame"); api.Logger.Notification("[WolfKillCounter]: Save Loaded."); - return loadData; - + return; } + // New SaveGame format if data exists already, get and load the data - else if (api.WorldManager.SaveGame.GetData("wolfkilldata") is Byte[] rawData) - { - // Read raw JSON from the file - rawData = api.WorldManager.SaveGame.GetData("wolfkilldata"); - // Replace the line causing the error with the following line - WolfKillData parsedData = rawData == null ? new WolfKillData() : SerializerUtil.Deserialize(rawData); - - // Load TotalKills and ServerKillGoal - var totalWolfKillCount = parsedData.TotalKills; - var serverKillGoal = parsedData.ServerKillGoal; + // Read raw JSON from the file + byte[] rawData = api.WorldManager.SaveGame.GetData("wolfkilldata"); + // Replace the line causing the error with the following line + WolfKillData parsedData = rawData == null ? new WolfKillData() : SerializerUtil.Deserialize(rawData); - // Load Leaderboard - var currentLeaderboard = parsedData.Leaderboard; - - // Load KillCounts with backward compatibility for the old format - var wolfKillCount = parsedData.NewKillCounts; - - var loadData = new WolfKillData() - { - NewKillCounts = wolfKillCount, - Leaderboard = currentLeaderboard, - TotalKills = totalWolfKillCount, - ServerKillGoal = serverKillGoal - }; - - api.Logger.Notification("[WolfKillCounter]: Save Loaded."); - return loadData; - } - // No SaveGame data exists, create new save data - else + data = new WolfKillData() { - // Fresh WolfKillData - var loadData = new WolfKillData() - { - NewKillCounts = new Dictionary(), - Leaderboard = new Dictionary(), - TotalKills = 0, - ServerKillGoal = 100 - }; + NewKillCounts = parsedData.NewKillCounts, + Leaderboard = parsedData.Leaderboard, + TotalKills = parsedData.TotalKills, + ServerKillGoal = parsedData.ServerKillGoal, + }; - // Store the fresh data - api.WorldManager.SaveGame.StoreData("wolfkilldata", loadData); - api.Logger.Notification("[WolfKillCounter]: Created new save data in SaveGame"); - - api.Logger.Notification("[WolfKillCounter]: Save Loaded."); - return loadData; - } + api.Logger.Notification("[WolfKillCounter]: Save Loaded."); } // Save the current kill data to the json file - public void SaveWolfKillData(ICoreServerAPI api) + public void SaveWolfKillData() { WolfKillCounterModSystem modSystem = api.ModLoader.GetModSystem(); diff --git a/WolfKillCounter/WolfKillCounter.csproj b/WolfKillCounter/WolfKillCounter.csproj index b210d75..fde520a 100644 --- a/WolfKillCounter/WolfKillCounter.csproj +++ b/WolfKillCounter/WolfKillCounter.csproj @@ -1,7 +1,7 @@  - net7.0 + net10.0 false bin\$(Configuration)\Mods\mod diff --git a/WolfKillCounter/WolfKillCounterModSystem.cs b/WolfKillCounter/WolfKillCounterModSystem.cs index 32c5db6..af854dd 100644 --- a/WolfKillCounter/WolfKillCounterModSystem.cs +++ b/WolfKillCounter/WolfKillCounterModSystem.cs @@ -1,19 +1,12 @@ -using Microsoft.Win32.SafeHandles; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json; -using System; -using System.Collections; +using System; using System.Collections.Generic; using System.Linq; -using Vintagestory.API.Client; using Vintagestory.API.Common; using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; using Vintagestory.API.Server; -using static System.Runtime.InteropServices.JavaScript.JSType; -using Vintagestory.API.Util; -using ProtoBuf; using WolfKillCounter.Config; +using WolfKillCounter.Commands; namespace WolfKillCounter { @@ -24,14 +17,7 @@ public class WolfKillCounterModSystem : ModSystem private ICoreServerAPI sapi; IServerNetworkChannel serverChannel; WolfKillCounterConfig config; - - // List of players and their total wolf kills from the first startup of this mod. - Dictionary wolfKillCount = new Dictionary(); - Dictionary currentLeaderboard = new Dictionary(); - int totalWolfKillCount = 0; - - // Server kill goal - int serverKillGoal = 0; + public WolfKillData Data; // Called on server and client // Useful for registering block/entity classes on both sides @@ -45,17 +31,19 @@ public override void StartServerSide(ICoreServerAPI api) Mod.Logger.Notification(": " + Lang.Get("wolfkillcounter:version")); sapi = api; // Get ModSystem Config - config = new WolfKillCounterConfig(); + config = new WolfKillCounterConfig(api); - config.LoadWolfKillData(sapi); - LoadLeaderboard(); + config.LoadWolfKillData(ref Data); + //LoadLeaderboard(); // Add function handler to trigger (function call) when an entity dies. api.Event.OnEntityDeath += OnEntityDeath; api.Event.PlayerJoin += OnPlayerJoin; // Update the event subscription to use a lambda function that calls the LoadWolfKillData method - api.Event.SaveGameLoaded += () => config.LoadWolfKillData(sapi); - api.Event.GameWorldSave += () => config.SaveWolfKillData(sapi); + //api.Event.SaveGameLoaded += config.LoadWolfKillData; + api.Event.GameWorldSave += config.SaveWolfKillData; + + Commands.Commands.RegisterCommands(api); } //public override void StartClientSide(ICoreClientAPI api) @@ -77,7 +65,7 @@ private void OnEntityDeath(Entity entity, DamageSource source) return; } - totalWolfKillCount++; + Data.TotalKills++; string playerName = null; EntityPlayer sourcePlayer = null; @@ -94,37 +82,37 @@ private void OnEntityDeath(Entity entity, DamageSource source) if (playerName != null) { - if (wolfKillCount.ContainsKey(playerName)) + if (Data.NewKillCounts.TryGetValue(playerName, out var count)) { - wolfKillCount[playerName].Kills++; - if (currentLeaderboard.ContainsKey(playerName)) + count.Kills++; + if (Data.Leaderboard.ContainsKey(playerName)) { - currentLeaderboard[playerName]++; + Data.Leaderboard[playerName]++; } else { - currentLeaderboard.Add(playerName, 1); + Data.Leaderboard.Add(playerName, 1); } } else { - wolfKillCount.Add(playerName, new KillCountData { Kills = 1, Goal = 50, Deaths = 0 }); - currentLeaderboard.Add(playerName, 1); + Data.NewKillCounts.Add(playerName, new KillCountData { Kills = 1, Goal = 50, Deaths = 0 }); + Data.Leaderboard.Add(playerName, 1); } // Check if the server kill goal has been reached and broadcast a message to all players. - if (totalWolfKillCount == serverKillGoal) + if (Data.TotalKills == Data.ServerKillGoal) { - BroadcastMessage(ServerKillGoal(serverKillGoal * 2)); - serverKillGoal *= 2; + BroadcastMessage(ServerKillGoal(Data.ServerKillGoal * 2)); + Data.ServerKillGoal *= 2; } // Check if the player has reached their personal kill goal and broadcast a message to all players. - if (wolfKillCount[playerName].Kills == wolfKillCount[playerName].Goal) + if (Data.NewKillCounts[playerName].Kills == Data.NewKillCounts[playerName].Goal) { - int newGoal = CalculateGoal(wolfKillCount[playerName].Goal); + int newGoal = CalculateGoal(Data.NewKillCounts[playerName].Goal); BroadcastMessage(PlayerKillGoal(playerName, newGoal), sourcePlayer?.Player); - wolfKillCount[playerName].Goal *= 2; + Data.NewKillCounts[playerName].Goal *= 2; } } @@ -134,18 +122,18 @@ private void OnEntityDeath(Entity entity, DamageSource source) { string playerName = player.Player.PlayerName; - Mod.Logger.Notification("" + wolfKillCount[playerName].Deaths); + Mod.Logger.Notification("" + Data.NewKillCounts[playerName].Deaths); Mod.Logger.Notification($"{playerName} has died to a Wolf! Skill Issue.\n"); - Mod.Logger.Notification($"Total deaths to wolves: {wolfKillCount[playerName].Deaths}"); + Mod.Logger.Notification($"Total deaths to wolves: {Data.NewKillCounts[playerName].Deaths}"); // Ensure the player is in the wolfKillCount dictionary - if (!wolfKillCount.ContainsKey(playerName)) + if (!Data.NewKillCounts.ContainsKey(playerName)) { - wolfKillCount.Add(playerName, new KillCountData { Kills = 0, Goal = 50, Deaths = 0 }); + Data.NewKillCounts.Add(playerName, new KillCountData { Kills = 0, Goal = 50, Deaths = 0 }); } // Check if the death was caused by a wolf - wolfKillCount[playerName].Deaths++; - Mod.Logger.Notification($"{playerName} has died to a Wolf! Skill Issue. Total deaths to wolves: {wolfKillCount[playerName].Deaths}"); + Data.NewKillCounts[playerName].Deaths++; + Mod.Logger.Notification($"{playerName} has died to a Wolf! Skill Issue. Total deaths to wolves: {Data.NewKillCounts[playerName].Deaths}"); } } catch (Exception ex) @@ -159,9 +147,9 @@ private void OnPlayerJoin(IServerPlayer player) // Check if the player is already in the wolfKillCount dictionary string playerName = player.PlayerName; - if (!wolfKillCount.ContainsKey(playerName)) + if (!Data.NewKillCounts.ContainsKey(playerName)) { - wolfKillCount.Add(playerName, new KillCountData { Kills = 0, Goal = 50, Deaths = 0 }); + Data.NewKillCounts.Add(playerName, new KillCountData { Kills = 0, Goal = 50, Deaths = 0 }); Mod.Logger.Notification($"{playerName} has been added to the Dictionary.\n"); } } @@ -184,35 +172,36 @@ public string CalculateKD(KillCountData KDlist) // If the player has not died to a wolf yet, no KD. if (KDlist.Deaths == 0) { - return "∞"; + return "INFINITE"; } kd = ((double) KDlist.Kills / (double) KDlist.Deaths); return System.String.Format("{0:F2}", kd); } - private void LoadLeaderboard() - { - if (sapi.LoadModConfig("wolfkills.json") is WolfKillData data) - { - currentLeaderboard = data.Leaderboard ?? wolfKillCount - .OrderByDescending(x => x.Value.Kills) // Use kills (index 0) for sorting - .Take(5) - .ToDictionary(x => x.Key, x => x.Value.Kills); // Use kills (index 0) as value - sapi.Logger.Notification("WolfKillCounter: Loaded saved leaderboard data."); - } - else - { - currentLeaderboard = new Dictionary(); - sapi.Logger.Notification("WolfKillCounter: No existing leaderboard data found. Starting fresh."); - } - } + // Likely unnecessary now, but commented out just in case. + // private void LoadLeaderboard() + // { + // if (sapi.LoadModConfig("wolfkills.json") is WolfKillData data) + // { + // currentLeaderboard = data.Leaderboard ?? wolfKillCount + // .OrderByDescending(x => x.Value.Kills) // Use kills (index 0) for sorting + // .Take(5) + // .ToDictionary(x => x.Key, x => x.Value.Kills); // Use kills (index 0) as value + // sapi.Logger.Notification("WolfKillCounter: Loaded saved leaderboard data."); + // } + // else + // { + // currentLeaderboard = new Dictionary(); + // sapi.Logger.Notification("WolfKillCounter: No existing leaderboard data found. Starting fresh."); + // } + // } // Function to check if total server kills reached a certain point private string ServerKillGoal(int newGoal) { string message = " *** WOLF SLAYERS UNITE! ***\n"; message += " -----------------------------------\n"; - message += $"| {serverKillGoal} reached! |\n"; + message += $"| {Data.ServerKillGoal} reached! |\n"; message += "| Server Pack Triumphs! |\n"; message += $"| New server goal: {newGoal} kills! |\n"; message += " -----------------------------------\n"; @@ -253,24 +242,24 @@ private void BroadcastMessage(string message, IPlayer player) // Function to add a player to the dictionary public void AddPlayer(string playerName, KillCountData data) { - if (!wolfKillCount.ContainsKey(playerName)) + if (!Data.NewKillCounts.ContainsKey(playerName)) { - wolfKillCount.Add(playerName, data); + Data.NewKillCounts.Add(playerName, data); Mod.Logger.Notification($"{playerName} has been added to the Dictionary.\n"); } } // Getters for External use - public Dictionary GetWolfKillCount() { return wolfKillCount; } - public Dictionary GetCurrentLeaderboard() { return currentLeaderboard; } - public int GetTotalWolfKillCount() { return totalWolfKillCount; } - public int GetServerKillGoal() { return serverKillGoal; } + public Dictionary GetWolfKillCount() { return Data.NewKillCounts; } + public Dictionary GetCurrentLeaderboard() { return Data.Leaderboard; } + public int GetTotalWolfKillCount() { return Data.TotalKills; } + public int GetServerKillGoal() { return Data.ServerKillGoal; } public WolfKillCounterConfig GetConfig() { return config; } // Setters for External use - public void SetWolfKillCount(Dictionary newWolfKillCount) { wolfKillCount = newWolfKillCount; } - public void SetCurrentLeaderboard(Dictionary newLeaderboard) { currentLeaderboard = newLeaderboard; } - public void SetTotalWolfKillCount(int newTotalWolfKillCount) { totalWolfKillCount = newTotalWolfKillCount; } - public void SetServerKillGoal(int newServerKillGoal) { serverKillGoal = newServerKillGoal; } + public void SetWolfKillCount(Dictionary newWolfKillCount) { Data.NewKillCounts = newWolfKillCount; } + public void SetCurrentLeaderboard(Dictionary newLeaderboard) { Data.Leaderboard = newLeaderboard; } + public void SetTotalWolfKillCount(int newTotalWolfKillCount) { Data.TotalKills = newTotalWolfKillCount; } + public void SetServerKillGoal(int newServerKillGoal) { Data.ServerKillGoal = newServerKillGoal; } } } diff --git a/ZZCakeBuild/CakeBuild.csproj b/ZZCakeBuild/CakeBuild.csproj index 8e2c970..e1c1a90 100644 --- a/ZZCakeBuild/CakeBuild.csproj +++ b/ZZCakeBuild/CakeBuild.csproj @@ -1,7 +1,7 @@ Exe - net7.0 + net10.0 $(MSBuildProjectDirectory)