diff --git a/AriasServerUtils/EventHandler.cs b/AriasServerUtils/EventHandler.cs index 1b5a646..6869045 100644 --- a/AriasServerUtils/EventHandler.cs +++ b/AriasServerUtils/EventHandler.cs @@ -7,6 +7,7 @@ using Vintagestory.API.Config; using Vintagestory.API.MathTools; using Vintagestory.API.Server; using Vintagestory.API.Util; +using Vintagestory.GameContent; namespace AriasServerUtils { @@ -274,7 +275,7 @@ namespace AriasServerUtils { ServerUtilities.config.AdminsBypassMaxHomes = bypass; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", bypass)); } return TextCommandResult.Success(); @@ -288,7 +289,7 @@ namespace AriasServerUtils ServerUtilities.config.MaxBackCache = max; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", max)); } return TextCommandResult.Success(); @@ -301,7 +302,7 @@ namespace AriasServerUtils ServerUtilities.config.MaxHomes = maxHomes; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", maxHomes)); } return TextCommandResult.Success(); @@ -310,19 +311,32 @@ namespace AriasServerUtils internal static TextCommandResult HandleUpdateASUMgrWarps(TextCommandCallingArgs args) { if (args[0] is bool mgr) + { ServerUtilities.config.onlyAdminsCreateWarps = mgr; + + ServerUtilities.MarkDirty(); + + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", mgr)); + } else ServerUtilities.config.onlyAdminsCreateWarps = true; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + + + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", true)); } internal static TextCommandResult HandleUpdateASUPSP(TextCommandCallingArgs args) { - if (args[0] is int psp) ServerUtilities.config.PlayerSleepingPercentage = psp; - ServerUtilities.MarkDirty(); + if (args[0] is int psp) + { + ServerUtilities.config.PlayerSleepingPercentage = psp; + ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", psp)); + } + + return TextCommandResult.Success(); } internal static TextCommandResult HandleWarp(TextCommandCallingArgs args) @@ -344,7 +358,7 @@ namespace AriasServerUtils ServerUtilities.NewBackCacheForPlayer(isp); ServerUtilities.serverWarps.warps[name].Location.Merge(isp.Entity); - ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-set", name)); + ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-tp", name)); @@ -430,7 +444,7 @@ namespace AriasServerUtils ServerUtilities.config.MaxRTPBlockDistance = maxDist; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", maxDist)); } return TextCommandResult.Success(); @@ -443,7 +457,7 @@ namespace AriasServerUtils ServerUtilities.config.Cooldowns[CooldownType.Back] = CD; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { @@ -461,7 +475,7 @@ namespace AriasServerUtils ServerUtilities.config.Cooldowns[CooldownType.Warp] = CD; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { @@ -479,7 +493,7 @@ namespace AriasServerUtils ServerUtilities.config.Cooldowns[CooldownType.Home] = CD; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { @@ -497,7 +511,7 @@ namespace AriasServerUtils ServerUtilities.config.Cooldowns[CooldownType.Spawn] = CD; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { @@ -515,7 +529,7 @@ namespace AriasServerUtils ServerUtilities.config.Cooldowns[CooldownType.RTP] = CD; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { @@ -541,7 +555,7 @@ namespace AriasServerUtils // Update the bypass ServerUtilities.config.AdminsBypassCooldowns = bypass; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", bypass)); } else return TextCommandResult.Success(); } @@ -553,11 +567,43 @@ namespace AriasServerUtils // Update the flag ServerUtilities.config.AdminsBypassRTPMaxDistance = bypass; ServerUtilities.MarkDirty(); - return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig")); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", bypass)); } else return TextCommandResult.Success(); } + + internal static TextCommandResult HandleUpdateASUFarmlandDowngrade(TextCommandCallingArgs args) + { + if (args[0] is bool downgrade) + { + // Update the flag + ServerUtilities.config.EnableFarmlandDowngrade = downgrade; + ServerUtilities.MarkDirty(); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", downgrade)); + } + else + { + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:farmland-downgrade", ServerUtilities.config.EnableFarmlandDowngrade)); + } + } + + + internal static TextCommandResult HandleUpdateASUFarmlandDrop(TextCommandCallingArgs args) + { + if (args[0] is bool drop) + { + // Update the flag + ServerUtilities.config.EnableFarmlandDrop = drop; + ServerUtilities.MarkDirty(); + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", drop)); + } + else + { + return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:farmland-drop", ServerUtilities.config.EnableFarmlandDrop)); + } + } + internal static TextCommandResult HandleListCooldowns(TextCommandCallingArgs args) { string sReturn = "SERVER COOLDOWN SETTINGS\n"; @@ -577,5 +623,63 @@ namespace AriasServerUtils } return TextCommandResult.Success(sReturn); } + + internal static TextCommandResult HandleSleepyDebug(TextCommandCallingArgs args) + { + EntityBehaviorTiredness sleepy = args.Caller.Entity.GetBehavior(); + if (sleepy != null) + { + sleepy.Tiredness = 100; + } + return TextCommandResult.Success(); + } + + internal static void CheckBreakFarmland(IServerPlayer byPlayer, BlockSelection blockSel, ref float dropQuantityMultiplier, ref EnumHandling handling) + { + if (!ServerUtilities.config.EnableFarmlandDrop) + { + return; // Default behavior + } + + if (blockSel.Block is BlockFarmland farmland) + { + BlockEntityFarmland beFarmland = farmland.GetBlockEntity(blockSel.Position); + string farmlandType = blockSel.Block.LastCodePart(); + + if (ServerUtilities.config.EnableFarmlandDowngrade) + { + + switch (farmlandType) + { + case "verylow": + { // barren + break; // Can't downgrade further + } + case "low": + { + farmlandType = "verylow"; + break; + } + case "medium": + { + farmlandType = "low"; + break; + } + case "compost": + { // high + farmlandType = "medium"; + break; + } + case "high": + { // Terra preta + farmlandType = "compost"; + break; + } + } + } + + byPlayer.Entity.World.SpawnItemEntity(new ItemStack(byPlayer.Entity.World.GetBlock(new AssetLocation($"soil-{farmlandType}-none"))), blockSel.Position.ToVec3d().Add(0.5, 0.5, 0.5)); + } + } } } \ No newline at end of file diff --git a/AriasServerUtils/Globals.cs b/AriasServerUtils/Globals.cs index a98b5cc..3436bbf 100644 --- a/AriasServerUtils/Globals.cs +++ b/AriasServerUtils/Globals.cs @@ -22,7 +22,7 @@ namespace AriasServerUtils { CooldownType.RTP, "30s" }, { CooldownType.Back, "5s" } }; - private static readonly int CURRENT_VERSION = 5; + private static readonly int CURRENT_VERSION = 6; public int Version { get; set; } = 0; @@ -36,11 +36,25 @@ namespace AriasServerUtils public int MaxRTPBlockDistance { get; set; } = 50000; public Dictionary Cooldowns { get; set; } = new Dictionary(); + + /// + /// If true, attempts to downgrade the soil quality when breaking farmland. + /// + public bool EnableFarmlandDowngrade { get; set; } = false; + + /// + /// If true, farmland will drop as soil when broken. + /// + public bool EnableFarmlandDrop { get; set; } = true; + public Dictionary GetDefaultCooldowns() { return m_defaultCD; } + /// + /// Performs some checks against known possible invalid values and sets them to sane values. + /// public void SanityCheck() { foreach (var cd in GetDefaultCooldowns()) diff --git a/AriasServerUtils/ModSystems/ASUClient.cs b/AriasServerUtils/ModSystems/ASUClient.cs new file mode 100644 index 0000000..2966dc3 --- /dev/null +++ b/AriasServerUtils/ModSystems/ASUClient.cs @@ -0,0 +1,19 @@ +using System; +using Vintagestory.API.Client; +using Vintagestory.API.Common; + +public class ASUModClient : ModSystem +{ + public static ICoreClientAPI CAPI; + bool accel = false; + + public override bool ShouldLoad(EnumAppSide forSide) + { + return forSide == EnumAppSide.Client; + } + + public override void StartClientSide(ICoreClientAPI api) + { + CAPI = api; + } +} \ No newline at end of file diff --git a/AriasServerUtils/ASUModSystem.cs b/AriasServerUtils/ModSystems/ASUServer.cs similarity index 70% rename from AriasServerUtils/ASUModSystem.cs rename to AriasServerUtils/ModSystems/ASUServer.cs index e2775d2..36a590d 100644 --- a/AriasServerUtils/ASUModSystem.cs +++ b/AriasServerUtils/ModSystems/ASUServer.cs @@ -7,6 +7,7 @@ using Vintagestory.API.Common; using Vintagestory.API.Common.CommandAbbr; using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; +using Vintagestory.API.Datastructures; using Vintagestory.API.MathTools; using Vintagestory.API.Server; using Vintagestory.API.Util; @@ -28,6 +29,7 @@ namespace AriasServerUtils internal static Warps serverWarps = new Warps(); internal static Random rng = new Random((int)TimeUtil.GetUnixEpochTimestamp()); + internal bool isFirstStart = true; internal static string[] saveInvTypes = new string[] { @@ -38,6 +40,12 @@ namespace AriasServerUtils GlobalConstants.characterInvClassName }; + List SleepingPlayers { get; set; } = new(); + float OriginalSpeed { get; set; } = 0.0f; + public double Hours { get; private set; } = 0.0; + bool Sleeping { get; set; } = false; + public IServerNetworkChannel ServerNetworkChannel { get; private set; } + /// /// Method to register all mod blocks /// @@ -56,6 +64,14 @@ namespace AriasServerUtils { } + + public override bool ShouldLoad(EnumAppSide side) + { + return side == EnumAppSide.Server; + } + + + // Called on server and client public override void Start(ICoreAPI api) { @@ -74,13 +90,11 @@ namespace AriasServerUtils api.Event.ServerRunPhase(EnumServerRunPhase.GameReady, OnGameReady); api.Event.ServerRunPhase(EnumServerRunPhase.Shutdown, OnShutdown); - api.Event.Timer(OnCheckModDirty, 20); - api.Event.Timer(OnCheckPlayerCooldowns, 1); - api.Event.Timer(RTPFactory.HandleRTPChecking, 1); api.Event.PlayerDeath += OnPlayerDeath; api.Event.PlayerJoin += OnPlayerJoin; api.Event.PlayerDisconnect += OnPlayerDC; api.Event.ChunkColumnLoaded += RTPFactory.ChunkLoaded; + api.Event.BreakBlock += Events.CheckBreakFarmland; //api.Event.PlayerLeave += OnPlayerDC; @@ -168,6 +182,18 @@ namespace AriasServerUtils .WithDescription("Update RTP Max block distance. Plus and/or minus this distance from player current position (Default is 50000)") .HandleWith(Events.HandleUpdateASURTPMax) .EndSubCommand() + .BeginSubCommand("farmlandDowngrade") + .RequiresPrivilege(Privilege.controlserver) + .WithArgs(parsers.OptionalBool("downgrade")) + .WithDescription("Enables or disables farmland downgrade when breaking farmland") + .HandleWith(Events.HandleUpdateASUFarmlandDowngrade) + .EndSubCommand() + .BeginSubCommand("farmlandDrop") + .RequiresPrivilege(Privilege.controlserver) + .WithArgs(parsers.OptionalBool("drop")) + .WithDescription("Enables or disables dropping soil when breaking farmland") + .HandleWith(Events.HandleUpdateASUFarmlandDrop) + .EndSubCommand() .BeginSubCommand("cooldowns") .WithDescription("Commands related to all the various cooldowns") .BeginSubCommand("back") @@ -221,6 +247,20 @@ namespace AriasServerUtils .RequiresPrivilege(Privilege.chat) .HandleWith(Events.HandleASU) .WithDescription("Lists all Aria's Server Utils commands") + .EndSubCommand() + .BeginSubCommand("test") + .RequiresPlayer() + .RequiresPrivilege(Privilege.controlserver) + .BeginSubCommand("sleep") + .RequiresPlayer() + .RequiresPrivilege(Privilege.controlserver) + .HandleWith(TestSleep) + .EndSubCommand() + .BeginSubCommand("sleepy") + .RequiresPlayer() + .RequiresPrivilege(Privilege.controlserver) + .HandleWith(Events.HandleSleepyDebug) + .EndSubCommand() .EndSubCommand(); api.ChatCommands.Create("setwarp").RequiresPlayer().RequiresPrivilege(Privilege.chat).WithDescription("Creates a new server warp").WithArgs(parsers.OptionalWord("name")).HandleWith(Events.HandleWarpUpdate); @@ -235,6 +275,162 @@ namespace AriasServerUtils api.ChatCommands.Create("listcooldowns").RequiresPrivilege(Privilege.chat).WithDescription("Lists the cooldown settings on the server, as well as your own active cooldowns if applicable.").HandleWith(Events.HandleListCooldowns); } + private TextCommandResult TestSleep(TextCommandCallingArgs args) + { + // Initiate the sleep process + // Basically run all the same commands as we would on a player in bed + Events.HandleSleepyDebug(args); + + OriginalSpeed = API.World.Calendar.CalendarSpeedMul; + if (args.Caller.Player is IServerPlayer isp) + { + Hours = API.World.Calendar.TotalHours; + SleepingPlayers.Add(isp.Entity); + API.Logger.Notification($"Game Hours: {API.World.Calendar.TotalHours}, Difference: {API.World.Calendar.TotalHours - Hours}"); + EntityAgent Agent = isp.Entity; + + EntityBehaviorTiredness ebt = Agent.GetBehavior(); + + ebt.IsSleeping = true; + ebt.Tiredness = 100; + Sleeping = true; + + API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); + } + + return TextCommandResult.Success($"Test initiated, original calendar multiplier: '{OriginalSpeed}'"); + } + + private TextCommandResult TestCalendarSpeed(TextCommandCallingArgs args) + { + if (args.Caller.Player is IServerPlayer isp) + { + EntityAgent agent = isp.Entity; + EntityBehaviorTiredness ebt = agent.GetBehavior("tiredness") as EntityBehaviorTiredness; + + SendMessageTo(isp, $"- Current calendar speed: {API.World.Calendar.CalendarSpeedMul}"); + SendMessageTo(isp, $"- Total Hours: {API.World.Calendar.TotalHours}"); + SendMessageTo(isp, $"- Tiredness: {ebt.Tiredness}"); + if (OriginalSpeed == 0) + { + // Apply multiplier + OriginalSpeed = 0.5f; + ebt.IsSleeping = true; + + API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); + + SendMessageTo(isp, "Applied calendar speed multiplier"); + } + else + { + // Unapply multiplier + OriginalSpeed = 0; + ebt.IsSleeping = false; + + API.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); + + SendMessageTo(isp, "Restored default calendar speed"); + } + } + + return TextCommandResult.Success(); + } + + private void OnCheckSleepingPlayers() + { + if (API.Side == EnumAppSide.Client) return; // This must only ever be called on the server! + if (isFirstStart) + { + API.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); + isFirstStart = false; + } + + if (Sleeping) + { + //API.Logger.Notification($"Game Hours: {API.World.Calendar.TotalHours}, Difference: {API.World.Calendar.TotalHours - Hours}"); + if (API.World.Calendar.TotalHours - Hours >= 6) + { + Sleeping = false; + foreach (var player in SleepingPlayers) + { + EntityBehaviorTiredness ebt = player.GetBehavior(); + ebt.IsSleeping = false; + ebt.Tiredness = 0; + } + + SleepingPlayers.Clear(); + + API.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); + + //API.Logger.Notification("Stopping PSP Time Acceleration"); + } + return; + } + if (config.PlayerSleepingPercentage == 100) return; // Normal behavior + // Iterate over all players, get their entity, check if mounted on a bed. + // If mounted on a bed, check tiredness + int TotalOnline = API.World.AllOnlinePlayers.Length; + if (TotalOnline == 0) return; // No one on, just abort the checks. + int TotalInBed = 0; + + List BEBs = new(); + + foreach (var player in API.World.AllOnlinePlayers) + { + EntityAgent ePlay = player.Entity; + if (ePlay.MountedOn is BlockEntityBed beb) + { + BEBs.Add(beb); + TotalInBed++; + //API.Logger.Notification($"Bed found for player {player.PlayerName}"); + } + if (ePlay.MountedOn == null) + { + //API.Logger.Notification($"No bed found for player {player.PlayerName}"); + + if (SleepingPlayers.Contains(ePlay)) + { + EntityBehaviorTiredness ebt = ePlay.GetBehavior(); + if (ebt != null) + ebt.IsSleeping = false; + } + } + } + + if (Sleeping) return; // Abort + + SleepingPlayers.Clear(); + + int Percentage = TotalInBed * 100 / TotalOnline; + + //API.Logger.Notification($"Percentage of players in bed: {Percentage}, Required percentage: {config.PlayerSleepingPercentage}"); + + if (Percentage >= config.PlayerSleepingPercentage) + { + + API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); + + // Call the API to make sleep happen + foreach (var bed in BEBs) + { + if (bed.MountedBy != null) SleepingPlayers.Add(bed.MountedBy); + + // Start sleep + EntityBehaviorTiredness EBT = bed.MountedBy.GetBehavior(); + + EBT.IsSleeping = true; + + //API.Logger.Notification("Starting PSP Time Acceleration"); + + bed.MountedBy.TryUnmount(); // Stand up. We cant trigger the real sleep phase, but all code for starting time accel has been executed. + } + + // Get current calendar speed + Hours = API.World.Calendar.TotalHours; + Sleeping = true; + } + } + private void OnCheckPlayerCooldowns() { foreach (var cdEntry in ServerUtilities.mPlayerData) @@ -395,6 +591,13 @@ namespace AriasServerUtils // -> Step 3. Load Mod Warps <- serverWarps = API.LoadModConfig(GetConfigurationFile("warps", ModConfigType.Global)); if (serverWarps == null) serverWarps = new Warps(); + + + + API.Event.Timer(OnCheckModDirty, 20); + API.Event.Timer(OnCheckPlayerCooldowns, 1); + API.Event.Timer(OnCheckSleepingPlayers, 5); + API.Event.Timer(RTPFactory.HandleRTPChecking, 1); } public string GetConfigurationFile(string sName, ModConfigType type) diff --git a/AriasServerUtils/RTPFactory.cs b/AriasServerUtils/RTPFactory.cs index ef37717..d2544a2 100644 --- a/AriasServerUtils/RTPFactory.cs +++ b/AriasServerUtils/RTPFactory.cs @@ -59,42 +59,6 @@ public class RTPFactory check.Y = height + 1; PPos.Y = height + 1; return PPos; - - int Y = 255; - bool lastBlockAir = true; - bool lastLastBlockAir = true; - bool curBlockAir = true; - bool safe = false; - for (Y = 255; Y > 1; Y--) - { - // Manually scan downwards - check.Y = Y; - var current = BA.GetBlock(check); - - if (current.BlockMaterial != EnumBlockMaterial.Air) - { - curBlockAir = false; - } - - - - lastLastBlockAir = lastBlockAir; - lastBlockAir = curBlockAir; - - - if (!curBlockAir && lastBlockAir && lastLastBlockAir) - { - // We found a safe spot to land - check.Y++; - safe = true; - break; - } - } - - if (!safe) return null; - - PPos.Y = check.Y; - return PPos; } /// diff --git a/AriasServerUtils/assets/ariasserverutils/lang/en.json b/AriasServerUtils/assets/ariasserverutils/lang/en.json index cf23780..7f983a4 100644 --- a/AriasServerUtils/assets/ariasserverutils/lang/en.json +++ b/AriasServerUtils/assets/ariasserverutils/lang/en.json @@ -20,9 +20,12 @@ "help": "All Aria's Server Utilities Commands: \n\nMax Homes: {0}; \nAdmins can bypass max homes: {1}\nMax back positions: {2}\n\n{3}", - "updatedconfig": "[ASU] server config updated", + "updatedconfig": "[ASU] server config updated with the new value: {0}", "config-value-reset": "[ASU] server config value reset to default", + "farmland-downgrade": "The current farmland downgrade setting is {0}", + "farmland-drop": "The current farmland drop setting is {0}", + "warp-tp": "Teleported to warp [{0}]", "warp-set": "Warp [{0}] created!", "warp-no": "You lack permissions to manage a warp", @@ -40,5 +43,8 @@ "rtp-fail": "Giving up on RTP search. No valid position could be found. Try again later", "rtp-capped": "The distance you tried to go [{0}] is greater than the maximum allowable by the server [{1}]", - "cmd-cooldown": "[{0}] is currently on cooldown. You can use this command again in [{1}]" + "cmd-cooldown": "[{0}] is currently on cooldown. You can use this command again in [{1}]", + + "psp": "[ASU] PSP Starting... you do not need to stay in bed", + "psp-ending": "[ASU] PSP Complete" } diff --git a/AriasServerUtils/modinfo.json b/AriasServerUtils/modinfo.json index e8b5349..cc1577f 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: 03-10-2025 @ 12:04 PM MST", - "version": "1.0.6", + "description": "A collection of server utilities\n\nBuild Date: 05-7-2025 @ 12:21 PM MST", + "version": "1.0.11", "dependencies": { "game": "" }