From 3886609251f2a20bdcde161133e3f00228903e1e Mon Sep 17 00:00:00 2001 From: xien <2383759126@qq.com> Date: Fri, 19 Apr 2024 18:40:27 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=EF=BC=9AAutoclear=E6=99=BA=E8=83=BD=E8=87=AA=E5=8A=A8=E6=89=AB?= =?UTF-8?q?=E5=9C=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Autoclear/Autoclear.cs | 139 +++++++++++++++++++++++++++++++++++++ Autoclear/Autoclear.csproj | 13 ++++ Autoclear/Configuration.cs | 72 +++++++++++++++++++ Autoclear/README.md | 39 +++++++++++ Plugin.sln | 10 +++ 5 files changed, 273 insertions(+) create mode 100644 Autoclear/Autoclear.cs create mode 100644 Autoclear/Autoclear.csproj create mode 100644 Autoclear/Configuration.cs create mode 100644 Autoclear/README.md diff --git a/Autoclear/Autoclear.cs b/Autoclear/Autoclear.cs new file mode 100644 index 000000000..805d39c06 --- /dev/null +++ b/Autoclear/Autoclear.cs @@ -0,0 +1,139 @@ +using System; +using System.Configuration; +using Terraria; +using TerrariaApi.Server; +using TShockAPI; +using TShockAPI.Hooks; + +namespace Autoclear +{ + [ApiVersion(2, 1)] + public class Autoclear : TerrariaPlugin + { + public override string Author => "大豆子[Mute适配1447],肝帝熙恩更新"; + public override string Description => "智能扫地机"; + public override string Name => "智能自动扫地"; + public override Version Version => new Version(1, 0, 3); + public static Configuration Config; + private bool _sweepScheduled = false; + private DateTime _sweepScheduledAt; + + public Autoclear(Main game) : base(game) + { + LoadConfig(); + } + + private static void LoadConfig() + { + Config = Configuration.Read(Configuration.FilePath); + Config.Write(Configuration.FilePath); + } + + private static void ReloadConfig(ReloadEventArgs args) + { + LoadConfig(); + args.Player?.SendSuccessMessage("[{0}] 重新加载配置完毕。", typeof(Autoclear).Name); + } + + public override void Initialize() + { + GeneralHooks.ReloadEvent += ReloadConfig; + ServerApi.Hooks.GameUpdate.Register(this, OnUpdate); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + ServerApi.Hooks.GameUpdate.Deregister(this, OnUpdate); + } + base.Dispose(disposing); + } + + private void OnUpdate(EventArgs args) + { + int totalItems2 = 0; + for (int i = 0; i < Main.item.Length; i++) + { + if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type)) + { + totalItems2++; + } + } + + if (totalItems2 >= Config.SmartSweepThreshold) + { + if (!_sweepScheduled) + { + _sweepScheduled = true; + _sweepScheduledAt = DateTime.UtcNow.AddSeconds(Config.DelayedSweepTimeoutSeconds); + + // 发送倒计时消息 + if (Config.SpecificMessage) + { + TSPlayer.All.SendSuccessMessage($"{Config.DelayedSweepCustomMessage}"); + } + } + } + if (_sweepScheduled && DateTime.UtcNow >= _sweepScheduledAt) + { + // 到达清扫时间,执行清扫任务 + _sweepScheduled = false; + PerformSmartSweep(); + } + } + + private void PerformSmartSweep() + { + int totalItems = 0; + int totalThrowable = 0; + int totalSwinging = 0; + int totalRegular = 0; + int totalEquipment = 0; + int totalVanity = 0; + + for (int i = 0; i < Main.item.Length; i++) + { + if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type)) + { + bool isThrowable = Main.item[i].damage > 0 && Main.item[i].maxStack > 1; + bool isSwinging = Main.item[i].damage > 0 && Main.item[i].maxStack == 1; + bool isRegular = Main.item[i].damage < 0 && Main.item[i].maxStack > 1; + bool isEquipment = Main.item[i].damage == 0 && Main.item[i].maxStack == 1; + bool isVanity = Main.item[i].damage < 0 && Main.item[i].maxStack == 1; + + if ((Config.SweepThrowable && isThrowable) || + (Config.SweepSwinging && isSwinging) || + (Config.SweepRegular && isRegular) || + (Config.SweepEquipment && isEquipment) || + (Config.SweepVanity && isVanity)) + { + Main.item[i].active = false; + TSPlayer.All.SendData(PacketTypes.ItemDrop, " ", i, 0f, 0f, 0f, 0); + totalItems++; + + if (isThrowable) totalThrowable++; + if (isSwinging) totalSwinging++; + if (isRegular) totalRegular++; + if (isEquipment) totalEquipment++; + if (isVanity) totalVanity++; + } + } + } + + if (totalItems > 0) + { + if (!string.IsNullOrEmpty(Config.CustomMessage)) + { + TSPlayer.All.SendSuccessMessage($"{Config.CustomMessage}"); + } + + if (Config.SpecificMessage) + { + TSPlayer.All.SendSuccessMessage($"智能扫地机已清扫:[c/FFFFFF:{totalItems}]种物品"); + TSPlayer.All.SendSuccessMessage($"包含:【投掷武器[c/FFFFFF:{totalThrowable}]】-【挥动武器[c/FFFFFF:{totalSwinging}]】-【普通物品[c/FFFFFF:{totalRegular}]】-【装备[c/FFFFFF:{totalEquipment}]】-【时装[c/FFFFFF:{totalVanity}]】"); + } + } + } + } +} \ No newline at end of file diff --git a/Autoclear/Autoclear.csproj b/Autoclear/Autoclear.csproj new file mode 100644 index 000000000..f041a9b95 --- /dev/null +++ b/Autoclear/Autoclear.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/Autoclear/Configuration.cs b/Autoclear/Configuration.cs new file mode 100644 index 000000000..bf808d44e --- /dev/null +++ b/Autoclear/Configuration.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.IO; +using Newtonsoft.Json; +using TShockAPI; + +namespace Autoclear +{ + public class Configuration + { + public static readonly string FilePath = Path.Combine(TShock.SavePath, "AutoClear.json"); + + [JsonProperty("不清扫的物品ID列表")] + public List NonSweepableItemIDs { get; set; } = new List(); + + [JsonProperty("智能清扫数量临界值")] + public int SmartSweepThreshold { get; set; } = 100; + + [JsonProperty("延迟清扫(s)")] + public int DelayedSweepTimeoutSeconds { get; set; } = 10; + + [JsonProperty("延迟清扫自定义消息")] + public string DelayedSweepCustomMessage { get; set; } = ""; + + [JsonProperty("是否清扫挥动武器")] + public bool SweepSwinging { get; set; } = true; + + [JsonProperty("是否清扫投掷武器")] + public bool SweepThrowable { get; set; } = true; + + [JsonProperty("是否清扫普通物品")] + public bool SweepRegular { get; set; } = true; + + [JsonProperty("是否清扫装备")] + public bool SweepEquipment { get; set; } = true; + + [JsonProperty("是否清扫时装")] + public bool SweepVanity { get; set; } = true; + + [JsonProperty("完成清扫自定义消息")] + public string CustomMessage { get; set; } = ""; + + [JsonProperty("具体消息")] + public bool SpecificMessage { get; set; } = true; + + + public void Write(string path) + { + using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write)) + { + var str = JsonConvert.SerializeObject(this, Formatting.Indented); + using (var sw = new StreamWriter(fs)) + { + sw.Write(str); + } + } + } + + public static Configuration Read(string path) + { + if (!File.Exists(path)) + return new Configuration(); + using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using (var sr = new StreamReader(fs)) + { + var cf = JsonConvert.DeserializeObject(sr.ReadToEnd()); + return cf; + } + } + } +} +} \ No newline at end of file diff --git a/Autoclear/README.md b/Autoclear/README.md new file mode 100644 index 000000000..b184db80f --- /dev/null +++ b/Autoclear/README.md @@ -0,0 +1,39 @@ +# Autoclear 智能自动扫地 + +- 作者: 大豆子[Mute适配1447],肝帝熙恩更新 +- 出处: TShock中文官方群 +- 当地面物品数量到达一定值开始清扫倒计时 +- 可自定义哪些/哪类物品不被清扫 + +## 更新日志 + +``` +暂无 +``` + +## 指令 + +``` +暂无 +``` + +## 配置 + +```json +{ + "不清扫的物品ID列表": [], + "智能清扫数量临界值": 100, + "延迟清扫(s)": 10, + "延迟清扫自定义消息": "", + "是否清扫挥动武器": true, + "是否清扫投掷武器": true, + "是否清扫普通物品": true, + "是否清扫装备": true, + "是否清扫时装": true, + "完成清扫自定义消息": "", + "具体消息": true +} +``` +## 反馈 +- 共同维护的插件库:https://github.com/THEXN/TShockPlugin/ +- 国内社区trhub.cn 或 TShock官方群等 \ No newline at end of file diff --git a/Plugin.sln b/Plugin.sln index 2a38d0050..fbe018c83 100644 --- a/Plugin.sln +++ b/Plugin.sln @@ -94,6 +94,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Invincibility", "Invincibil EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ezperm", "Ezperm\Ezperm.csproj", "{4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Autoclear", "Autoclear\Autoclear.csproj", "{75442E3B-E8FD-4B36-BA0B-7113005E5D11}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -446,6 +448,14 @@ Global {4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|Any CPU.Build.0 = Release|Any CPU {4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|x64.ActiveCfg = Release|Any CPU {4AB96380-C0D3-4746-87FF-D5FF0AFF1AE3}.Release|x64.Build.0 = Release|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|x64.ActiveCfg = Debug|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Debug|x64.Build.0 = Debug|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|Any CPU.Build.0 = Release|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|x64.ActiveCfg = Release|Any CPU + {75442E3B-E8FD-4B36-BA0B-7113005E5D11}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From dd18a1b4b75f24b95a0b64a588a0cee97e825530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=82=9D=E5=B8=9D=E7=86=99=E6=81=A9?= <111548550+THEXN@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:41:29 +0800 Subject: [PATCH 2/4] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 77024deee..7ae1c3c7e 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,4 @@ | [History](History/README.md) | 历史图格记录 | 无 | | [Invincibility](Invincibility/README.md) | 限时无敌 | 无 | | [Ezperm](Ezperm/README.md) | 批量改权限 | 无 | +| [AutoClear](AutoClear/README.md) | 智能自动扫地 | 无 | From 5e5147bcfca687e98d753690e77a864d01a27731 Mon Sep 17 00:00:00 2001 From: xien <2383759126@qq.com> Date: Fri, 19 Apr 2024 19:10:07 +0800 Subject: [PATCH 3/4] =?UTF-8?q?1=E7=A7=92=E6=A3=80=E6=B5=8B=E4=B8=80?= =?UTF-8?q?=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Autoclear/Autoclear.cs | 46 +++++++++++++++++++++----------------- Autoclear/Autoclear.csproj | 12 ++-------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/Autoclear/Autoclear.cs b/Autoclear/Autoclear.cs index 805d39c06..8b291b877 100644 --- a/Autoclear/Autoclear.cs +++ b/Autoclear/Autoclear.cs @@ -17,6 +17,7 @@ public class Autoclear : TerrariaPlugin public static Configuration Config; private bool _sweepScheduled = false; private DateTime _sweepScheduledAt; + private int _updateCounter; public Autoclear(Main game) : base(game) { @@ -52,34 +53,39 @@ protected override void Dispose(bool disposing) private void OnUpdate(EventArgs args) { - int totalItems2 = 0; - for (int i = 0; i < Main.item.Length; i++) + _updateCounter++; + + if (_updateCounter % 60 == 0) { - if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type)) + int totalItems2 = 0; + for (int i = 0; i < Main.item.Length; i++) { - totalItems2++; + if (Main.item[i].active && !Config.NonSweepableItemIDs.Contains(Main.item[i].type)) + { + totalItems2++; + } } - } - if (totalItems2 >= Config.SmartSweepThreshold) - { - if (!_sweepScheduled) + if (totalItems2 >= Config.SmartSweepThreshold) { - _sweepScheduled = true; - _sweepScheduledAt = DateTime.UtcNow.AddSeconds(Config.DelayedSweepTimeoutSeconds); - - // 发送倒计时消息 - if (Config.SpecificMessage) + if (!_sweepScheduled) { - TSPlayer.All.SendSuccessMessage($"{Config.DelayedSweepCustomMessage}"); + _sweepScheduled = true; + _sweepScheduledAt = DateTime.UtcNow.AddSeconds(Config.DelayedSweepTimeoutSeconds); + + // 发送倒计时消息 + if (Config.SpecificMessage) + { + TSPlayer.All.SendSuccessMessage($"{Config.DelayedSweepCustomMessage}"); + } } } - } - if (_sweepScheduled && DateTime.UtcNow >= _sweepScheduledAt) - { - // 到达清扫时间,执行清扫任务 - _sweepScheduled = false; - PerformSmartSweep(); + if (_sweepScheduled && DateTime.UtcNow >= _sweepScheduledAt) + { + // 到达清扫时间,执行清扫任务 + _sweepScheduled = false; + PerformSmartSweep(); + } } } diff --git a/Autoclear/Autoclear.csproj b/Autoclear/Autoclear.csproj index f041a9b95..639adc026 100644 --- a/Autoclear/Autoclear.csproj +++ b/Autoclear/Autoclear.csproj @@ -1,13 +1,5 @@ - - net6.0 - enable - enable - + - - - - - + \ No newline at end of file From 4678f0b605b1fde626e398a5d85a3cf4f1fea3dd Mon Sep 17 00:00:00 2001 From: xien <2383759126@qq.com> Date: Fri, 19 Apr 2024 19:17:31 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=A4=9A=E4=B9=85=E6=A3=80=E6=B5=8B=E4=B8=80=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Autoclear/Autoclear.cs | 2 +- Autoclear/Configuration.cs | 5 ++++- Autoclear/README.md | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Autoclear/Autoclear.cs b/Autoclear/Autoclear.cs index 8b291b877..ef6d3f697 100644 --- a/Autoclear/Autoclear.cs +++ b/Autoclear/Autoclear.cs @@ -55,7 +55,7 @@ private void OnUpdate(EventArgs args) { _updateCounter++; - if (_updateCounter % 60 == 0) + if (_updateCounter % (60 * Config.detectionIntervalSeconds) == 0) { int totalItems2 = 0; for (int i = 0; i < Main.item.Length; i++) diff --git a/Autoclear/Configuration.cs b/Autoclear/Configuration.cs index bf808d44e..974dc0018 100644 --- a/Autoclear/Configuration.cs +++ b/Autoclear/Configuration.cs @@ -9,11 +9,14 @@ public class Configuration { public static readonly string FilePath = Path.Combine(TShock.SavePath, "AutoClear.json"); + [JsonProperty("多久检测一次(s)")] + public int SmartSweepThreshold { get; set; } = 100; + [JsonProperty("不清扫的物品ID列表")] public List NonSweepableItemIDs { get; set; } = new List(); [JsonProperty("智能清扫数量临界值")] - public int SmartSweepThreshold { get; set; } = 100; + public int detectionIntervalSeconds { get; set; } = 10; [JsonProperty("延迟清扫(s)")] public int DelayedSweepTimeoutSeconds { get; set; } = 10; diff --git a/Autoclear/README.md b/Autoclear/README.md index b184db80f..375834397 100644 --- a/Autoclear/README.md +++ b/Autoclear/README.md @@ -21,6 +21,7 @@ ```json { + "多久检测一次(s)": 10, "不清扫的物品ID列表": [], "智能清扫数量临界值": 100, "延迟清扫(s)": 10,