Annoying Server Side Inventory implemented. Needs extensive testing.
If enabled, all player actions are disabled until they /login which triggers a inventory check against the server. If they fail the check the login doesn't occur and they can't act. Default inventory for new accounts or characters requires a new character's inventory and health. Every inventory change that occurs is stored back into playerData memory and then onLeave it's stored back into the database, to be loaded at next /login
This commit is contained in:
parent
ed21c2e8a4
commit
bc7fac9b73
6 changed files with 200 additions and 20 deletions
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue