diff --git a/ViewInventory.cs b/ViewInventory.cs new file mode 100644 index 0000000..9b446a1 --- /dev/null +++ b/ViewInventory.cs @@ -0,0 +1,514 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using TShockAPI; +using Terraria; +using TerrariaApi.Server; +using Microsoft.Xna.Framework; +using System.Data; +using TShockAPI.DB; +using Terraria.ID; +//using + +namespace ViewInventory +{ + [ApiVersion(2, 1)] + public class ViewInventory : TerrariaPlugin + { + /// + /// Gets the author(s) of this plugin + /// + public override string Author => "z枳"; + + /// + /// Gets the description of this plugin. + /// A short, one lined description that tells people what your plugin does. + /// + public override string Description => "查阅背包"; + + /// + /// Gets the name of this plugin. + /// + public override string Name => "ViewInventory"; + + /// + /// Gets the version of this plugin. + /// + public override Version Version => new Version(1, 0, 0, 0); + + /// + /// Initializes a new instance of the TestPlugin class. + /// This is where you set the plugin's order and perfrom other constructor logic + ///初始化TestPlugin类的新实例。 + ///这是设置插件顺序和性能的地方,来自其他构造函数逻辑 + /// + public ViewInventory(Main game) : base(game) + { + } + + /// + /// Handles plugin initialization. + /// Fired when the server is started and the plugin is being loaded. + /// You may register hooks, perform loading procedures etc here. + ///处理插件初始化。 + ///在服务器启动和插件加载时触发。 + ///您可以在此处注册挂钩、执行加载过程等。 + /// + public override void Initialize() + { + Commands.ChatCommands.Add(new Command("vi", ViewInvent, "vi", "VI", "Vi", "vI", "v i") + { + HelpText = "输入 /vi 【玩家名】 来查看该玩家的库存\nEnter /vi [player name] to view the player's inventory" + }); + Commands.ChatCommands.Add(new Command("vi", ViewInventDisorder, "vid", "VID", "Vid", "vId") + { + HelpText = "输入 /vid 【玩家名】 来查看该玩家的库存,不进行排列\nEnter / vid [player name] to view the player's inventory without sorting" + }); + Commands.ChatCommands.Add(new Command("vi", ViewInventText, "vit", "VIT", "Vit", "vIt") + { + HelpText = "输入 /vit 【玩家名】 来查看该玩家的库存,不进行排列\nEnter / vit [player name] to view the player's inventory without sorting" + }); + } + + + /// + /// Handles plugin disposal logic. + /// *Supposed* to fire when the server shuts down. + /// You should deregister hooks and free all resources here. + ///处理插件处理逻辑。 + ///*Supposed**应该*在服务器关闭时触发。 + ///您应该取消注册挂钩并释放此处的所有资源。 + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + } + base.Dispose(disposing); + } + + //分类查阅指令 + private void ViewInvent(CommandArgs args) + { + if (!args.Parameters.Any()) + { + args.Player.SendInfoMessage("输入 /vi 【玩家名】 来查看该玩家的库存\nEnter / vi [player name] to view the player's inventory"); + return; + } + string name = args.Parameters[0]; + if (args.Parameters.Count > 1) + { + name = string.Join(" ", args.Parameters); + } + + List list = TSPlayer.FindByNameOrID(name); + if (list.Any()) + { + foreach (var li in list) + { + StringBuilder sb = new StringBuilder(); + string inventory = GetItemsString(li.TPlayer.inventory, NetItem.InventorySlots); + string armor = GetItemsString(li.TPlayer.armor, NetItem.ArmorSlots); + string dyestuff = GetItemsString(li.TPlayer.dye, NetItem.DyeSlots); + string misc = GetItemsString(li.TPlayer.miscEquips, NetItem.MiscEquipSlots); + string miscDye = GetItemsString(li.TPlayer.miscDyes, NetItem.MiscDyeSlots); + string trash = string.Format("【[i/s{0}:{1}]】 ", li.TPlayer.trashItem.stack, li.TPlayer.trashItem.netID); + + string pig = GetItemsFromChestString(li.TPlayer.bank, NetItem.PiggySlots); + string safe = GetItemsFromChestString(li.TPlayer.bank2, NetItem.SafeSlots); + string forge = GetItemsFromChestString(li.TPlayer.bank3, NetItem.ForgeSlots); + string vault = GetItemsFromChestString(li.TPlayer.bank4, NetItem.VoidSlots); + + sb.AppendLine("玩家 【" + li.Name + "】 的所有库存如下:"); + if (inventory.Length > 0 && inventory != null && inventory != "") + { + sb.AppendLine("背包:"); + sb.AppendLine(FormatArrangement(inventory, 20, " ")); + } + if (armor.Length > 0 && armor != null && armor != "") + { + sb.AppendLine("盔甲 + 饰品 + 时装:"); + sb.AppendLine(armor); + } + if (dyestuff.Length > 0 && dyestuff != null && dyestuff != "") + { + sb.AppendLine("染料:"); + sb.AppendLine(dyestuff); + } + if (misc.Length > 0 && misc != null && misc != "") + { + sb.AppendLine("宠物 + 矿车 + 坐骑 + 钩爪:"); + sb.AppendLine(misc); + } + if (miscDye.Length > 0 && miscDye != null && miscDye != "") + { + sb.AppendLine("宠物 矿车 坐骑 钩爪 染料:"); + sb.AppendLine(miscDye); + } + if (trash != "【[i/s0:0]】 ") + { + sb.AppendLine("垃圾桶:"); + sb.AppendLine(trash); + } + if (pig.Length > 0 && pig != null && pig != "") + { + sb.AppendLine("猪猪储蓄罐:"); + sb.AppendLine(FormatArrangement(pig, 20, " ")); + } + if (safe.Length > 0 && safe != null && safe != "") + { + sb.AppendLine("保险箱:"); + sb.AppendLine(FormatArrangement(safe, 20, " ")); + } + if (forge.Length > 0 && forge != null && forge != "") + { + sb.AppendLine("护卫熔炉:"); + sb.AppendLine(FormatArrangement(forge, 20, " ")); + } + if (vault.Length > 0 && vault != null && vault != "") + { + sb.AppendLine("虚空金库:"); + sb.AppendLine(FormatArrangement(vault, 20, " ")); + } + if (sb.Length > 0 && sb != null && sb.ToString() != "") + args.Player.SendMessage(sb.ToString(), TextColor()); + else + args.Player.SendInfoMessage("没有任何东西"); + } + } + else + { + args.Player.SendInfoMessage("所查询玩家不在线,正在查询离线数据"); + string offAll = GetOfflinePlayerInv(TShock.DB, name); + offAll = FormatArrangement(offAll, 35); + if (offAll != "") + { + args.Player.SendMessage("玩家 【" + name + "】 的所有库存如下:" + "\n" + offAll, TextColor()); + } + else + { + args.Player.SendInfoMessage("该玩家不存在!"); + } + } + } + + //不分类查阅指令 + private void ViewInventDisorder(CommandArgs args) + { + if (!args.Parameters.Any()) + { + args.Player.SendInfoMessage("输入 /vid 【玩家名】 来查看该玩家的库存,不进行排列\nEnter / vid [player name] to view the player's inventory without sorting"); + return; + } + string name = args.Parameters[0]; + if (args.Parameters.Count > 1) + { + name = string.Join(" ", args.Parameters); + } + + List list = TSPlayer.FindByNameOrID(name); + if (list.Any()) + { + foreach (var li in list) + { + string inventory = GetItemsString(li.TPlayer.inventory, NetItem.InventorySlots); + string armor = GetItemsString(li.TPlayer.armor, NetItem.ArmorSlots); + string dyestuff = GetItemsString(li.TPlayer.dye, NetItem.DyeSlots); + string misc = GetItemsString(li.TPlayer.miscEquips, NetItem.MiscEquipSlots); + string miscDye = GetItemsString(li.TPlayer.miscDyes, NetItem.MiscDyeSlots); + string trash = string.Format("【[i/s{0}:{1}]】 ", li.TPlayer.trashItem.stack, li.TPlayer.trashItem.netID); + + string pig = GetItemsFromChestString(li.TPlayer.bank, NetItem.PiggySlots); + string safe = GetItemsFromChestString(li.TPlayer.bank2, NetItem.SafeSlots); + string forge = GetItemsFromChestString(li.TPlayer.bank3, NetItem.ForgeSlots); + string vault = GetItemsFromChestString(li.TPlayer.bank4, NetItem.VoidSlots); + + if (trash == "【[i/s0:0]】 ") + trash = ""; + + string all = inventory + armor + dyestuff + misc + misc + miscDye + trash + pig + safe + forge + vault; + all = FormatArrangement(all, 35); + if (all != "") + { + args.Player.SendMessage("玩家 【" + li.Name + "】 的所有库存如下:\n" + all, TextColor()); + } + else + args.Player.SendInfoMessage("没有任何东西"); + } + } + else + { + args.Player.SendInfoMessage("所查询玩家不在线,正在查询离线数据"); + string offAll = GetOfflinePlayerInv(TShock.DB, name); + offAll = FormatArrangement(offAll, 35); + if (offAll != "") + { + args.Player.SendMessage("玩家 【" + name + "】 的所有库存如下:" + "\n" + offAll, TextColor()); + } + else + { + args.Player.SendInfoMessage("该玩家不存在!"); + } + } + } + + //返回文本查阅背包 + private void ViewInventText(CommandArgs args) + { + if (!args.Parameters.Any()) + { + args.Player.SendInfoMessage("输入 /vit 【玩家名】 来查看该玩家的库存\nEnter / vit [player name] to view the player's inventory"); + return; + } + string name = args.Parameters[0]; + if (args.Parameters.Count > 1) + { + name = string.Join(" ", args.Parameters); + } + + List list = TSPlayer.FindByNameOrID(name); + if (list.Any()) + { + foreach (var li in list) + { + StringBuilder sb = new StringBuilder(); + string inventory = GetItemsString(li.TPlayer.inventory, NetItem.InventorySlots,1); + string armor = GetItemsString(li.TPlayer.armor, NetItem.ArmorSlots,1); + string dyestuff = GetItemsString(li.TPlayer.dye, NetItem.DyeSlots,1); + string misc = GetItemsString(li.TPlayer.miscEquips, NetItem.MiscEquipSlots,1); + string miscDye = GetItemsString(li.TPlayer.miscDyes, NetItem.MiscDyeSlots,1); + string trash = $" [{Lang.prefix[li.TPlayer.trashItem.prefix].Value}.{li.TPlayer.trashItem.Name}:{li.TPlayer.trashItem.stack}] "; + + string pig = GetItemsFromChestString(li.TPlayer.bank, NetItem.PiggySlots,1); + string safe = GetItemsFromChestString(li.TPlayer.bank2, NetItem.SafeSlots,1); + string forge = GetItemsFromChestString(li.TPlayer.bank3, NetItem.ForgeSlots,1); + string vault = GetItemsFromChestString(li.TPlayer.bank4, NetItem.VoidSlots,1); + + sb.AppendLine("玩家 【" + li.Name + "】 的所有库存如下:"); + if (inventory.Length > 0 && inventory != null && inventory != "") + { + sb.AppendLine("背包:"); + sb.AppendLine(FormatArrangement(inventory, 20, " ")); + } + if (armor.Length > 0 && armor != null && armor != "") + { + sb.AppendLine("盔甲 + 饰品 + 时装:"); + sb.AppendLine(armor); + } + if (dyestuff.Length > 0 && dyestuff != null && dyestuff != "") + { + sb.AppendLine("染料:"); + sb.AppendLine(dyestuff); + } + if (misc.Length > 0 && misc != null && misc != "") + { + sb.AppendLine("宠物 + 矿车 + 坐骑 + 钩爪:"); + sb.AppendLine(misc); + } + if (miscDye.Length > 0 && miscDye != null && miscDye != "") + { + sb.AppendLine("宠物 矿车 坐骑 钩爪 染料:"); + sb.AppendLine(miscDye); + } + if (trash != " [.:0] ") + { + sb.AppendLine("垃圾桶:"); + sb.AppendLine(trash); + } + if (pig.Length > 0 && pig != null && pig != "") + { + sb.AppendLine("猪猪储蓄罐:"); + sb.AppendLine(FormatArrangement(pig, 20, " ")); + } + if (safe.Length > 0 && safe != null && safe != "") + { + sb.AppendLine("保险箱:"); + sb.AppendLine(FormatArrangement(safe, 20, " ")); + } + if (forge.Length > 0 && forge != null && forge != "") + { + sb.AppendLine("护卫熔炉:"); + sb.AppendLine(FormatArrangement(forge, 20, " ")); + } + if (vault.Length > 0 && vault != null && vault != "") + { + sb.AppendLine("虚空金库:"); + sb.AppendLine(FormatArrangement(vault, 20, " ")); + } + if (sb.Length > 0 && sb != null && sb.ToString() != "") + args.Player.SendMessage(sb.ToString(), TextColor()); + else + args.Player.SendInfoMessage("没有任何东西"); + } + } + else + { + args.Player.SendInfoMessage("所查询玩家不在线,正在查询离线数据"); + string offAll = GetOfflinePlayerInv(TShock.DB, name, 1); + offAll = FormatArrangement(offAll, 35); + if (offAll != "") + { + args.Player.SendMessage("玩家 【" + name + "】 的所有库存如下:" + "\n" + offAll, TextColor()); + } + else + { + args.Player.SendInfoMessage("该玩家不存在!"); + } + } + } + + //返回玩家身上物品的字符串 + public static string GetItemsString(Item[] items, int slots, int Model = 0) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < slots; i++) + { + Item item = items[i]; + if (Model == 0 && !item.IsAir) + { + if (item.prefix != 0) + sb.Append(string.Format("【[i/p{0}:{1}]】 ", item.prefix, item.netID)); + else + sb.Append(string.Format("【[i/s{0}:{1}]】 ", item.stack, item.netID)); + } + if (Model == 1 && !item.IsAir) + { + if (item.prefix != 0) + sb.Append($"[{Lang.prefix[item.prefix].Value}.{item.Name}]"); + else + sb.Append($"[{item.Name}:{item.stack}]"); + } + } + return sb.ToString(); + } + + //返回玩家猪猪等储蓄物内的物品的字符串 + public static string GetItemsFromChestString(Chest chest, int slots, int Model = 0) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < slots; i++) + { + Item item = chest.item[i]; + if (Model == 0 && !item.IsAir) + { + if (item.prefix != 0) + sb.Append(string.Format("【[i/p{0}:{1}]】 ", item.prefix, item.netID)); + else + sb.Append(string.Format("【[i/s{0}:{1}]】 ", item.stack, item.netID)); + } + + if (Model == 1 && !item.IsAir) + { + if (item.prefix != 0) + sb.Append($"[{Lang.prefix[item.prefix].Value}.{item.Name}]"); + else + sb.Append($"[{item.Name}:{item.stack}]"); + } + } + return sb.ToString(); + } + + //查询离线玩家sqlite查询 + public static string GetOfflinePlayerInv(IDbConnection db, string plrName, int Model = 0) + { + int userAccountID = TShock.UserAccounts.GetUserAccountID(plrName); + string result; + using (QueryResult queryResult = DbExt.QueryReader(db, "SELECT * FROM tsCharacter WHERE Account=" + userAccountID)) + { + if (queryResult.Read()) + { + List list = queryResult.Get("Inventory").Split(new char[] { '~' }).Select(new Func(NetItem.Parse)).ToList(); + if (list.Count < NetItem.MaxInventory) + { + list.InsertRange(67, new NetItem[2]); + list.InsertRange(77, new NetItem[2]); + list.InsertRange(87, new NetItem[2]); + list.AddRange(new NetItem[NetItem.MaxInventory - list.Count]); + } + result = GetItemsString(list.ToArray(), list.Count, Model); + } + else + { + result = ""; + } + } + return result; + } + + //返回离线玩家身上的字符串 + public static string GetItemsString(NetItem[] items, int slots, int Model = 0) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < slots; i++) + { + NetItem item = items[i]; + if (Model == 0 && item.NetId != 0) + { + if (item.PrefixId != 0) + sb.Append(string.Format("【[i/p{0}:{1}]】 ", item.PrefixId, item.NetId)); + else + sb.Append(string.Format("【[i/s{0}:{1}]】 ", item.Stack, item.NetId)); + } + if (Model == 1 && item.NetId != 0) + { + if (item.PrefixId != 0) + sb.Append($"[{Lang.prefix[item.PrefixId].Value}.{Lang.GetItemName(item.NetId)}]"); + else + sb.Append($"[{Lang.GetItemName(item.NetId)}:{item.Stack}]"); + } + } + return sb.ToString(); + } + + //给出一个字符串和每行几个物品数,返回排列好的字符串 + public static string FormatArrangement(string str, int num, string block = "") + { + if (!string.IsNullOrWhiteSpace(str)) + { + List ls = str.Split(' ').ToList(); + for (int i = 0; i < ls.Count; i++) + { + if ((i + 1) % (num + 1) == 0) + { + ls.Insert(i, "\n"); + } + } + + if (block == "") + return string.Join(block, ls); + else + { + StringBuilder sb = new StringBuilder(); + foreach (string s in ls) + { + if (s != "\n") + { + sb.Append(s); + sb.Append(block); + } + else + { + sb.AppendLine(); + } + } + return sb.ToString(); + } + } + else + { + return ""; + } + } + + //返回颜色 + public static Color TextColor() + { + int r, g, b; + r = Main.rand.Next(60, 255); + g = Main.rand.Next(60, 255); + b = Main.rand.Next(60, 255); + return new Color(r, g, b); + } + } +} \ No newline at end of file diff --git a/ViewInventory.csproj b/ViewInventory.csproj index 4c93369..30188cc 100644 --- a/ViewInventory.csproj +++ b/ViewInventory.csproj @@ -66,7 +66,7 @@ - +