diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index e90fa304..0665d8ca 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -341,10 +341,26 @@ namespace TShockAPI } else if (user.Password.ToUpper() == encrPass.ToUpper()) { + args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Parameters[0])); + + if (TShock.Config.ServerSideInventory) + { + if (!TShock.CheckInventory(args.Player)) + { + args.Player.SendMessage("Login Failed, Please fix the above errors then log back in.", Color.Cyan); + return; + } + } + args.Player.Group = TShock.Utils.GetGroup(user.Group); args.Player.UserAccountName = args.Parameters[0]; args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); args.Player.IsLoggedIn = true; + args.Player.IgnoreActionsForInventory = false; + + args.Player.PlayerData.CopyInventory(args.Player); + TShock.InventoryDB.InsertPlayerData(args.Player, args.Player.UserID); + args.Player.SendMessage("Authenticated as " + args.Parameters[0] + " successfully.", Color.LimeGreen); Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Parameters[0]); } @@ -1343,7 +1359,8 @@ namespace TShockAPI if (args.Player.Teleport(plr.TileX, plr.TileY + 3)) { args.Player.SendMessage(string.Format("Teleported to {0}", plr.Name)); - plr.SendMessage(args.Player.Name + " Teleported To You"); + if(args.Player.Group.HasPermission(Permissions.tphide)) + plr.SendMessage(args.Player.Name + " Teleported To You"); } } } diff --git a/TShockAPI/DB/InventoryManager.cs b/TShockAPI/DB/InventoryManager.cs index 28fc90e3..c9ffbbf0 100644 --- a/TShockAPI/DB/InventoryManager.cs +++ b/TShockAPI/DB/InventoryManager.cs @@ -33,7 +33,7 @@ namespace TShockAPI.DB database = db; var table = new SqlTable("Inventory", - new SqlColumn("AccountName", MySqlDbType.VarChar, 32) { Primary = true }, + new SqlColumn("Account", MySqlDbType.Int32) { Primary = true }, new SqlColumn("CharacterName", MySqlDbType.VarChar, 50), new SqlColumn("MaxHealth", MySqlDbType.Int32), new SqlColumn("MaxMana", MySqlDbType.Int32), @@ -43,13 +43,13 @@ namespace TShockAPI.DB creator.EnsureExists(table); } - public PlayerData GetPlayerData(TSPlayer player) + public PlayerData GetPlayerData(TSPlayer player, int acctid) { PlayerData playerData = new PlayerData(player); try { - using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE AccountName=@0 AND CharacterName=@1", player.UserAccountName, player.Name)) + using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE Account=@0 AND CharacterName=@1", acctid, player.Name)) { if (reader.Read()) { @@ -69,15 +69,16 @@ namespace TShockAPI.DB return playerData; } - public void InsertPlayerData(TSPlayer player) + public bool InsertPlayerData(TSPlayer player, int acctid) { PlayerData playerData = player.PlayerData; - if (!GetPlayerData(player).exists) + if (!GetPlayerData(player, acctid).exists) { try { - database.Query("INSERT INTO Inventory (AccountName, CharacterName, MaxHealth, MaxMana, Inventory) VALUES (@0, @1, @2, @3, @4);", playerData.accountName, playerData.characterName, playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory)); + database.Query("INSERT INTO Inventory (Account, CharacterName, MaxHealth, MaxMana, Inventory) VALUES (@0, @1, @2, @3, @4);", acctid, player.Name, playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory)); + return true; } catch (Exception ex) { @@ -88,13 +89,15 @@ namespace TShockAPI.DB { try { - database.Query("UPDATE Inventory SET MaxHealth = @0, MaxMana = @1, Inventory = @3 WHERE AccountName = @4 AND CharacterName = @5;", playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory), playerData.accountName, playerData.characterName); + database.Query("UPDATE Inventory SET MaxHealth = @0, MaxMana = @1, Inventory = @3 WHERE Account = @4 AND CharacterName = @5;", playerData.maxHealth, playerData.maxMana, NetItem.ToString(playerData.inventory), player.Name, acctid); + return true; } catch (Exception ex) { Log.Error(ex.ToString()); } } + return false; } } } diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index ba253a37..c57f8438 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -123,16 +123,28 @@ namespace TShockAPI short prefix = (short) args.Data.ReadInt8(); int type = (int) args.Data.ReadInt16(); - if (type == 0) + if (plr != args.Player.Index) + { return true; + } + + if (slot < 0 || slot > NetItem.maxNetInventory) + { + return true; + } var item = new Item(); item.netDefaults(type); item.Prefix(prefix); - if (stack > item.maxStack) + if (stack > item.maxStack && type != 0) { - return TShock.Utils.HandleCheater(args.Player, String.Format("Stack cheat detected. Remove {0} ({1}) > {2} and then rejoin", item.name, stack, item.maxStack)); + TShock.Utils.HandleCheater(args.Player, String.Format("Stack cheat detected. Remove {0} ({1}) > {2} and then rejoin", item.name, stack, item.maxStack)); + } + + if (args.Player.IsLoggedIn) + { + args.Player.PlayerData.StoreSlot(slot, type, prefix, stack); } return false; @@ -146,7 +158,7 @@ namespace TShockAPI if (cur > 600 || max > 600) { - return TShock.Utils.HandleCheater(args.Player, "Health cheat detected. Please use a different character."); + TShock.Utils.HandleCheater(args.Player, "Health cheat detected. Please use a different character."); } return false; @@ -160,7 +172,7 @@ namespace TShockAPI if (cur > 600 || max > 600) { - return TShock.Utils.HandleCheater(args.Player, "Mana cheat detected. Please use a different character."); + TShock.Utils.HandleCheater(args.Player, "Mana cheat detected. Please use a different character."); } return false; diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 85c2624d..5d2798a2 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -138,6 +138,9 @@ namespace TShockAPI [Description("Users can tp to anyone")] public static readonly string tpall; + [Description("Users can tp to people without showing a notice")] + public static readonly string tphide; + [Description("User can convert hallow into corruption and vice-versa")] public static readonly string converthardmode; diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index c5ec7a28..5f6c947e 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -438,14 +438,10 @@ namespace TShockAPI public NetItem[] inventory = new NetItem[NetItem.maxNetInventory]; public int maxHealth = 100; public int maxMana = 100; - public string accountName; - public string characterName; public bool exists = false; public PlayerData(TSPlayer player) { - this.accountName = player.UserAccountName; - this.characterName = player.Name; this.inventory[0].netID = -15; this.inventory[0].stack = 1; if(player.TPlayer.inventory[0].netID == -15) @@ -459,6 +455,58 @@ namespace TShockAPI if (player.TPlayer.inventory[2].netID == -16) this.inventory[2].prefix = player.TPlayer.inventory[2].prefix; } + + public void StoreSlot(int slot, int netID, int prefix, int stack) + { + this.inventory[slot].netID = netID; + if (this.inventory[slot].netID != 0) + { + this.inventory[slot].stack = stack; + this.inventory[slot].prefix = prefix; + } + else + { + this.inventory[slot].stack = 0; + this.inventory[slot].prefix = 0; + } + } + + public void CopyInventory(TSPlayer player) + { + Item[] inventory = player.TPlayer.inventory; + Item[] armor = player.TPlayer.armor; + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + if (i < 49) + { + this.inventory[i].netID = inventory[i].netID; + if (this.inventory[i].netID != 0) + { + this.inventory[i].stack = inventory[i].stack; + this.inventory[i].prefix = inventory[i].prefix; + } + else + { + this.inventory[i].stack = 0; + this.inventory[i].prefix = 0; + } + } + else + { + this.inventory[i].netID = armor[i].netID; + if (this.inventory[i].netID != 0) + { + this.inventory[i].stack = armor[i].stack; + this.inventory[i].prefix = armor[i].prefix; + } + else + { + this.inventory[i].stack = 0; + this.inventory[i].prefix = 0; + } + } + } + } } public class NetItem diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 4af85358..e13ea94e 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -62,7 +62,7 @@ namespace TShockAPI public static UserManager Users; public static ItemManager Itembans; public static RemeberedPosManager RememberedPos; - public static InventoryManager Inventory; + public static InventoryManager InventoryDB; public static ConfigFile Config { get; set; } public static IDbConnection DB; public static bool OverridePort; @@ -178,7 +178,7 @@ namespace TShockAPI Regions = new RegionManager(DB); Itembans = new ItemManager(DB); RememberedPos = new RemeberedPosManager(DB); - Inventory = new InventoryManager(DB); + InventoryDB = new InventoryManager(DB); RestApi = new SecureRest(Netplay.serverListenIP, 8080); RestApi.Verify += RestApi_Verify; RestApi.Port = Config.RestApiPort; @@ -552,6 +552,12 @@ namespace TShockAPI TShock.Utils.Broadcast(tsplr.Name + " has left", Color.Yellow); Log.Info(string.Format("{0} left.", tsplr.Name)); + if (tsplr.IsLoggedIn) + { + tsplr.PlayerData.CopyInventory(tsplr); + InventoryDB.InsertPlayerData(tsplr, tsplr.UserID); + } + if (Config.RememberLeavePos) { RememberedPos.InsertLeavePos(tsplr.Name, tsplr.IP, (int)(tsplr.X / 16), (int)(tsplr.Y / 16)); @@ -723,6 +729,11 @@ namespace TShockAPI TShock.Utils.HandleCheater(player, "Health/Mana cheat detected. Please use a different character."); } + if (TShock.Config.ServerSideInventory) + { + player.IgnoreActionsForInventory = true; + player.SendMessage("Server Side Inventory is enabled! Please /register or /login to play!", Color.Red); + } NetMessage.syncPlayers(); @@ -1005,8 +1016,94 @@ namespace TShockAPI public static bool CheckInventory(TSPlayer player) { + PlayerData playerData = player.PlayerData; + bool check = true; - return false; + if (player.TPlayer.statLifeMax > playerData.maxHealth) + { + player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server", Color.Cyan); + check = false; + } + + if (player.TPlayer.statManaMax > playerData.maxMana) + { + player.SendMessage("Error: Your max mana exceeded (" + playerData.maxMana + ") which is stored on server", Color.Cyan); + check = false; + } + + Item[] inventory = player.TPlayer.inventory; + Item[] armor = player.TPlayer.armor; + for (int i = 0; i < NetItem.maxNetInventory; i++) + { + if (i < 49) + { + Item item = new Item(); + Item serverItem = new Item(); + if (inventory[i].netID != 0) + { + if (playerData.inventory[i].netID != inventory[i].netID) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your item (" + item.name + ") needs to be deleted.", Color.Cyan); + check = false; + } + else if (playerData.inventory[i].prefix != inventory[i].prefix) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your item (" + item.name + ") needs to be deleted.", Color.Cyan); + check = false; + } + + if (inventory[i].stack > playerData.inventory[i].stack) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + playerData.inventory[i].stack + ").", Color.Cyan); + check = false; + } + } + } + else + { + Item item = new Item(); + Item serverItem = new Item(); + if (armor[i].netID != 0) + { + if (playerData.inventory[i].netID != armor[i].netID) + { + item.netDefaults(armor[i].netID); + item.Prefix(armor[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your armor (" + item.name + ") needs to be deleted.", Color.Cyan); + check = false; + } + else if (playerData.inventory[i].prefix != armor[i].prefix) + { + item.netDefaults(armor[i].netID); + item.Prefix(armor[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your armor (" + item.name + ") needs to be deleted.", Color.Cyan); + check = false; + } + + if (armor[i].stack > playerData.inventory[i].stack) + { + item.netDefaults(armor[i].netID); + item.Prefix(armor[i].prefix); + item.AffixName(); + player.SendMessage("Error: Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" + playerData.inventory[i].stack + ").", Color.Cyan); + check = false; + } + } + } + } + + return check; } public static bool CheckIgnores(TSPlayer player)