From 0f318a9efa586238747311b74b068317711cd543 Mon Sep 17 00:00:00 2001 From: zontreck Date: Sat, 18 Jan 2025 02:59:24 -0700 Subject: [PATCH] Add spawn related commands and data storage system --- AriasServerUtils/ASUModSystem.cs | 85 ++++++++++++++++++- AriasServerUtils/EventHandler.cs | 52 ++++++++++++ AriasServerUtils/ModConfig.cs | 17 ++++ AriasServerUtils/PlayerData.cs | 45 ++++++++++ .../Properties/launchSettings.json | 8 +- .../assets/ariasserverutils/lang/en.json | 9 +- AriasServerUtils/modinfo.json | 4 +- 7 files changed, 211 insertions(+), 9 deletions(-) create mode 100644 AriasServerUtils/EventHandler.cs create mode 100644 AriasServerUtils/ModConfig.cs create mode 100644 AriasServerUtils/PlayerData.cs diff --git a/AriasServerUtils/ASUModSystem.cs b/AriasServerUtils/ASUModSystem.cs index 0bd3fb5..dd3405b 100644 --- a/AriasServerUtils/ASUModSystem.cs +++ b/AriasServerUtils/ASUModSystem.cs @@ -1,13 +1,20 @@ -using Vintagestory.API.Client; +using System; +using System.IO; +using Vintagestory.API.Client; using Vintagestory.API.Common; +using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; using Vintagestory.API.Server; +using Vintagestory.GameContent; -namespace ServerUtilities +namespace AriasServerUtils { public class ServerUtilities : ModSystem { public static string MOD_ID = "ariasserverutils"; + public static ASUModConfig config = new ASUModConfig(); + private static ICoreServerAPI API; + private static bool bDirty = false; /// /// Method to register all mod blocks @@ -35,16 +42,90 @@ namespace ServerUtilities RegisterBlocks(api); RegisterBlockEntities(api); + } public override void StartServerSide(ICoreServerAPI api) { + API = api; api.Logger.Notification(Lang.Get($"{MOD_ID}:start")); + + api.Event.ServerRunPhase(EnumServerRunPhase.GameReady, OnGameReady); + api.Event.ServerRunPhase(EnumServerRunPhase.Shutdown, OnShutdown); + api.Event.Timer(OnCheckModDirty, 20); + + api.ChatCommands.Create("setspawn").RequiresPrivilege(Privilege.controlserver).HandleWith(Events.HandleSetSpawn); + api.ChatCommands.Create("spawn").RequiresPrivilege(Privilege.chat).HandleWith(Events.HandleSpawn); + api.ChatCommands.Create("delspawn").RequiresPrivilege(Privilege.controlserver).HandleWith(Events.HandleClearSpawn); + } + + private void OnCheckModDirty() + { + if (bDirty) + { + //API.Logger.Notification(Lang.Get($"{MOD_ID}:timer")); + bDirty = false; + SaveGlobalConfig(); + } + } + + private void OnShutdown() + { + // Mod Shutdown // + // Handle any remaining tasks before shutdown + OnCheckModDirty(); + } + + public void SaveGlobalConfig() + { + API.StoreModConfig(config, GetConfigurationFile("", ModConfigType.Global)); + } + + private void OnGameReady() + { + // Mod Setup Info // + // -> Step 1. Load Mod Global Config <- + + config = API.LoadModConfig(GetConfigurationFile("", ModConfigType.Global)); + if (config == null) config = new ASUModConfig(); + } + + public string GetConfigurationFile(string sName, ModConfigType type) + { + if (type == ModConfigType.Global) + { + return "ariaserverconfig/global.json"; + } + else if (type == ModConfigType.World) + { + return $"ariaserverconfig/{GetWorldName()}/{sName}.json"; + } + else return $"ariaserverconfig/global.json"; + } + + /// + /// This function is used to mark the mod's global config, and all loaded player configs as dirty. They will be flushed to disk, then the dirty flag will be cleared. + /// + public static void MarkDirty() + { + bDirty = true; + } + + public string GetWorldName() + { + string[] lName = API.WorldManager.CurrentWorldName.Split(Path.DirectorySeparatorChar); + string sName = lName[lName.Length - 1]; + return sName.Substring(0, sName.Length - 6); } public override void StartClientSide(ICoreClientAPI api) { api.Logger.Notification(Lang.Get($"{MOD_ID}:start")); } + + public static void SendMessageTo(IServerPlayer player, string sMsg) + { + player.SendMessage(0, sMsg, EnumChatType.CommandSuccess); + } } } diff --git a/AriasServerUtils/EventHandler.cs b/AriasServerUtils/EventHandler.cs new file mode 100644 index 0000000..9b07682 --- /dev/null +++ b/AriasServerUtils/EventHandler.cs @@ -0,0 +1,52 @@ +using System; +using Vintagestory.API.Common; +using Vintagestory.API.Config; +using Vintagestory.API.Server; + +namespace AriasServerUtils +{ + public class Events + { + internal static TextCommandResult HandleClearSpawn(TextCommandCallingArgs args) + { + ServerUtilities.config.Spawn = null; + ServerUtilities.MarkDirty(); + + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:rmspawn")); + } + + internal static TextCommandResult HandleSetSpawn(TextCommandCallingArgs args) + { + PlayerPosition pos = PlayerPosition.from(args.Caller.Entity); + ServerUtilities.config.Spawn = pos; + if (args.Caller.Player is IServerPlayer isp) + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:setspawn")); + + ServerUtilities.MarkDirty(); + + return TextCommandResult.Success(); + } + + internal static TextCommandResult HandleSpawn(TextCommandCallingArgs args) + { + if (ServerUtilities.config.Spawn == null) + { + if (args.Caller.Player is IServerPlayer isp) + { + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:spawn-not-set")); + } + } + else + { + if (args.Caller.Player is IServerPlayer isp) + { + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:tp-spawn")); + + ServerUtilities.config.Spawn.Merge(args.Caller.Player.Entity); + } + } + + return TextCommandResult.Success(); + } + } +} \ No newline at end of file diff --git a/AriasServerUtils/ModConfig.cs b/AriasServerUtils/ModConfig.cs new file mode 100644 index 0000000..eb5915b --- /dev/null +++ b/AriasServerUtils/ModConfig.cs @@ -0,0 +1,17 @@ +using System; + +namespace AriasServerUtils +{ + public enum ModConfigType + { + Global, + World + } + + [Serializable] + public class ASUModConfig + { + public int MaxHomes { get; set; } = 20; + public PlayerPosition Spawn { get; set; } + } +} \ No newline at end of file diff --git a/AriasServerUtils/PlayerData.cs b/AriasServerUtils/PlayerData.cs new file mode 100644 index 0000000..4bc8108 --- /dev/null +++ b/AriasServerUtils/PlayerData.cs @@ -0,0 +1,45 @@ +using System; +using Vintagestory.API.Common.Entities; +using Vintagestory.API.MathTools; + +namespace AriasServerUtils +{ + [Serializable] + public class PlayerPosition + { + public int X { get; set; } = 0; + public int Y { get; set; } = 0; + public int Z { get; set; } = 0; + public int Dimension { get; set; } = 0; + + public float Yaw { get; set; } = 0.0f; + + + public void Merge(Entity entity) + { + entity.TeleportTo(new BlockPos(X, Y, Z, Dimension)); + entity.Pos.SetYaw(Yaw); + } + + + /// + /// Generates a PlayerPosition object using a entity. + /// + /// A player entity + /// PlayerPos snapshot object of the entity + public static PlayerPosition from(Entity entity) + { + PlayerPosition pos = new PlayerPosition(); + + BlockPos playerPos = entity.Pos.AsBlockPos; + pos.X = playerPos.X; + pos.Y = playerPos.Y; + pos.Z = playerPos.Z; + pos.Dimension = playerPos.dimension; + + pos.Yaw = entity.Pos.Yaw; + + return pos; + } + } +} \ No newline at end of file diff --git a/AriasServerUtils/Properties/launchSettings.json b/AriasServerUtils/Properties/launchSettings.json index 9f0cd9b..8ba4701 100644 --- a/AriasServerUtils/Properties/launchSettings.json +++ b/AriasServerUtils/Properties/launchSettings.json @@ -2,15 +2,15 @@ "profiles": { "Client": { "commandName": "Executable", - "executablePath": "$(VINTAGE_STORY)/Vintagestory.exe", + "executablePath": "~/.local/share/vintagestory/Vintagestory", "commandLineArgs": "--tracelog --addModPath \"$(ProjectDir)/bin/$(Configuration)/Mods\"", - "workingDirectory": "$(VINTAGE_STORY)" + "workingDirectory": "~/.local/share/vintagestory" }, "Server": { "commandName": "Executable", - "executablePath": "$(VINTAGE_STORY)/VintagestoryServer.exe", + "executablePath": "~/.local/share/vintagestory/VintagestoryServer", "commandLineArgs": "--tracelog --addModPath \"$(ProjectDir)/bin/$(Configuration)/Mods\"", - "workingDirectory": "$(VINTAGE_STORY)" + "workingDirectory": "~/.local/share/vintagestory" } } } diff --git a/AriasServerUtils/assets/ariasserverutils/lang/en.json b/AriasServerUtils/assets/ariasserverutils/lang/en.json index 0967ef4..9152f36 100644 --- a/AriasServerUtils/assets/ariasserverutils/lang/en.json +++ b/AriasServerUtils/assets/ariasserverutils/lang/en.json @@ -1 +1,8 @@ -{} +{ + "setspawn": "Spawn location set successfully.", + "timer": "[DEBUG] timer executed", + + "spawn-not-set": "A world spawn location is not currently set", + "tp-spawn": "Teleported to spawn", + "rmspawn": "World Spawn cleared. The /spawn command will now be non-functional until a new spawn is set" +} diff --git a/AriasServerUtils/modinfo.json b/AriasServerUtils/modinfo.json index 074c663..1b97d54 100644 --- a/AriasServerUtils/modinfo.json +++ b/AriasServerUtils/modinfo.json @@ -3,8 +3,8 @@ "modid": "ariasserverutils", "name": "Aria's Server Utilities", "authors": ["zontreck"], - "description": "A collection of server utilities\n\nBuild Date: 01-17-2025 @ 03:12 PM", - "version": "1.0.0-dev.1", + "description": "A collection of server utilities\n\nBuild Date: 01-18-2025 @ 02:58 AM", + "version": "1.0.0-dev.2", "dependencies": { "game": "" }