public void InfiniteChests_ChestDataImport( ProtectionManager protectionManager, out int importedChests, out int overwrittenChests, out int protectFailures ) { string sqliteDatabaseFilePath = Path.Combine(TShock.SavePath, "chests.sqlite"); if (!File.Exists(sqliteDatabaseFilePath)) { throw new FileNotFoundException("Sqlite database file not found.", sqliteDatabaseFilePath); } IDbConnection dbConnection = null; try { switch (TShock.Config.StorageType.ToLower()) { case "mysql": string[] host = TShock.Config.MySqlHost.Split(':'); dbConnection = new MySqlConnection(string.Format( "Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", host[0], host.Length == 1 ? "3306" : host[1], TShock.Config.MySqlDbName, TShock.Config.MySqlUsername, TShock.Config.MySqlPassword )); break; case "sqlite": dbConnection = new SqliteConnection( string.Format("uri=file://{0},Version=3", sqliteDatabaseFilePath) ); break; default: throw new NotImplementedException("Unsupported database."); } importedChests = 0; overwrittenChests = 0; protectFailures = 0; using (QueryResult reader = dbConnection.QueryReader( "SELECT X, Y, Account, Flags, Items FROM Chests WHERE WorldID = @0", Main.worldID) ) { while (reader.Read()) { int rawX = reader.Get <int>("X"); int rawY = reader.Get <int>("Y"); string rawAccount = reader.Get <string>("Account"); InfiniteChestsChestFlags rawFlags = (InfiniteChestsChestFlags)reader.Get <int>("Flags"); string rawItems = reader.Get <string>("Items"); if (!TerrariaUtils.Tiles.IsValidCoord(rawX, rawY)) { continue; } DPoint chestLocation = new DPoint(rawX, rawY); if (!TerrariaUtils.Tiles[chestLocation].active() || TerrariaUtils.Tiles[chestLocation].type != (int)BlockType.Chest) { this.PluginTrace.WriteLineWarning(string.Format( "The chest data on the location {0} could not be imported because no corresponding chest does exist in the world.", chestLocation )); continue; } // TSPlayer.All means that the chest must not be protected at all. TSPlayer owner = TSPlayer.All; if (!string.IsNullOrEmpty(rawAccount)) { User tUser = TShock.Users.GetUserByName(rawAccount); if (tUser != null) { owner = new TSPlayer(0) { UserID = tUser.ID, UserAccountName = tUser.Name, Group = TShock.Groups.GetGroupByName(tUser.Group), }; } else { // The original owner of the chest does not exist anymore, so we just protect it for the server player. owner = TSPlayer.Server; } } int chestIndex = Chest.FindChest(rawX, rawY); if (chestIndex == -1) { chestIndex = Chest.CreateChest(rawX, rawY); } else { this.PluginTrace.WriteLineWarning(string.Format("The items of the chest {0} were overwritten.", chestLocation)); overwrittenChests++; } Chest tChest = Main.chest[chestIndex]; int[] itemArgs = new int[60]; string[] itemData = rawItems.Split(','); for (int i = 0; i < 120; i++) { itemArgs[i] = int.Parse(itemData[i]); } for (int i = 0; i < 40; i++) { tChest.item[i] = new Item(); tChest.item[i].netDefaults(itemArgs[i * 3]); tChest.item[i].prefix = (byte)itemArgs[i * 3 + 2]; tChest.item[i].stack = itemArgs[i * 3 + 1]; } importedChests++; if (owner != TSPlayer.All) { try { ProtectionEntry protection = protectionManager.CreateProtection(owner, chestLocation, true, false, false); protection.IsSharedWithEveryone = (rawFlags & InfiniteChestsChestFlags.PUBLIC) != 0; if ((rawFlags & InfiniteChestsChestFlags.REFILL) != 0) { protectionManager.SetUpRefillChest(owner, chestLocation, TimeSpan.Zero); } } catch (Exception ex) { this.PluginTrace.WriteLineWarning( "Failed to create protection or define refill chest at {0}:\n{1}", chestLocation, ex ); protectFailures++; } } } } } finally { if (dbConnection != null) { dbConnection.Close(); } } }
public void InfiniteChests_ChestDataImport( ChestManager chestManager, ProtectionManager protectionManager, out int importedChests, out int protectFailures ) { Contract.Assert(this.ChestManager != null); importedChests = 0; protectFailures = 0; IDbConnection dbConnection = null; try { switch (TShock.Config.StorageType.ToLower()) { case "mysql": string[] host = TShock.Config.MySqlHost.Split(':'); dbConnection = new MySqlConnection(string.Format( "Server={0}; Port={1}; Database={2}; Uid={3}; Pwd={4};", host[0], host.Length == 1 ? "3306" : host[1], TShock.Config.MySqlDbName, TShock.Config.MySqlUsername, TShock.Config.MySqlPassword )); break; case "sqlite": string sqliteDatabaseFilePath = Path.Combine(TShock.SavePath, "chests.sqlite"); if (!File.Exists(sqliteDatabaseFilePath)) { throw new FileNotFoundException("Sqlite database file not found.", sqliteDatabaseFilePath); } dbConnection = new SqliteConnection($"uri=file://{sqliteDatabaseFilePath},Version=3"); break; default: throw new NotImplementedException("Unsupported database."); } using (QueryResult reader = dbConnection.QueryReader( "SELECT X, Y, Account, Flags, Items, RefillTime FROM Chests WHERE WorldID = @0", Main.worldID) ) { while (reader.Read()) { int rawX = reader.Get <int>("X"); int rawY = reader.Get <int>("Y"); string rawAccount = reader.Get <string>("Account"); InfiniteChestsChestFlags rawFlags = (InfiniteChestsChestFlags)reader.Get <int>("Flags"); string rawItems = reader.Get <string>("Items"); int refillTime = reader.Get <int>("RefillTime"); if (!TerrariaUtils.Tiles.IsValidCoord(rawX, rawY)) { continue; } DPoint chestLocation = new DPoint(rawX, rawY); ITile chestTile = TerrariaUtils.Tiles[chestLocation]; if (!chestTile.active() || (chestTile.type != TileID.Containers && chestTile.type != TileID.Containers2 && chestTile.type != TileID.Dressers)) { this.PluginTrace.WriteLineWarning($"Chest data at {chestLocation} could not be imported because no corresponding chest tiles exist in the world."); continue; } // TSPlayer.All = chest will not be protected TSPlayer owner = TSPlayer.All; if (!string.IsNullOrEmpty(rawAccount)) { UserAccount tUser = TShock.UserAccounts.GetUserAccountByName(rawAccount); if (tUser != null) { owner = new TSPlayer(0); owner.Account.ID = tUser.ID; owner.Account.Name = tUser.Name; owner.Group = TShock.Groups.GetGroupByName(tUser.Group); } else { // The original owner of the chest does not exist anymore, so we just protect it for the server player. owner = TSPlayer.Server; } } IChest importedChest; try { importedChest = this.ChestManager.ChestFromLocation(chestLocation); if (importedChest == null) { importedChest = this.ChestManager.CreateChestData(chestLocation); } } catch (LimitEnforcementException) { this.PluginTrace.WriteLineWarning($"Chest limit of {Main.chest.Length + this.Config.MaxProtectorChests - 1} has been reached!"); break; } string[] itemData = rawItems.Split(','); int[] itemArgs = new int[itemData.Length]; for (int i = 0; i < itemData.Length; i++) { itemArgs[i] = int.Parse(itemData[i]); } for (int i = 0; i < 40; i++) { int type = itemArgs[i * 3]; int stack = itemArgs[i * 3 + 1]; int prefix = (byte)itemArgs[i * 3 + 2]; importedChest.Items[i] = new ItemData(prefix, type, stack); } importedChests++; if (owner != TSPlayer.All) { try { ProtectionEntry protection = protectionManager.CreateProtection(owner, chestLocation, false, false, false); protection.IsSharedWithEveryone = (rawFlags & InfiniteChestsChestFlags.PUBLIC) != 0; if ((rawFlags & InfiniteChestsChestFlags.REFILL) != 0) { chestManager.SetUpRefillChest(owner, chestLocation, TimeSpan.FromSeconds(refillTime)); } } catch (Exception ex) { this.PluginTrace.WriteLineWarning($"Failed to create protection or define refill chest at {chestLocation}:\n{ex}"); protectFailures++; } } } } } finally { dbConnection?.Close(); } }