diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs index d0beb4ab..3222b1ff 100644 --- a/TShockAPI/DB/ItemManager.cs +++ b/TShockAPI/DB/ItemManager.cs @@ -1,22 +1,28 @@ using System; using System.Collections.Generic; using System.Data; +using System.Diagnostics.CodeAnalysis; + using System.IO; +using System.Linq; +using System.Xml; using MySql.Data.MySqlClient; +using Terraria; namespace TShockAPI.DB { public class ItemManager { private IDbConnection database; - public List ItemBans = new List(); + public List ItemBans = new List(); public ItemManager(IDbConnection db) { database = db; var table = new SqlTable("ItemBans", - new SqlColumn("ItemName", MySqlDbType.VarChar, 50) { Primary = true } + new SqlColumn("ItemName", MySqlDbType.VarChar, 50) { Primary = true }, + new SqlColumn("AllowedGroups", MySqlDbType.Text ) ); var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); creator.EnsureExists(table); @@ -33,13 +39,13 @@ namespace TShockAPI.DB { string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO 'ItemBans' (ItemName) VALUES (@0);" : - "INSERT IGNORE INTO ItemBans SET ItemName=@0;"; + "INSERT OR IGNORE INTO 'ItemBans' (ItemName, AllowedGroups) VALUES (@0, @1);" : + "INSERT IGNORE INTO ItemBans SET ItemName=@0,AllowedGroups=@1 ;"; int id = 0; int.TryParse(line, out id); - database.Query(query, TShock.Utils.GetItemById(id).name); + database.Query(query, TShock.Utils.GetItemById(id).name, ""); } } } @@ -62,17 +68,22 @@ namespace TShockAPI.DB using (var reader = database.QueryReader("SELECT * FROM ItemBans")) { - while (reader != null && reader.Read()) - ItemBans.Add(reader.Get("ItemName")); + while (reader != null && reader.Read()) + { + ItemBan ban = new ItemBan(reader.Get("ItemName")); + ban.SetAllowedGroups( reader.Get("AllowedGroups") ); + ItemBans.Add(ban); + } } } + public void AddNewBan(string itemname = "") { try { - database.Query("INSERT INTO ItemBans (ItemName) VALUES (@0);", TShock.Utils.GetItemByName(itemname)[0].name); - if (!ItemIsBanned(itemname)) - ItemBans.Add(itemname); + database.Query("INSERT INTO ItemBans (ItemName, AllowedGroups) VALUES (@0, @1);", TShock.Utils.GetItemByName(itemname)[0].name, ""); + if (!ItemIsBanned(itemname, null)) + ItemBans.Add( new ItemBan(itemname) ); } catch (Exception ex) { @@ -82,12 +93,12 @@ namespace TShockAPI.DB public void RemoveBan(string itemname) { - if (!ItemIsBanned(itemname)) + if (!ItemIsBanned(itemname, null)) return; try { database.Query("Delete FROM 'ItemBans' WHERE ItemName=@0;", TShock.Utils.GetItemByName(itemname)[0].name); - ItemBans.Remove(itemname); + ItemBans.Remove( new ItemBan(itemname) ); } catch (Exception ex) { @@ -95,12 +106,118 @@ namespace TShockAPI.DB } } - public bool ItemIsBanned(string name) + public bool ItemIsBanned(string name, TSPlayer ply) { - if (ItemBans.Contains(name)) - return true; - - return false; + if (ItemBans.Contains( new ItemBan(name) ) ) + { + ItemBan b = GetItemBanByName(name); + Console.WriteLine("Item ban exists"); + Console.WriteLine( "Can use: {0}",b.HasPermissionToUseItem(ply)); + return !b.HasPermissionToUseItem(ply); + } + return false; } + + public bool AllowGroup(string item, string name) + { + string groupsNew = ""; + ItemBan b = GetItemBanByName(item); + if (b != null) + { + groupsNew = String.Join(",", b.AllowedGroups); + if (groupsNew.Length > 0) + groupsNew += ","; + groupsNew += name; + b.SetAllowedGroups(groupsNew); + + int q = database.Query("UPDATE ItemBans SET AllowedGroups=@0 WHERE ItemName=@1", groupsNew, + item); + + return q > 0; + } + + return false; + } + + public bool RemoveGroup(string item, string group) + { + ItemBan b = GetItemBanByName(item); + if (b != null) + { + b.RemoveGroup(group); + string groups = string.Join(",", b.AllowedGroups); + int q = database.Query("UPDATE ItemBans SET AllowedGroups=@0 WHERE ItemName=@1", groups, + item); + if (q > 0) + return true; + } + return false; + } + + public ItemBan GetItemBanByName(String name) + { + foreach (ItemBan b in ItemBans) + { + if (b.Name == name) + { + return b; + } + } + return null; + } } + + public class ItemBan : IEquatable + { + public string Name { get; set; } + public List AllowedGroups { get; set; } + + public ItemBan(string name) + : this() + { + Name = name; + AllowedGroups = new List(); + } + + public ItemBan() + { + Name = ""; + AllowedGroups = new List(); + } + + public bool Equals(ItemBan other) + { + return Name == other.Name; + } + + public bool HasPermissionToUseItem(TSPlayer ply) + { + if (ply == null) + return false; + Console.WriteLine(ply.Group.Name); + return AllowedGroups.Contains(ply.Group.Name); // could add in the other permissions in this class instead of a giant if switch. + } + + public void SetAllowedGroups( String groups ) + { + // prevent null pointer exceptions + if (!string.IsNullOrEmpty(groups)) + { + List groupArr = groups.Split(',').ToList(); + + for (int i = 0; i < groupArr.Count; i++) + { + groupArr[i] = groupArr[i].Trim(); + Console.WriteLine(groupArr[i]); + } + AllowedGroups = groupArr; + } + } + + public bool RemoveGroup(string groupName) + { + return AllowedGroups.Remove(groupName); + } + } + } diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 44bcdb91..64155671 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -646,7 +646,7 @@ namespace TShockAPI.DB return true; } - return AllowedIDs.Contains(ply.UserID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.UserAccountName; + return AllowedIDs.Contains(ply.UserID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.UserAccountName || ply.Group.HasPermission("manageregion"); } public void setAllowedIDs(String ids) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index e9e3c46c..210b65dc 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -481,7 +481,7 @@ namespace TShockAPI args.Player.SendTileSquare(tileX, tileY); return true; } - if (tiletype == 48 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Spikes")) + if (tiletype == 48 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Spikes", args.Player)) { args.Player.SendTileSquare(tileX, tileY); return true; @@ -492,7 +492,7 @@ namespace TShockAPI args.Player.SendTileSquare(tileX, tileY); return true; } - if (tiletype == 141 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Explosives")) + if (tiletype == 141 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Explosives", args.Player)) { args.Player.SendTileSquare(tileX, tileY); return true; @@ -661,7 +661,7 @@ namespace TShockAPI if ((control & 32) == 32) { - if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name)) + if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(args.TPlayer.inventory[item].name, args.Player)) { control -= 32; args.Player.LastThreat = DateTime.UtcNow; @@ -896,14 +896,14 @@ namespace TShockAPI bucket = 2; } - if (lava && bucket != 2 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Lava Bucket")) + if (lava && bucket != 2 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player)) { args.Player.LastThreat = DateTime.UtcNow; args.Player.SendTileSquare(tileX, tileY); return true; } - if (!lava && bucket != 1 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Water Bucket")) + if (!lava && bucket != 1 && !args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Water Bucket", args.Player)) { args.Player.LastThreat = DateTime.UtcNow; args.Player.SendTileSquare(tileX, tileY); @@ -1042,7 +1042,7 @@ namespace TShockAPI Item item = new Item(); item.netDefaults(type); - if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name)) + if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) { return false; } @@ -1175,7 +1175,7 @@ namespace TShockAPI Item item = new Item(); item.netDefaults(type); - if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name)) + if (stacks > item.maxStack || TShock.Itembans.ItemIsBanned(item.name, args.Player)) { args.Player.SendData(PacketTypes.ItemDrop, "", id); return true; @@ -1335,7 +1335,7 @@ namespace TShockAPI if (buff == 10) { - if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Invisibility Potion")) + if (!args.Player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Invisibility Potion", args.Player) ) buff = 0; else if (TShock.Config.DisableInvisPvP && args.TPlayer.hostile) buff = 0; diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index d1176ac2..d65eeb82 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -424,11 +424,14 @@ namespace TShockAPI { foreach(Chest chest in Main.chest) { - foreach(Item item in chest.item) - { - if (item.stack > item.maxStack) - item.stack = item.maxStack; - } + if (chest != null) + { + foreach (Item item in chest.item) + { + if (item != null && item.stack > item.maxStack) + item.stack = item.maxStack; + } + } } } @@ -816,7 +819,7 @@ namespace TShockAPI void OnNpcSetDefaults(SetDefaultsEventArgs e) { - if (TShock.Itembans.ItemIsBanned(e.Object.name)) + if (TShock.Itembans.ItemIsBanned(e.Object.name, null) ) { e.Object.SetDefaults(0); } @@ -975,12 +978,12 @@ namespace TShockAPI return true; } - if (type == 17 && !player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Dirt Wand")) //Dirt Wand Projectile + if (type == 17 && !player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Dirt Wand", player)) //Dirt Wand Projectile { return true; } - if ((type == 42 || type == 65 || type == 68) && !player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Sandgun")) //Sandgun Projectiles + if ((type == 42 || type == 65 || type == 68) && !player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned("Sandgun", player)) //Sandgun Projectiles { return true; } @@ -988,7 +991,7 @@ namespace TShockAPI Projectile proj = new Projectile(); proj.SetDefaults(type); - if (!player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(proj.name)) + if (!player.Group.HasPermission(Permissions.usebanneditem) && TShock.Itembans.ItemIsBanned(proj.name, player)) { return true; }