Esempio n. 1
0
        private void Game_PostInitialize(EventArgs e)
        {
            ServerApi.Hooks.GamePostInitialize.Deregister(this, this.Game_PostInitialize);

            if (!Directory.Exists(ProtectorPlugin.DataDirectory))
            {
                Directory.CreateDirectory(ProtectorPlugin.DataDirectory);
            }

            if (!this.InitConfig())
            {
                return;
            }
            if (!this.InitServerMetdataHandler())
            {
                return;
            }
            if (!this.InitWorldMetdataHandler())
            {
                return;
            }

            this.pluginCooperationHandler = new PluginCooperationHandler(this.Trace);
            this.protectionManager        = new ProtectionManager(
                this.Trace, this.Config, this.ServerMetadataHandler, this.WorldMetadataHandler.Metadata
                );

            this.InitUserInteractionHandler();
            this.UserInteractionHandler.EnsureProtectionData(TSPlayer.Server);

            this.hooksEnabled = true;

            Task.Factory.StartNew(() => {
                // Wait a bit until other plugins might have registered their hooks in PostInitialize.
                Thread.Sleep(1000);

                this.AddPostHooks();
            });
        }
        private void ProtectionSharePreValidation(
            TSPlayer player, DPoint tileLocation, bool shareOrUnshare, bool checkPermissions, out ProtectionEntry protection
            )
        {
            ITile tile      = TerrariaUtils.Tiles[tileLocation];
            int   blockType = tile.type;

            if (!ProtectionManager.IsShareableBlockType(blockType))
            {
                throw new InvalidBlockTypeException(blockType);
            }

            if (checkPermissions)
            {
                if (
                    (tile.type == TileID.Containers || tile.type == TileID.Containers2 || tile.type == TileID.Dressers) &&
                    !player.Group.HasPermission(ProtectorPlugin.ChestSharing_Permission)
                    )
                {
                    throw new MissingPermissionException(ProtectorPlugin.ChestSharing_Permission);
                }

                if (
                    TerrariaUtils.Tiles.IsSwitchableObject(tile.type) &&
                    !player.Group.HasPermission(ProtectorPlugin.SwitchSharing_Permission)
                    )
                {
                    throw new MissingPermissionException(ProtectorPlugin.SwitchSharing_Permission);
                }

                if (
                    (
                        tile.type == TileID.Signs ||
                        tile.type == TileID.Tombstones ||
                        tile.type == TileID.Beds ||
                        tile.type == TileID.OpenDoor ||
                        tile.type == TileID.ClosedDoor
                    ) &&
                    !player.Group.HasPermission(ProtectorPlugin.OtherSharing_Permission)
                    )
                {
                    throw new MissingPermissionException(ProtectorPlugin.OtherSharing_Permission);
                }
            }

            tileLocation = TerrariaUtils.Tiles.MeasureObject(tileLocation).OriginTileLocation;
            lock (this.WorldMetadata.Protections)
                if (!this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection))
                {
                    throw new NoProtectionException(tileLocation);
                }

            if (checkPermissions)
            {
                if (
                    protection.BankChestKey != BankChestDataKey.Invalid &&
                    !player.Group.HasPermission(ProtectorPlugin.BankChestShare_Permission)
                    )
                {
                    throw new MissingPermissionException(ProtectorPlugin.BankChestShare_Permission);
                }
            }

            if (protection.Owner != player.Account.ID && !player.Group.HasPermission(ProtectorPlugin.ProtectionMaster_Permission))
            {
                if (!protection.IsSharedWithPlayer(player))
                {
                    throw new TileProtectedException(tileLocation);
                }

                if (shareOrUnshare)
                {
                    if (!this.Config.AllowChainedSharing)
                    {
                        throw new TileProtectedException(tileLocation);
                    }
                }
                else if (!this.Config.AllowChainedShareAltering)
                {
                    throw new TileProtectedException(tileLocation);
                }
            }
        }
        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);
                owner.User.ID = tUser.ID;
                owner.User.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;
              }
            }

            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 InfiniteSigns_SignDataImport(
            ProtectionManager protectionManager,
            out int importedSigns, out int protectFailures
            )
        {
            string sqliteDatabaseFilePath = Path.Combine(TShock.SavePath, "signs.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.");
            }

            importedSigns = 0;
            protectFailures = 0;
            using (QueryResult reader = dbConnection.QueryReader(
              "SELECT X, Y, Account, Text FROM Signs 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");
            string rawText = reader.Get<string>("Text");

            if (!TerrariaUtils.Tiles.IsValidCoord(rawX, rawY))
              continue;

            // TSPlayer.All means that the sign 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);
                owner.User.ID = tUser.ID;
                owner.User.Name = tUser.Name;
                owner.Group = TShock.Groups.GetGroupByName(tUser.Group);
              } else {
                // The original owner of the sign does not exist anymore, so we just protect it for the server player.
                owner = TSPlayer.Server;
              }
            }

            DPoint signLocation = new DPoint(rawX, rawY);
            int signIndex = -1;
            for (int i = 0; i < Main.sign.Length; i++) {
              Sign sign = Main.sign[i];
              if (sign == null || sign.x != signLocation.X || sign.y != signLocation.Y)
                continue;

              signIndex = i;
              break;
            }

            if (signIndex == -1) {
              Tile signTile = TerrariaUtils.Tiles[signLocation];
              if (!signTile.active() || (signTile.type != (int)BlockType.Sign && signTile.type != (int)BlockType.Tombstone)) {
                this.PluginTrace.WriteLineWarning(string.Format(
                  "The sign data on the location {0} could not be imported because no corresponding sign does exist in the world.",
                  signLocation
                ));
                continue;
              }

              for (int i = 0; i < Main.sign.Length; i++) {
                Sign sign = Main.sign[i];
                if (sign == null)
                  continue;

                Main.sign[i] = new Sign() {
                  x = rawX,
                  y = rawY,
                  text = rawText
                };

                signIndex = i;
                break;
              }
            } else {
              Sign.TextSign(signIndex, rawText);
              importedSigns++;
            }

            if (owner != TSPlayer.All) {
              try {
                protectionManager.CreateProtection(owner, signLocation, true, false, false);
              } catch (Exception ex) {
                this.PluginTrace.WriteLineWarning("Failed to create protection at {0}:\n{1}", signLocation, ex);
                protectFailures++;
              }
            }
              }
            }
              } finally {
            if (dbConnection != null)
              dbConnection.Close();
              }
        }
        public UserInteractionHandler(
            PluginTrace trace, PluginInfo pluginInfo, Configuration config, ServerMetadataHandler serverMetadataHandler,
            WorldMetadata worldMetadata, ProtectionManager protectionManager, ChestManager chestManager,
            PluginCooperationHandler pluginCooperationHandler, Func<Configuration> reloadConfigurationCallback
            )
            : base(trace)
        {
            Contract.Requires<ArgumentNullException>(trace != null);
              Contract.Requires<ArgumentException>(!pluginInfo.Equals(PluginInfo.Empty));
              Contract.Requires<ArgumentNullException>(config != null);
              Contract.Requires<ArgumentNullException>(serverMetadataHandler != null);
              Contract.Requires<ArgumentNullException>(worldMetadata != null);
              Contract.Requires<ArgumentNullException>(protectionManager != null);
              Contract.Requires<ArgumentNullException>(pluginCooperationHandler != null);
              Contract.Requires<ArgumentNullException>(reloadConfigurationCallback != null);

              this.PluginInfo = pluginInfo;
              this.Config = config;
              this.ServerMetadataHandler = serverMetadataHandler;
              this.WorldMetadata = worldMetadata;
              this.ChestManager = chestManager;
              this.ProtectionManager = protectionManager;
              this.PluginCooperationHandler = pluginCooperationHandler;
              this.ReloadConfigurationCallback = reloadConfigurationCallback;

              this.PlayerIndexChestDictionary = new Dictionary<int,DPoint>(20);
              this.ChestPlayerIndexDictionary = new Dictionary<DPoint,int>(20);

              #region Command Setup
              base.RegisterCommand(
            new[] { "protector" }, this.RootCommand_Exec, this.RootCommand_HelpCallback
              );
              base.RegisterCommand(
            new[] { "protect", "pt" },
            this.ProtectCommand_Exec, this.ProtectCommand_HelpCallback, ProtectorPlugin.ManualProtect_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "deprotect", "dp" },
            this.DeprotectCommand_Exec, this.DeprotectCommand_HelpCallback, ProtectorPlugin.ManualDeprotect_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "protectioninfo", "ptinfo", "pi" }, this.ProtectionInfoCommand_Exec, this.ProtectionInfoCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "share" }, this.ShareCommand_Exec, this.ShareCommandHelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unshare" }, this.UnshareCommand_Exec, this.UnshareCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "sharepublic" }, this.SharePublicCommand_Exec, this.SharePublicCommandHelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unsharepublic" }, this.UnsharePublicCommand_Exec, this.UnsharePublicCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "sharegroup" }, this.ShareGroupCommand_Exec, this.ShareGroupCommand_HelpCallback,
            ProtectorPlugin.ShareWithGroups_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unsharegroup" }, this.UnshareGroupCommand_Exec, this.UnshareGroup_HelpCallback,
            ProtectorPlugin.ShareWithGroups_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "lockchest", "lchest" },
            this.LockChestCommand_Exec, this.LockChestCommand_HelpCallback, ProtectorPlugin.Utility_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "swapchest", "schest" },
            this.SwapChestCommand_Exec, this.SwapChestCommand_HelpCallback, ProtectorPlugin.Utility_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "refillchest", "rchest" },
            this.RefillChestCommand_Exec, this.RefillChestCommand_HelpCallback, ProtectorPlugin.SetRefillChests_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "refillchestmany", "rchestmany" },
            this.RefillChestManyCommand_Exec, this.RefillChestManyCommand_HelpCallback, ProtectorPlugin.Utility_Permission
              );
              base.RegisterCommand(
            new[] { "bankchest", "bchest" },
            this.BankChestCommand_Exec, this.BankChestCommand_HelpCallback, ProtectorPlugin.SetBankChests_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "dumpbankchest", "dbchest" },
            this.DumpBankChestCommand_Exec, this.DumpBankChestCommand_HelpCallback, ProtectorPlugin.DumpBankChests_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "tradechest", "tchest" },
            this.TradeChestCommand_Exec, this.TradeChestCommand_HelpCallback, ProtectorPlugin.SetTradeChests_Permission,
            allowServer: false
              );
              #endregion

              #if DEBUG
              base.RegisterCommand(new[] { "fc" }, args => {
            for (int i= 0; i < Main.chest.Length; i++) {
              if (i != ChestManager.DummyChestIndex)
            Main.chest[i] = Main.chest[i] ?? new Chest();
            }
              }, requiredPermission: Permissions.maintenance);
              base.RegisterCommand(new[] { "fcnames" }, args => {
            for (int i= 0; i < Main.chest.Length; i++) {
              if (i != ChestManager.DummyChestIndex) {
            Main.chest[i] = Main.chest[i] ?? new Chest();
            Main.chest[i].name = "Chest!";
              }
            }
              }, requiredPermission: Permissions.maintenance);
              #endif
        }
        public UserInteractionHandler(
            PluginTrace trace, PluginInfo pluginInfo, Configuration config, ServerMetadataHandler serverMetadataHandler,
            WorldMetadata worldMetadata, ProtectionManager protectionManager, PluginCooperationHandler pluginCooperationHandler,
            Func<Configuration> reloadConfigurationCallback
            )
            : base(trace)
        {
            Contract.Requires<ArgumentNullException>(trace != null);
              Contract.Requires<ArgumentException>(!pluginInfo.Equals(PluginInfo.Empty));
              Contract.Requires<ArgumentNullException>(config != null);
              Contract.Requires<ArgumentNullException>(serverMetadataHandler != null);
              Contract.Requires<ArgumentNullException>(worldMetadata != null);
              Contract.Requires<ArgumentNullException>(protectionManager != null);
              Contract.Requires<ArgumentNullException>(pluginCooperationHandler != null);
              Contract.Requires<ArgumentNullException>(reloadConfigurationCallback != null);

              this.PluginInfo = pluginInfo;
              this.Config = config;
              this.ServerMetadataHandler = serverMetadataHandler;
              this.WorldMetadata = worldMetadata;
              this.ProtectionManager = protectionManager;
              this.PluginCooperationHandler = pluginCooperationHandler;
              this.ReloadConfigurationCallback = reloadConfigurationCallback;

              #region Command Setup
              base.RegisterCommand(
            new[] { "protector" }, this.RootCommand_Exec, this.RootCommand_HelpCallback
              );
              base.RegisterCommand(
            new[] { "protect", "pt" },
            this.ProtectCommand_Exec, this.ProtectCommand_HelpCallback, ProtectorPlugin.ManualProtect_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "deprotect", "dp" },
            this.DeprotectCommand_Exec, this.DeprotectCommand_HelpCallback, ProtectorPlugin.ManualDeprotect_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "protectioninfo", "ptinfo", "pi" }, this.ProtectionInfoCommand_Exec, this.ProtectionInfoCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "share" }, this.ShareCommand_Exec, this.ShareCommandHelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unshare" }, this.UnshareCommand_Exec, this.UnshareCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "sharepublic" }, this.SharePublicCommand_Exec, this.SharePublicCommandHelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unsharepublic" }, this.UnsharePublicCommand_Exec, this.UnsharePublicCommand_HelpCallback,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "sharegroup" }, this.ShareGroupCommand_Exec, this.ShareGroupCommand_HelpCallback,
            ProtectorPlugin.ShareWithGroups_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "unsharegroup" }, this.UnshareGroupCommand_Exec, this.UnshareGroup_HelpCallback,
            ProtectorPlugin.ShareWithGroups_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "lockchest", "lchest" },
            this.LockChestCommand_Exec, this.LockChestCommand_HelpCallback, ProtectorPlugin.Utility_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "refillchest", "rchest" },
            this.RefillChestCommand_Exec, this.RefillChestCommand_HelpCallback, ProtectorPlugin.SetRefillChests_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "refillchestmany", "rchestmany" },
            this.RefillChestManyCommand_Exec, this.RefillChestManyCommand_HelpCallback, ProtectorPlugin.Utility_Permission
              );
              base.RegisterCommand(
            new[] { "bankchest", "bchest" },
            this.BankChestCommand_Exec, this.BankChestCommand_HelpCallback, ProtectorPlugin.SetBankChests_Permission,
            allowServer: false
              );
              base.RegisterCommand(
            new[] { "dumpbankchest", "dbchest" },
            this.DumpBankChestCommand_Exec, this.DumpBankChestCommand_HelpCallback, ProtectorPlugin.DumpBankChests_Permission,
            allowServer: false
              );
              #endregion
        }
        private void Game_PostInitialize(EventArgs e)
        {
            ServerApi.Hooks.GamePostInitialize.Deregister(this, this.Game_PostInitialize);

              if (!Directory.Exists(ProtectorPlugin.DataDirectory))
            Directory.CreateDirectory(ProtectorPlugin.DataDirectory);

              if (!this.InitConfig())
            return;
              if (!this.InitServerMetdataHandler())
            return;
              if (!this.InitWorldMetdataHandler())
            return;

              this.pluginCooperationHandler = new PluginCooperationHandler(this.Trace);
              this.protectionManager = new ProtectionManager(
            this.Trace, this.Config, this.ServerMetadataHandler, this.WorldMetadataHandler.Metadata
              );

              this.InitUserInteractionHandler();
              this.UserInteractionHandler.EnsureProtectionData(TSPlayer.Server);

              this.hooksEnabled = true;

              Task.Factory.StartNew(() => {
            // Wait a bit until other plugins might have registered their hooks in PostInitialize.
            Thread.Sleep(1000);

            this.AddPostHooks();
              });
        }
Esempio n. 8
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();
                }
            }
        }
Esempio n. 9
0
        public void InfiniteSigns_SignDataImport(
            ProtectionManager protectionManager,
            out int importedSigns, out int protectFailures
            )
        {
            string sqliteDatabaseFilePath = Path.Combine(TShock.SavePath, "signs.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.");
                }

                importedSigns   = 0;
                protectFailures = 0;
                using (QueryResult reader = dbConnection.QueryReader(
                           "SELECT X, Y, Account, Text FROM Signs 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");
                        string rawText    = reader.Get <string>("Text");

                        if (!TerrariaUtils.Tiles.IsValidCoord(rawX, rawY))
                        {
                            continue;
                        }

                        // TSPlayer.All means that the sign 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 sign does not exist anymore, so we just protect it for the server player.
                                owner = TSPlayer.Server;
                            }
                        }

                        DPoint signLocation = new DPoint(rawX, rawY);
                        int    signIndex    = -1;
                        for (int i = 0; i < Main.sign.Length; i++)
                        {
                            Sign sign = Main.sign[i];
                            if (sign == null || sign.x != signLocation.X || sign.y != signLocation.Y)
                            {
                                continue;
                            }

                            signIndex = i;
                            break;
                        }

                        if (signIndex == -1)
                        {
                            Tile signTile = TerrariaUtils.Tiles[signLocation];
                            if (!signTile.active() || (signTile.type != (int)BlockType.Sign && signTile.type != (int)BlockType.Tombstone))
                            {
                                this.PluginTrace.WriteLineWarning(string.Format(
                                                                      "The sign data on the location {0} could not be imported because no corresponding sign does exist in the world.",
                                                                      signLocation
                                                                      ));
                                continue;
                            }

                            for (int i = 0; i < Main.sign.Length; i++)
                            {
                                Sign sign = Main.sign[i];
                                if (sign == null)
                                {
                                    continue;
                                }

                                Main.sign[i] = new Sign()
                                {
                                    x    = rawX,
                                    y    = rawY,
                                    text = rawText
                                };

                                signIndex = i;
                                break;
                            }
                        }
                        else
                        {
                            Sign.TextSign(signIndex, rawText);
                            importedSigns++;
                        }

                        if (owner != TSPlayer.All)
                        {
                            try {
                                protectionManager.CreateProtection(owner, signLocation, true, false, false);
                            } catch (Exception ex) {
                                this.PluginTrace.WriteLineWarning("Failed to create protection at {0}:\n{1}", signLocation, 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();
            }
        }