From a2e0a425d8ed8fae27667a8cc38ec2af4439ad00 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 22 Oct 2024 01:26:54 +0000 Subject: [PATCH 01/14] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AD=90=E6=A8=A1=E5=9D=97=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Submodules/Yaaiomni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Submodules/Yaaiomni b/src/Submodules/Yaaiomni index ad2829677..debf82951 160000 --- a/src/Submodules/Yaaiomni +++ b/src/Submodules/Yaaiomni @@ -1 +1 @@ -Subproject commit ad2829677d3534e614d709773017bf03c252f24d +Subproject commit debf82951dd84bd307fc7bce06a1c03160479976 From 437143129e2b589b7e9f9cfd526da9b9a970ea3e Mon Sep 17 00:00:00 2001 From: xien <2383759126@qq.com> Date: Tue, 22 Oct 2024 23:21:43 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=EF=BC=9AAutoAirItem=20=E8=87=AA=E5=8A=A8=E5=9E=83=E5=9C=BE?= =?UTF-8?q?=E6=A1=B6=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugin.sln | 12 +- src/AutoAirItem/AutoAirItem.cs | 211 +++++++++++++++++++++++++++++ src/AutoAirItem/AutoAirItem.csproj | 5 + src/AutoAirItem/Commands.cs | 164 ++++++++++++++++++++++ src/AutoAirItem/Configuration.cs | 61 +++++++++ src/AutoAirItem/MyData.cs | 44 ++++++ src/AutoAirItem/README.md | 91 +++++++++++++ 7 files changed, 587 insertions(+), 1 deletion(-) create mode 100644 src/AutoAirItem/AutoAirItem.cs create mode 100644 src/AutoAirItem/AutoAirItem.csproj create mode 100644 src/AutoAirItem/Commands.cs create mode 100644 src/AutoAirItem/Configuration.cs create mode 100644 src/AutoAirItem/MyData.cs create mode 100644 src/AutoAirItem/README.md diff --git a/Plugin.sln b/Plugin.sln index af8293b70..888237a1d 100644 --- a/Plugin.sln +++ b/Plugin.sln @@ -232,7 +232,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DonotFuck", "src\DonotFuck\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lagrange.XocMat.Adapter", "src\Lagrange.XocMat.Adapter\Lagrange.XocMat.Adapter.csproj", "{AF5C3B5E-D8CD-4292-8047-EF129C839BB2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ItemBox", "src\ItemBox\ItemBox.csproj", "{F1C47139-1211-4951-B922-BBF4BCEE36FE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ItemBox", "src\ItemBox\ItemBox.csproj", "{F1C47139-1211-4951-B922-BBF4BCEE36FE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoAirItem", "src\AutoAirItem\AutoAirItem.csproj", "{E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1146,6 +1148,14 @@ Global {F1C47139-1211-4951-B922-BBF4BCEE36FE}.Release|Any CPU.Build.0 = Release|Any CPU {F1C47139-1211-4951-B922-BBF4BCEE36FE}.Release|x64.ActiveCfg = Release|Any CPU {F1C47139-1211-4951-B922-BBF4BCEE36FE}.Release|x64.Build.0 = Release|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Debug|x64.ActiveCfg = Debug|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Debug|x64.Build.0 = Debug|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Release|Any CPU.Build.0 = Release|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Release|x64.ActiveCfg = Release|Any CPU + {E08099EC-478F-4B1A-9EBF-9EA8A27C52C9}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/AutoAirItem/AutoAirItem.cs b/src/AutoAirItem/AutoAirItem.cs new file mode 100644 index 000000000..1290a8359 --- /dev/null +++ b/src/AutoAirItem/AutoAirItem.cs @@ -0,0 +1,211 @@ +using System.Text; +using Terraria; +using Terraria.ID; +using TerrariaApi.Server; +using TShockAPI; +using TShockAPI.Hooks; + +namespace AutoAirItem; + +[ApiVersion(2, 1)] +public class AutoAirItem : TerrariaPlugin +{ + #region 插件信息 + public override string Name => "自动垃圾桶"; + public override string Author => "羽学"; + public override Version Version => new Version(1, 1, 0); + public override string Description => "涡轮增压不蒸鸭"; + #endregion + + #region 注册与释放 + public AutoAirItem(Main game) : base(game) { } + private GeneralHooks.ReloadEventD _reloadHandler; + internal static Configuration Config = new(); + internal static MyData data = new(); + public override void Initialize() + { + LoadConfig(); + this._reloadHandler = (_) => LoadConfig(); + GeneralHooks.ReloadEvent += this._reloadHandler; + ServerApi.Hooks.GameUpdate.Register(this, this.OnGameUpdate); + ServerApi.Hooks.ServerJoin.Register(this, OnJoin); + ServerApi.Hooks.ServerLeave.Register(this, OnLeave); + TShockAPI.Commands.ChatCommands.Add(new Command("AutoAir.use", Commands.AirCmd, "air", "垃圾")); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + GeneralHooks.ReloadEvent -= this._reloadHandler; + ServerApi.Hooks.GameUpdate.Deregister(this, this.OnGameUpdate); + ServerApi.Hooks.ServerJoin.Deregister(this, OnJoin); + ServerApi.Hooks.ServerLeave.Deregister(this, OnLeave); + TShockAPI.Commands.ChatCommands.RemoveAll(x => x.CommandDelegate == Commands.AirCmd); + } + base.Dispose(disposing); + } + #endregion + + #region 配置重载读取与写入方法 + private static void LoadConfig() + { + Config = Configuration.Read(); + Config.Write(); + TShock.Log.ConsoleInfo("[自动垃圾桶]重新加载配置完毕。"); + } + #endregion + + #region 玩家更新配置方法(计入记录时间并创建配置结构) + private void OnJoin(JoinEventArgs args) + { + var plr = TShock.Players[args.Who]; + var list = data.Items.FirstOrDefault(x => x.Name == plr.Name); + + if (!Config.Open) + { + return; + } + + //不是数据表里玩家则给他自动创建数据 + if (!data.Items.Any(item => item.Name == plr.Name)) + { + data.Items.Add(new MyData.ItemData() + { + Name = plr.Name, + Enabled = true, + IsActive = true, + Auto = true, + LogTime = DateTime.Now, + Mess = true, + ItemName = new List() + }); + } + else + { + list!.LogTime = DateTime.Now; + list.IsActive = true; + } + } + #endregion + + #region 玩家离开服务器更新记录时间,横比所有玩家的记录时间,如超过清理周期,则自动删除玩家数据 + private static int ClearCount = 0; //需要清理的玩家计数 + private void OnLeave(LeaveEventArgs args) + { + var plr = TShock.Players[args.Who]; + var list = data.Items.FirstOrDefault(x => x.Name == plr.Name); + + if (!Config.Open) + { + return; + } + + //离开服务器更新记录时间与活跃状态 + if (data.Items.Any(item => item.Name == plr.Name)) + { + list!.LogTime = DateTime.Now; + list.IsActive = false; + } + + if (Config.ClearData) + { + var Remove = data.Items.Where(list => list.LogTime != default && + (DateTime.Now - list.LogTime).TotalHours >= Config.timer).ToList(); + + //数据清理的播报内容 + var mess = new StringBuilder(); + mess.AppendLine($"[i:3455][c/AD89D5:自][c/D68ACA:动][c/DF909A:垃][c/E5A894:圾][c/E5BE94:桶][i:3454]"); + mess.AppendLine($"以下玩家 与 [c/ABD6C7:{plr.Name}] 离开时间\n【[c/A1D4C2:{DateTime.Now}]】\n" + + $"超过 [c/E17D8C:{Config.timer}] 小时 已清理 [c/76D5B4:自动垃圾桶] 数据:"); + + foreach (var plr2 in Remove) + { + //只显示小时数 F0整数 F1保留1位小数 F2保留2位 如:24.01小时 + var hours = (DateTime.Now - plr2.LogTime).TotalHours; + FormattableString Hours = $"{hours:F0}"; + + //更新时间超过Config预设的时间,并该玩家更新状态为false则添加计数并移除数据 + if (hours >= Config.timer && !plr2.IsActive) + { + ClearCount++; + mess.AppendFormat("[c/A7DDF0:{0}]:[c/74F3C9:{1}小时], ", plr2.Name, Hours); + data.Items.Remove(plr2); + } + } + + //确保有一个玩家计数,只播报一次 + if (ClearCount > 0 && mess.Length > 0) + { + //广告开关 + if (Config.Enabled) + { + //自定义广告内容 + mess.AppendLine(Config.Advertisement); + } + + TShock.Utils.Broadcast(mess.ToString(), 247, 244, 150); + ClearCount = 0; + } + } + } + #endregion + + #region 触发自动垃圾桶 + public static long Timer = 0L; + private void OnGameUpdate(EventArgs args) + { + Timer++; + + if (!Config.Open) + { + return; + } + + foreach (var plr in TShock.Players.Where(plr => plr != null && plr.Active && plr.IsLoggedIn)) + { + var list = data.Items.FirstOrDefault(x => x.Name == plr.Name); + if (list != null && list.Enabled && Timer % Config.UpdateRate == 0) + { + AutoAirItems(plr, list.ItemName, list.Auto, list.Mess); + } + } + } + #endregion + + #region 自动清理物品方法 + public static bool AutoAirItems(TSPlayer player, List List, bool Auto, bool mess) + { + var plr = player.TPlayer; + + for (int i = 0; i < plr.inventory.Length; i++) + { + var item = plr.inventory[i]; + var id = TShock.Utils.GetItemById(item.type).netID; + + if (Auto) + { + if (!plr.trashItem.IsAir && !List.Contains(plr.trashItem.Name)) + { + List.Add(plr.trashItem.Name); + player.SendMessage($"已将 '[c/92C5EC:{plr.trashItem.Name}]'添加到自动垃圾桶|指令菜单:[c/A1D4C2:/air]", 255, 246, 158); + } + } + + if (item != null && List.Contains(item.Name) && item.Name != plr.inventory[plr.selectedItem].Name) + { + item.TurnToAir(); + player.SendData(PacketTypes.PlayerSlot, null, player.Index, PlayerItemSlotID.Inventory0 + i); + + if (mess) + { + var itemName = Lang.GetItemNameValue(id); + player.SendMessage($"【自动垃圾桶】已将 '[c/92C5EC:{itemName}]'从您的背包中移除", 255, 246, 158); + } + return true; + } + } + return false; + } + #endregion +} diff --git a/src/AutoAirItem/AutoAirItem.csproj b/src/AutoAirItem/AutoAirItem.csproj new file mode 100644 index 000000000..f489ab64e --- /dev/null +++ b/src/AutoAirItem/AutoAirItem.csproj @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/AutoAirItem/Commands.cs b/src/AutoAirItem/Commands.cs new file mode 100644 index 000000000..992446f9a --- /dev/null +++ b/src/AutoAirItem/Commands.cs @@ -0,0 +1,164 @@ +using Microsoft.Xna.Framework; +using Terraria; +using TShockAPI; + +namespace AutoAirItem; + +public class Commands +{ + public static void AirCmd(CommandArgs args) + { + var name = args.Player.Name; + var data = AutoAirItem.data.Items.FirstOrDefault(item => item.Name == name); + + if (!AutoAirItem.Config.Open) + { + return; + } + + if (data == null) + { + args.Player.SendInfoMessage("请用角色[c/D95065:重进服务器]后输入:/air 指令查看菜单\n羽学声明:本插件纯属[c/7E93DE:免费]请勿上当受骗", 217,217,217); + return; + } + + if (args.Parameters.Count == 0) + { + HelpCmd(args.Player); + if (!data.Enabled) + { + args.Player.SendSuccessMessage($"请输入该指令开启→: [c/92C5EC:/air on] "); + } + else + { + args.Player.SendSuccessMessage($"您的垃圾桶监听状态为:[c/92C5EC:{data.Auto}]"); + args.Player.SendSuccessMessage($"输入指令切换自动模式:[c/92C5EC:/air auto]"); + } + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "list") + { + args.Player.SendInfoMessage($"[{data.Name}的垃圾桶]\n" + string.Join(", ", data.ItemName.Select(x => "[c/92C5EC:{0}]".SFormat(x)))); + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "on") + { + var isEnabled = data.Enabled; + data.Enabled = !isEnabled; + var Mess = isEnabled ? "禁用" : "启用"; + args.Player.SendSuccessMessage($"玩家 [{args.Player.Name}] 已[c/92C5EC:{Mess}]自动垃圾桶功能。"); + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "clear") + { + data.ItemName.Clear(); + args.Player.SendSuccessMessage($"已清理[c/92C5EC: {args.Player.Name} ]的自动垃圾桶表"); + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "yes") + { + data.ItemName.Add(args.TPlayer.inventory[args.TPlayer.selectedItem].Name); + args.Player.SendSuccessMessage("手选物品 [c/92C5EC:{0}] 已加入自动垃圾桶中! 脱手即清!", args.TPlayer.inventory[args.TPlayer.selectedItem].Name); + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "auto") + { + var isEnabled = data.Auto; + data.Auto = !isEnabled; + var Mess = isEnabled ? "禁用" : "启用"; + args.Player.SendSuccessMessage($"玩家 [{args.Player.Name}] 的垃圾桶位格监听功能已[c/92C5EC:{Mess}]"); + return; + } + + if (args.Parameters.Count == 1 && args.Parameters[0].ToLower() == "mess") + { + var isEnabled = data.Mess; + data.Mess = !isEnabled; + var Mess = isEnabled ? "禁用" : "启用"; + args.Player.SendSuccessMessage($"玩家 [{args.Player.Name}] 的自动清理消息已[c/92C5EC:{Mess}]"); + return; + } + + if (args.Parameters.Count == 2) + { + Item item; + List Items = TShock.Utils.GetItemByIdOrName(args.Parameters[1]); + if (Items.Count > 1) + { + args.Player.SendMultipleMatchError(Items.Select(i => i.Name)); + return; + } + + if (Items.Count == 0) + { + args.Player.SendErrorMessage("不存在该物品,\"物品查询\": \"[c/92C5EC:https://terraria.wiki.gg/zh/wiki/Item_IDs]\""); + return; + } + + else + { + item = Items[0]; + } + + switch (args.Parameters[0].ToLower()) + { + case "add": + { + if (data.ItemName.Contains(item.Name)) + { + args.Player.SendErrorMessage("物品 [c/92C5EC:{0}] 已在垃圾桶中!", item.Name); + return; + } + data.ItemName.Add(item.Name); + args.Player.SendSuccessMessage("已成功将物品添加到垃圾桶: [c/92C5EC:{0}]!", item.Name); + break; + } + case "delete": + case "del": + case "remove": + { + if (!data.ItemName.Contains(item.Name)) + { + args.Player.SendErrorMessage("物品 {0} 不在垃圾桶中!", item.Name); + return; + } + data.ItemName.Remove(item.Name); + args.Player.SendSuccessMessage("已成功从垃圾桶删除物品: [c/92C5EC:{0}]!", item.Name); + break; + } + + default: + { + HelpCmd(args.Player); + break; + } + } + } + } + + #region 菜单方法 + private static void HelpCmd(TSPlayer player) + { + if (player == null) return; + else + { + player.SendMessage("【自动垃圾桶】指令菜单\n" + + "/air —— 查看垃圾桶菜单\n" + + "/air on —— 开启|关闭垃圾桶功能\n" + + "/air list —— 列出自己的垃圾桶\n" + + "/air clear —— 清理垃圾桶\n" + + "/air yes —— 将手持物品加入垃圾桶\n" + + "/air auto —— 监听垃圾桶位格开关\n" + + "/air mess —— 开启|关闭清理消息\n" + + "/air add 或 del 物品名字 —— 添加|删除《自动垃圾桶》的物品", Color.AntiqueWhite); + } + } + #endregion + + +} diff --git a/src/AutoAirItem/Configuration.cs b/src/AutoAirItem/Configuration.cs new file mode 100644 index 000000000..3c401661d --- /dev/null +++ b/src/AutoAirItem/Configuration.cs @@ -0,0 +1,61 @@ +using Newtonsoft.Json; +using TShockAPI; + +namespace AutoAirItem; + +internal class Configuration +{ + #region 实例变量 + [JsonProperty("插件指令权限", Order = -16)] + public string Text { get; set; } = "指令菜单:/air 或 /垃圾,权限名【AutoAir.use】,给玩家权限:/group addperm default AutoAir.use"; + + [JsonProperty("使用说明", Order = -15)] + public string Text2 { get; set; } = "玩家每次进出服都会更新【记录时间】,玩家A离线时间与玩家B登录时间相差超过【清理周期】所设定的时间,则自动清理该玩家A的数据"; + + [JsonProperty("插件开关", Order = -14)] + public bool Open { get; set; } = true; + + [JsonProperty("清理垃圾速度", Order = -2)] + public int UpdateRate = 10; + + [JsonProperty("广告开关", Order = -1)] + public bool Enabled { get; set; } = true; + + [JsonProperty("广告内容", Order = -1)] + public string Advertisement { get; set; } = $"\n[i:3456][C/F2F2C7:插件开发] [C/BFDFEA:by] [c/00FFFF:羽学][i:3459]"; + + [JsonProperty("是否清理数据", Order = 1)] + public bool ClearData { get; set; } = true; + + [JsonProperty("清理数据周期/小时", Order = 2)] + public long timer { get; set; } = 24; + + + #endregion + + #region 读取与创建配置文件方法 + public static readonly string FilePath = Path.Combine(TShock.SavePath, "自动垃圾桶.json"); + + public void Write() + { + var json = JsonConvert.SerializeObject(this, Formatting.Indented); + File.WriteAllText(FilePath, json); + } + + public static Configuration Read() + { + if (!File.Exists(FilePath)) + { + var NewConfig = new Configuration(); + new Configuration().Write(); + return NewConfig; + } + else + { + var jsonContent = File.ReadAllText(FilePath); + return JsonConvert.DeserializeObject(jsonContent)!; + } + } + #endregion + +} \ No newline at end of file diff --git a/src/AutoAirItem/MyData.cs b/src/AutoAirItem/MyData.cs new file mode 100644 index 000000000..71a79f2fb --- /dev/null +++ b/src/AutoAirItem/MyData.cs @@ -0,0 +1,44 @@ +namespace AutoAirItem; + +public class MyData +{ + //玩家数据表 + public List Items { get; set; } = new List(); + + #region 数据结构 + public class ItemData + { + //玩家名字 + public string Name { get; set; } + + public bool IsActive { get; set; } + + //玩家出入服务器的记录时间 + public DateTime LogTime { get; set; } + + //玩家自己的垃圾桶开关 + public bool Enabled { get; set; } = false; + + //监听垃圾桶位格开关 + public bool Auto { get; set; } = false; + + //垃圾桶的回收提示 + public bool Mess { get; set; } = true; + + //垃圾桶表 + public List ItemName { get; set; } + + public ItemData(string name = "",bool Active = true, bool enabled = true, bool auto = true, bool mess = true, DateTime time = default, List item = null!) + { + this.Name = name ?? ""; + this.IsActive = Active; + this.Enabled = enabled; + this.LogTime = time; + this.Auto = auto; + this.Mess = mess; + this.ItemName = item ?? new List(); + } + } + + #endregion +} diff --git a/src/AutoAirItem/README.md b/src/AutoAirItem/README.md new file mode 100644 index 000000000..46a01febe --- /dev/null +++ b/src/AutoAirItem/README.md @@ -0,0 +1,91 @@ +# AutoAirItem 自动垃圾桶插件 + +- 作者: 羽学 +- 出处: 无 +- Tshock版自动垃圾桶,帮助玩家清理自身垃圾的小插件 +- 由玩家使用指令独立运行的插件,无需服主写配置, +- 它会自动根据玩家加入服务器自动创建配置结构。 +- 通过玩家指令交互的一款全自动插件。 + +## 更新日志 +``` +v1.1.0 +将数据表内容从Config移到插件内部的MyData类里, +不再以来对配置文件的频繁写入,避免玩家太多时把Config写爆。 +第一次进服自动开启垃圾桶功能,并在玩家把物品放到垃圾桶时会触发相关指令提示 +加入了对玩家在线状态判断,避免人在服里玩了24小时导致无辜被清理数据。 +加入了对清理哪些玩家数据时的离服播报 + + +v1.0.2 +加入了将手持物品加入垃圾桶指令:/air yes +未选中后才会清理,选中时哪怕输错了,也可以用/air del 物品名 移除 +加入了开启关闭清理信息指令:/air mess +加入了监听玩家垃圾桶位格功能,当物品放入垃圾桶时自动添加到《垃圾桶表》处理 + +v1.0.1 +移除了每次/air add 或 del时的插件启用状态提醒 +加入【清理数据周期】逻辑: +玩家每次进出服都会更新【记录时间】, +玩家A离线时间与玩家B登录时间相差 +超过【清理周期】所设定的时间,则自动清理该玩家A的数据 +如果《清理数据周期》:设置超过9999999999小时,就相当于永远不清理数据了 + +v1.0.0 +根据使用Mod《更好的体验》的想法,实现的一个Tshock版自动垃圾桶 +清理垃圾速度单位为帧率,数值越小清理越快。 +使用指令/air on开启插件 +使用/air add 物品名 或 物品id 或 Alt+左键点选物品,自动将物品名写入到配置文件当中 +根据玩家进服事件自动创建 "玩家数据表", +"垃圾桶物品"存在物品且开启了"垃圾桶开关"时会主动触发清理逻辑 +配备了"登录时间"用于给服主参考:是否需要自己手动移除该玩家的数据 +``` + +## 指令 + +| 语法 | 别名 | 权限 | 说明 | +| -------------------------------- | :---: | :--------------: | :--------------------------------------: | +| /air | /垃圾 | AutoAir.use | 指令菜单 | +| /air on | /垃圾 on | AutoAir.use | 开启或关闭自身的垃圾桶功能 | +| /air list | /垃圾 list | AutoAir.use | 列出自己的垃圾桶物品名 | +| /air clear | /垃圾 clear | AutoAir.use | 清空自己的垃圾桶表 | +| /air yes | /垃圾 yes | AutoAir.use | 手持物品加入垃圾桶表 | +| /air auto | /垃圾 auto | AutoAir.use | 将物品放入垃圾桶位格时自动添加垃圾桶表 | +| /air mess | /垃圾 mess | AutoAir.use | 开启或关闭清理消息 | +| /air add 或 del id | /垃圾 add 或 del 物品名| AutoAir.use | 添加或移除自己的垃圾桶物品 | + +--- +注意事项 +--- +1.`如何给玩家添加权限`请使用该指令在控制台发送: `/group addperm default AutoAir.use` + +2.`垃圾桶开关`与`垃圾桶物品`和均由玩家游戏内指令触发! + +3.`玩家数据表`由玩家加入服务器后`自动写入`,假设存在同名玩家,则会更新该玩家的`记录时间`(离线也会更新一次记录时间) + +4.`清理垃圾速度`的单位为帧率,数值越小清理`速度越快`。 + +5.`清理数据周期` 玩家A`离线时间为00:00`,玩家B`登录时间为00:10`,`清理周期为10小时` 玩家A未能在`10:10之前`登录游戏,`当玩家B离开`就会`清空玩家A`的自动垃圾桶数据 + +6.`清理数据周期`如果设置超过`9999999999小时`就相当于永远不清理数据了 + +7.`监听垃圾桶`使用指令`/air auto`开启,当垃圾桶位格放入物品时自动添加垃圾桶表内 + +## 配置 + +```json +{ + "插件指令权限": "指令菜单:/air 或 /垃圾,权限名【AutoAir.use】,给玩家权限:/group addperm default AutoAir.use", + "使用说明": "玩家每次进出服都会更新【记录时间】,玩家A离线时间与玩家B登录时间相差超过【清理周期】所设定的时间,则自动清理该玩家A的数据", + "插件开关": true, + "清理垃圾速度": 60, + "广告开关": true, + "广告内容": "[i:3456][C/F2F2C7:插件开发] [C/BFDFEA:by] [c/00FFFF:羽学][i:3459]", + "是否清理数据": true, + "清理数据周期/小时": 24 +} +``` +## 反馈 +- 优先发issued -> 共同维护的插件库:https://github.com/UnrealMultiple/TShockPlugin +- 次优先:TShock官方群:816771079 +- 大概率看不到但是也可以:国内社区trhub.cn ,bbstr.net , tr.monika.love \ No newline at end of file From 246ce6302c170713d5088add539450ff75798d96 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: Tue, 22 Oct 2024 23:22:17 +0800 Subject: [PATCH 03/14] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5ae45c28c..9363d00f1 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ | [AutoPluginManager](src/AutoPluginManager/README.md) | 一键自动更新插件 | 无 | | [AdditionalPylons](src/AdditionalPylons/README.md) | 放置更多晶塔 | 无 | | [AnnouncementBoxPlus](src/AnnouncementBoxPlus/README.md) | 广播盒功能强化 | 无 | +| [AutoAirItem](src/AutoAirItem/README.md) | 自动垃圾桶插件 | 无 | | [AutoBroadcast](src/AutoBroadcast/README.md) | 自动广播 | 无 | | [AutoClear](src/Autoclear/README.md) | 智能自动扫地 | 无 | | [AutoReset](src/AutoReset/README.md) | 完全自动重置 | 无 | From 2d69440f366eb990498782062cc935d19bb07237 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: Tue, 22 Oct 2024 23:23:13 +0800 Subject: [PATCH 04/14] Update README_en.md --- README_en.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_en.md b/README_en.md index 0a63e79ff..2b2db68ba 100644 --- a/README_en.md +++ b/README_en.md @@ -61,6 +61,7 @@ | [AdditionalPylons](src/AdditionalPylons/README_EN.md) | Yes | Place more Pylons | No | | [AnnouncementBoxPlus](src/AnnouncementBoxPlus/README.md) | No | Enhance Broadcast Box Functionality | No | | [AutoBroadcast](src/AutoBroadcast/README_EN.md) | Yes | Automatic broadcast | No | +| [AutoAirItem](src/AutoAirItem/README.md) | Automatic trash cans | No | | [AutoClear](src/Autoclear/README_EN.md) | Yes | Intelligent automatic cleaning | No | | [AutoReset](src/AutoReset/README_EN.md) | Yes | Fully automatic reset | No | | [AutoStoreItems](src/AutoStoreItems/README_EN.md) | Yes | Automatic storage | No | From 56ef7804f86e075179fa6103394e1136dd4ff10c Mon Sep 17 00:00:00 2001 From: xien <2383759126@qq.com> Date: Wed, 23 Oct 2024 20:54:08 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9AEssentialsPlus?= =?UTF-8?q?=E7=9A=84i18n=E6=94=AF=E6=8C=81=E8=8B=B1=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BedSet/README_EN.md | 2 +- src/EssentialsPlus/Commands.cs | 252 ++++++------ src/EssentialsPlus/EssentialsPlus.cs | 56 +-- src/EssentialsPlus/README.md | 8 +- src/EssentialsPlus/README_EN.md | 91 +++++ src/EssentialsPlus/i18n/en-US.po | 542 ++++++++++++++++++++++++++ src/EssentialsPlus/i18n/es-ES.po | 540 ++++++++++++++++++++++++++ src/EssentialsPlus/i18n/template.pot | 555 +++++++++++++++++++++++++++ 8 files changed, 1888 insertions(+), 158 deletions(-) create mode 100644 src/EssentialsPlus/README_EN.md create mode 100644 src/EssentialsPlus/i18n/en-US.po create mode 100644 src/EssentialsPlus/i18n/es-ES.po create mode 100644 src/EssentialsPlus/i18n/template.pot diff --git a/src/BedSet/README_EN.md b/src/BedSet/README_EN.md index 1831b7333..56aba91d5 100644 --- a/src/BedSet/README_EN.md +++ b/src/BedSet/README_EN.md @@ -6,7 +6,7 @@ ## Command -| 语法 | 权限 | 说明 | +| Command | Permission | Details | | -------------- | :-----------------: | :------: | | /shome | bed.spawn.set | set spawn point| diff --git a/src/EssentialsPlus/Commands.cs b/src/EssentialsPlus/Commands.cs index acbc96585..c79202275 100644 --- a/src/EssentialsPlus/Commands.cs +++ b/src/EssentialsPlus/Commands.cs @@ -20,14 +20,14 @@ public static async void Find(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("格式错误!正确的语法是:{0}find <-类> <名称...> [页数]", + e.Player.SendErrorMessage(GetString("格式错误!正确的语法是:{0}find <-参数> <名称...> [页数]"), TShock.Config.Settings.CommandSpecifier); - e.Player.SendSuccessMessage("有效的 {0}find 类:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-command: 查找命令."); - e.Player.SendInfoMessage("-item: 查找物品."); - e.Player.SendInfoMessage("-npc: 查找NPC."); - e.Player.SendInfoMessage("-tile: 查找方块."); - e.Player.SendInfoMessage("-wall: 查找墙壁."); + e.Player.SendSuccessMessage(GetString("有效的 {0}find 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-command: 查找命令.")); + e.Player.SendInfoMessage(GetString("-item: 查找物品.")); + e.Player.SendInfoMessage(GetString("-npc: 查找NPC.")); + e.Player.SendInfoMessage(GetString("-tile: 查找方块.")); + e.Player.SendInfoMessage(GetString("-wall: 查找墙壁.")); return; } @@ -35,7 +35,7 @@ public static async void Find(CommandArgs e) if (!string.IsNullOrWhiteSpace(match.Groups["page"].Value) && (!int.TryParse(match.Groups["page"].Value, out page) || page <= 0)) { - e.Player.SendErrorMessage("无效的页数 '{0}'!", match.Groups["page"].Value); + e.Player.SendErrorMessage(GetString("无效的页数 '{0}'!"), match.Groups["page"].Value); return; } @@ -55,16 +55,16 @@ await Task.Run(() => var command in TShockAPI.Commands.ChatCommands.FindAll(c => c.Names.Any(s => s.ContainsInsensitive(match.Groups[2].Value)))) { - commands.Add(string.Format("{0} (权限: {1})", command.Name, command.Permissions.FirstOrDefault())); + commands.Add(string.Format(GetString("{0} (权限: {1})"), command.Name, command.Permissions.FirstOrDefault())); } }); PaginationTools.SendPage(e.Player, page, commands, new PaginationTools.Settings { - HeaderFormat = "找到的命令 ({0}/{1}):", - FooterFormat = string.Format("输入 /find -command {0} {{0}} 查看更多", match.Groups[2].Value), - NothingToDisplayString = "未找到命令。" + HeaderFormat = GetString("找到的命令 ({0}/{1}):"), + FooterFormat = string.Format(GetString("输入 /find -command {0} {{0}} 查看更多"), match.Groups[2].Value), + NothingToDisplayString = GetString("未找到命令。") }); return; } @@ -102,9 +102,9 @@ await Task.Run(() => PaginationTools.SendPage(e.Player, page, items, new PaginationTools.Settings { - HeaderFormat = "找到的物品 ({0}/{1}):", - FooterFormat = string.Format("输入 /find -item {0} {{0}} 查看更多", match.Groups[2].Value), - NothingToDisplayString = "未找到物品。" + HeaderFormat = GetString("找到的物品 ({0}/{1}):"), + FooterFormat = string.Format(GetString("输入 /find -item {0} {{0}} 查看更多"), match.Groups[2].Value), + NothingToDisplayString = GetString("未找到物品。") }); return; } @@ -143,9 +143,9 @@ await Task.Run(() => PaginationTools.SendPage(e.Player, page, npcs, new PaginationTools.Settings { - HeaderFormat = "找到的NPC ({0}/{1}):", - FooterFormat = string.Format("输入 /find -npc {0} {{0}} 查看更多", match.Groups[2].Value), - NothingToDisplayString = "未找到NPC。", + HeaderFormat = GetString("找到的NPC ({0}/{1}):"), + FooterFormat = string.Format(GetString("输入 /find -npc {0} {{0}} 查看更多"), match.Groups[2].Value), + NothingToDisplayString = GetString("未找到NPC。"), }); return; } @@ -189,9 +189,9 @@ await Task.Run(() => PaginationTools.SendPage(e.Player, page, tiles, new PaginationTools.Settings { - HeaderFormat = "找到的方块 ({0}/{1}):", - FooterFormat = string.Format("输入 /find -tile {0} {{0}} 查看更多", match.Groups[2].Value), - NothingToDisplayString = "未找到方块。", + HeaderFormat = GetString("找到的方块 ({0}/{1}):"), + FooterFormat = string.Format(GetString("输入 /find -tile {0} {{0}} 查看更多"), match.Groups[2].Value), + NothingToDisplayString = GetString("未找到方块。"), }); return; } @@ -234,9 +234,9 @@ await Task.Run(() => PaginationTools.SendPage(e.Player, page, walls, new PaginationTools.Settings { - HeaderFormat = "找到的墙壁 ({0}/{1}):", - FooterFormat = string.Format("输入 /find -wall {0} {{0}} 查看更多", match.Groups[2].Value), - NothingToDisplayString = "未找到墙壁。", + HeaderFormat = GetString("找到的墙壁 ({0}/{1}):"), + FooterFormat = string.Format(GetString("输入 /find -wall {0} {{0}} 查看更多"), match.Groups[2].Value), + NothingToDisplayString = GetString("未找到墙壁。"), }); return; } @@ -245,12 +245,12 @@ await Task.Run(() => default: { - e.Player.SendSuccessMessage("有效的 {0}find 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-command: 查找命令."); - e.Player.SendInfoMessage("-item: 查找物品."); - e.Player.SendInfoMessage("-npc: 查找NPC."); - e.Player.SendInfoMessage("-tile: 查找方块."); - e.Player.SendInfoMessage("-wall: 查找墙壁."); + e.Player.SendSuccessMessage(GetString("有效的 {0}find 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-command: 查找命令.")); + e.Player.SendInfoMessage(GetString("-item: 查找物品.")); + e.Player.SendInfoMessage(GetString("-npc: 查找NPC.")); + e.Player.SendInfoMessage(GetString("-tile: 查找方块.")); + e.Player.SendInfoMessage(GetString("-wall: 查找墙壁.")); return; } } @@ -263,7 +263,7 @@ public static void FreezeTime(CommandArgs e) if (FreezeTimer.Enabled) { FreezeTimer.Stop(); - TSPlayer.All.SendInfoMessage("{0} 解除了时间冻结。", e.Player.Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 解除了时间冻结。"), e.Player.Name); } else { @@ -279,7 +279,7 @@ public static void FreezeTime(CommandArgs e) TSPlayer.All.SendData(PacketTypes.TimeSet); }; FreezeTimer.Start(); - TSPlayer.All.SendInfoMessage("{0} 冻结了时间。", e.Player.Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 冻结了时间。"), e.Player.Name); } } @@ -287,7 +287,7 @@ public static void DeleteHome(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("语法错误!正确的语法是:{0}delhome <家的名称>", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("语法错误!正确的语法是:{0}delhome <家的名称>"), TShock.Config.Settings.CommandSpecifier); return; } @@ -297,16 +297,16 @@ public static void DeleteHome(CommandArgs e) { if (EssentialsPlus.Homes.DeleteHome(e.Player, homeName)) { - e.Player.SendSuccessMessage("成功删除您的家 '{0}'。", homeName); + e.Player.SendSuccessMessage(GetString("成功删除您的家 '{0}'。"), homeName); } else { - e.Player.SendErrorMessage("无法删除家,请检查日志获取更多详细信息。"); + e.Player.SendErrorMessage(GetString("无法删除家,请检查日志获取更多详细信息。")); } } else { - e.Player.SendErrorMessage("无效的家 '{0}'!", homeName); + e.Player.SendErrorMessage(GetString("无效的家 '{0}'!"), homeName); } } @@ -314,14 +314,14 @@ public static async void MyHome(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("语法错误!正确的语法是:{0}myhome <家的名称>", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("语法错误!正确的语法是:{0}myhome <家的名称>"), TShock.Config.Settings.CommandSpecifier); return; } if (Regex.Match(e.Message, @"^\w+ -l(?:ist)?$").Success) { var homes = EssentialsPlus.Homes.GetAllAsync(e.Player); - e.Player.SendInfoMessage(homes.Count == 0 ? "您没有设置家。" : "家的列表: {0}", string.Join(", ", homes.Select(h => h.Name))); + e.Player.SendInfoMessage(homes.Count == 0 ? GetString("您没有设置家。") : GetString("家的列表: {0}"), string.Join(", ", homes.Select(h => h.Name))); } else { @@ -330,11 +330,11 @@ public static async void MyHome(CommandArgs e) if (home != null) { e.Player.Teleport(home.X, home.Y); - e.Player.SendSuccessMessage("传送您到您的家 '{0}'。", homeName); + e.Player.SendSuccessMessage(GetString("传送您到您的家 '{0}'。"), homeName); } else { - e.Player.SendErrorMessage("无效的家 '{0}'!", homeName); + e.Player.SendErrorMessage(GetString("无效的家 '{0}'!"), homeName); } } } @@ -343,7 +343,7 @@ public static async void SetHome(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("语法错误!正确的语法是:{0}sethome <家的名称>", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("语法错误!正确的语法是:{0}sethome <家的名称>"), TShock.Config.Settings.CommandSpecifier); return; } @@ -352,28 +352,28 @@ public static async void SetHome(CommandArgs e) { if (EssentialsPlus.Homes.UpdateHome(e.Player, homeName, e.Player.X, e.Player.Y)) { - e.Player.SendSuccessMessage("更新了您的家 '{0}'。", homeName); + e.Player.SendSuccessMessage(GetString("更新了您的家 '{0}'。"), homeName); } else { - e.Player.SendErrorMessage("无法更新家,请检查日志获取更多详细信息。"); + e.Player.SendErrorMessage(GetString("无法更新家,请检查日志获取更多详细信息。")); } return; } if (EssentialsPlus.Homes.GetAllAsync(e.Player).Count >= e.Player.Group.GetDynamicPermission(Permissions.HomeSet)) { - e.Player.SendErrorMessage("您已达到家的设置上限!"); + e.Player.SendErrorMessage(GetString("您已达到家的设置上限!")); return; } if (EssentialsPlus.Homes.AddHome(e.Player, homeName, e.Player.X, e.Player.Y)) { - e.Player.SendSuccessMessage("设置了您的家 '{0}'。", homeName); + e.Player.SendSuccessMessage(GetString("设置了您的家 '{0}'。"), homeName); } else { - e.Player.SendErrorMessage("无法设置家,请检查日志获取更多详细信息。"); + e.Player.SendErrorMessage(GetString("无法设置家,请检查日志获取更多详细信息。")); } } @@ -391,23 +391,23 @@ public static async void KickAll(CommandArgs e) noSave = true; continue; default: - e.Player.SendSuccessMessage("有效的 {0}kickall 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-nosave: 踢出时不保存 SSC 数据."); + e.Player.SendSuccessMessage(GetString("有效的 {0}kickall 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-nosave: 踢出时不保存 SSC 数据.")); return; } } var kickLevel = e.Player.Group.GetDynamicPermission(Permissions.KickAll); - var reason = string.IsNullOrWhiteSpace(match.Groups[2].Value) ? "没有原因。" : match.Groups[2].Value; + var reason = string.IsNullOrWhiteSpace(match.Groups[2].Value) ? GetString("没有原因。") : match.Groups[2].Value; await Task.WhenAll(TShock.Players.Where(p => p != null && p.Group.GetDynamicPermission(Permissions.KickAll) < kickLevel).Select(p => Task.Run(() => { if (!noSave && p.IsLoggedIn) { p.SaveServerCharacter(); } - p.Disconnect("踢出原因: " + reason); + p.Disconnect(GetString("踢出原因: ") + reason); }))); - e.Player.SendSuccessMessage("成功踢出所有人。原因: '{0}'。", reason); + e.Player.SendSuccessMessage(GetString("成功踢出所有人。原因: '{0}'。"), reason); } @@ -416,11 +416,11 @@ public static async void RepeatLast(CommandArgs e) var lastCommand = e.Player.GetPlayerInfo().LastCommand; if (string.IsNullOrWhiteSpace(lastCommand)) { - e.Player.SendErrorMessage("您没有上次的命令!"); + e.Player.SendErrorMessage(GetString("您没有上次的命令!")); return; } - e.Player.SendSuccessMessage("重复执行上次的命令 '{0}{1}'!", TShock.Config.Settings.CommandSpecifier, lastCommand); + e.Player.SendSuccessMessage(GetString("重复执行上次的命令 '{0}{1}'!"), TShock.Config.Settings.CommandSpecifier, lastCommand); await Task.Run(() => TShockAPI.Commands.HandleCommand(e.Player, TShock.Config.Settings.CommandSpecifier + lastCommand)); } @@ -447,11 +447,11 @@ await Task.Run(() => } if (!full) { - e.Player.SendSuccessMessage("填满了您的物品栏。"); + e.Player.SendSuccessMessage(GetString("填满了您的物品栏。")); } else { - e.Player.SendErrorMessage("您的物品栏已经满了。"); + e.Player.SendErrorMessage(GetString("您的物品栏已经满了。")); } } else @@ -460,14 +460,14 @@ await Task.Run(() => var amtToAdd = item.maxStack - item.stack; if (amtToAdd == 0) { - e.Player.SendErrorMessage("您的{0}已经满了。", item.Name); + e.Player.SendErrorMessage(GetString("您的{0}已经满了。"), item.Name); } else if (amtToAdd > 0 && item.stack > 0) { e.Player.GiveItem(item.type, amtToAdd); } - e.Player.SendSuccessMessage("增加了您的{0}的堆叠数量。", item.Name); + e.Player.SendSuccessMessage(GetString("增加了您的{0}的堆叠数量。"), item.Name); } }); } @@ -485,7 +485,7 @@ public static async void Mute(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:/mute add <名称> [时间]"); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:/mute add <名称> [时间]")); return; } @@ -494,7 +494,7 @@ public static async void Mute(CommandArgs e) (!TShock.Utils.TryParseTime(match.Groups[3].Value, out seconds) || seconds <= 0 || seconds > int.MaxValue / 1000)) { - e.Player.SendErrorMessage("无效的时间 '{0}'!", match.Groups[3].Value); + e.Player.SendErrorMessage(GetString("无效的时间 '{0}'!"), match.Groups[3].Value); return; } @@ -507,50 +507,50 @@ public static async void Mute(CommandArgs e) var user = TShock.UserAccounts.GetUserAccountByName(playerName); if (user == null) { - e.Player.SendErrorMessage("无效的玩家或账户 '{0}'!", playerName); + e.Player.SendErrorMessage(GetString("无效的玩家或账户 '{0}'!"), playerName); } else { if (TShock.Groups.GetGroupByName(user.Group).GetDynamicPermission(Permissions.Mute) >= e.Player.Group.GetDynamicPermission(Permissions.Mute)) { - e.Player.SendErrorMessage("您不能禁言 {0}!", user.Name); + e.Player.SendErrorMessage(GetString("您不能禁言 {0}!"), user.Name); return; } if (EssentialsPlus.Mutes.AddMute(user, DateTime.UtcNow.AddSeconds(seconds))) { - TSPlayer.All.SendInfoMessage("{0} 禁言了 {1}。", e.Player.Name, user.Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 禁言了 {1}。"), e.Player.Name, user.Name); } else { - e.Player.SendErrorMessage("无法禁言,请查看日志获取更多信息。"); + e.Player.SendErrorMessage(GetString("无法禁言,请查看日志获取更多信息。")); } } } else if (players.Count > 1) { - e.Player.SendErrorMessage("匹配到多个玩家:{0}", string.Join(", ", players.Select(p => p.Name))); + e.Player.SendErrorMessage(GetString("匹配到多个玩家:{0}"), string.Join(", ", players.Select(p => p.Name))); } else { if (players[0].Group.GetDynamicPermission(Permissions.Mute) >= e.Player.Group.GetDynamicPermission(Permissions.Mute)) { - e.Player.SendErrorMessage("您不能禁言 {0}!", players[0].Name); + e.Player.SendErrorMessage(GetString("您不能禁言 {0}!"), players[0].Name); return; } if (EssentialsPlus.Mutes.AddMute(players[0], DateTime.UtcNow.AddSeconds(seconds))) { - TSPlayer.All.SendInfoMessage("{0} 禁言了 {1}。", e.Player.Name, players[0].Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 禁言了 {1}。"), e.Player.Name, players[0].Name); players[0].mute = true; try { await Task.Delay(TimeSpan.FromSeconds(seconds), players[0].GetPlayerInfo().MuteToken); players[0].mute = false; - players[0].SendInfoMessage("您已解除禁言。"); + players[0].SendInfoMessage(GetString("您已解除禁言。")); } catch (TaskCanceledException) { @@ -558,7 +558,7 @@ public static async void Mute(CommandArgs e) } else { - e.Player.SendErrorMessage("无法禁言,请查看日志获取更多信息。"); + e.Player.SendErrorMessage(GetString("无法禁言,请查看日志获取更多信息。")); } } } @@ -575,7 +575,7 @@ public static async void Mute(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:/mute del <名称>"); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:/mute del <名称>")); return; } @@ -588,34 +588,34 @@ public static async void Mute(CommandArgs e) var user = TShock.UserAccounts.GetUserAccountByName(playerName); if (user == null) { - e.Player.SendErrorMessage("无效的玩家或账户 '{0}'!", playerName); + e.Player.SendErrorMessage(GetString("无效的玩家或账户 '{0}'!"), playerName); } else { if (EssentialsPlus.Mutes.DeleteMute(user)) { - TSPlayer.All.SendInfoMessage("{0} 解除了 {1} 的禁言。", e.Player.Name, user.Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 解除了 {1} 的禁言。"), e.Player.Name, user.Name); } else { - e.Player.SendErrorMessage("无法解除禁言,请查看日志获取更多信息。"); + e.Player.SendErrorMessage(GetString("无法解除禁言,请查看日志获取更多信息。")); } } } else if (players.Count > 1) { - e.Player.SendErrorMessage("匹配到多个玩家:{0}", string.Join(", ", players.Select(p => p.Name))); + e.Player.SendErrorMessage(GetString("匹配到多个玩家:{0}"), string.Join(", ", players.Select(p => p.Name))); } else { if (EssentialsPlus.Mutes.DeleteMute(players[0])) { players[0].mute = false; - TSPlayer.All.SendInfoMessage("{0} 解除了 {1} 的禁言。", e.Player.Name, players[0].Name); + TSPlayer.All.SendInfoMessage(GetString("{0} 解除了 {1} 的禁言。"), e.Player.Name, players[0].Name); } else { - e.Player.SendErrorMessage("无法解除禁言,请查看日志获取更多信息。"); + e.Player.SendErrorMessage(GetString("无法解除禁言,请查看日志获取更多信息。")); } } } @@ -626,9 +626,9 @@ public static async void Mute(CommandArgs e) #region 帮助 default: - e.Player.SendSuccessMessage("禁言子命令:"); - e.Player.SendInfoMessage("add <名称> [时间] - 禁言玩家或账户。"); - e.Player.SendInfoMessage("del <名称> - 解除禁言玩家或账户。"); + e.Player.SendSuccessMessage(GetString("禁言子命令:")); + e.Player.SendInfoMessage(GetString("add <名称> [时间] - 禁言玩家或账户。")); + e.Player.SendInfoMessage(GetString("del <名称> - 解除禁言玩家或账户。")); return; #endregion @@ -650,7 +650,7 @@ public static void Ruler(CommandArgs e) { if (e.Player.TempPoints.Any(p => p == Point.Zero)) { - e.Player.SendErrorMessage("尺规未设置!"); + e.Player.SendErrorMessage(GetString("尺规未设置!")); return; } @@ -659,28 +659,28 @@ public static void Ruler(CommandArgs e) var x = Math.Abs(p1.X - p2.X); var y = Math.Abs(p1.Y - p2.Y); var cartesian = Math.Sqrt((x * x) + (y * y)); - e.Player.SendInfoMessage("距离:X轴:{0},Y轴:{1},直角距离:{2:N3}", x, y, cartesian); + e.Player.SendInfoMessage(GetString("距离:X轴:{0},Y轴:{1},直角距离:{2:N3}"), x, y, cartesian); } else if (e.Parameters.Count == 1) { if (e.Parameters[0] == "1") { e.Player.AwaitingTempPoint = 1; - e.Player.SendInfoMessage("修改一个方块以设置第一个尺规点。"); + e.Player.SendInfoMessage(GetString("修改一个方块以设置第一个尺规点。")); } else if (e.Parameters[0] == "2") { e.Player.AwaitingTempPoint = 2; - e.Player.SendInfoMessage("修改一个方块以设置第二个尺规点。"); + e.Player.SendInfoMessage(GetString("修改一个方块以设置第二个尺规点。")); } else { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}ruler [1/2]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}ruler [1/2]"), TShock.Config.Settings.CommandSpecifier); } } else { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}ruler [1/2]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}ruler [1/2]"), TShock.Config.Settings.CommandSpecifier); } } @@ -691,7 +691,7 @@ public static void Send(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}send [r,g,b] <文本...>", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}send [r,g,b] <文本...>"), TShock.Config.Settings.CommandSpecifier); return; } @@ -701,7 +701,7 @@ public static void Send(CommandArgs e) if (!string.IsNullOrWhiteSpace(match.Groups[1].Value) && !string.IsNullOrWhiteSpace(match.Groups[2].Value) && !string.IsNullOrWhiteSpace(match.Groups[3].Value) && (!byte.TryParse(match.Groups[1].Value, out r) || !byte.TryParse(match.Groups[2].Value, out g) || !byte.TryParse(match.Groups[3].Value, out b))) { - e.Player.SendErrorMessage("无效的颜色!"); + e.Player.SendErrorMessage(GetString("无效的颜色!")); return; } TSPlayer.All.SendMessage(match.Groups[4].Value, new Color(r, g, b)); @@ -714,9 +714,9 @@ public static async void Sudo(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}sudo [-switches...] <玩家> <命令...>", TShock.Config.Settings.CommandSpecifier); - e.Player.SendSuccessMessage("有效的 {0}sudo 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-f, -force: 强制sudo,忽略权限限制。"); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}sudo [-switches...] <玩家> <命令...>"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendSuccessMessage(GetString("有效的 {0}sudo 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-f, -force: 强制sudo,忽略权限限制。")); return; } @@ -729,14 +729,14 @@ public static async void Sudo(CommandArgs e) case "force": if (!e.Player.Group.HasPermission(Permissions.SudoForce)) { - e.Player.SendErrorMessage("您没有访问 '-{0}' 开关的权限!", capture.Value); + e.Player.SendErrorMessage(GetString("您没有访问 '-{0}' 参数的权限!"), capture.Value); return; } force = true; continue; default: - e.Player.SendSuccessMessage("有效的 {0}sudo 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-f, -force: 强制sudo,忽略权限限制。"); + e.Player.SendSuccessMessage(GetString("有效的 {0}sudo 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-f, -force: 强制sudo,忽略权限限制。")); return; } } @@ -747,25 +747,25 @@ public static async void Sudo(CommandArgs e) var players = TShock.Players.FindPlayers(playerName); if (players.Count == 0) { - e.Player.SendErrorMessage("无效的玩家 '{0}'!", playerName); + e.Player.SendErrorMessage(GetString("无效的玩家 '{0}'!"), playerName); } else if (players.Count > 1) { - e.Player.SendErrorMessage("匹配到多个玩家:{0}", string.Join(", ", players.Select(p => p.Name))); + e.Player.SendErrorMessage(GetString("匹配到多个玩家:{0}"), string.Join(", ", players.Select(p => p.Name))); } else { if ((e.Player.Group.GetDynamicPermission(Permissions.Sudo) <= players[0].Group.GetDynamicPermission(Permissions.Sudo)) && !e.Player.Group.HasPermission(Permissions.SudoSuper)) { - e.Player.SendErrorMessage("您无法强制 {0} 执行 {1}{2}!", players[0].Name, TShock.Config.Settings.CommandSpecifier, command); + e.Player.SendErrorMessage(GetString("您无法强制 {0} 执行 {1}{2}!"), players[0].Name, TShock.Config.Settings.CommandSpecifier, command); return; } - e.Player.SendSuccessMessage("强制 {0} 执行 {1}{2}。", players[0].Name, TShock.Config.Settings.CommandSpecifier, command); + e.Player.SendSuccessMessage(GetString("强制 {0} 执行 {1}{2}。"), players[0].Name, TShock.Config.Settings.CommandSpecifier, command); if (!e.Player.Group.HasPermission(Permissions.SudoInvisible)) { - players[0].SendInfoMessage("{0} 强制您执行 {1}{2}。", e.Player.Name, TShock.Config.Settings.CommandSpecifier, command); + players[0].SendInfoMessage(GetString("{0} 强制您执行 {1}{2}。"), e.Player.Name, TShock.Config.Settings.CommandSpecifier, command); } var fakePlayer = new TSPlayer(players[0].Index) @@ -792,9 +792,9 @@ public static async void TimeCmd(CommandArgs e) var match = regex.Match(e.Message); if (!match.Success) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}timecmd [-switches...] <时间> <命令...>", TShock.Config.Settings.CommandSpecifier); - e.Player.SendSuccessMessage("有效的 {0}timecmd 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-r, -repeat: 重复执行时间命令。"); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}timecmd [-switches...] <时间> <命令...>"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendSuccessMessage(GetString("有效的 {0}timecmd 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-r, -repeat: 重复执行时间命令。")); return; } @@ -808,31 +808,31 @@ public static async void TimeCmd(CommandArgs e) repeat = true; break; default: - e.Player.SendSuccessMessage("有效的 {0}timecmd 开关:", TShock.Config.Settings.CommandSpecifier); - e.Player.SendInfoMessage("-r, -repeat: 重复执行时间命令。"); + e.Player.SendSuccessMessage(GetString("有效的 {0}timecmd 参数:"), TShock.Config.Settings.CommandSpecifier); + e.Player.SendInfoMessage(GetString("-r, -repeat: 重复执行时间命令。")); return; } } if (!TShock.Utils.TryParseTime(match.Groups[2].Value, out int seconds) || seconds <= 0 || seconds > int.MaxValue / 1000) { - e.Player.SendErrorMessage("无效的时间 '{0}'!", match.Groups[2].Value); + e.Player.SendErrorMessage(GetString("无效的时间 '{0}'!"), match.Groups[2].Value); return; } if (repeat) { - e.Player.SendSuccessMessage("已排队执行命令 '{0}{1}'。使用 /cancel 取消!", TShock.Config.Settings.CommandSpecifier, match.Groups[3].Value); + e.Player.SendSuccessMessage(GetString("已排队执行命令 '{0}{1}'。使用 /cancel 取消!"), TShock.Config.Settings.CommandSpecifier, match.Groups[3].Value); } else { - e.Player.SendSuccessMessage("已排队执行命令 '{0}{1}'。使用 /cancel 取消!", TShock.Config.Settings.CommandSpecifier, match.Groups[3].Value); + e.Player.SendSuccessMessage(GetString("已排队执行命令 '{0}{1}'。使用 /cancel 取消!"), TShock.Config.Settings.CommandSpecifier, match.Groups[3].Value); } e.Player.AddResponse("cancel", o => { e.Player.GetPlayerInfo().CancelTimeCmd(); - e.Player.SendSuccessMessage("取消所有时间命令!"); + e.Player.SendSuccessMessage(GetString("取消所有时间命令!")); }); var token = e.Player.GetPlayerInfo().TimeCmdToken; @@ -858,26 +858,26 @@ public static void Back(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}eback [步数]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}eback [步数]"), TShock.Config.Settings.CommandSpecifier); return; } var steps = 1; if (e.Parameters.Count > 0 && (!int.TryParse(e.Parameters[0], out steps) || steps <= 0)) { - e.Player.SendErrorMessage("无效的步数 '{0}'!", e.Parameters[0]); + e.Player.SendErrorMessage(GetString("无效的步数 '{0}'!"), e.Parameters[0]); return; } var info = e.Player.GetPlayerInfo(); if (info.BackHistoryCount == 0) { - e.Player.SendErrorMessage("无法传送回上一个位置!"); + e.Player.SendErrorMessage(GetString("无法传送回上一个位置!")); return; } steps = Math.Min(steps, info.BackHistoryCount); - e.Player.SendSuccessMessage("传送回 {0} 步.", steps); + e.Player.SendSuccessMessage(GetString("传送回 {0} 步."), steps); var vector = info.PopBackHistory(steps); e.Player.Teleport(vector.X, vector.Y); } @@ -886,14 +886,14 @@ public static async void Down(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}down [层数]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}down [层数]"), TShock.Config.Settings.CommandSpecifier); return; } var levels = 1; if (e.Parameters.Count > 0 && (!int.TryParse(e.Parameters[0], out levels) || levels <= 0)) { - e.Player.SendErrorMessage("无效的层数 '{0}'!", levels); + e.Player.SendErrorMessage(GetString("无效的层数 '{0}'!"), levels); return; } @@ -923,7 +923,7 @@ await Task.Run(() => if (currentLevel == 0) { - e.Player.SendErrorMessage("无法传送下去!"); + e.Player.SendErrorMessage(GetString("无法传送下去!")); } else { @@ -933,7 +933,7 @@ await Task.Run(() => } e.Player.Teleport(16 * x, (16 * y) - 10); - e.Player.SendSuccessMessage("传送下 {0} 层.", currentLevel); + e.Player.SendSuccessMessage(GetString("传送下 {0} 层."), currentLevel); } } @@ -941,14 +941,14 @@ public static async void Left(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}left [层数]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}left [层数]"), TShock.Config.Settings.CommandSpecifier); return; } var levels = 1; if (e.Parameters.Count > 0 && (!int.TryParse(e.Parameters[0], out levels) || levels <= 0)) { - e.Player.SendErrorMessage("无效的层数 '{0}'!", levels); + e.Player.SendErrorMessage(GetString("无效的层数 '{0}'!"), levels); return; } @@ -981,7 +981,7 @@ await Task.Run(() => if (currentLevel == 0) { - e.Player.SendErrorMessage("无法传送左边!"); + e.Player.SendErrorMessage(GetString("无法传送左边!")); } else { @@ -991,7 +991,7 @@ await Task.Run(() => } e.Player.Teleport((16 * x) + 12, 16 * y); - e.Player.SendSuccessMessage("传送左 {0} 层.", currentLevel); + e.Player.SendSuccessMessage(GetString("传送左 {0} 层."), currentLevel); } } @@ -999,14 +999,14 @@ public static async void Right(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}right [层数]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}right [层数]"), TShock.Config.Settings.CommandSpecifier); return; } var levels = 1; if (e.Parameters.Count > 0 && (!int.TryParse(e.Parameters[0], out levels) || levels <= 0)) { - e.Player.SendErrorMessage("无效的层数 '{0}'!", levels); + e.Player.SendErrorMessage(GetString("无效的层数 '{0}'!"), levels); return; } @@ -1039,7 +1039,7 @@ await Task.Run(() => if (currentLevel == 0) { - e.Player.SendErrorMessage("无法传送右边!"); + e.Player.SendErrorMessage(GetString("无法传送右边!")); } else { @@ -1049,7 +1049,7 @@ await Task.Run(() => } e.Player.Teleport(16 * x, 16 * y); - e.Player.SendSuccessMessage("传送右 {0} 层.", currentLevel); + e.Player.SendSuccessMessage(GetString("传送右 {0} 层."), currentLevel); } } @@ -1057,14 +1057,14 @@ public static async void Up(CommandArgs e) { if (e.Parameters.Count > 1) { - e.Player.SendErrorMessage("无效的语法!正确的语法是:{0}up [层数]", TShock.Config.Settings.CommandSpecifier); + e.Player.SendErrorMessage(GetString("无效的语法!正确的语法是:{0}up [层数]"), TShock.Config.Settings.CommandSpecifier); return; } var levels = 1; if (e.Parameters.Count > 0 && (!int.TryParse(e.Parameters[0], out levels) || levels <= 0)) { - e.Player.SendErrorMessage("无效的层数 '{0}'!", levels); + e.Player.SendErrorMessage(GetString("无效的层数 '{0}'!"), levels); return; } @@ -1097,7 +1097,7 @@ await Task.Run(() => if (currentLevel == 0) { - e.Player.SendErrorMessage("无法传送上面!"); + e.Player.SendErrorMessage(GetString("无法传送上面!")); } else { @@ -1107,7 +1107,7 @@ await Task.Run(() => } e.Player.Teleport(16 * x, (16 * y) + 6); - e.Player.SendSuccessMessage("传送上 {0} 层.", currentLevel); + e.Player.SendSuccessMessage(GetString("传送上 {0} 层."), currentLevel); } } diff --git a/src/EssentialsPlus/EssentialsPlus.cs b/src/EssentialsPlus/EssentialsPlus.cs index 9d6fba452..feb25e2d3 100644 --- a/src/EssentialsPlus/EssentialsPlus.cs +++ b/src/EssentialsPlus/EssentialsPlus.cs @@ -24,7 +24,7 @@ public class EssentialsPlus : TerrariaPlugin public override string Name => "EssentialsPlus"; - public override Version Version => new Version(1, 0, 2); + public override Version Version => new Version(1, 0, 3); public EssentialsPlus(Main game) @@ -67,7 +67,7 @@ private void OnReload(ReloadEventArgs e) Config.Write(path); } Homes.Reload(); - e.Player.SendSuccessMessage("[EssentialsPlus] 重新加载配置和家!"); + e.Player.SendSuccessMessage(GetString("[EssentialsPlus] 重新加载配置和家!")); } private readonly List teleportCommands = new List @@ -93,7 +93,7 @@ private void OnPlayerCommand(PlayerCommandEventArgs e) .Intersect(Config.DisabledCommandsInPvp.Select(s => s.ToLowerInvariant())) .Any()) { - e.Player.SendErrorMessage("在PvP中无法使用该命令!"); + e.Player.SendErrorMessage(GetString("在PvP中无法使用该命令!")); e.Handled = true; return; } @@ -131,9 +131,9 @@ private void OnInitialize(EventArgs e) string.IsNullOrWhiteSpace(Config.MySqlDbName)) { Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("[Essentials+] MySQL已启用,但未设置Essentials+ MySQL配置。"); - Console.WriteLine("[Essentials+] 请在essentials.json中配置您的MySQL服务器信息,然后重新启动服务器。"); - Console.WriteLine("[Essentials+] 此插件现在将禁用自身..."); + Console.WriteLine(GetString("[Essentials+] MySQL已启用,但未设置Essentials+ MySQL配置。")); + Console.WriteLine(GetString("[Essentials+] 请在essentials.json中配置您的MySQL服务器信息,然后重新启动服务器。")); + Console.WriteLine(GetString("[Essentials+] 此插件现在将禁用自身...")); Console.ResetColor(); GeneralHooks.ReloadEvent -= this.OnReload; @@ -150,7 +150,7 @@ private void OnInitialize(EventArgs e) var host = Config.MySqlHost.Split(':'); Db = new MySqlConnection { - ConnectionString = string.Format("Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", + ConnectionString = string.Format( "Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", host[0], host.Length == 1 ? "3306" : host[1], Config.MySqlDbName, @@ -163,7 +163,7 @@ private void OnInitialize(EventArgs e) Db = TShock.Config.Settings.StorageType.Equals("sqlite", StringComparison.OrdinalIgnoreCase) ? (IDbConnection) new SqliteConnection( "Data Source=" + Path.Combine(TShock.SavePath, "essentials.sqlite")) - : throw new InvalidOperationException("无效的存储类型!"); + : throw new InvalidOperationException(GetString("无效的存储类型!")); } Mutes = new MuteManager(Db); @@ -183,103 +183,103 @@ private void OnInitialize(EventArgs e) Add(new Command(Permissions.Find, Commands.Find, "find", "查找") { - HelpText = "查找具有指定名称的物品和/或NPC。" + HelpText = GetString("查找具有指定名称的物品和/或NPC。") }); Add(new Command(Permissions.FreezeTime, Commands.FreezeTime, "freezetime", "冻结时间") { - HelpText = "切换冻结时间。" + HelpText = GetString("切换冻结时间。") }); Add(new Command(Permissions.HomeDelete, Commands.DeleteHome, "delhome", "删除家点") { AllowServer = false, - HelpText = "删除您的一个家点。" + HelpText = GetString("删除您的一个家点。") }); Add(new Command(Permissions.HomeSet, Commands.SetHome, "sethome", "设置家点") { AllowServer = false, - HelpText = "设置您的一个家点。" + HelpText = GetString("设置您的一个家点。") }); Add(new Command(Permissions.HomeTp, Commands.MyHome, "myhome", "我的家点") { AllowServer = false, - HelpText = "传送到您的一个家点。" + HelpText = GetString("传送到您的一个家点。") }); Add(new Command(Permissions.KickAll, Commands.KickAll, "kickall", "踢出所有人") { - HelpText = "踢出服务器上的所有人。" + HelpText = GetString("踢出服务器上的所有人。") }); Add(new Command(Permissions.LastCommand, Commands.RepeatLast, "=", "重复上一条命令") { - HelpText = "允许您重复上一条命令。" + HelpText = GetString("允许您重复上一条命令。") }); Add(new Command(Permissions.More, Commands.More, "more", "最大化堆叠") { AllowServer = false, - HelpText = "最大化手持物品的堆叠。" + HelpText = GetString("最大化手持物品的堆叠。") }); //这将覆盖TShock的 'mute' 命令 Add(new Command(Permissions.Mute, Commands.Mute, "mute", "禁言管理") { - HelpText = "管理禁言。" + HelpText = GetString("管理禁言。") }); Add(new Command(Permissions.PvP, Commands.PvP, "pvpget2", "切换PvP状态") { AllowServer = false, - HelpText = "切换您的PvP状态。" + HelpText = GetString("切换您的PvP状态。") }); Add(new Command(Permissions.Ruler, Commands.Ruler, "ruler", "测量工具") { AllowServer = false, - HelpText = "允许您测量两个方块之间的距离。" + HelpText = GetString("允许您测量两个方块之间的距离。") }); Add(new Command(Permissions.Send, Commands.Send, "send", "广播消息") { - HelpText = "以自定义颜色广播消息。" + HelpText = GetString("以自定义颜色广播消息。") }); Add(new Command(Permissions.Sudo, Commands.Sudo, "sudo", "代执行") { - HelpText = "允许您以其他用户的身份执行命令。" + HelpText = GetString("允许您以其他用户的身份执行命令。") }); Add(new Command(Permissions.TimeCmd, Commands.TimeCmd, "timecmd", "定时命令") { - HelpText = "在给定时间间隔后执行命令。" + HelpText = GetString("在给定时间间隔后执行命令。") }); Add(new Command(Permissions.TpBack, Commands.Back, "eback", "b", "回到") { AllowServer = false, - HelpText = "在死亡或传送后将您传送回之前的位置。" + HelpText = GetString("在死亡或传送后将您传送回之前的位置。") }); Add(new Command(Permissions.TpDown, Commands.Down, "down", "向下传送") { AllowServer = false, - HelpText = "通过一个方块层向下传送您。" + HelpText = GetString("通过一个方块层向下传送您。") }); Add(new Command(Permissions.TpLeft, Commands.Left, "left", "向左传送") { AllowServer = false, - HelpText = "通过一个方块层向左传送您。" + HelpText = GetString("通过一个方块层向左传送您。") }); Add(new Command(Permissions.TpRight, Commands.Right, "right", "向右传送") { AllowServer = false, - HelpText = "通过一个方块层向右传送您。" + HelpText = GetString("通过一个方块层向右传送您。") }); Add(new Command(Permissions.TpUp, Commands.Up, "up", "向上传送") { AllowServer = false, - HelpText = "通过一个方块层向上传送您。" + HelpText = GetString("通过一个方块层向上传送您。") }); @@ -314,7 +314,7 @@ private async void OnJoin(JoinEventArgs e) { await Task.Delay(muteExpiration - DateTime.UtcNow, player.GetPlayerInfo().MuteToken); player.mute = false; - player.SendInfoMessage("您已被解除禁言。"); + player.SendInfoMessage(GetString("您已被解除禁言。")); } catch (TaskCanceledException) { diff --git a/src/EssentialsPlus/README.md b/src/EssentialsPlus/README.md index f28aa0ad9..c01522f24 100644 --- a/src/EssentialsPlus/README.md +++ b/src/EssentialsPlus/README.md @@ -2,17 +2,19 @@ - 作者: WhiteX等人,Average,Cjx,肝帝熙恩适配与修改,Cai更新 - 出处: [github](https://github.com/QuiCM/EssentialsPlus) -- 提供一些管理指令 +- Essentials+ 是一种组合,用于改进和优化 Essentials 和 MoreAdminCommands 中的某些功能。所有命令都是异步执行的。不包括 Flag 命令。 ## 更新日志 ``` +1.0.3 +i18n完成,且预置es-EN 1.0.2 修复数据库错误 1.0.1 修复重启无法获取禁言的BUG, 重命名一些方法 ``` -## 指令 ## +## 指令 - **/find** 或 **/查找** -> 包含多个子命令: - **-command** 或 **-命令** -> 根据输入搜索特定命令,返回匹配的命令及其权限。 @@ -46,7 +48,7 @@ -## 权限 ## +## 权限 - essentials.find -> 允许使用 /find 命令。 - essentials.freezetime -> 允许使用 /freezetime 命令。 diff --git a/src/EssentialsPlus/README_EN.md b/src/EssentialsPlus/README_EN.md new file mode 100644 index 000000000..fef6879a0 --- /dev/null +++ b/src/EssentialsPlus/README_EN.md @@ -0,0 +1,91 @@ +# EssentialsPlus + +- Authors: WhiteX等人,Average,Cjx,肝帝熙恩适配与修改,Cai更新 +- Source: [github](https://github.com/QuiCM/EssentialsPlus) +- Essentials+ is a combination of things from Essentials and things from MoreAdminCommands made better. All commands run asynchronously. It does not include Sign Commands. + + +## Commands + +- **/find** -> Includes several subcommands: + - **-command** -> Searches for specific commands based on input and returns matching commands and their permissions. + - **-item** -> Searches for specific items based on input and returns matching items and their IDs. + - **-tile** -> Searches for specific tiles based on input and returns matching tiles and their IDs. + - **-wall** -> Searches for specific walls based on input and returns matching walls and their IDs. +- **/freezetime** -> Freezes or unfreezes time. +- **/delhome** -> Deletes one of your home points. +- **/sethome** -> Sets one of your home points. +- **/myhome** -> Teleports you to one of your home points. +- **/kickall** -> Kicks all players from the server. +- **/=** -> Repeats the last command you entered (does not include other iterations of /=). +- **/more** -> Maximizes the stack of the item in your hand. Subcommand: + - **-all** -> Maximizes all stackable items in the player's inventory. +- **/mute** -> Overrides TShock's /mute command. Includes subcommands: + - **add**