using System; using System.Collections.Generic; using System.Linq; using System.Text; using Vintagestory.API.Common; using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; using Vintagestory.API.MathTools; using Vintagestory.API.Server; using Vintagestory.API.Util; using Vintagestory.GameContent; namespace AriasServerUtils { public class Events { internal static TextCommandResult HandleASU(TextCommandCallingArgs args) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:help", ServerUtilities.config.MaxHomes, ServerUtilities.config.AdminsBypassMaxHomes, ServerUtilities.config.MaxBackCache, string.Join(", ", new string[] { "setspawn", "spawn", "delspawn", "sethome", "home", "delhome", "homes", "restoreinv", "asu", "warp", "setwarp", "delwarp", "warps", "back", "rtp", "listcooldowns" }))); } internal static TextCommandResult HandleBack(TextCommandCallingArgs args) { PlayerStorage ps = ServerUtilities.GetPlayerData(args.Caller.Player as IServerPlayer); if (ps.ActiveCooldowns.ContainsKey(CooldownType.Back)) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:cmd-cooldown", "/back", TimeUtil.EncodeTimeNotation(ps.ActiveCooldowns.Get(CooldownType.Back) - TimeUtil.GetUnixEpochTimestamp()))); } PlayerPosition pos = ServerUtilities.backCaches.ReadAndPopNewestPosition(args.Caller.Player.PlayerName); if (pos == null) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:back-no")); } else { // Go back to old position pos.Merge(args.Caller.Player.Entity); ps.ActiveCooldowns.Add(CooldownType.Back, TimeUtil.DecodeTimeNotation(ServerUtilities.config.Cooldowns.Get(CooldownType.Back)) + TimeUtil.GetUnixEpochTimestamp()); ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:back")); } } internal static TextCommandResult HandleClearSpawn(TextCommandCallingArgs args) { ServerUtilities.config.Spawn = null; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:rmspawn")); } internal static TextCommandResult HandleRTP(TextCommandCallingArgs args) { if (args.Caller.Player is IServerPlayer isp) { int maxDistance = ServerUtilities.config.MaxRTPBlockDistance; if (args[0] is int ix) { if (ix == -1) ix = maxDistance; if (ix > maxDistance && !(ServerUtilities.config.AdminsBypassRTPMaxDistance && isp.HasPrivilege(Privilege.controlserver))) { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:rtp-capped", ix, maxDistance)); } else maxDistance = ix; } PlayerStorage ps = ServerUtilities.GetPlayerData(isp); if (ps.ActiveCooldowns.ContainsKey(CooldownType.RTP)) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:cmd-cooldown", "/rtp", TimeUtil.EncodeTimeNotation(ps.ActiveCooldowns.Get(CooldownType.RTP) - TimeUtil.GetUnixEpochTimestamp()))); } ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:rtp-search")); RTPFactory.TryRTP(isp, maxDistance: maxDistance); } return TextCommandResult.Success(); } internal static TextCommandResult HandleDelHome(TextCommandCallingArgs args) { string homeName = "default"; if (args.ArgCount > 0) { homeName = args[0] as string ?? "default"; } if (args.Caller.Player is IServerPlayer isp) { PlayerStorage data = ServerUtilities.GetPlayerData(isp); if (data.Homes.ContainsKey(homeName)) { data.Homes.Remove(homeName); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-del")); ServerUtilities.MarkDirty(); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-no")); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleGoHome(TextCommandCallingArgs args) { string homeName = "default"; if (args.ArgCount > 0) { homeName = args[0] as string ?? "default"; } if (args.Caller.Player is IServerPlayer isp) { PlayerStorage data = ServerUtilities.GetPlayerData(isp); if (data.ActiveCooldowns.ContainsKey(CooldownType.Home)) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:cmd-cooldown", "/home", TimeUtil.EncodeTimeNotation(data.ActiveCooldowns.Get(CooldownType.Home) - TimeUtil.GetUnixEpochTimestamp()))); } if (data.Homes.ContainsKey(homeName)) { Home home = data.Homes[homeName]; ServerUtilities.NewBackCacheForPlayer(isp); home.Location.Merge(isp.Entity, unmount: !home.CanHaveMount); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-tp")); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-no")); } data.ActiveCooldowns.Add(CooldownType.Home, TimeUtil.DecodeTimeNotation(ServerUtilities.config.Cooldowns.Get(CooldownType.Home)) + TimeUtil.GetUnixEpochTimestamp()); ServerUtilities.MarkDirty(); } return TextCommandResult.Success(); } internal static TextCommandResult HandleListHomes(TextCommandCallingArgs args) { if (args.Caller.Player is IServerPlayer isp) { PlayerStorage data = ServerUtilities.GetPlayerData(isp); List lTmp = new List(); foreach (var entry in data.Homes) { lTmp.Add(entry.Key); } ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-list", data.Homes.Count, string.Join(", ", lTmp))); } return TextCommandResult.Success(); } internal static TextCommandResult HandleReturnItems(TextCommandCallingArgs args) { IPlayer player = args[0] as IPlayer; if (player is IServerPlayer isp) { if (ServerUtilities.backupInventory.ContainsKey(player.PlayerName)) isp.InventoryManager.DiscardAll(); else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:nobackup")); return TextCommandResult.Success(); } foreach (var stack in ServerUtilities.backupInventory[player.PlayerName].Items) { isp.InventoryManager.TryGiveItemstack(stack.Clone()); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleSetHome(TextCommandCallingArgs args) { bool isOp = args.Caller.HasPrivilege(Privilege.controlserver); string homeName = "default"; if (args.ArgCount > 0) { homeName = args[0] as string ?? "default"; } if (args.Caller.Player is IServerPlayer isp) { bool withMount = false; if (args.Command.Name == "sethomemount") { // Check for the gears and pay here, or show error. withMount = true; } bool bypass = isOp && ServerUtilities.config.AdminsBypassMaxHomes; var data = ServerUtilities.GetPlayerData(isp); if (bypass || data.Homes.Count < ServerUtilities.config.MaxHomes || data.Homes.ContainsKey(homeName)) { data.Homes[homeName] = Home.MakeHome(args.Caller.Player.Entity, homeName, withMount: withMount); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-set")); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:home-max")); } ServerUtilities.MarkDirty(); } return TextCommandResult.Success(); } 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) { PlayerStorage data = ServerUtilities.GetPlayerData(isp); if (data.ActiveCooldowns.ContainsKey(CooldownType.Spawn)) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:cmd-cooldown", "/spawn", TimeUtil.EncodeTimeNotation(data.ActiveCooldowns.Get(CooldownType.Spawn) - TimeUtil.GetUnixEpochTimestamp()))); } ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:tp-spawn")); ServerUtilities.NewBackCacheForPlayer(isp); ServerUtilities.config.Spawn.Merge(args.Caller.Player.Entity); data.ActiveCooldowns.Add(CooldownType.Spawn, TimeUtil.DecodeTimeNotation(ServerUtilities.config.Cooldowns.Get(CooldownType.Spawn)) + TimeUtil.GetUnixEpochTimestamp()); ServerUtilities.MarkDirty(); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASUBypass(TextCommandCallingArgs args) { if (args[0] is bool bypass) { ServerUtilities.config.AdminsBypassMaxHomes = bypass; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", bypass)); } return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASUMaxBack(TextCommandCallingArgs args) { if (args[0] is int max) { ServerUtilities.config.MaxBackCache = max; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", max)); } return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASUMaxHomes(TextCommandCallingArgs args) { if (args[0] is int maxHomes) { ServerUtilities.config.MaxHomes = maxHomes; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", maxHomes)); } return TextCommandResult.Success(); } 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", true)); } internal static TextCommandResult HandleUpdateASUPSP(TextCommandCallingArgs args) { if (args[0] is int psp) { ServerUtilities.config.PlayerSleepingPercentage = psp; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", psp)); } return TextCommandResult.Success(); } internal static TextCommandResult HandleWarp(TextCommandCallingArgs args) { string name = "default"; if (args.ArgCount > 0) name = args[0] as string ?? "default"; if (args.Caller.Player is IServerPlayer isp) { PlayerStorage data = ServerUtilities.GetPlayerData(isp); if (data.ActiveCooldowns.ContainsKey(CooldownType.Warp)) { return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:cmd-cooldown", "/warp", TimeUtil.EncodeTimeNotation(data.ActiveCooldowns.Get(CooldownType.Warp) - TimeUtil.GetUnixEpochTimestamp()))); } if (ServerUtilities.serverWarps.warps.ContainsKey(name)) { Warp warp = ServerUtilities.serverWarps.warps[name]; ServerUtilities.NewBackCacheForPlayer(isp); warp.Location.Merge(isp.Entity, unmount: !warp.CanHaveMount); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-tp", name)); data.ActiveCooldowns.Add(CooldownType.Warp, TimeUtil.DecodeTimeNotation(ServerUtilities.config.Cooldowns.Get(CooldownType.Warp)) + TimeUtil.GetUnixEpochTimestamp()); ServerUtilities.MarkDirty(); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-fail", name)); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleWarpDelete(TextCommandCallingArgs args) { string name = "default"; if (args.ArgCount > 0) name = args[0] as string ?? "default"; if (args.Caller.Player is IServerPlayer isp) { if (isp.HasPrivilege(Privilege.controlserver) || !ServerUtilities.config.onlyAdminsCreateWarps) { ServerUtilities.serverWarps.warps.Remove(name); ServerUtilities.MarkDirty(); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-del")); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-no")); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleWarpList(TextCommandCallingArgs args) { List warps = new List(); foreach (string id in ServerUtilities.serverWarps.warps.Keys) { warps.Add(id); } return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:warp-list", warps.Count, string.Join(", ", warps))); } internal static TextCommandResult HandleWarpUpdate(TextCommandCallingArgs args) { string name = "default"; if (args.ArgCount > 0) name = args[0] as string ?? "default"; if (args.Caller.Player is IServerPlayer isp) { if (isp.HasPrivilege(Privilege.controlserver) || !ServerUtilities.config.onlyAdminsCreateWarps) { ServerUtilities.serverWarps.warps[name] = Warp.Create(isp); ServerUtilities.MarkDirty(); ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-set", name)); } else { ServerUtilities.SendMessageTo(isp, Lang.Get($"{ServerUtilities.MOD_ID}:warp-no")); } } return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASURTPMax(TextCommandCallingArgs args) { if (args[0] is int maxDist) { ServerUtilities.config.MaxRTPBlockDistance = maxDist; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", maxDist)); } return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASUCDBack(TextCommandCallingArgs args) { if (args[0] is string CD) { ServerUtilities.config.Cooldowns[CooldownType.Back] = CD; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { ServerUtilities.config.Cooldowns[CooldownType.Back] = "5s"; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } } internal static TextCommandResult HandleUpdateASUCDWarp(TextCommandCallingArgs args) { if (args[0] is string CD) { ServerUtilities.config.Cooldowns[CooldownType.Warp] = CD; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { ServerUtilities.config.Cooldowns[CooldownType.Warp] = "10s"; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } } internal static TextCommandResult HandleUpdateASUCDHome(TextCommandCallingArgs args) { if (args[0] is string CD) { ServerUtilities.config.Cooldowns[CooldownType.Home] = CD; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { ServerUtilities.config.Cooldowns[CooldownType.Home] = "5s"; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } } internal static TextCommandResult HandleUpdateASUCDSpawn(TextCommandCallingArgs args) { if (args[0] is string CD) { ServerUtilities.config.Cooldowns[CooldownType.Spawn] = CD; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { ServerUtilities.config.Cooldowns[CooldownType.Spawn] = "5s"; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } } internal static TextCommandResult HandleUpdateASUCDRTP(TextCommandCallingArgs args) { if (args[0] is string CD) { ServerUtilities.config.Cooldowns[CooldownType.RTP] = CD; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", CD)); } else { ServerUtilities.config.Cooldowns[CooldownType.RTP] = "30s"; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } } internal static TextCommandResult HandleUpdateASUCDReset(TextCommandCallingArgs args) { ServerUtilities.config.Cooldowns = ServerUtilities.config.GetDefaultCooldowns(); ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:config-value-reset")); } internal static TextCommandResult HandleUpdateASUBypassCD(TextCommandCallingArgs args) { if (args[0] is bool bypass) { // Update the bypass ServerUtilities.config.AdminsBypassCooldowns = bypass; ServerUtilities.MarkDirty(); return TextCommandResult.Success(Lang.Get($"{ServerUtilities.MOD_ID}:updatedconfig", bypass)); } else return TextCommandResult.Success(); } internal static TextCommandResult HandleUpdateASUBypassRTPMaxDist(TextCommandCallingArgs args) { if (args[0] is bool bypass) { // Update the flag ServerUtilities.config.AdminsBypassRTPMaxDistance = bypass; ServerUtilities.MarkDirty(); 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"; foreach (var cd in ServerUtilities.config.Cooldowns) { sReturn += $"{cd.Key}: {cd.Value}\n"; } if (args.Caller.Player is IServerPlayer isp) { sReturn += "\nYour active cooldowns:"; foreach (var cd in ServerUtilities.GetPlayerData(isp).ActiveCooldowns) { long remain = cd.Value - TimeUtil.GetUnixEpochTimestamp(); string sCDVal = TimeUtil.EncodeTimeNotation(remain); sReturn += $"{cd.Key}: {sCDVal}\n"; } } 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)); } } } }