diff --git a/src/ServerTools/Command/NPCSpawnRate.cs b/src/ServerTools/Command/NPCSpawnRate.cs new file mode 100644 index 000000000..d3b272e81 --- /dev/null +++ b/src/ServerTools/Command/NPCSpawnRate.cs @@ -0,0 +1,68 @@ +using LazyAPI.Attributes; +using Terraria; +using TShockAPI; + +namespace ServerTools.Command; + +[Command("birthrate", "br")] +[Permissions("server.tool.npcspawn")] +public class NPCSpawnRate +{ + [Alias("enable", "on")] + [RealPlayer] + public static void Enable(CommandArgs args) + { + var rate = GetPlayerSpawnRate(args.Player.TPlayer); + rate.Enable = true; + args.Player.SendInfoMessage(GetString($"开启怪物生成率,当前生成率{{spawnRate: {rate.spawnRate}, maxSpawn: {rate.maxSpawns}}}")); + } + + [Alias("off")] + [RealPlayer] + public static void Off(CommandArgs args) + { + if(Plugin.PlayerSpawnRates.TryGetValue(args.Player.TPlayer, out var rate)) + { + rate.Enable = false; + } + args.Player.SendInfoMessage(GetString("已关闭怪物生成率")); + } + + [Alias("rate")] + [RealPlayer] + public static void ModifySpawnRate(CommandArgs args, int num) + { + var rate = GetPlayerSpawnRate(args.Player.TPlayer); + rate.spawnRate = num; + args.Player.SendInfoMessage(GetString($"设置生成速率{{spawnRate: {rate.spawnRate}, maxSpawn: {rate.maxSpawns}}}")); + } + + [Alias("max")] + [RealPlayer] + public static void ModifySpawnMax(CommandArgs args, int max) + { + var rate = GetPlayerSpawnRate(args.Player.TPlayer); + rate.maxSpawns = max; + args.Player.SendInfoMessage(GetString($"设置最大生成数量{{spawnRate: {rate.spawnRate}, maxSpawn: {rate.maxSpawns}}}")); + } + + [Alias("help")] + public static void Help(CommandArgs args) + { + args.Player.SendInfoMessage(GetString("/spawnrate on 启用生成率修改")); + args.Player.SendInfoMessage(GetString("/spawnrate off 关闭生成率修改")); + args.Player.SendInfoMessage(GetString("/spawnrate rate [生成率] 设置NPC生成速率(越小越快)")); + args.Player.SendInfoMessage(GetString("/spawnrate max [数量] 设置每次生成最大可生成数量")); + } + + private static Plugin.PlayerSpawnRate GetPlayerSpawnRate(Player player) + { + if(Plugin.PlayerSpawnRates.TryGetValue(player, out var item)) + { + return item; + } + var rate = new Plugin.PlayerSpawnRate(); + Plugin.PlayerSpawnRates[player] = rate; + return rate; + } +} diff --git a/src/ServerTools/ModifyClientDetect.cs b/src/ServerTools/ModifyClientDetect.cs index d0a1529e5..db6eb20d4 100644 --- a/src/ServerTools/ModifyClientDetect.cs +++ b/src/ServerTools/ModifyClientDetect.cs @@ -31,7 +31,7 @@ public static void CheckModify(MessageBuffer instance, int value) var player = TShockAPI.TShock.Players[instance.whoAmI]; if (CheckPacket(value) && player != null) { - var text = $"[警告]玩家 {player.Name} 使用修改后的客户端进入服务器!"; + var text = GetString($"[警告]玩家 {player.Name} 使用修改后的客户端进入服务器!"); TShockAPI.TShock.Log.ConsoleWarn(text); TShockAPI.TShock.Utils.Broadcast(text, Microsoft.Xna.Framework.Color.Red); if(Config.Instance.KickCheater) diff --git a/src/ServerTools/Plugin.Handler.cs b/src/ServerTools/Plugin.Handler.cs index a92fdc213..f9be67295 100644 --- a/src/ServerTools/Plugin.Handler.cs +++ b/src/ServerTools/Plugin.Handler.cs @@ -12,6 +12,13 @@ namespace ServerTools; public partial class Plugin { + internal class PlayerSpawnRate + { + public int spawnRate = 600; + public int maxSpawns = 5; + public bool Enable = false; + } + private static long TimerCount = 0; private readonly Dictionary PlayerDeath = []; @@ -22,6 +29,19 @@ public partial class Plugin public static readonly List ActivePlayers = []; + internal static readonly Dictionary PlayerSpawnRates = []; + + private void Spawner_GetSpawnRate(On.Terraria.NPC.Spawner.orig_GetSpawnRate orig, NPC.Spawner self, Player player, out int spawnRate, out int maxSpawns) + { + if(PlayerSpawnRates.TryGetValue(player, out var inner) && inner.Enable) + { + spawnRate = inner.spawnRate; + maxSpawns = inner.maxSpawns; + return; + } + orig(self, player, out spawnRate, out maxSpawns); + } + private void OnGreet(GreetPlayerEventArgs args) { var ply = TShock.Players[args.Who]; diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index 64194618f..3e934cafe 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -15,7 +15,7 @@ public partial class Plugin : LazyPlugin public override string Name => Assembly.GetExecutingAssembly().GetName().Name!; - public override Version Version => new Version(1, 3, 0, 0); + public override Version Version => new Version(1, 3, 0, 1); public const string ReaderPath = "ReaderPlayers"; @@ -44,6 +44,7 @@ public override void Initialize() GetDataHandlers.KillMe.Register(this.KillMe); GetDataHandlers.PlayerSpawn.Register(this.OnPlayerSpawn); GetDataHandlers.PlayerUpdate.Register(this.OnUpdate); + On.Terraria.NPC.Spawner.GetSpawnRate += this.Spawner_GetSpawnRate; HookManager.Add(typeof(TSRestPlayer).GetConstructor([typeof(string), typeof(TShockAPI.Group)])!, RestPlayerCtor); HookManager.Add(typeof(Commands).GetMethod("ViewAccountInfo", BindingFlags.NonPublic | BindingFlags.Static)!, ViewAccountInfo); OnTimer += this.OnUpdatePlayerOnline; @@ -74,6 +75,8 @@ protected override void Dispose(bool disposing) GetDataHandlers.PlayerSpawn.UnRegister(this.OnPlayerSpawn); GetDataHandlers.PlayerUpdate.UnRegister(this.OnUpdate); On.OTAPI.Hooks.MessageBuffer.InvokeGetData -= this.MessageBuffer_InvokeGetData; + On.Terraria.NPC.Spawner.GetSpawnRate -= this.Spawner_GetSpawnRate; + IL.Terraria.MessageBuffer.GetData -= this.MessageBuffer_GetData; OnTimer -= this.OnUpdatePlayerOnline; } base.Dispose(disposing); diff --git a/src/ServerTools/README.md b/src/ServerTools/README.md index a8425aee4..c6e9b1441 100644 --- a/src/ServerTools/README.md +++ b/src/ServerTools/README.md @@ -22,6 +22,10 @@ | /readplayer | servertool.readplayer.use | 读取并保存文件夹下所有存档到数据库 | | /readplayer [文件名] | servertool.readplayer.use | 读取并保存文件夹下指定文存档到数据库 | | /readplayer [文件名] [角色名] | servertool.readplayer.use | 读取存档到指定角色下 | +| /birthrate on | server.tool.npcspawn | 启用生成率修改 | +| /birthrate off | server.tool.npcspawn | 关闭生成率修改 | +| /birthrate rate [速率] | server.tool.npcspawn | 修改生成速率 | +| /birthrate max [数量] | server.tool.npcspawn | 修改生成数量 | ## REST API @@ -164,6 +168,9 @@ ## 更新日志 +### v1.3.0.1 +- 添加修改NPC生成速率 + ### v1.3.0.0 — 检测作弊者