public void ProtectionTableConstructorTest() { ProtectionTable target = new ProtectionTable(new ProtectionEntry(ProtectionMode.Super, EntryType.User, " ", " ", " ", false)); ProtectionEntry Entry1 = new ProtectionEntry(ProtectionMode.Admin, EntryType.Group, "admin_user", "win-admin-host", "//...", false); ProtectionEntry Entry2 = new ProtectionEntry(ProtectionMode.Read, EntryType.User, "read_user", "win-user-host", "//depot/test/...", false); target.Add(Entry1); target.Add(Entry2); Assert.AreEqual(Entry1, target[0]); Assert.AreEqual(Entry2, target[1]); }
public void HostTest() { ProtectionMode mode = new ProtectionMode(); // TODO: Initialize to an appropriate value EntryType type = EntryType.User; string grouporusername = string.Empty; // TODO: Initialize to an appropriate value string host = "win-user_bob"; // only adding host string path = string.Empty; // TODO: Initialize to an appropriate value ProtectionEntry target = new ProtectionEntry(mode, type, grouporusername, host, path, false); // TODO: Initialize to an appropriate value string expected = string.Empty; // TODO: Initialize to an appropriate value string actual; target.Host = expected; actual = target.Host; Assert.AreEqual(expected, actual); }
public void PathTest() { ProtectionMode mode = new ProtectionMode(); // TODO: Initialize to an appropriate value EntryType type = new EntryType(); string grouporusername = string.Empty; // TODO: Initialize to an appropriate value string host = string.Empty; // TODO: Initialize to an appropriate value string path = string.Empty; // TODO: Initialize to an appropriate value ProtectionEntry target = new ProtectionEntry(mode, type, grouporusername, host, path, false); // TODO: Initialize to an appropriate value string expected = "//..."; // only adding wide open path string actual; target.Path = expected; actual = target.Path; Assert.AreEqual(expected, actual); }
public void ModeTest() { ProtectionMode mode = new ProtectionMode(); // TODO: Initialize to an appropriate value EntryType type = new EntryType(); string grouporusername = string.Empty; // TODO: Initialize to an appropriate value string host = string.Empty; // TODO: Initialize to an appropriate value string path = string.Empty; // TODO: Initialize to an appropriate value ProtectionEntry target = new ProtectionEntry(mode, type, grouporusername, host, path, false); // TODO: Initialize to an appropriate value ProtectionMode expected = ProtectionMode.Super; // only adding protection mode super ProtectionMode actual; target.Mode = expected; actual = target.Mode; Assert.AreEqual(expected, actual); }
public void TypeTest() { ProtectionMode mode = new ProtectionMode(); // TODO: Initialize to an appropriate value EntryType type = EntryType.User; string grouporusername = string.Empty; // TODO: Initialize to an appropriate value string host = string.Empty; // TODO: Initialize to an appropriate value string path = string.Empty; // TODO: Initialize to an appropriate value ProtectionEntry target = new ProtectionEntry(mode, type, grouporusername, host, path, false); // TODO: Initialize to an appropriate value EntryType expected = EntryType.User; EntryType actual; target.Type = expected; actual = target.Type; Assert.AreEqual(expected, actual); }
private void PerformTrade(TSPlayer player, ProtectionEntry protection, Inventory chestInventory, Item sellItem, Item payItem) { Inventory playerInventory = new Inventory(new PlayerItemsAdapter(player.Index, player.TPlayer.inventory, 0, 53), specificPrefixes: false); ItemData sellItemData = ItemData.FromItem(sellItem); ItemData payItemData = ItemData.FromItem(payItem); ItemData?[] playerInvUpdates; try { playerInvUpdates = playerInventory.Remove(payItemData); playerInventory.Add(playerInvUpdates, sellItemData); } catch (InvalidOperationException) { player.SendErrorMessage($"You either don't have the needed {TShock.Utils.ItemTag(payItem)} to purchase {TShock.Utils.ItemTag(sellItem)} or your inventory is full."); return; } bool isRefillChest = (protection.RefillChestData != null); ItemData?[] chestInvUpdates; try { if (isRefillChest) { chestInvUpdates = chestInventory.Add(payItemData); } else { chestInvUpdates = chestInventory.Remove(sellItemData); chestInventory.Add(chestInvUpdates, payItemData); } } catch (InvalidOperationException) { player.SendErrorMessage("The items in the trade chest are either sold out or there's no space in it to add your payment."); return; } try { protection.TradeChestData.AddOrUpdateLooter(player.User.ID); } catch (InvalidOperationException) { player.SendErrorMessage($"The vendor doesn't allow more than {protection.TradeChestData.LootLimitPerPlayer} purchases per player."); return; } playerInventory.ApplyUpdates(playerInvUpdates); chestInventory.ApplyUpdates(chestInvUpdates); protection.TradeChestData.AddJournalEntry(player.Name, sellItem, payItem); player.SendSuccessMessage($"You've just purchased {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)} from {TShock.Utils.ColorTag(GetUserName(protection.Owner), Color.Red)}."); }
private void InitTrade(TSPlayer player, IChest chest, ProtectionEntry protection) { TradeChestMetadata tradeChestData = protection.TradeChestData; Item sellItem = new Item(); sellItem.netDefaults(tradeChestData.ItemToSellId); sellItem.stack = tradeChestData.ItemToSellAmount; Item payItem = new Item(); payItem.netDefaults(tradeChestData.ItemToPayId); payItem.stack = tradeChestData.ItemToPayAmount; player.SendMessage($"This is a trade chest owned by {TShock.Utils.ColorTag(GetUserName(protection.Owner), Color.Red)}.", Color.LightGray); Inventory chestInventory = new Inventory(chest.Items, specificPrefixes: false); int stock = chestInventory.Amount(sellItem.netID); if (stock < sellItem.stack) { player.SendMessage($"It was trading {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)} but it is out of stock.", Color.LightGray); return; } player.SendMessage($"Click again to purchase {TShock.Utils.ItemTag(sellItem)} for {TShock.Utils.ItemTag(payItem)}", Color.LightGray); CommandInteraction interaction = this.StartOrResetCommandInteraction(player); interaction.ChestOpenCallback += (playerLocal, chestLocation) => { bool complete; bool wasThisChestHit = (chestLocation == chest.Location); if (wasThisChestHit) { // this is important to check, otherwise players could use trade chests to easily duplicate items if (!this.IsChestInUse(playerLocal, chest)) this.PerformTrade(player, protection, chestInventory, sellItem, payItem); else player.SendErrorMessage("Another player is currently viewing the content of this chest."); complete = false; } else { this.HandleChestGetContents(playerLocal, chestLocation, skipInteractions: true); complete = true; } playerLocal.SendTileSquare(chest.Location); return new CommandInteractionResult {IsHandled = true, IsInteractionCompleted = complete}; }; }
public bool CheckBlockAccess(TSPlayer player, DPoint tileLocation, bool fullAccessRequired, out ProtectionEntry relatedProtection) { foreach (ProtectionEntry protection in this.EnumerateProtectionEntries(tileLocation)) { relatedProtection = protection; if (!this.CheckProtectionAccess(protection, player, fullAccessRequired)) { relatedProtection = protection; return false; } // If full access is not required, then there's no use in checking the adjacent blocks. if (!fullAccessRequired) return true; } relatedProtection = null; return true; }
private void ProtectionSharePreValidation( TSPlayer player, DPoint tileLocation, bool shareOrUnshare, bool checkPermissions, out ProtectionEntry protection ) { Tile tile = TerrariaUtils.Tiles[tileLocation]; BlockType blockType = (BlockType)tile.type; if (!ProtectionManager.IsShareableBlockType(blockType)) throw new InvalidBlockTypeException(blockType); if (checkPermissions) { if ( (tile.type == (int)BlockType.Chest || tile.type == (int)BlockType.Dresser) && !player.Group.HasPermission(ProtectorPlugin.ChestSharing_Permission) ) { throw new MissingPermissionException(ProtectorPlugin.ChestSharing_Permission); } if ( TerrariaUtils.Tiles.IsSwitchableBlockType((BlockType)tile.type) && !player.Group.HasPermission(ProtectorPlugin.SwitchSharing_Permission) ) { throw new MissingPermissionException(ProtectorPlugin.SwitchSharing_Permission); } if ( ( tile.type == (int)BlockType.Sign || tile.type == (int)BlockType.Tombstone || tile.type == (int)BlockType.Bed || tile.type == (int)BlockType.DoorOpened || tile.type == (int)BlockType.DoorClosed ) && !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.User.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 ProtectionEntry CreateProtection( TSPlayer player, DPoint tileLocation, bool checkIfBlockTypeProtectableByConfig = true, bool checkTShockBuildAndRegionAccess = true, bool checkLimits = true ) { Contract.Requires<ArgumentNullException>(player != null); Contract.Requires<ArgumentException>(TerrariaUtils.Tiles[tileLocation] != null, "tileLocation"); Contract.Requires<ArgumentException>(TerrariaUtils.Tiles[tileLocation].active(), "tileLocation"); Tile tile = TerrariaUtils.Tiles[tileLocation]; BlockType blockType = (BlockType)tile.type; tileLocation = TerrariaUtils.Tiles.MeasureObject(tileLocation).OriginTileLocation; if (checkIfBlockTypeProtectableByConfig && !this.Config.ManuallyProtectableTiles[tile.type]) throw new InvalidBlockTypeException(blockType); if (checkTShockBuildAndRegionAccess && TShock.CheckTilePermission(player, tileLocation.X, tileLocation.Y)) throw new TileProtectedException(tileLocation); if ( checkLimits && !player.Group.HasPermission(ProtectorPlugin.NoProtectionLimits_Permission) && this.WorldMetadata.CountUserProtections(player.User.ID) >= this.Config.MaxProtectionsPerPlayerPerWorld ) { throw new LimitEnforcementException(); } ProtectionEntry protection; lock (this.WorldMetadata.Protections) { if (this.WorldMetadata.Protections.TryGetValue(tileLocation, out protection)) { if (protection.Owner == player.User.ID) throw new AlreadyProtectedException(); throw new TileProtectedException(tileLocation); } } protection = new ProtectionEntry(player.User.ID, tileLocation, (BlockType)tile.type); lock (this.WorldMetadata.Protections) this.WorldMetadata.Protections.Add(tileLocation, protection); return protection; }
public bool CheckProtectionAccess(ProtectionEntry protection, TSPlayer player, bool fullAccessRequired = false) { bool hasAccess = (player.IsLoggedIn && protection.Owner == player.User.ID); if (!hasAccess && !fullAccessRequired) { hasAccess = player.Group.HasPermission(ProtectorPlugin.UseEverything_Permision); if (!hasAccess) hasAccess = protection.IsSharedWithPlayer(player); } return hasAccess; }
public bool EnsureRefillChest(ProtectionEntry protection) { if (protection.RefillChestData == null) return false; if (this.ChestFromLocation(protection.TileLocation) == null) { protection.RefillChestData = null; return false; } protection.RefillChestData.RefillTimer.Data = protection.RefillChestData; protection.RefillChestData.RefillTimer.Callback = this.RefillTimerCallbackHandler; this.RefillTimers.ContinueTimer(protection.RefillChestData.RefillTimer); return true; }
public bool EnsureBankChest(ProtectionEntry protection, bool resetContent) { if (protection.BankChestKey == BankChestDataKey.Invalid) return false; BankChestMetadata bankChest = this.ServerMetadataHandler.EnqueueGetBankChestMetadata(protection.BankChestKey).Result; if (bankChest == null) { protection.BankChestKey = BankChestDataKey.Invalid; return false; } IChest chest = this.ChestFromLocation(protection.TileLocation); if (chest == null) { protection.BankChestKey = BankChestDataKey.Invalid; return false; } User owner = TShock.Users.GetUserByID(protection.Owner); if (owner == null) { this.DestroyChest(chest); protection.BankChestKey = BankChestDataKey.Invalid; return false; } Group ownerGroup = TShock.Groups.GetGroupByName(owner.Group); if (ownerGroup != null) { if (protection.SharedUsers != null && !ownerGroup.HasPermission(ProtectorPlugin.BankChestShare_Permission)) protection.SharedUsers.Clear(); if (protection.SharedGroups != null && !ownerGroup.HasPermission(ProtectorPlugin.BankChestShare_Permission)) protection.SharedGroups.Clear(); if (protection.IsSharedWithEveryone && !ownerGroup.HasPermission(ProtectorPlugin.BankChestShare_Permission)) protection.IsSharedWithEveryone = false; } if (resetContent) { for (int i = 0; i < Chest.maxItems; i++) chest.Items[i] = bankChest.Items[i]; } return true; }