From b316ba82007c3cf6108244b769da62e2c989ff8d Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Thu, 21 Dec 2017 10:57:46 -0700 Subject: [PATCH] Move inventory stack hack detection to TSPlayer Only called in one method, the stack hack detection can move to TSPlayer as it only ever operates on one player. In a future commit, this will replace the stack hack detection OnSecondUpdate() and also set the disabled flag if a player has a hacked stack when called. --- TShockAPI/GetDataHandlers.cs | 4 +- TShockAPI/TSPlayer.cs | 206 +++++++++++++++++++++++++++++++++++ TShockAPI/TShock.cs | 197 --------------------------------- 3 files changed, 209 insertions(+), 198 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index e5336967..d8eb344d 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1916,7 +1916,9 @@ namespace TShockAPI if (!args.Player.HasPermission(Permissions.ignorestackhackdetection)) { - TShock.HackedInventory(args.Player); + // TODO: When checkignores gets merged, this needs to set the hacked item stack flag + // and get moved to bouncer + args.Player.HasHackedItemStacks(true); } if (TShock.Utils.ActivePlayers() + 1 > TShock.Config.MaxSlots && diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 868f20b2..fcc29b04 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -300,6 +300,212 @@ namespace TShockAPI return IgnoreActionsForInventory != "none" || IgnoreActionsForCheating != "none" || IgnoreActionsForDisabledArmor != "none" || IgnoreActionsForClearingTrashCan || !IsLoggedIn && TShock.Config.RequireLogin; } + /// Checks to see if a player has hacked item stacks in their inventory, and messages them as it checks. + /// If the check should send a message to the player with the results of the check. + /// True if any stacks don't conform. + public bool HasHackedItemStacks(bool shouldSendMessage = false) + { + bool check = false; + + Item[] inventory = TPlayer.inventory; + Item[] armor = TPlayer.armor; + Item[] dye = TPlayer.dye; + Item[] miscEquips = TPlayer.miscEquips; + Item[] miscDyes = TPlayer.miscDyes; + Item[] piggy = TPlayer.bank.item; + Item[] safe = TPlayer.bank2.item; + Item[] forge = TPlayer.bank3.item; + Item trash = TPlayer.trashItem; + for (int i = 0; i < NetItem.MaxInventory; i++) + { + if (i < NetItem.InventoryIndex.Item2) + { + //0-58 + Item item = new Item(); + if (inventory[i] != null && inventory[i].netID != 0) + { + item.netDefaults(inventory[i].netID); + item.Prefix(inventory[i].prefix); + item.AffixName(); + if (inventory[i].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove item {0} ({1}) and then rejoin.", item.Name, inventory[i].stack); + } + } + } + } + else if (i < NetItem.ArmorIndex.Item2) + { + //59-78 + var index = i - NetItem.ArmorIndex.Item1; + Item item = new Item(); + if (armor[index] != null && armor[index].netID != 0) + { + item.netDefaults(armor[index].netID); + item.Prefix(armor[index].prefix); + item.AffixName(); + if (armor[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove armor {0} ({1}) and then rejoin.", item.Name, armor[index].stack); + } + } + } + } + else if (i < NetItem.DyeIndex.Item2) + { + //79-88 + var index = i - NetItem.DyeIndex.Item1; + Item item = new Item(); + if (dye[index] != null && dye[index].netID != 0) + { + item.netDefaults(dye[index].netID); + item.Prefix(dye[index].prefix); + item.AffixName(); + if (dye[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove dye {0} ({1}) and then rejoin.", item.Name, dye[index].stack); + } + } + } + } + else if (i < NetItem.MiscEquipIndex.Item2) + { + //89-93 + var index = i - NetItem.MiscEquipIndex.Item1; + Item item = new Item(); + if (miscEquips[index] != null && miscEquips[index].netID != 0) + { + item.netDefaults(miscEquips[index].netID); + item.Prefix(miscEquips[index].prefix); + item.AffixName(); + if (miscEquips[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove item {0} ({1}) and then rejoin.", item.Name, miscEquips[index].stack); + } + } + } + } + else if (i < NetItem.MiscDyeIndex.Item2) + { + //93-98 + var index = i - NetItem.MiscDyeIndex.Item1; + Item item = new Item(); + if (miscDyes[index] != null && miscDyes[index].netID != 0) + { + item.netDefaults(miscDyes[index].netID); + item.Prefix(miscDyes[index].prefix); + item.AffixName(); + if (miscDyes[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove item dye {0} ({1}) and then rejoin.", item.Name, miscDyes[index].stack); + } + } + } + } + else if (i < NetItem.PiggyIndex.Item2) + { + //98-138 + var index = i - NetItem.PiggyIndex.Item1; + Item item = new Item(); + if (piggy[index] != null && piggy[index].netID != 0) + { + item.netDefaults(piggy[index].netID); + item.Prefix(piggy[index].prefix); + item.AffixName(); + + if (piggy[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove Piggy-bank item {0} ({1}) and then rejoin.", item.Name, piggy[index].stack); + } + } + } + } + else if (i < NetItem.SafeIndex.Item2) + { + //138-178 + var index = i - NetItem.SafeIndex.Item1; + Item item = new Item(); + if (safe[index] != null && safe[index].netID != 0) + { + item.netDefaults(safe[index].netID); + item.Prefix(safe[index].prefix); + item.AffixName(); + + if (safe[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove Safe item {0} ({1}) and then rejoin.", item.Name, safe[index].stack); + } + } + } + } + else if (i < NetItem.TrashIndex.Item2) + { + //179-219 + Item item = new Item(); + if (trash != null && trash.netID != 0) + { + item.netDefaults(trash.netID); + item.Prefix(trash.prefix); + item.AffixName(); + + if (trash.stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove trash item {0} ({1}) and then rejoin.", item.Name, trash.stack); + } + } + } + } + else + { + //220 + var index = i - NetItem.ForgeIndex.Item1; + Item item = new Item(); + if (forge[index] != null && forge[index].netID != 0) + { + item.netDefaults(forge[index].netID); + item.Prefix(forge[index].prefix); + item.AffixName(); + + if (forge[index].stack > item.maxStack) + { + check = true; + if (shouldSendMessage) + { + SendErrorMessage("Stack cheat detected. Remove Defender's Forge item {0} ({1}) and then rejoin.", item.Name, forge[index].stack); + } + } + } + + } + } + + return check; + } + /// /// The player's server side inventory data. /// diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 9766b93d..503e8d01 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -1948,203 +1948,6 @@ namespace TShockAPI return Utils.Distance(value1, value2); } - /// HackedInventory - Checks to see if a user has a hacked inventory. In addition, messages players the result. - /// player - The TSPlayer object. - /// bool - True if the player has a hacked inventory. - public static bool HackedInventory(TSPlayer player) - { - bool check = false; - - Item[] inventory = player.TPlayer.inventory; - Item[] armor = player.TPlayer.armor; - Item[] dye = player.TPlayer.dye; - Item[] miscEquips = player.TPlayer.miscEquips; - Item[] miscDyes = player.TPlayer.miscDyes; - Item[] piggy = player.TPlayer.bank.item; - Item[] safe = player.TPlayer.bank2.item; - Item[] forge = player.TPlayer.bank3.item; - Item trash = player.TPlayer.trashItem; - for (int i = 0; i < NetItem.MaxInventory; i++) - { - if (i < NetItem.InventoryIndex.Item2) - { - //0-58 - Item item = new Item(); - if (inventory[i] != null && inventory[i].netID != 0) - { - item.netDefaults(inventory[i].netID); - item.Prefix(inventory[i].prefix); - item.AffixName(); - if (inventory[i].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove item {0} ({1}) and then rejoin", item.Name, inventory[i].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.ArmorIndex.Item2) - { - //59-78 - var index = i - NetItem.ArmorIndex.Item1; - Item item = new Item(); - if (armor[index] != null && armor[index].netID != 0) - { - item.netDefaults(armor[index].netID); - item.Prefix(armor[index].prefix); - item.AffixName(); - if (armor[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove armor {0} ({1}) and then rejoin", item.Name, armor[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.DyeIndex.Item2) - { - //79-88 - var index = i - NetItem.DyeIndex.Item1; - Item item = new Item(); - if (dye[index] != null && dye[index].netID != 0) - { - item.netDefaults(dye[index].netID); - item.Prefix(dye[index].prefix); - item.AffixName(); - if (dye[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove dye {0} ({1}) and then rejoin", item.Name, dye[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.MiscEquipIndex.Item2) - { - //89-93 - var index = i - NetItem.MiscEquipIndex.Item1; - Item item = new Item(); - if (miscEquips[index] != null && miscEquips[index].netID != 0) - { - item.netDefaults(miscEquips[index].netID); - item.Prefix(miscEquips[index].prefix); - item.AffixName(); - if (miscEquips[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove item {0} ({1}) and then rejoin", item.Name, miscEquips[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.MiscDyeIndex.Item2) - { - //93-98 - var index = i - NetItem.MiscDyeIndex.Item1; - Item item = new Item(); - if (miscDyes[index] != null && miscDyes[index].netID != 0) - { - item.netDefaults(miscDyes[index].netID); - item.Prefix(miscDyes[index].prefix); - item.AffixName(); - if (miscDyes[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove item dye {0} ({1}) and then rejoin", item.Name, miscDyes[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.PiggyIndex.Item2) - { - //98-138 - var index = i - NetItem.PiggyIndex.Item1; - Item item = new Item(); - if (piggy[index] != null && piggy[index].netID != 0) - { - item.netDefaults(piggy[index].netID); - item.Prefix(piggy[index].prefix); - item.AffixName(); - - if (piggy[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove Piggy-bank item {0} ({1}) and then rejoin", item.Name, piggy[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.SafeIndex.Item2) - { - //138-178 - var index = i - NetItem.SafeIndex.Item1; - Item item = new Item(); - if (safe[index] != null && safe[index].netID != 0) - { - item.netDefaults(safe[index].netID); - item.Prefix(safe[index].prefix); - item.AffixName(); - - if (safe[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove Safe item {0} ({1}) and then rejoin", item.Name, safe[index].stack), - Color.Cyan); - } - } - } - else if (i < NetItem.TrashIndex.Item2) - { - //179-219 - Item item = new Item(); - if (trash != null && trash.netID != 0) - { - item.netDefaults(trash.netID); - item.Prefix(trash.prefix); - item.AffixName(); - - if (trash.stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove trash item {0} ({1}) and then rejoin", item.Name, trash.stack), - Color.Cyan); - } - } - } - else - { - //220 - var index = i - NetItem.ForgeIndex.Item1; - Item item = new Item(); - if (forge[index] != null && forge[index].netID != 0) - { - item.netDefaults(forge[index].netID); - item.Prefix(forge[index].prefix); - item.AffixName(); - - if (forge[index].stack > item.maxStack) - { - check = true; - player.SendMessage( - String.Format("Stack cheat detected. Remove Defender's Forge item {0} ({1}) and then rejoin", item.Name, forge[index].stack), - Color.Cyan); - } - } - - } - } - - return check; - } - /// OnConfigRead - Fired when the config file has been read. /// file - The config file object. public void OnConfigRead(ConfigFile file)