Пример #1
0
        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();
            }
        }