diff --git a/CaiLib/CaiLib.csproj b/CaiLib/CaiLib.csproj
new file mode 100644
index 00000000..93120391
--- /dev/null
+++ b/CaiLib/CaiLib.csproj
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+
+
+
+ ..\lib\SixLabors.ImageSharp.dll
+
+
+
+
\ No newline at end of file
diff --git a/CaiLib/Commad.cs b/CaiLib/Commad.cs
new file mode 100644
index 00000000..a8ddc3a6
--- /dev/null
+++ b/CaiLib/Commad.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TShockAPI;
+using Terraria;
+using Terraria.Localization;
+
+namespace CaiLib
+{
+ public static class CaiCommand
+ {
+ ///
+ /// 删除指定命令
+ ///
+ /// 命令名字
+ public static void DelCommand(List names)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Any(n => names.Contains(n)));
+ }
+ ///
+ /// 删除指定命令
+ ///
+ /// 命令名字
+ public static void DelCommand(string names)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Contains(names));
+ }
+ ///
+ /// 添加一条命令
+ ///
+ /// 权限
+ /// 命令回调函数
+ /// 命令名字
+ /// 替换原命令
+ /// 帮助提示
+ /// 帮助文档
+ /// 允许非玩家
+ /// 日志记录参数
+ public static void AddCommand(List perms, CommandDelegate commandDelegate, List names, bool replaceCommand = false, string helpText = null,string[] helpDesc = null, bool allowServer = true, bool doLog = true)
+ {
+ if (replaceCommand)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Any(n => names.Contains(n)));
+ }
+ Commands.ChatCommands.Add(new Command(perms, commandDelegate, names.ToArray())
+ {
+ AllowServer = allowServer,
+ HelpDesc = helpDesc,
+ HelpText = helpText,
+ DoLog = doLog,
+ });
+ }
+ ///
+ /// 添加一条命令
+ ///
+ /// 权限
+ /// 命令回调函数
+ /// 命令名字
+ /// 替换原命令
+ /// 帮助提示
+ /// 帮助文档
+ /// 允许非玩家
+ /// 日志记录参数
+ public static void AddCommand(string perms, CommandDelegate commandDelegate, List names, bool replaceCommand = false, string helpText = null, string[] helpDesc = null, bool allowServer = true, bool doLog = true)
+ {
+ if (replaceCommand)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Any(n => names.Contains(n)));
+ }
+ Commands.ChatCommands.Add(new Command(perms, commandDelegate, names.ToArray())
+ {
+ AllowServer = allowServer,
+ HelpDesc = helpDesc,
+ HelpText = helpText,
+ DoLog = doLog,
+ });
+ }
+ ///
+ /// 添加一条命令
+ ///
+ /// 权限
+ /// 命令回调函数
+ /// 命令名字
+ /// 替换原命令
+ /// 帮助提示
+ /// 帮助文档
+ /// 允许非玩家
+ /// 日志记录参数
+ public static void AddCommand(List perms, CommandDelegate commandDelegate, string names, bool replaceCommand = false, string helpText = null, string[] helpDesc = null, bool allowServer = true, bool doLog = true)
+ {
+ if (replaceCommand)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Any(n => names.Contains(n)));
+ }
+ Commands.ChatCommands.Add(new Command(perms, commandDelegate, names)
+ {
+ AllowServer = allowServer,
+ HelpDesc = helpDesc,
+ HelpText = helpText,
+ DoLog = doLog,
+ });
+ }
+ ///
+ /// 添加一条命令
+ ///
+ /// 权限
+ /// 命令回调函数
+ /// 命令名字
+ /// 替换原命令
+ /// 帮助提示
+ /// 帮助文档
+ /// 允许非玩家
+ /// 日志记录参数
+ public static void AddCommand(string perms, CommandDelegate commandDelegate, string names, bool replaceCommand = false, string helpText = null, string[] helpDesc = null, bool allowServer = true, bool doLog = true)
+ {
+ if (replaceCommand)
+ {
+ Commands.ChatCommands.RemoveAll(c => c.Names.Any(n => names.Contains(n)));
+ }
+ Commands.ChatCommands.Add(new Command(perms, commandDelegate, names)
+ {
+ AllowServer = allowServer,
+ HelpDesc = helpDesc,
+ HelpText = helpText,
+ DoLog = doLog,
+ });
+ }
+ }
+}
diff --git a/CaiLib/Config.cs b/CaiLib/Config.cs
new file mode 100644
index 00000000..4b5d3835
--- /dev/null
+++ b/CaiLib/Config.cs
@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+using TShockAPI;
+using TShockAPI.Configuration;
+
+namespace CaiLib
+{
+ public class CaiConfig where TSettings : new()
+ {
+ ///
+ /// 设置Config对象
+ ///
+ /// 配置文件的名字
+ /// 配置文件的类模板
+ public CaiConfig(string name, TSettings settings)
+ {
+ FilePath = Path.Combine(TShock.SavePath, name);
+ Settings = settings;
+ }
+
+
+ [JsonIgnore]
+ public string FilePath = Path.Combine(TShock.SavePath, "CaiLib.json");
+
+ public virtual TSettings Settings { get; set; } = new TSettings();
+
+ ///
+ /// 写入Config
+ ///
+ public void Write()
+ {
+ using (var fs = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.Write))
+ {
+ var str = JsonConvert.SerializeObject(this, Formatting.Indented);
+ using (var sw = new StreamWriter(fs))
+ {
+ sw.Write(str);
+ }
+ }
+ }
+ ///
+ /// 创造并读取Config
+ ///
+ public CaiConfig Read()
+ {
+ if (!File.Exists(FilePath))
+ return this;
+ using (var fs = new FileStream(FilePath, 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/CaiLib/FileTools.cs b/CaiLib/FileTools.cs
new file mode 100644
index 00000000..a4da4612
--- /dev/null
+++ b/CaiLib/FileTools.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CaiLib
+{
+ public class CaiFileTools
+ {
+ ///
+ /// 文件转base64
+ ///
+ /// base64字符串
+ public static string FileToBase64String(string path)
+ {
+ FileStream fsForRead = new FileStream(path, FileMode.Open);//文件路径
+ string base64Str = "";
+ try
+ {
+ fsForRead.Seek(0, SeekOrigin.Begin);
+ byte[] bs = new byte[fsForRead.Length];
+ int log = Convert.ToInt32(fsForRead.Length);
+ fsForRead.Read(bs, 0, log);
+ base64Str = Convert.ToBase64String(bs);
+ return base64Str;
+ }
+ catch (Exception ex)
+ {
+ Console.Write(ex.Message);
+ Console.ReadLine();
+ return base64Str;
+ }
+ finally
+ {
+ fsForRead.Close();
+ }
+ }
+
+ ///
+ /// base64字符串转文件
+ ///
+ /// Base64字符串
+ /// 文件路径
+ ///
+
+ public static bool Base64StringToFile(string base64String, string fileFullPath)
+ {
+ bool opResult = false;
+ string strbase64 = base64String.Trim().Substring(base64String.IndexOf(",") + 1); //将‘,’以前的多余字符串删除
+ MemoryStream stream = new MemoryStream(Convert.FromBase64String(strbase64));
+ FileStream fs = new FileStream(fileFullPath, FileMode.OpenOrCreate, FileAccess.Write);
+ byte[] b = stream.ToArray();
+ fs.Write(b, 0, b.Length);
+ fs.Close();
+
+ opResult = true;
+ return opResult;
+ }
+ }
+}
diff --git a/CaiLib/Map.cs b/CaiLib/Map.cs
new file mode 100644
index 00000000..0b13415d
--- /dev/null
+++ b/CaiLib/Map.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.PixelFormats;
+using Terraria.Map;
+using Terraria;
+using System.Reflection;
+
+namespace CaiLib
+{
+ public static class CaiMap
+ {
+ private static Assembly LoadLib()
+ {
+ string resourceName = "CaiLib.SixLabors.ImageSharp.dll";
+ using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
+ {
+ byte[] assemblyData = new byte[stream.Length];
+ stream.Read(assemblyData, 0, assemblyData.Length);
+ return Assembly.Load(assemblyData);
+ }
+ }
+
+ public static Image CreateMapImage()
+ {
+ LoadLib();
+ Image image = new Image(Main.maxTilesX, Main.maxTilesY);
+
+ MapHelper.Initialize();
+ if (Main.Map == null)
+ {
+ Main.Map = new WorldMap(0, 0);
+ }
+ for (var x = 0; x < Main.maxTilesX; x++)
+ {
+ for (var y = 0; y < Main.maxTilesY; y++)
+ {
+ var tile = MapHelper.CreateMapTile(x, y, byte.MaxValue);
+ var col = MapHelper.GetMapTileXnaColor(ref tile);
+ image[x, y] = new Rgba32(col.R, col.G, col.B, col.A);
+ }
+ }
+
+ return image;
+ }
+ }
+}
diff --git a/CaiLib/Player.cs b/CaiLib/Player.cs
new file mode 100644
index 00000000..a6aa7357
--- /dev/null
+++ b/CaiLib/Player.cs
@@ -0,0 +1,345 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using Terraria.IO;
+using TShockAPI;
+using Terraria;
+using Terraria.ID;
+using Terraria.GameContent.Creative;
+using TShockAPI.DB;
+
+namespace CaiLib
+{
+ public static class CaiPlayer
+ {
+ ///
+ /// 导出玩家文件(hufang)
+ ///
+ /// 玩家账号
+ /// 路径
+ /// 玩家角色难度(软核0,中核1,硬核2,旅行3)
+ public static void SavePlayerFile(UserAccount account, string path, int difficulty = 0)
+ {
+ var data = TShock.CharacterDB.GetPlayerData(new TSPlayer(-1), account.ID);
+ SavePlayerFile(ModifyData(account.Name, data), path, difficulty);
+ }
+ ///
+ /// 导出玩家文件(hufang)
+ ///
+ /// 玩家对象
+ /// 路径
+ /// 玩家角色难度(软核0,中核1,硬核2,旅行3)
+ public static void SavePlayerFile(Player player, string path,int difficulty = 0)
+ {
+ // Player.cs Serialize();
+ //RijndaelManaged rijndaelManaged = new RijndaelManaged();
+ //using (CryptoStream cryptoStream = new CryptoStream(stream, rijndaelManaged.CreateEncryptor(Player.ENCRYPTION_KEY, Player.ENCRYPTION_KEY), CryptoStreamMode.Write))
+ Aes myAes = Aes.Create();
+ using (Stream stream = new FileStream(path, FileMode.Create))
+ {
+ using (CryptoStream cryptoStream = new(stream, myAes.CreateEncryptor(Player.ENCRYPTION_KEY, Player.ENCRYPTION_KEY), CryptoStreamMode.Write))
+ {
+ PlayerFileData playerFileData = new()
+ {
+ Metadata = FileMetadata.FromCurrentSettings(FileType.Player),
+ Player = player,
+ _isCloudSave = false,
+ _path = path
+ };
+ Main.LocalFavoriteData.ClearEntry(playerFileData);
+ using (BinaryWriter binaryWriter = new(cryptoStream))
+ {
+ //230 1.4.0.5
+ //269 1.4.4.0
+ binaryWriter.Write(269);
+ playerFileData.Metadata.Write(binaryWriter);
+ binaryWriter.Write(player.name);
+ binaryWriter.Write(difficulty);
+ binaryWriter.Write(playerFileData.GetPlayTime().Ticks);
+ binaryWriter.Write(player.hair);
+ binaryWriter.Write(player.hairDye);
+ BitsByte bitsByte = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ bitsByte[i] = player.hideVisibleAccessory[i];
+ }
+ binaryWriter.Write(bitsByte);
+ bitsByte = 0;
+ for (int j = 0; j < 2; j++)
+ {
+ bitsByte[j] = player.hideVisibleAccessory[j + 8];
+ }
+ binaryWriter.Write(bitsByte);
+ binaryWriter.Write(player.hideMisc);
+ binaryWriter.Write((byte)player.skinVariant);
+ binaryWriter.Write(player.statLife);
+ binaryWriter.Write(player.statLifeMax);
+ binaryWriter.Write(player.statMana);
+ binaryWriter.Write(player.statManaMax);
+ binaryWriter.Write(player.extraAccessory);
+ binaryWriter.Write(player.unlockedBiomeTorches);
+ binaryWriter.Write(player.UsingBiomeTorches);
+
+ binaryWriter.Write(player.ateArtisanBread);
+ binaryWriter.Write(player.usedAegisCrystal);
+ binaryWriter.Write(player.usedAegisFruit);
+ binaryWriter.Write(player.usedArcaneCrystal);
+ binaryWriter.Write(player.usedGalaxyPearl);
+ binaryWriter.Write(player.usedGummyWorm);
+ binaryWriter.Write(player.usedAmbrosia);
+
+ binaryWriter.Write(player.downedDD2EventAnyDifficulty);
+ binaryWriter.Write(player.taxMoney);
+
+ binaryWriter.Write(player.numberOfDeathsPVE);
+ binaryWriter.Write(player.numberOfDeathsPVP);
+
+ binaryWriter.Write(player.hairColor.R);
+ binaryWriter.Write(player.hairColor.G);
+ binaryWriter.Write(player.hairColor.B);
+ binaryWriter.Write(player.skinColor.R);
+ binaryWriter.Write(player.skinColor.G);
+ binaryWriter.Write(player.skinColor.B);
+ binaryWriter.Write(player.eyeColor.R);
+ binaryWriter.Write(player.eyeColor.G);
+ binaryWriter.Write(player.eyeColor.B);
+ binaryWriter.Write(player.shirtColor.R);
+ binaryWriter.Write(player.shirtColor.G);
+ binaryWriter.Write(player.shirtColor.B);
+ binaryWriter.Write(player.underShirtColor.R);
+ binaryWriter.Write(player.underShirtColor.G);
+ binaryWriter.Write(player.underShirtColor.B);
+ binaryWriter.Write(player.pantsColor.R);
+ binaryWriter.Write(player.pantsColor.G);
+ binaryWriter.Write(player.pantsColor.B);
+ binaryWriter.Write(player.shoeColor.R);
+ binaryWriter.Write(player.shoeColor.G);
+ binaryWriter.Write(player.shoeColor.B);
+ for (int k = 0; k < player.armor.Length; k++)
+ {
+ binaryWriter.Write(player.armor[k].netID);
+ binaryWriter.Write(player.armor[k].prefix);
+ }
+ for (int l = 0; l < player.dye.Length; l++)
+ {
+ binaryWriter.Write(player.dye[l].netID);
+ binaryWriter.Write(player.dye[l].prefix);
+ }
+ for (int m = 0; m < 58; m++)
+ {
+ binaryWriter.Write(player.inventory[m].netID);
+ binaryWriter.Write(player.inventory[m].stack);
+ binaryWriter.Write(player.inventory[m].prefix);
+ binaryWriter.Write(player.inventory[m].favorited);
+ }
+ for (int n = 0; n < player.miscEquips.Length; n++)
+ {
+ binaryWriter.Write(player.miscEquips[n].netID);
+ binaryWriter.Write(player.miscEquips[n].prefix);
+ binaryWriter.Write(player.miscDyes[n].netID);
+ binaryWriter.Write(player.miscDyes[n].prefix);
+ }
+ for (int num = 0; num < 40; num++)
+ {
+ binaryWriter.Write(player.bank.item[num].netID);
+ binaryWriter.Write(player.bank.item[num].stack);
+ binaryWriter.Write(player.bank.item[num].prefix);
+ }
+ for (int num2 = 0; num2 < 40; num2++)
+ {
+ binaryWriter.Write(player.bank2.item[num2].netID);
+ binaryWriter.Write(player.bank2.item[num2].stack);
+ binaryWriter.Write(player.bank2.item[num2].prefix);
+ }
+ for (int num3 = 0; num3 < 40; num3++)
+ {
+ binaryWriter.Write(player.bank3.item[num3].netID);
+ binaryWriter.Write(player.bank3.item[num3].stack);
+ binaryWriter.Write(player.bank3.item[num3].prefix);
+ }
+ for (int num4 = 0; num4 < 40; num4++)
+ {
+ binaryWriter.Write(player.bank4.item[num4].netID);
+ binaryWriter.Write(player.bank4.item[num4].stack);
+ binaryWriter.Write(player.bank4.item[num4].prefix);
+ binaryWriter.Write(player.bank4.item[num4].favorited);
+ }
+ binaryWriter.Write(player.voidVaultInfo);
+ for (int num5 = 0; num5 < 44; num5++)
+ {
+ if (Main.buffNoSave[player.buffType[num5]])
+ {
+ binaryWriter.Write(0);
+ binaryWriter.Write(0);
+ }
+ else
+ {
+ binaryWriter.Write(player.buffType[num5]);
+ binaryWriter.Write(player.buffTime[num5]);
+ }
+ }
+ for (int num6 = 0; num6 < 200; num6++)
+ {
+ if (player.spN[num6] == null)
+ {
+ binaryWriter.Write(-1);
+ break;
+ }
+ binaryWriter.Write(player.spX[num6]);
+ binaryWriter.Write(player.spY[num6]);
+ binaryWriter.Write(player.spI[num6]);
+ binaryWriter.Write(player.spN[num6]);
+ }
+ binaryWriter.Write(player.hbLocked);
+ for (int num7 = 0; num7 < player.hideInfo.Length; num7++)
+ {
+ binaryWriter.Write(player.hideInfo[num7]);
+ }
+ binaryWriter.Write(player.anglerQuestsFinished);
+ for (int num8 = 0; num8 < player.DpadRadial.Bindings.Length; num8++)
+ {
+ binaryWriter.Write(player.DpadRadial.Bindings[num8]);
+ }
+ for (int num9 = 0; num9 < player.builderAccStatus.Length; num9++)
+ {
+ binaryWriter.Write(player.builderAccStatus[num9]);
+ }
+ binaryWriter.Write(player.bartenderQuestLog);
+ binaryWriter.Write(player.dead);
+ if (player.dead)
+ {
+ binaryWriter.Write(player.respawnTimer);
+ }
+ long value = DateTime.UtcNow.ToBinary();
+ binaryWriter.Write(value);
+ binaryWriter.Write(player.golferScoreAccumulated);
+ SaveSacrifice(binaryWriter);
+ player.SaveTemporaryItemSlotContents(binaryWriter);
+ CreativePowerManager.Instance.SaveToPlayer(player, binaryWriter);
+ BitsByte bitsByte2 = default;
+ bitsByte2[0] = player.unlockedSuperCart;
+ bitsByte2[1] = player.enabledSuperCart;
+ binaryWriter.Write(bitsByte2);
+ binaryWriter.Write(player.CurrentLoadoutIndex);
+ for (int num10 = 0; num10 < player.Loadouts.Length; num10++)
+ {
+ player.Loadouts[num10].Serialize(binaryWriter);
+ }
+
+ binaryWriter.Flush();
+ cryptoStream.FlushFinalBlock();
+ stream.Flush();
+
+ }
+ }
+ }
+ }
+
+ ///
+ /// 导出物品研究(hufang)
+ ///
+ ///
+ public static void SaveSacrifice(BinaryWriter writer)
+ {
+ //player.creativeTracker.Save(binaryWriter);
+ Dictionary dictionary = TShock.ResearchDatastore.GetSacrificedItems();
+ writer.Write(dictionary.Count);
+ foreach (KeyValuePair item in dictionary)
+ {
+ writer.Write(ContentSamples.ItemPersistentIdsByNetIds[item.Key]);
+ writer.Write(item.Value);
+ }
+ }
+ public static Item NetItem2Item(NetItem item)
+ {
+ var i = new Item();
+ i.SetDefaults(item.NetId);
+ i.stack = item.Stack;
+ i.prefix = item.PrefixId;
+ return i;
+ }
+ private static Player ModifyData(string name, PlayerData data)
+ {
+ Player player = new();
+ if (data != null)
+ {
+ player.name = name;
+ player.SpawnX = data.spawnX;
+ player.SpawnY = data.spawnY;
+
+ player.hideVisibleAccessory = data.hideVisuals;
+ player.skinVariant = data.skinVariant ?? default;
+ player.statLife = data.health;
+ player.statLifeMax = data.maxHealth;
+ player.statMana = data.mana;
+ player.statManaMax = data.maxMana;
+ player.extraAccessory = data.extraSlot == 1;
+
+ player.difficulty = (byte)0;
+
+ // 火把神
+ player.unlockedBiomeTorches = data.unlockedBiomeTorches == 1;
+
+ player.hairColor = data.hairColor ?? default;
+ player.skinColor = data.skinColor ?? default;
+ player.eyeColor = data.eyeColor ?? default;
+ player.shirtColor = data.shirtColor ?? default;
+ player.underShirtColor = data.underShirtColor ?? default;
+ player.pantsColor = data.pantsColor ?? default;
+ player.shoeColor = data.shoeColor ?? default;
+
+ player.hair = data.hair ?? default;
+ player.hairDye = data.hairDye;
+
+ player.anglerQuestsFinished = data.questsCompleted;
+ player.CurrentLoadoutIndex = data.currentLoadoutIndex;
+
+ //player.numberOfDeathsPVE = data.numberOfDeathsPVE;
+ //player.numberOfDeathsPVP = data.numberOfDeathsPVP;
+
+
+ for (int i = 0; i < NetItem.MaxInventory; i++)
+ {
+ // 0~49 背包 5*10
+ // 50、51、52、53 钱
+ // 54、55、56、57 弹药
+ // 59 ~68 饰品栏
+ // 69 ~78 社交栏
+ // 79 ~88 染料1
+ // 89 ~93 宠物、照明、矿车、坐骑、钩爪
+ // 94 ~98 染料2
+ // 99~138 储蓄罐
+ // 139~178 保险箱(商人)
+ // 179 垃圾桶
+ // 180~219 护卫熔炉
+ // 220~259 虚空保险箱
+ // 260~350 装备123
+ if (i < 59) player.inventory[i] = NetItem2Item(data.inventory[i]);
+ else if (i >= 59 && i < 79) player.armor[i - 59] = NetItem2Item(data.inventory[i]);
+ else if (i >= 79 && i < 89) player.dye[i - 79] = NetItem2Item(data.inventory[i]);
+ else if (i >= 89 && i < 94) player.miscEquips[i - 89] = NetItem2Item(data.inventory[i]);
+ else if (i >= 94 && i < 99) player.miscDyes[i - 94] = NetItem2Item(data.inventory[i]);
+ else if (i >= 99 && i < 139) player.bank.item[i - 99] = NetItem2Item(data.inventory[i]);
+ else if (i >= 139 && i < 179) player.bank2.item[i - 139] = NetItem2Item(data.inventory[i]);
+ else if (i == 179) player.trashItem = NetItem2Item(data.inventory[i]);
+ else if (i >= 180 && i < 220) player.bank3.item[i - 180] = NetItem2Item(data.inventory[i]);
+ else if (i >= 220 && i < 260) player.bank4.item[i - 220] = NetItem2Item(data.inventory[i]);
+
+ else if (i >= 260 && i < 280) player.Loadouts[0].Armor[i - 260] = NetItem2Item(data.inventory[i]);
+ else if (i >= 280 && i < 290) player.Loadouts[0].Dye[i - 280] = NetItem2Item(data.inventory[i]);
+
+ else if (i >= 290 && i < 310) player.Loadouts[1].Armor[i - 290] = NetItem2Item(data.inventory[i]);
+ else if (i >= 310 && i < 320) player.Loadouts[1].Dye[i - 310] = NetItem2Item(data.inventory[i]);
+
+ else if (i >= 320 && i < 340) player.Loadouts[2].Armor[i - 320] = NetItem2Item(data.inventory[i]);
+ else if (i >= 340 && i < 350) player.Loadouts[2].Dye[i - 340] = NetItem2Item(data.inventory[i]);
+ }
+ }
+ return player;
+ }
+
+ }
+}
diff --git a/CaiLib/README.md b/CaiLib/README.md
new file mode 100644
index 00000000..6ab1e798
--- /dev/null
+++ b/CaiLib/README.md
@@ -0,0 +1,26 @@
+# CaiLib
+- 作者: Cai
+- 出处: 此仓库
+- Cai的奇奇怪怪类库
+- 一般大概是用作前置的
+
+## 更新日志
+
+```
+无
+```
+
+## 指令
+
+```
+无
+```
+
+## 配置
+
+```json
+无
+```
+## 反馈
+- 共同维护的插件库:https://github.com/Controllerdestiny/TShockPlugin
+- 国内社区trhub.cn 或 TShock官方群等
\ No newline at end of file
diff --git a/CaiLib/SixLabors.ImageSharp.dll b/CaiLib/SixLabors.ImageSharp.dll
new file mode 100644
index 00000000..17bffaa5
Binary files /dev/null and b/CaiLib/SixLabors.ImageSharp.dll differ
diff --git a/Plugin.sln b/Plugin.sln
index f7675c3b..dc13f927 100644
--- a/Plugin.sln
+++ b/Plugin.sln
@@ -128,6 +128,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerTools", "ServerTools\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform", "Platform\Platform.csproj", "{3F528630-8E37-4001-BCB9-71148D841127}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaiLib", "CaiLib\CaiLib.csproj", "{3B98CF6B-A295-485C-8ABC-64388BA995BE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -616,6 +618,14 @@ Global
{3F528630-8E37-4001-BCB9-71148D841127}.Release|Any CPU.Build.0 = Release|Any CPU
{3F528630-8E37-4001-BCB9-71148D841127}.Release|x64.ActiveCfg = Release|Any CPU
{3F528630-8E37-4001-BCB9-71148D841127}.Release|x64.Build.0 = Release|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Debug|x64.Build.0 = Debug|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|x64.ActiveCfg = Release|Any CPU
+ {3B98CF6B-A295-485C-8ABC-64388BA995BE}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/lib/SixLabors.ImageSharp.dll b/lib/SixLabors.ImageSharp.dll
new file mode 100644
index 00000000..17bffaa5
Binary files /dev/null and b/lib/SixLabors.ImageSharp.dll differ