From 4d474c99b3c45193cffc8e14dc0f308d62762187 Mon Sep 17 00:00:00 2001 From: Controllerdestiny <523321293@qq.co> Date: Wed, 25 Dec 2024 14:37:08 +0800 Subject: [PATCH 1/5] fix: ServerTools resetApi request error --- src/ServerTools/Plugin.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index cb8219ab3..4b9682bb5 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -20,7 +20,7 @@ public partial class Plugin : TerrariaPlugin public override string Name => "ServerTools";// 插件名字 - public override Version Version => new Version(1, 1, 7, 10);// 插件版本 + public override Version Version => new Version(1, 1, 8, 0);// 插件版本 private static Config Config = new(); @@ -288,8 +288,8 @@ public static void RestPlayerCtor(Action { self.Account = new() { - Name = self.Name, - Group = self.Group.Name, + Name = name, + Group = group.Name, ID = self.Index }; orig(self, name, group); From 7e014e03940acb7a7e0f6442a0c8cb10e729434b Mon Sep 17 00:00:00 2001 From: Controllerdestiny <523321293@qq.co> Date: Wed, 25 Dec 2024 20:00:51 +0800 Subject: [PATCH 2/5] using LazyAPi --- src/ServerTools/Config.cs | 80 +++++++++------ src/ServerTools/DB/PlayerDeath.cs | 61 ++++++----- src/ServerTools/DB/PlayerOnline.cs | 93 ++++++----------- src/ServerTools/Plugin.Commamd.cs | 8 +- src/ServerTools/Plugin.DeathRank.cs | 12 +-- src/ServerTools/Plugin.Online.cs | 9 +- src/ServerTools/Plugin.cs | 150 +++++++--------------------- src/ServerTools/ServerTools.csproj | 3 + 8 files changed, 159 insertions(+), 257 deletions(-) diff --git a/src/ServerTools/Config.cs b/src/ServerTools/Config.cs index af6fee617..5d73e60a2 100644 --- a/src/ServerTools/Config.cs +++ b/src/ServerTools/Config.cs @@ -1,89 +1,113 @@ -using Newtonsoft.Json; +using LazyAPI.ConfigFiles; +using Newtonsoft.Json; namespace ServerTools; -public class Config +public class Config : JsonConfigBase { - [JsonProperty("死亡延续")] + [LocalizedPropertyName(CultureType.Chinese, "死亡延续")] + [LocalizedPropertyName(CultureType.English, "DeathLast")] public bool DeathLast = true; - [JsonProperty("限制哨兵数量")] + [LocalizedPropertyName(CultureType.Chinese, "限制哨兵数量")] + [LocalizedPropertyName(CultureType.English, "SentryLimit")] public int sentryLimit = 20; - [JsonProperty("限制召唤物数量")] + [LocalizedPropertyName(CultureType.Chinese, "限制召唤物数量")] + [LocalizedPropertyName(CultureType.English, "SummonLimit")] public int summonLimit = 11; - [JsonProperty("仅允许软核进入")] + [LocalizedPropertyName(CultureType.Chinese, "仅允许软核进入")] + [LocalizedPropertyName(CultureType.English, "OnlySoftCoresAreAllowed")] public bool OnlySoftCoresAreAllowed = false; - [JsonProperty("是否设置世界模式")] + [LocalizedPropertyName(CultureType.Chinese, "是否设置世界模式")] + [LocalizedPropertyName(CultureType.English, "SetWorldMode")] public bool SetWorldMode = true; - [JsonProperty("世界模式")] + [LocalizedPropertyName(CultureType.Chinese, "世界模式")] + [LocalizedPropertyName(CultureType.English, "WorldMode")] public int WorldMode = 2; - [JsonProperty("限制发言长度")] + [LocalizedPropertyName(CultureType.Chinese, "限制发言长度")] + [LocalizedPropertyName(CultureType.English, "ChatLength")] public int ChatLength = 50; - [JsonProperty("设置旅途模式难度")] + [LocalizedPropertyName(CultureType.Chinese, "设置旅途模式难度")] + [LocalizedPropertyName(CultureType.English, "SetJourneyDifficult")] public bool SetJourneyDifficult = false; - [JsonProperty("旅途模式难度")] + [LocalizedPropertyName(CultureType.Chinese, "旅途模式难度")] + [LocalizedPropertyName(CultureType.English, "JourneyDifficult")] public string JourneyMode = "master"; - [JsonProperty("阻止未注册进入")] + [LocalizedPropertyName(CultureType.Chinese, "阻止未注册进入")] + [LocalizedPropertyName(CultureType.English, "BlockUnregisteredEntry")] public bool BlockUnregisteredEntry = false; - [JsonProperty("禁止怪物捡钱")] + [LocalizedPropertyName(CultureType.Chinese, "禁止怪物捡钱")] + [LocalizedPropertyName(CultureType.English, "MonsterPickUpMoney")] public bool PickUpMoney = true; - [JsonProperty("清理掉落物")] + [LocalizedPropertyName(CultureType.Chinese, "清理掉落物")] + [LocalizedPropertyName(CultureType.English, "ClearDrop")] public bool ClearDrop = false; - [JsonProperty("死亡倒计时")] + [LocalizedPropertyName(CultureType.Chinese, "死亡倒计时")] + [LocalizedPropertyName(CultureType.English, "DeadTimer")] public bool DeadTimer = false; - [JsonProperty("阻止死亡角色进入")] + [LocalizedPropertyName(CultureType.Chinese, "阻止死亡角色进入")] + [LocalizedPropertyName(CultureType.English, "PreventsDeath")] public bool PreventsDeathStateJoin = true; - [JsonProperty("禁止双箱")] + [LocalizedPropertyName(CultureType.Chinese, "禁止双箱")] + [LocalizedPropertyName(CultureType.English, "KeepOpenChest")] public bool KeepOpenChest = true; - [JsonProperty("禁止双饰品")] + [LocalizedPropertyName(CultureType.Chinese, "禁止双饰品")] + [LocalizedPropertyName(CultureType.English, "KeepArmor")] public bool KeepArmor = true; - [JsonProperty("禁止肉前第七格饰品")] + [LocalizedPropertyName(CultureType.Chinese, "禁止肉前第七格饰品")] + [LocalizedPropertyName(CultureType.English, "KeepArmor2")] public bool KeepArmor2 = true; - [JsonProperty("死亡倒计时格式")] + [LocalizedPropertyName(CultureType.Chinese, "死亡倒计时格式")] + [LocalizedPropertyName(CultureType.English, "DeadFormat")] public string DeadFormat = "你还有{0}秒复活!"; - [JsonProperty("未注册阻止语句")] + [LocalizedPropertyName(CultureType.Chinese, "未注册阻止语句")] + [LocalizedPropertyName(CultureType.English, "BlockEntryStatement")] public string BlockEntryStatement = "未注册不能进入服务器"; - [JsonProperty("未注册启动服务器执行命令")] + [LocalizedPropertyName(CultureType.Chinese, "未注册启动服务器执行命令")] + [LocalizedPropertyName(CultureType.English, "BlockEntryExecCommands")] public string[] ResetExecCommands = Array.Empty(); [JsonProperty("开启NPC保护", Order = 7)] + [LocalizedPropertyName(CultureType.English, "EnableNpcProtect")] public bool NpcProtect = false; [JsonProperty("NPC保护表", Order = 7)] + [LocalizedPropertyName(CultureType.English, "NpcProtects")] public List NpcProtectList = new(); [JsonProperty("禁止多鱼线", Order = 8)] + [LocalizedPropertyName(CultureType.English, "MultipleFishingRodsAreProhibited")] public bool MultipleFishingRodsAreProhibited = true; [JsonProperty("浮漂列表", Order = 8)] + [LocalizedPropertyName(CultureType.English, "ForbiddenBuoys")] public List ForbiddenBuoys = new(); - public static Config Read(string PATH) - { - return File.Exists(PATH) ? JsonConvert.DeserializeObject(File.ReadAllText(PATH)) ?? new() : new(); - } + protected override string Filename => "ServerTools"; - public void Write(string PATH) + protected override void SetDefault() { - File.WriteAllText(PATH, JsonConvert.SerializeObject(this, Formatting.Indented)); + this.ForbiddenBuoys = new List() { 360, 361, 362, 363, 364, 365, 366, 381, 382, 760, 775, 986, 987, 988, 989, 990, 991, 992, 993 }; + this.NpcProtectList = new List() { 17, 18, 19, 20, 38, 105, 106, 107, 108, 160, 123, 124, 142, 207, 208, 227, 228, 229, 353, 354, 376, 441, 453, 550, 579, 588, 589, 633, 663, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 375, 442, 443, 539, 444, 445, 446, 447, 448, 605, 627, 601, 613 }; + } } \ No newline at end of file diff --git a/src/ServerTools/DB/PlayerDeath.cs b/src/ServerTools/DB/PlayerDeath.cs index d986a0e18..2ae3b4091 100644 --- a/src/ServerTools/DB/PlayerDeath.cs +++ b/src/ServerTools/DB/PlayerDeath.cs @@ -1,53 +1,50 @@ -using MySql.Data.MySqlClient; +using LazyAPI.Database; +using LinqToDB; +using LinqToDB.Mapping; +using MySql.Data.MySqlClient; using System.Data; using TShockAPI; using TShockAPI.DB; namespace ServerTools.DB; -public class PlayerDeath : Dictionary +[Table("Death")] +public class PlayerDeath : RecordBase { - private new int this[string key] - { - get => this.TryGetValue(key, out var result) ? result : 0; + [PrimaryKey, Identity] + [Column("Name")] + public string Name { get; set; } = string.Empty; - set => base[key] = value; - } - private readonly IDbConnection database; - public PlayerDeath() - { - this.database = TShock.DB; - var Skeleton = new SqlTable("Death", - new SqlColumn("Count", MySqlDbType.Int32) { Length = 255 }, - new SqlColumn("Name", MySqlDbType.VarChar) { Length = 255, Unique = true } - ); - var List = new SqlTableCreator(this.database, this.database.GetSqlType() == SqlType.Sqlite ? new SqliteQueryCreator() : new MysqlQueryCreator()); - List.EnsureTableStructure(Skeleton); - this.ReadAll(); + [Column("Count")] + public int Count { get; set; } + + + private static Context? _context; + + public static Context Instance => _context ??= Db.Context("Death"); + + public static PlayerDeath? GetPlayerDeath(string name) + { + return Instance.Records.FirstOrDefault(x => x.Name == name); } - private void ReadAll() + public static List GetDeathRank() { - using var reader = this.database.QueryReader("SELECT * FROM Death"); - while (reader.Read()) - { - var Name = reader.Get("Name"); - var Count = reader.Get("Count"); - this[Name] = Count; - } + return Instance.Records.OrderByDescending(x => x.Count).ToList(); } - public void Add(string name) + public static void Add(string name) { - if (this.ContainsKey(name)) + var record = GetPlayerDeath(name); + if (record == null) { - this[name] += 1; - this.database.Query("UPDATE Death SET Count = @0 WHERE Name = @1", this[name], name); + record = new PlayerDeath { Name = name, Count = 1 }; + Instance.Insert(record); } else { - this[name] = 1; - this.database.Query("INSERT INTO `Death` (`Name`, `Count`) VALUES (@0, @1)", name, 1); + record.Count++; + Instance.Update(record); } } } \ No newline at end of file diff --git a/src/ServerTools/DB/PlayerOnline.cs b/src/ServerTools/DB/PlayerOnline.cs index f98be5520..ed5208b64 100644 --- a/src/ServerTools/DB/PlayerOnline.cs +++ b/src/ServerTools/DB/PlayerOnline.cs @@ -1,87 +1,50 @@ -using MySql.Data.MySqlClient; +using LazyAPI.Database; +using LinqToDB; +using LinqToDB.Mapping; using System.Data; -using TShockAPI; -using TShockAPI.DB; namespace ServerTools.DB; -public class PlayerOnline : Dictionary +[Table("OnlineDuration")] +public class PlayerOnline : RecordBase { - private readonly HashSet _players = new(); - public new int this[string key] - { - get => this.TryGetValue(key, out var result) ? result : 0; + [PrimaryKey, Identity] + [Column("username")] + public string Name { get; set; } = string.Empty; - set => base[key] = value; - } - private readonly IDbConnection database; - public PlayerOnline() - { - this.database = TShock.DB; - var Skeleton = new SqlTable("OnlineDuration", - new SqlColumn("username", MySqlDbType.Text) { Length = 500 }, - new SqlColumn("duration", MySqlDbType.Int32) { Length = 255 } - ); - var List = new SqlTableCreator(this.database, this.database.GetSqlType() == SqlType.Sqlite ? new SqliteQueryCreator() : new MysqlQueryCreator()); - List.EnsureTableStructure(Skeleton); - this.ReadAll(); - } + [Column("duration")] + public int Duration { get; set; } - public void ReadAll() - { - using var reader = this.database.QueryReader("SELECT * FROM OnlineDuration"); - while (reader.Read()) - { - var username = reader.Get("username"); - var duration = reader.Get("duration"); - this[username] = duration; - this._players.Add(username); - } - } - public bool Read(string name, out int duration) - { - using var reader = this.database.QueryReader("SELECT * FROM `OnlineDuration` WHERE `username` LIKE @0", name); - if (reader.Read()) - { - duration = reader.Get("duration"); - return true; - } - else - { - duration = 0; - return false; - } - } + private static Context? _context; - public bool Update(string Name, int duration) - { - return 1 == this.database.Query("UPDATE `OnlineDuration` SET `duration` = @0 WHERE `OnlineDuration`.`username` = @1", duration, Name); + public static Context Instance => _context ??= Db.Context("Death"); - } - public bool Insert(string Name, int duration) + public static PlayerOnline? GetPlayerOnline(string name) { - this._players.Add(Name); - return 1 == this.database.Query("INSERT INTO `OnlineDuration` (`username`, `duration`) VALUES (@0, @1)", Name, duration); + return Instance.Records.FirstOrDefault(x => x.Name == name); } + public static List GetOnlineRank() + { + return Instance.Records.OrderByDescending(x => x.Duration).ToList(); + } - - - public void AddOrUpdate(string name, int duration) + public static bool Add(string Name, int duration) { - if (this._players.Contains(name)) + var online = GetPlayerOnline(Name); + if (online == null) { - this.Update(name, duration); + online = new PlayerOnline { Name = Name, Duration = duration }; + Instance.Insert(online); + return true; } else { - this.Insert(name, duration); + online.Duration += duration; + Instance.Update(online); + return false; } } - - public void UpdateAll() - { - this.ForEach(x => this.AddOrUpdate(x.Key, x.Value)); - } + } \ No newline at end of file diff --git a/src/ServerTools/Plugin.Commamd.cs b/src/ServerTools/Plugin.Commamd.cs index 632194d32..7b9e9f066 100644 --- a/src/ServerTools/Plugin.Commamd.cs +++ b/src/ServerTools/Plugin.Commamd.cs @@ -1,4 +1,5 @@ using Microsoft.Xna.Framework; +using ServerTools.DB; using Terraria; using TShockAPI; @@ -28,10 +29,7 @@ void ShowOnline(List line) } ); } - var OnlineInfo = from online in PlayerOnlines - orderby online.Value descending - where online.Value > 0 - select GetString($"{online.Key} 在线时长: {Math.Ceiling(Convert.ToDouble(online.Value * 1.0f / 60))}分钟").Color(TShockAPI.Utils.GreenHighlight); + var OnlineInfo = PlayerOnline.GetOnlineRank().Select(online => GetString($"{online.Name} 在线时长: {Math.Ceiling(Convert.ToDouble(online.Duration * 1.0f / 60))}分钟").Color(TShockAPI.Utils.GreenHighlight)).ToList(); ShowOnline(OnlineInfo.ToList()); } @@ -58,7 +56,7 @@ void Show(List line) } ); } - var line = PlayerDeathRank.OrderByDescending(x => x.Value).Select(x => GetString($"[{x.Key}] => 死亡{x.Value}次")).ToList(); + var line = DB.PlayerDeath.GetDeathRank().Select(x => GetString($"[{x.Name}] => 死亡{x.Count}次")).ToList(); Show(line); } diff --git a/src/ServerTools/Plugin.DeathRank.cs b/src/ServerTools/Plugin.DeathRank.cs index ad884cf36..816cbc22e 100644 --- a/src/ServerTools/Plugin.DeathRank.cs +++ b/src/ServerTools/Plugin.DeathRank.cs @@ -6,13 +6,8 @@ namespace ServerTools; public partial class Plugin { - public static readonly PlayerDeath PlayerDeathRank = new(); public static readonly List Deads = new(); - public void InitDeathRank() - { - - } private void KillMe(object? sender, GetDataHandlers.KillMeEventArgs e) { @@ -21,15 +16,14 @@ private void KillMe(object? sender, GetDataHandlers.KillMeEventArgs e) return; } - PlayerDeathRank.Add(e.Player.Name); + DB.PlayerDeath.Add(e.Player.Name); Deads.Add(e.Player); } private object DeadRank(RestRequestArgs args) { - var data = PlayerDeathRank - .OrderByDescending(x => x.Value) - .Select(x => new { Name = x.Key, Count = x.Value }) + var data = DB.PlayerDeath.GetDeathRank() + .Select(x => new { x.Name , x.Count }) .ToList(); return new RestObject("200") { diff --git a/src/ServerTools/Plugin.Online.cs b/src/ServerTools/Plugin.Online.cs index fe50f26b1..34dc41953 100644 --- a/src/ServerTools/Plugin.Online.cs +++ b/src/ServerTools/Plugin.Online.cs @@ -9,18 +9,15 @@ public partial class Plugin { public static readonly List ActivePlayers = new(); - public static readonly PlayerOnline PlayerOnlines = new(); - private object Queryduration(RestRequestArgs args) { - var data = PlayerOnlines.OrderByDescending(x => x.Value).Select(x => new { name = x.Key, duration = x.Value }); + var data = PlayerOnline.GetOnlineRank().Select(x => new { name = x.Name, duration = x.Duration }); return new RestObject() { { "response", "查询成功" }, { "data", data } }; } - private void _OnLeave(LeaveEventArgs args) + private void OnLeaveV2(LeaveEventArgs args) { ActivePlayers.Remove(TShock.Players[args.Who]); - PlayerOnlines.UpdateAll(); } private void OnGreet(GreetPlayerEventArgs args) @@ -40,7 +37,7 @@ private void OnUpdatePlayerOnline(EventArgs args) { if (p != null && p.Active) { - PlayerOnlines[p.Name] += 1; + PlayerOnline.Add(p.Name, 1); } }); } diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index 4b9682bb5..4adea4423 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -1,18 +1,18 @@ +using LazyAPI; using Microsoft.Xna.Framework; using MonoMod.RuntimeDetour; using Newtonsoft.Json; using Rests; -using System.Text.RegularExpressions; +using System.Text; using Terraria; using Terraria.GameContent.Creative; using TerrariaApi.Server; using TShockAPI; -using TShockAPI.Hooks; namespace ServerTools; [ApiVersion(2, 1)] -public partial class Plugin : TerrariaPlugin +public partial class Plugin : LazyPlugin { public override string Author => "少司命";// 插件作者 @@ -22,10 +22,6 @@ public partial class Plugin : TerrariaPlugin public override Version Version => new Version(1, 1, 8, 0);// 插件版本 - private static Config Config = new(); - - private readonly string PATH = Path.Combine(TShock.SavePath, "ServerTools.json"); - private DateTime LastCommandUseTime = DateTime.Now; private static long TimerCount = 0; @@ -40,23 +36,21 @@ public partial class Plugin : TerrariaPlugin public Plugin(Main game) : base(game) { - this._reloadHandler = (_) => this.LoadConfig(); + typeof(TextLog).GetField("_logWriter")?.SetValue(TShock.Log, new StreamWriter(TShock.Log.FileName, true, new UTF32Encoding(true, true))); } - private readonly GeneralHooks.ReloadEventD _reloadHandler; + private RestCommand[] addRestCommands = null!; public override void Initialize() { - - this.LoadConfig(); ServerApi.Hooks.GamePostInitialize.Register(this, this.PostInitialize); ServerApi.Hooks.ServerJoin.Register(this, this.OnJoin); ServerApi.Hooks.GameInitialize.Register(this, this.OnInitialize); ServerApi.Hooks.NetGreetPlayer.Register(this, this.OnGreetPlayer); - ServerApi.Hooks.ServerLeave.Register(this, this.OnLeave); + ServerApi.Hooks.ServerLeave.Register(this, this.OnLeaveV2); ServerApi.Hooks.GameUpdate.Register(this, this.OnUpdate); ServerApi.Hooks.NetGetData.Register(this, this.GetData); ServerApi.Hooks.NetGreetPlayer.Register(this, this.OnGreet); - ServerApi.Hooks.ServerLeave.Register(this, this._OnLeave); + ServerApi.Hooks.ServerLeave.Register(this, this.OnLeave); ServerApi.Hooks.NpcStrike.Register(this, OnStrike); ServerApi.Hooks.NpcAIUpdate.Register(this, OnNPCUpdate); Commands.ChatCommands.Add(new Command(Permissions.clear, this.Clear, "clp")); @@ -74,7 +68,6 @@ public override void Initialize() GetDataHandlers.KillMe.Register(this.KillMe); GetDataHandlers.PlayerSpawn.Register(this.OnPlayerSpawn); GetDataHandlers.PlayerUpdate.Register(this.OnUpdate); - GeneralHooks.ReloadEvent += this._reloadHandler; CmdHook = new Hook(typeof(TSRestPlayer).GetConstructor(new Type[] { typeof(string), typeof(TShockAPI.Group) }), RestPlayerCtor); AccountInfoHook = new Hook(typeof(Commands).GetMethod("ViewAccountInfo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static), ViewAccountInfo); this.addRestCommands = new RestCommand[] @@ -87,7 +80,6 @@ public override void Initialize() TShock.RestApi.Register(command); } Timer += this.OnUpdatePlayerOnline; - On.OTAPI.Hooks.MessageBuffer.InvokeGetData += this.MessageBuffer_InvokeGetData; this.HandleCommandLine(Environment.GetCommandLineArgs()); } protected override void Dispose(bool disposing) @@ -95,7 +87,6 @@ protected override void Dispose(bool disposing) if (disposing) { #region 钩子 - GeneralHooks.ReloadEvent -= this._reloadHandler; ServerApi.Hooks.GamePostInitialize.Deregister(this, this.PostInitialize); ServerApi.Hooks.ServerJoin.Deregister(this, this.OnJoin); ServerApi.Hooks.GameInitialize.Deregister(this, this.OnInitialize); @@ -104,7 +95,7 @@ protected override void Dispose(bool disposing) ServerApi.Hooks.GameUpdate.Deregister(this, this.OnUpdate); ServerApi.Hooks.NetGetData.Deregister(this, this.GetData); ServerApi.Hooks.NetGreetPlayer.Deregister(this, this.OnGreet); - ServerApi.Hooks.ServerLeave.Deregister(this, this._OnLeave); + ServerApi.Hooks.ServerLeave.Deregister(this, this.OnLeave); ServerApi.Hooks.NpcStrike.Deregister(this, OnStrike); ServerApi.Hooks.NpcAIUpdate.Deregister(this, OnNPCUpdate); #endregion @@ -120,56 +111,17 @@ protected override void Dispose(bool disposing) GetDataHandlers.KillMe.UnRegister(this.KillMe); GetDataHandlers.PlayerSpawn.UnRegister(this.OnPlayerSpawn); GetDataHandlers.PlayerUpdate.UnRegister(this.OnUpdate); - GeneralHooks.ReloadEvent -= this._reloadHandler; #endregion CmdHook?.Dispose(); AccountInfoHook?.Dispose(); Timer -= this.OnUpdatePlayerOnline; - On.OTAPI.Hooks.MessageBuffer.InvokeGetData -= this.MessageBuffer_InvokeGetData; - } base.Dispose(disposing); } - - //private void NPC_AI1(On.Terraria.NPC.orig_AI orig, NPC self) - //{ - // if(Collision.CanHit(self.Center,)) - //} - - - - private bool MessageBuffer_InvokeGetData(On.OTAPI.Hooks.MessageBuffer.orig_InvokeGetData orig, MessageBuffer instance, ref byte packetId, ref int readOffset, ref int start, ref int length, ref int messageType, int maxPackets) - { - - if (packetId == (byte) PacketTypes.LoadNetModule) - { - using var ms = new MemoryStream(instance.readBuffer); - ms.Position = readOffset; - using var reader = new BinaryReader(ms); - var id = reader.ReadUInt16(); - if (id == Terraria.Net.NetManager.Instance.GetId()) - { - var msg = Terraria.Chat.ChatMessage.Deserialize(reader); - if (msg.Text.Length > Config.ChatLength) - { - return false; - } - - if (Regex.IsMatch(msg.Text, @"[\uD800-\uDBFF][\uDC00-\uDFFF]")) - { - return false; - } - } - } - return orig(instance, ref packetId, ref readOffset, ref start, ref length, ref messageType, maxPackets); - } - - - #region 禁双饰品与肉前第7格饰品位方法 private void OnUpdate(object? sender, GetDataHandlers.PlayerUpdateEventArgs e) { - if (!Config.KeepArmor || e.Player.HasPermission("servertool.armor.white")) + if (!Config.Instance.KeepArmor || e.Player.HasPermission("servertool.armor.white")) { return; } @@ -193,24 +145,22 @@ private void OnUpdate(object? sender, GetDataHandlers.PlayerUpdateEventArgs e) Utils.ClearItem(ArmorGroup.ToArray(), e.Player); } - if (Config.KeepArmor2 && !Main.hardMode) + if (Config.Instance.KeepArmor2 && !Main.hardMode) { Utils.Clear7Item(e.Player); } } } - #endregion - #region NPC保护方法 private static void OnStrike(NpcStrikeEventArgs args) { - if (!Config.NpcProtect || TShock.Players[args.Player.whoAmI].HasPermission("servertool.npc.strike")) + if (!Config.Instance.NpcProtect || TShock.Players[args.Player.whoAmI].HasPermission("servertool.npc.strike")) { return; } - if (Config.NpcProtectList.Contains(args.Npc.netID)) + if (Config.Instance.NpcProtectList.Contains(args.Npc.netID)) { args.Handled = true; TShock.Players[args.Player.whoAmI].SendInfoMessage("[ServerTools] " + args.Npc.FullName + GetString(" 被系统保护")); @@ -219,19 +169,18 @@ private static void OnStrike(NpcStrikeEventArgs args) private static void OnNPCUpdate(NpcAiUpdateEventArgs args) { - if (!Config.NpcProtect) + if (!Config.Instance.NpcProtect) { return; } - if (Config.NpcProtectList.Contains(args.Npc.netID) && args.Npc.active) + if (Config.Instance.NpcProtectList.Contains(args.Npc.netID) && args.Npc.active) { args.Npc.life = args.Npc.lifeMax; args.Npc.active = true; TSPlayer.All.SendData((PacketTypes) 23, "", args.Npc.whoAmI, 0f, 0f, 0f, 0); } } - #endregion private static void ViewAccountInfo(CommandArgs args) { @@ -305,7 +254,7 @@ private void OnPlayerSpawn(object? sender, GetDataHandlers.SpawnEventArgs e) private void OnItemDrop(object? sender, GetDataHandlers.ItemDropEventArgs e) { - if (e.Player != null && e.Player.Dead && Config.ClearDrop) + if (e.Player != null && e.Player.Dead && Config.Instance.ClearDrop) { Main.item[e.ID].active = false; e.Handled = true; @@ -315,7 +264,7 @@ private void OnItemDrop(object? sender, GetDataHandlers.ItemDropEventArgs e) private void OnGreetPlayer(GreetPlayerEventArgs args) { - if (Config.PreventsDeathStateJoin && Main.player[args.Who].dead) + if (Config.Instance.PreventsDeathStateJoin && Main.player[args.Who].dead) { Task.Run(async () => { @@ -339,13 +288,13 @@ private void OnUpdate(EventArgs e) if (TimerCount % 60 == 0) { Timer?.Invoke(e); - if (Config.DeadTimer) + if (Config.Instance.DeadTimer) { foreach (var ply in Deads) { if (ply != null && ply.Active && ply.Dead && ply.RespawnTimer > 0) { - ply.SendInfoMessage(Config.DeadFormat, ply.RespawnTimer); + ply.SendInfoMessage(Config.Instance.DeadFormat, ply.RespawnTimer); } } } @@ -370,15 +319,15 @@ private void OnLeave(LeaveEventArgs args) private void NewProj(object? sender, GetDataHandlers.NewProjectileEventArgs e) { - if (Main.projectile.Where(x => x != null && x.owner == e.Owner && x.sentry && x.active).Count() > Config.sentryLimit) + if (Main.projectile.Where(x => x != null && x.owner == e.Owner && x.sentry && x.active).Count() > Config.Instance.sentryLimit) { - e.Player.Disconnect(GetString($"你因哨兵数量超过{Config.sentryLimit}被踢出")); + e.Player.Disconnect(GetString($"你因哨兵数量超过{Config.Instance.sentryLimit}被踢出")); } - if (e.Player.TPlayer.slotsMinions > Config.summonLimit) + if (e.Player.TPlayer.slotsMinions > Config.Instance.summonLimit) { - e.Player.Disconnect(GetString($"你因召唤物数量超过{Config.summonLimit}被踢出")); + e.Player.Disconnect(GetString($"你因召唤物数量超过{Config.Instance.summonLimit}被踢出")); } - if (Main.projectile[e.Index].bobber && Config.MultipleFishingRodsAreProhibited && Config.ForbiddenBuoys.FindAll(f => f == e.Type).Count > 0) + if (Main.projectile[e.Index].bobber && Config.Instance.MultipleFishingRodsAreProhibited && Config.Instance.ForbiddenBuoys.FindAll(f => f == e.Type).Count > 0) { var bobber = Main.projectile.Where(f => f != null && f.owner == e.Owner && f.active && f.type == e.Type); if (bobber.Count() > 2) @@ -402,29 +351,6 @@ private void HandleCommandLine(string[] param) } } } - - public void LoadConfig() - { - if (File.Exists(this.PATH)) - { - try - { - Config = Config.Read(this.PATH); - } - catch (Exception e) - { - - TShock.Log.ConsoleError(GetString("ServerTools.json配置读取错误:{0}"), e.ToString()); - } - } - else - { - Config.ForbiddenBuoys = new List() { 360, 361, 362, 363, 364, 365, 366, 381, 382, 760, 775, 986, 987, 988, 989, 990, 991, 992, 993 }; - Config.NpcProtectList = new List() { 17, 18, 19, 20, 38, 105, 106, 107, 108, 160, 123, 124, 142, 207, 208, 227, 228, 229, 353, 354, 376, 441, 453, 550, 579, 588, 589, 633, 663, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 375, 442, 443, 539, 444, 445, 446, 447, 448, 605, 627, 601, 613 }; - } - Config.Write(this.PATH); - } - public bool SetJourneyDiff(string diffName) { float diff; @@ -455,18 +381,18 @@ public bool SetJourneyDiff(string diffName) private void PostInitialize(EventArgs args) { //设置世界模式 - if (Config.SetWorldMode) + if (Config.Instance.SetWorldMode) { - if (Config.WorldMode > 1 && Config.WorldMode < 4) + if (Config.Instance.WorldMode > 1 && Config.Instance.WorldMode < 4) { - Main.GameMode = Config.WorldMode; + Main.GameMode = Config.Instance.WorldMode; TSPlayer.All.SendData(PacketTypes.WorldInfo); } } //旅途难度 - if (Main._currentGameModeInfo.IsJourneyMode && Config.SetJourneyDifficult) + if (Main._currentGameModeInfo.IsJourneyMode && Config.Instance.SetJourneyDifficult) { - this.SetJourneyDiff(Config.JourneyMode); + this.SetJourneyDiff(Config.Instance.JourneyMode); } } @@ -478,7 +404,7 @@ private void GetData(GetDataEventArgs args) return; } - if (Config.PickUpMoney && args.MsgID == PacketTypes.SyncExtraValue) + if (Config.Instance.PickUpMoney && args.MsgID == PacketTypes.SyncExtraValue) { using BinaryReader reader = new(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)); var npcid = reader.ReadInt16(); @@ -491,7 +417,7 @@ private void GetData(GetDataEventArgs args) } - if (Config.KeepOpenChest && args.MsgID == PacketTypes.ChestOpen) + if (Config.Instance.KeepOpenChest && args.MsgID == PacketTypes.ChestOpen) { using BinaryReader binaryReader5 = new(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)); @@ -505,7 +431,7 @@ private void GetData(GetDataEventArgs args) } } - if (args.MsgID == PacketTypes.ChestGetContents && Config.KeepOpenChest) + if (args.MsgID == PacketTypes.ChestGetContents && Config.Instance.KeepOpenChest) { if (ply.ActiveChest != -1) { @@ -520,11 +446,11 @@ private void GetData(GetDataEventArgs args) private void OnInitialize(EventArgs args) { //执行命令 - if (TShock.UserAccounts.GetUserAccounts().Count == 0 && Config.ResetExecCommands.Length > 0) + if (TShock.UserAccounts.GetUserAccounts().Count == 0 && Config.Instance.ResetExecCommands.Length > 0) { - for (var i = 0; i < Config.ResetExecCommands.Length; i++) + for (var i = 0; i < Config.Instance.ResetExecCommands.Length; i++) { - Commands.HandleCommand(TSPlayer.Server, Config.ResetExecCommands[i]); + Commands.HandleCommand(TSPlayer.Server, Config.Instance.ResetExecCommands[i]); } } } @@ -536,22 +462,22 @@ private void OnJoin(JoinEventArgs args) return; } - if (Config.OnlySoftCoresAreAllowed) + if (Config.Instance.OnlySoftCoresAreAllowed) { if (TShock.Players[args.Who].Difficulty != 0) { TShock.Players[args.Who].Disconnect(GetString("仅允许软核进入!")); } } - if (Config.BlockUnregisteredEntry) + if (Config.Instance.BlockUnregisteredEntry) { //阻止未注册进入 if (args.Who == -1 || TShock.Players[args.Who] == null || TShock.UserAccounts.GetUserAccountsByName(TShock.Players[args.Who].Name).Count == 0) { - TShock.Players[args.Who].Disconnect(Config.BlockEntryStatement); + TShock.Players[args.Who].Disconnect(Config.Instance.BlockEntryStatement); } } - if (Config.DeathLast && TShock.Players[args.Who] != null) + if (Config.Instance.DeathLast && TShock.Players[args.Who] != null) { if (this.PlayerDeath.TryGetValue(TShock.Players[args.Who].Name, out var time)) { diff --git a/src/ServerTools/ServerTools.csproj b/src/ServerTools/ServerTools.csproj index 3c450acf5..b747d0f0b 100644 --- a/src/ServerTools/ServerTools.csproj +++ b/src/ServerTools/ServerTools.csproj @@ -1,3 +1,6 @@ + + + \ No newline at end of file From d2bea9479f104c7816cd6b80e8b828186d9dc764 Mon Sep 17 00:00:00 2001 From: Controllerdestiny <523321293@qq.co> Date: Wed, 25 Dec 2024 20:17:33 +0800 Subject: [PATCH 3/5] fix ts StreamWrite --- src/ServerTools/Plugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index 4adea4423..9df363d85 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -36,7 +36,7 @@ public partial class Plugin : LazyPlugin public Plugin(Main game) : base(game) { - typeof(TextLog).GetField("_logWriter")?.SetValue(TShock.Log, new StreamWriter(TShock.Log.FileName, true, new UTF32Encoding(true, true))); + typeof(TextLog).GetField("_logWriter")?.SetValue(TShock.Log, new StreamWriter(TShock.Log.FileName, true, new UTF8Encoding(true, true))); } private RestCommand[] addRestCommands = null!; From 70e4b6797936f5a43b8f515139835310e9891d91 Mon Sep 17 00:00:00 2001 From: Controllerdestiny <523321293@qq.co> Date: Wed, 25 Dec 2024 20:51:39 +0800 Subject: [PATCH 4/5] fix --- src/ServerTools/Plugin.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index 9df363d85..1d286b418 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -36,7 +36,8 @@ public partial class Plugin : LazyPlugin public Plugin(Main game) : base(game) { - typeof(TextLog).GetField("_logWriter")?.SetValue(TShock.Log, new StreamWriter(TShock.Log.FileName, true, new UTF8Encoding(true, true))); + new Hook(typeof(TextLog).GetConstructor(new Type[] { typeof(string), typeof(bool) }), TextLogCtor); + } private RestCommand[] addRestCommands = null!; @@ -244,6 +245,14 @@ public static void RestPlayerCtor(Action orig(self, name, group); } + public static void TextLogCtor(Action orig, TextLog self, string filename, bool clear) + { + typeof(TextLog) + .GetField("_logWriter", System.Reflection.BindingFlags.NonPublic) + ?.SetValue(self, new StreamWriter(TShock.Log.FileName, !clear, new UTF8Encoding(true, true))); + orig(self, filename, clear); + } + private void OnPlayerSpawn(object? sender, GetDataHandlers.SpawnEventArgs e) { if (e.Player != null) From c6b42c026b78d31e90a025c56a555f1bcf35d304 Mon Sep 17 00:00:00 2001 From: Controllerdestiny <523321293@qq.co> Date: Wed, 25 Dec 2024 21:04:43 +0800 Subject: [PATCH 5/5] add config disable emoji option --- src/ServerTools/Config.cs | 4 ++++ src/ServerTools/Plugin.cs | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/ServerTools/Config.cs b/src/ServerTools/Config.cs index 5d73e60a2..938604fbc 100644 --- a/src/ServerTools/Config.cs +++ b/src/ServerTools/Config.cs @@ -38,6 +38,10 @@ public class Config : JsonConfigBase [LocalizedPropertyName(CultureType.English, "SetJourneyDifficult")] public bool SetJourneyDifficult = false; + [LocalizedPropertyName(CultureType.Chinese, "禁用Emoji消息")] + [LocalizedPropertyName(CultureType.English, "DisableEmojiMessage")] + public bool DisableEmojiMessage = false; + [LocalizedPropertyName(CultureType.Chinese, "旅途模式难度")] [LocalizedPropertyName(CultureType.English, "JourneyDifficult")] public string JourneyMode = "master"; diff --git a/src/ServerTools/Plugin.cs b/src/ServerTools/Plugin.cs index 1d286b418..c1ddd7727 100644 --- a/src/ServerTools/Plugin.cs +++ b/src/ServerTools/Plugin.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using Rests; using System.Text; +using System.Text.RegularExpressions; using Terraria; using Terraria.GameContent.Creative; using TerrariaApi.Server; @@ -36,7 +37,6 @@ public partial class Plugin : LazyPlugin public Plugin(Main game) : base(game) { - new Hook(typeof(TextLog).GetConstructor(new Type[] { typeof(string), typeof(bool) }), TextLogCtor); } @@ -81,6 +81,7 @@ public override void Initialize() TShock.RestApi.Register(command); } Timer += this.OnUpdatePlayerOnline; + On.OTAPI.Hooks.MessageBuffer.InvokeGetData += this.MessageBuffer_InvokeGetData; this.HandleCommandLine(Environment.GetCommandLineArgs()); } protected override void Dispose(bool disposing) @@ -113,6 +114,7 @@ protected override void Dispose(bool disposing) GetDataHandlers.PlayerSpawn.UnRegister(this.OnPlayerSpawn); GetDataHandlers.PlayerUpdate.UnRegister(this.OnUpdate); #endregion + On.OTAPI.Hooks.MessageBuffer.InvokeGetData -= this.MessageBuffer_InvokeGetData; CmdHook?.Dispose(); AccountInfoHook?.Dispose(); Timer -= this.OnUpdatePlayerOnline; @@ -152,6 +154,32 @@ private void OnUpdate(object? sender, GetDataHandlers.PlayerUpdateEventArgs e) } } } + + private bool MessageBuffer_InvokeGetData(On.OTAPI.Hooks.MessageBuffer.orig_InvokeGetData orig, MessageBuffer instance, ref byte packetId, ref int readOffset, ref int start, ref int length, ref int messageType, int maxPackets) + { + + if (packetId == (byte) PacketTypes.LoadNetModule) + { + using var ms = new MemoryStream(instance.readBuffer); + ms.Position = readOffset; + using var reader = new BinaryReader(ms); + var id = reader.ReadUInt16(); + if (id == Terraria.Net.NetManager.Instance.GetId()) + { + var msg = Terraria.Chat.ChatMessage.Deserialize(reader); + if (msg.Text.Length > Config.Instance.ChatLength) + { + return false; + } + + if (Config.Instance.DisableEmojiMessage && Regex.IsMatch(msg.Text, @"[\uD800-\uDBFF][\uDC00-\uDFFF]")) + { + return false; + } + } + } + return orig(instance, ref packetId, ref readOffset, ref start, ref length, ref messageType, maxPackets); + } private static void OnStrike(NpcStrikeEventArgs args) @@ -245,14 +273,6 @@ public static void RestPlayerCtor(Action orig(self, name, group); } - public static void TextLogCtor(Action orig, TextLog self, string filename, bool clear) - { - typeof(TextLog) - .GetField("_logWriter", System.Reflection.BindingFlags.NonPublic) - ?.SetValue(self, new StreamWriter(TShock.Log.FileName, !clear, new UTF8Encoding(true, true))); - orig(self, filename, clear); - } - private void OnPlayerSpawn(object? sender, GetDataHandlers.SpawnEventArgs e) { if (e.Player != null)