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 index 2f678b3..2966dc3 100644 --- a/AriasServerUtils/ModSystems/ASUClient.cs +++ b/AriasServerUtils/ModSystems/ASUClient.cs @@ -15,20 +15,5 @@ public class ASUModClient : ModSystem public override void StartClientSide(ICoreClientAPI api) { CAPI = api; - api.Network.RegisterChannel("asutimeaccel") - .RegisterMessageType() - .SetMessageHandler(onReceiveTimeAccel); - } - - private void onReceiveTimeAccel(ASUTimeAcceleration packet) - { - // Time acceleration handler - accel = packet.Sleeping; - - if (accel) - { - CAPI.World.Calendar.SetTimeSpeedModifier("asu_psp", 500); - } - else CAPI.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); } } \ No newline at end of file diff --git a/AriasServerUtils/ModSystems/ASUServer.cs b/AriasServerUtils/ModSystems/ASUServer.cs index 31b6bab..36a590d 100644 --- a/AriasServerUtils/ModSystems/ASUServer.cs +++ b/AriasServerUtils/ModSystems/ASUServer.cs @@ -29,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[] { @@ -93,13 +94,10 @@ namespace AriasServerUtils api.Event.PlayerJoin += OnPlayerJoin; api.Event.PlayerDisconnect += OnPlayerDC; api.Event.ChunkColumnLoaded += RTPFactory.ChunkLoaded; + api.Event.BreakBlock += Events.CheckBreakFarmland; //api.Event.PlayerLeave += OnPlayerDC; - ServerNetworkChannel = api.Network.RegisterChannel("asutimeaccel") - .RegisterMessageType(); - - api.ChatCommands.Create("setspawn").RequiresPrivilege(Privilege.controlserver).HandleWith(Events.HandleSetSpawn); api.ChatCommands.Create("spawn").RequiresPrivilege(Privilege.chat).HandleWith(Events.HandleSpawn); @@ -184,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") @@ -238,7 +248,7 @@ namespace AriasServerUtils .HandleWith(Events.HandleASU) .WithDescription("Lists all Aria's Server Utils commands") .EndSubCommand() - /*.BeginSubCommand("test") + .BeginSubCommand("test") .RequiresPlayer() .RequiresPrivilege(Privilege.controlserver) .BeginSubCommand("sleep") @@ -246,12 +256,12 @@ namespace AriasServerUtils .RequiresPrivilege(Privilege.controlserver) .HandleWith(TestSleep) .EndSubCommand() - .BeginSubCommand("calendarspeed") + .BeginSubCommand("sleepy") .RequiresPlayer() .RequiresPrivilege(Privilege.controlserver) - .HandleWith(TestCalendarSpeed) + .HandleWith(Events.HandleSleepyDebug) .EndSubCommand() - .EndSubCommand()*/ ; + .EndSubCommand(); api.ChatCommands.Create("setwarp").RequiresPlayer().RequiresPrivilege(Privilege.chat).WithDescription("Creates a new server warp").WithArgs(parsers.OptionalWord("name")).HandleWith(Events.HandleWarpUpdate); api.ChatCommands.Create("warp").RequiresPlayer().RequiresPrivilege(Privilege.chat).WithDescription("Warp to the specified server warp").WithArgs(parsers.OptionalWord("name")).HandleWith(Events.HandleWarp); @@ -269,23 +279,22 @@ namespace AriasServerUtils { // 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("tiredness") as EntityBehaviorTiredness; + + EntityBehaviorTiredness ebt = Agent.GetBehavior(); + ebt.IsSleeping = true; ebt.Tiredness = 100; Sleeping = true; - - ServerNetworkChannel.BroadcastPacket(new ASUTimeAcceleration - { - Sleeping = true - }); - API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); } @@ -308,11 +317,6 @@ namespace AriasServerUtils OriginalSpeed = 0.5f; ebt.IsSleeping = true; - ServerNetworkChannel.BroadcastPacket(new ASUTimeAcceleration - { - Sleeping = true - }); - API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); SendMessageTo(isp, "Applied calendar speed multiplier"); @@ -323,11 +327,6 @@ namespace AriasServerUtils OriginalSpeed = 0; ebt.IsSleeping = false; - ServerNetworkChannel.BroadcastPacket(new ASUTimeAcceleration - { - Sleeping = false - }); - API.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); SendMessageTo(isp, "Restored default calendar speed"); @@ -340,27 +339,30 @@ namespace AriasServerUtils 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) { - if (API.World.Calendar.TotalHours - Hours >= 7) + //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("tiredness") as EntityBehaviorTiredness; + EntityBehaviorTiredness ebt = player.GetBehavior(); ebt.IsSleeping = false; ebt.Tiredness = 0; } SleepingPlayers.Clear(); - - ServerNetworkChannel.BroadcastPacket(new ASUTimeAcceleration - { - Sleeping = false - }); - API.World.Calendar.RemoveTimeSpeedModifier("asu_psp"); + + //API.Logger.Notification("Stopping PSP Time Acceleration"); } return; } @@ -368,10 +370,9 @@ namespace AriasServerUtils // 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; - bool isAlreadySleeping = false; - List BEBs = new(); foreach (var player in API.World.AllOnlinePlayers) @@ -381,35 +382,32 @@ namespace AriasServerUtils { 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("tiredness") as EntityBehaviorTiredness; + EntityBehaviorTiredness ebt = ePlay.GetBehavior(); if (ebt != null) ebt.IsSleeping = false; } } - - EntityBehaviorTiredness EBT = ePlay.GetBehavior("tiredness") as EntityBehaviorTiredness; - if (EBT == null) continue; - if (EBT.IsSleeping) isAlreadySleeping = true; } - if (isAlreadySleeping) return; // Abort + 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) { - ServerNetworkChannel.BroadcastPacket(new ASUTimeAcceleration - { - Sleeping = true - }); - API.World.Calendar.SetTimeSpeedModifier("asu_psp", 1000); // Call the API to make sleep happen @@ -418,9 +416,12 @@ namespace AriasServerUtils if (bed.MountedBy != null) SleepingPlayers.Add(bed.MountedBy); // Start sleep - EntityBehaviorTiredness EBT = bed.MountedBy.GetBehavior("tiredness") as EntityBehaviorTiredness; + 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. } 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 162d5a9..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", diff --git a/AriasServerUtils/modinfo.json b/AriasServerUtils/modinfo.json index e8035c4..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-11-2025 @ 00:52 AM MST", - "version": "1.0.7", + "description": "A collection of server utilities\n\nBuild Date: 05-7-2025 @ 12:21 PM MST", + "version": "1.0.11", "dependencies": { "game": "" } diff --git a/AriasServerUtils/network/ASUTimeAccelPacket.cs b/AriasServerUtils/network/ASUTimeAccelPacket.cs deleted file mode 100644 index bb66753..0000000 --- a/AriasServerUtils/network/ASUTimeAccelPacket.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; - -[Serializable] -public class ASUTimeAcceleration -{ - public bool Sleeping = false; -} \ No newline at end of file