Initial server side character system implementation.

This commit is contained in:
Zidonuke Ghost 2013-10-01 06:22:08 -04:00
parent aff4314f8a
commit 0d351778a7
9 changed files with 208 additions and 221 deletions

View file

@ -240,8 +240,8 @@ namespace TShockAPI
add(Permissions.hardmode, DisableHardMode, "stophardmode", "disablehardmode"); add(Permissions.hardmode, DisableHardMode, "stophardmode", "disablehardmode");
add(Permissions.serverinfo, ServerInfo, "stats"); add(Permissions.serverinfo, ServerInfo, "stats");
add(Permissions.worldinfo, WorldInfo, "world"); add(Permissions.worldinfo, WorldInfo, "world");
add(Permissions.savessi, SaveSSI, "savessi"); add(Permissions.savessi, SaveSSC, "savessc");
add(Permissions.savessi, OverrideSSI, "overridessi", "ossi"); add(Permissions.savessi, OverrideSSC, "overridessc", "ossc");
add(Permissions.xmas, ForceXmas, "forcexmas"); add(Permissions.xmas, ForceXmas, "forcexmas");
add(Permissions.settempgroup, TempGroup, "tempgroup"); add(Permissions.settempgroup, TempGroup, "tempgroup");
add(null, Aliases, "aliases"); add(null, Aliases, "aliases");
@ -444,23 +444,17 @@ namespace TShockAPI
} }
else if (user.Password.ToUpper() == encrPass.ToUpper() || (user.UUID == args.Player.UUID && !TShock.Config.DisableUUIDLogin)) else if (user.Password.ToUpper() == encrPass.ToUpper() || (user.UUID == args.Player.UUID && !TShock.Config.DisableUUIDLogin))
{ {
args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(user.Name)); args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, TShock.Users.GetUserID(user.Name));
var group = TShock.Utils.GetGroup(user.Group); var group = TShock.Utils.GetGroup(user.Group);
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
{ {
if (group.HasPermission(Permissions.bypassinventorychecks)) if (group.HasPermission(Permissions.bypassinventorychecks))
{ {
args.Player.IgnoreActionsForClearingTrashCan = false; args.Player.IgnoreActionsForClearingTrashCan = false;
} }
else if (!TShock.CheckInventory(args.Player)) args.Player.PlayerData.RestoreCharacter(args.Player);
{
args.Player.LoginFailsBySsi = true;
args.Player.SendErrorMessage("Login failed. Please fix the above errors then /login again.");
args.Player.IgnoreActionsForClearingTrashCan = true;
return;
}
} }
args.Player.LoginFailsBySsi = false; args.Player.LoginFailsBySsi = false;
@ -479,8 +473,8 @@ namespace TShockAPI
if (!args.Player.IgnoreActionsForClearingTrashCan) if (!args.Player.IgnoreActionsForClearingTrashCan)
{ {
args.Player.PlayerData.CopyInventory(args.Player); args.Player.PlayerData.CopyCharacter(args.Player);
TShock.InventoryDB.InsertPlayerData(args.Player); TShock.CharacterDB.InsertPlayerData(args.Player);
} }
args.Player.SendSuccessMessage("Authenticated as " + user.Name + " successfully."); args.Player.SendSuccessMessage("Authenticated as " + user.Name + " successfully.");
@ -1078,31 +1072,31 @@ namespace TShockAPI
args.Player.SendSuccessMessage("You will " + (args.Player.DisplayLogs ? "now" : "no longer") + " receive logs."); args.Player.SendSuccessMessage("You will " + (args.Player.DisplayLogs ? "now" : "no longer") + " receive logs.");
} }
private static void SaveSSI(CommandArgs args) private static void SaveSSC(CommandArgs args)
{ {
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
{ {
args.Player.SendSuccessMessage("SSI has been saved."); args.Player.SendSuccessMessage("SSC has been saved.");
foreach (TSPlayer player in TShock.Players) foreach (TSPlayer player in TShock.Players)
{ {
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan) if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
{ {
TShock.InventoryDB.InsertPlayerData(player); TShock.CharacterDB.InsertPlayerData(player);
} }
} }
} }
} }
private static void OverrideSSI(CommandArgs args) private static void OverrideSSC(CommandArgs args)
{ {
if (!TShock.Config.ServerSideInventory) if (!TShock.Config.ServerSideCharacter)
{ {
args.Player.SendErrorMessage("Server Side Inventory is disabled."); args.Player.SendErrorMessage("Server Side Characters is disabled.");
return; return;
} }
if( args.Parameters.Count < 1 ) if( args.Parameters.Count < 1 )
{ {
args.Player.SendErrorMessage("Correct usage: /overridessi|/ossi <player name>"); args.Player.SendErrorMessage("Correct usage: /overridessc|/ossc <player name>");
return; return;
} }
@ -1136,8 +1130,8 @@ namespace TShockAPI
return; return;
} }
TShock.InventoryDB.InsertPlayerData(matchedPlayer); TShock.CharacterDB.InsertPlayerData(matchedPlayer);
args.Player.SendSuccessMessage("SSI of player \"{0}\" has been overriden.", matchedPlayer.Name); args.Player.SendSuccessMessage("SSC of player \"{0}\" has been overriden.", matchedPlayer.Name);
} }
private static void ForceXmas(CommandArgs args) private static void ForceXmas(CommandArgs args)
@ -1224,13 +1218,13 @@ namespace TShockAPI
private static void Off(CommandArgs args) private static void Off(CommandArgs args)
{ {
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
{ {
foreach (TSPlayer player in TShock.Players) foreach (TSPlayer player in TShock.Players)
{ {
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan) if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
{ {
player.SaveServerInventory(); player.SaveServerCharacter();
} }
} }
} }
@ -2390,7 +2384,7 @@ namespace TShockAPI
SaveManager.Instance.SaveWorld(false); SaveManager.Instance.SaveWorld(false);
foreach (TSPlayer tsply in TShock.Players.Where(tsply => tsply != null)) foreach (TSPlayer tsply in TShock.Players.Where(tsply => tsply != null))
{ {
tsply.SaveServerInventory(); tsply.SaveServerCharacter();
} }
args.Player.SendSuccessMessage("Save succeeded."); args.Player.SendSuccessMessage("Save succeeded.");
} }

View file

@ -157,9 +157,9 @@ namespace TShockAPI
[Description("Disables the dungeon guardian from being spawned by player packets, this will instead force a respawn.")] public bool DisableDungeonGuardian; [Description("Disables the dungeon guardian from being spawned by player packets, this will instead force a respawn.")] public bool DisableDungeonGuardian;
[Description("Enable server side inventory checks, EXPERIMENTAL")] public bool ServerSideInventory; [Description("Enable server side characters, This stops the client from saving character data! EXPERIMENTAL!!!!!")] public bool ServerSideCharacter;
[Description("How often SSI should save, in minutes.")] public int ServerSideInventorySave = 15; [Description("How often SSC should save, in minutes.")] public int ServerSideCharacterSave = 5;
[Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON.")] public int LogonDiscardThreshold=250; [Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON.")] public int LogonDiscardThreshold=250;
@ -240,7 +240,7 @@ namespace TShockAPI
[Description("Prevent banned items from being /i or /give.")] public bool PreventBannedItemSpawn = false; [Description("Prevent banned items from being /i or /give.")] public bool PreventBannedItemSpawn = false;
[Description("Prevent banks on SSI.")] public bool DisablePiggybanksOnSSI = false; [Description("Prevent banks on SSC.")] public bool DisablePiggybanksOnSSC = true;
[Description("Prevent players from interacting with the world if dead.")] public bool PreventDeadModification = [Description("Prevent players from interacting with the world if dead.")] public bool PreventDeadModification =
true; true;

View file

@ -22,17 +22,19 @@ using MySql.Data.MySqlClient;
namespace TShockAPI.DB namespace TShockAPI.DB
{ {
public class InventoryManager public class CharacterManager
{ {
public IDbConnection database; public IDbConnection database;
public InventoryManager(IDbConnection db) public CharacterManager(IDbConnection db)
{ {
database = db; database = db;
var table = new SqlTable("Inventory", var table = new SqlTable("Character",
new SqlColumn("Account", MySqlDbType.Int32) {Primary = true}, new SqlColumn("Account", MySqlDbType.Int32) {Primary = true},
new SqlColumn("Health", MySqlDbType.Int32),
new SqlColumn("MaxHealth", MySqlDbType.Int32), new SqlColumn("MaxHealth", MySqlDbType.Int32),
new SqlColumn("Mana", MySqlDbType.Int32),
new SqlColumn("MaxMana", MySqlDbType.Int32), new SqlColumn("MaxMana", MySqlDbType.Int32),
new SqlColumn("Inventory", MySqlDbType.Text) new SqlColumn("Inventory", MySqlDbType.Text)
); );
@ -49,12 +51,15 @@ namespace TShockAPI.DB
try try
{ {
using (var reader = database.QueryReader("SELECT * FROM Inventory WHERE Account=@0", acctid)) using (var reader = database.QueryReader("SELECT * FROM Character WHERE Account=@0", acctid))
{ {
if (reader.Read()) if (reader.Read())
{ {
playerData.exists = true; playerData.exists = true;
playerData.health = reader.Get<int>("Health");
playerData.maxHealth = reader.Get<int>("MaxHealth"); playerData.maxHealth = reader.Get<int>("MaxHealth");
playerData.mana = reader.Get<int>("Mana");
playerData.maxMana = reader.Get<int>("MaxMana");
playerData.inventory = NetItem.Parse(reader.Get<string>("Inventory")); playerData.inventory = NetItem.Parse(reader.Get<string>("Inventory"));
return playerData; return playerData;
} }
@ -79,8 +84,8 @@ namespace TShockAPI.DB
{ {
try try
{ {
database.Query("INSERT INTO Inventory (Account, MaxHealth, Inventory) VALUES (@0, @1, @2);", player.UserID, database.Query("INSERT INTO Character (Account, Health, MaxHealth, Mana, MaxMana, Inventory) VALUES (@0, @1, @2, @3, @4, @5);", player.UserID,
playerData.maxHealth, NetItem.ToString(playerData.inventory)); playerData.health, playerData.maxHealth, playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory));
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -92,8 +97,8 @@ namespace TShockAPI.DB
{ {
try try
{ {
database.Query("UPDATE Inventory SET MaxHealth = @0, Inventory = @1 WHERE Account = @2;", playerData.maxHealth, database.Query("UPDATE Inventory SET Health = @0, MaxHealth = @1, Mana = @2, MaxMana = @3, Inventory = @4 WHERE Account = @5;", playerData.health, playerData.maxHealth,
NetItem.ToString(playerData.inventory), player.UserID); playerData.mana, playerData.maxMana, NetItem.ToString(playerData.inventory), player.UserID);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)

View file

@ -1289,7 +1289,7 @@ namespace TShockAPI
args.Player.PlayerData.StoreSlot(slot, type, prefix, stack); args.Player.PlayerData.StoreSlot(slot, type, prefix, stack);
} }
else if ( else if (
TShock.Config.ServerSideInventory && TShock.Config.DisableLoginBeforeJoin && !bypassTrashCanCheck && TShock.Config.ServerSideCharacter && TShock.Config.DisableLoginBeforeJoin && !bypassTrashCanCheck &&
args.Player.HasSentInventory && !args.Player.Group.HasPermission(Permissions.bypassinventorychecks) args.Player.HasSentInventory && !args.Player.Group.HasPermission(Permissions.bypassinventorychecks)
) { ) {
// The player might have moved an item to their trash can before they performed a single login attempt yet. // The player might have moved an item to their trash can before they performed a single login attempt yet.
@ -1400,7 +1400,7 @@ namespace TShockAPI
{ {
if(user.UUID == args.Player.UUID) if(user.UUID == args.Player.UUID)
{ {
args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name)); args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name));
if (args.Player.State == 1) if (args.Player.State == 1)
args.Player.State = 2; args.Player.State = 2;
@ -1408,19 +1408,13 @@ namespace TShockAPI
var group = TShock.Utils.GetGroup(user.Group); var group = TShock.Utils.GetGroup(user.Group);
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
{ {
if (group.HasPermission(Permissions.bypassinventorychecks)) if (group.HasPermission(Permissions.bypassinventorychecks))
{ {
args.Player.IgnoreActionsForClearingTrashCan = false; args.Player.IgnoreActionsForClearingTrashCan = false;
} }
else if (!TShock.CheckInventory(args.Player)) args.Player.PlayerData.RestoreCharacter(args.Player);
{
args.Player.LoginFailsBySsi = true;
args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan);
args.Player.IgnoreActionsForClearingTrashCan = true;
return true;
}
} }
args.Player.LoginFailsBySsi = false; args.Player.LoginFailsBySsi = false;
@ -1439,8 +1433,8 @@ namespace TShockAPI
if (!args.Player.IgnoreActionsForClearingTrashCan) if (!args.Player.IgnoreActionsForClearingTrashCan)
{ {
args.Player.PlayerData.CopyInventory(args.Player); args.Player.PlayerData.CopyCharacter(args.Player);
TShock.InventoryDB.InsertPlayerData(args.Player); TShock.CharacterDB.InsertPlayerData(args.Player);
} }
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
@ -1484,7 +1478,7 @@ namespace TShockAPI
if (user.Password.ToUpper() == encrPass.ToUpper()) if (user.Password.ToUpper() == encrPass.ToUpper())
{ {
args.Player.RequiresPassword = false; args.Player.RequiresPassword = false;
args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name)); args.Player.PlayerData = TShock.CharacterDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name));
if (args.Player.State == 1) if (args.Player.State == 1)
args.Player.State = 2; args.Player.State = 2;
@ -1492,19 +1486,13 @@ namespace TShockAPI
var group = TShock.Utils.GetGroup(user.Group); var group = TShock.Utils.GetGroup(user.Group);
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
{ {
if (group.HasPermission(Permissions.bypassinventorychecks)) if (group.HasPermission(Permissions.bypassinventorychecks))
{ {
args.Player.IgnoreActionsForClearingTrashCan = false; args.Player.IgnoreActionsForClearingTrashCan = false;
} }
else if (!TShock.CheckInventory(args.Player)) args.Player.PlayerData.RestoreCharacter(args.Player);
{
args.Player.LoginFailsBySsi = true;
args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan);
args.Player.IgnoreActionsForClearingTrashCan = true;
return true;
}
} }
args.Player.LoginFailsBySsi = false; args.Player.LoginFailsBySsi = false;
@ -1523,8 +1511,8 @@ namespace TShockAPI
if (!args.Player.IgnoreActionsForClearingTrashCan) if (!args.Player.IgnoreActionsForClearingTrashCan)
{ {
args.Player.PlayerData.CopyInventory(args.Player); args.Player.PlayerData.CopyCharacter(args.Player);
TShock.InventoryDB.InsertPlayerData(args.Player); TShock.CharacterDB.InsertPlayerData(args.Player);
} }
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen); args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + "."); Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
@ -1960,9 +1948,9 @@ namespace TShockAPI
args.Player.SendTileSquare(tileX, tileY); args.Player.SendTileSquare(tileX, tileY);
return true; return true;
} }
if (action == EditAction.PlaceTile && (editData == 29 || editData == 97) && TShock.Config.ServerSideInventory && TShock.Config.DisablePiggybanksOnSSI) if (action == EditAction.PlaceTile && (editData == 29 || editData == 97) && TShock.Config.ServerSideCharacter && TShock.Config.DisablePiggybanksOnSSC)
{ {
args.Player.SendMessage("You cannot place this tile because server side inventory is enabled.", Color.Red); args.Player.SendMessage("You cannot place this tile because server side characters are enabled.", Color.Red);
args.Player.SendTileSquare(tileX, tileY); args.Player.SendTileSquare(tileX, tileY);
return true; return true;
} }
@ -2917,7 +2905,7 @@ namespace TShockAPI
args.Player.SendData(PacketTypes.ItemDrop, "", id); args.Player.SendData(PacketTypes.ItemDrop, "", id);
return true; return true;
} }
if ((TShock.Config.ServerSideInventory) && (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - args.Player.LoginMS < TShock.Config.LogonDiscardThreshold)) if ((TShock.Config.ServerSideCharacter) && (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - args.Player.LoginMS < TShock.Config.LogonDiscardThreshold))
{ {
//Player is probably trying to sneak items onto the server in their hands!!! //Player is probably trying to sneak items onto the server in their hands!!!
Log.ConsoleInfo(string.Format("Player {0} tried to sneak {1} onto the server!", args.Player.Name, item.name)); Log.ConsoleInfo(string.Format("Player {0} tried to sneak {1} onto the server!", args.Player.Name, item.name));

View file

@ -258,7 +258,7 @@ namespace TShockAPI
rules.Add("PvPMode", TShock.Config.PvPMode); rules.Add("PvPMode", TShock.Config.PvPMode);
rules.Add("SpawnProtection", TShock.Config.SpawnProtection); rules.Add("SpawnProtection", TShock.Config.SpawnProtection);
rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius); rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius);
rules.Add("ServerSideInventory", TShock.Config.ServerSideInventory); rules.Add("ServerSideInventory", TShock.Config.ServerSideCharacter);
ret.Add("rules", rules); ret.Add("rules", rules);
} }

View file

@ -335,16 +335,16 @@ namespace TShockAPI
/// Saves the player's inventory to SSI /// Saves the player's inventory to SSI
/// </summary> /// </summary>
/// <returns>bool - True/false if it saved successfully</returns> /// <returns>bool - True/false if it saved successfully</returns>
public bool SaveServerInventory() public bool SaveServerCharacter()
{ {
if (!TShock.Config.ServerSideInventory) if (!TShock.Config.ServerSideCharacter)
{ {
return false; return false;
} }
try try
{ {
PlayerData.CopyInventory(this); PlayerData.CopyCharacter(this);
TShock.InventoryDB.InsertPlayerData(this); TShock.CharacterDB.InsertPlayerData(this);
return true; return true;
} catch (Exception e) } catch (Exception e)
{ {
@ -354,6 +354,29 @@ namespace TShockAPI
} }
/// <summary>
/// Sends the players server side character to client
/// </summary>
/// <returns>bool - True/false if it saved successfully</returns>
public bool SendServerCharacter()
{
if (!TShock.Config.ServerSideCharacter)
{
return false;
}
try
{
PlayerData.RestoreCharacter(this);
return true;
}
catch (Exception e)
{
Log.Error(e.Message);
return false;
}
}
/// <summary> /// <summary>
/// Terraria Player /// Terraria Player
/// </summary> /// </summary>
@ -980,8 +1003,10 @@ namespace TShockAPI
public class PlayerData public class PlayerData
{ {
public NetItem[] inventory = new NetItem[NetItem.maxNetInventory]; public NetItem[] inventory = new NetItem[NetItem.maxNetInventory];
public int health = 100;
public int maxHealth = 100; public int maxHealth = 100;
//public int maxMana = 100; public int mana = 20;
public int maxMana = 20;
public bool exists; public bool exists;
public PlayerData(TSPlayer player) public PlayerData(TSPlayer player)
@ -1024,9 +1049,12 @@ namespace TShockAPI
} }
} }
public void CopyInventory(TSPlayer player) public void CopyCharacter(TSPlayer player)
{ {
this.health = player.TPlayer.statLife > 0 ? player.TPlayer.statLife : 1;
this.maxHealth = player.TPlayer.statLifeMax; this.maxHealth = player.TPlayer.statLifeMax;
this.mana = player.TPlayer.statMana;
this.maxMana = player.TPlayer.statManaMax;
Item[] inventory = player.TPlayer.inventory; Item[] inventory = player.TPlayer.inventory;
Item[] armor = player.TPlayer.armor; Item[] armor = player.TPlayer.armor;
Item[] dye = player.TPlayer.dye; Item[] dye = player.TPlayer.dye;
@ -1082,7 +1110,7 @@ namespace TShockAPI
var index = i - (NetItem.maxNetInventory - NetItem.dyeSlots); var index = i - (NetItem.maxNetInventory - NetItem.dyeSlots);
if (player.TPlayer.dye[index] != null) if (player.TPlayer.dye[index] != null)
{ {
this.inventory[i].netID = armor[index].netID; this.inventory[i].netID = dye[index].netID;
} }
else else
{ {
@ -1091,8 +1119,8 @@ namespace TShockAPI
if (this.inventory[i].netID != 0) if (this.inventory[i].netID != 0)
{ {
this.inventory[i].stack = armor[index].stack; this.inventory[i].stack = dye[index].stack;
this.inventory[i].prefix = armor[index].prefix; this.inventory[i].prefix = dye[index].prefix;
} }
else else
{ {
@ -1102,6 +1130,111 @@ namespace TShockAPI
} }
} }
} }
public void RestoreCharacter(TSPlayer player)
{
player.TPlayer.statLife = this.health;
player.TPlayer.statLifeMax = this.maxHealth;
player.TPlayer.statMana = this.mana;
player.TPlayer.statManaMax = this.maxMana;
player.TPlayer.name = player.UserAccountName;
for (int i = 0; i < NetItem.maxNetInventory; i++)
{
if (i < NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots))
{
if (this.inventory[i] != null)
{
player.TPlayer.inventory[i].netDefaults(this.inventory[i].netID);
}
else
{
player.TPlayer.inventory[i].netDefaults(0);
}
if (player.TPlayer.inventory[i].netID != 0)
{
player.TPlayer.inventory[i].stack = this.inventory[i].stack;
player.TPlayer.inventory[i].prefix = (byte)this.inventory[i].prefix;
}
}
else if (i < NetItem.maxNetInventory - NetItem.dyeSlots)
{
var index = i - (NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots));
if (this.inventory[i] != null)
{
player.TPlayer.armor[index].netDefaults(this.inventory[i].netID);
}
else
{
player.TPlayer.armor[index].netDefaults(0);
}
if (player.TPlayer.armor[index].netID != 0)
{
player.TPlayer.armor[index].stack = this.inventory[i].stack;
player.TPlayer.armor[index].prefix = (byte)this.inventory[i].prefix;
}
}
else
{
var index = i - (NetItem.maxNetInventory - NetItem.dyeSlots);
if (this.inventory[i] != null)
{
player.TPlayer.dye[index].netDefaults(this.inventory[i].netID);
}
else
{
player.TPlayer.dye[index].netDefaults(0);
}
if (player.TPlayer.dye[index].netID != 0)
{
player.TPlayer.dye[index].stack = this.inventory[i].stack;
player.TPlayer.dye[index].prefix = (byte)this.inventory[i].prefix;
}
}
}
for (int k = 0; k < 59; k++)
{
NetMessage.SendData(5, -1, -1, Main.player[player.Index].inventory[k].name, player.Index, (float)k, (float)Main.player[player.Index].inventory[k].prefix, 0f, 0);
}
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[0].name, player.Index, 59f, (float)Main.player[player.Index].armor[0].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[1].name, player.Index, 60f, (float)Main.player[player.Index].armor[1].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[2].name, player.Index, 61f, (float)Main.player[player.Index].armor[2].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[3].name, player.Index, 62f, (float)Main.player[player.Index].armor[3].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[4].name, player.Index, 63f, (float)Main.player[player.Index].armor[4].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[5].name, player.Index, 64f, (float)Main.player[player.Index].armor[5].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[6].name, player.Index, 65f, (float)Main.player[player.Index].armor[6].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[7].name, player.Index, 66f, (float)Main.player[player.Index].armor[7].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[0].name, player.Index, 70f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[1].name, player.Index, 71f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
NetMessage.SendData(5, -1, -1, Main.player[player.Index].dye[2].name, player.Index, 72f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
NetMessage.SendData(4, -1, -1, Main.player[player.Index].name, player.Index, 0f, 0f, 0f, 0);
for (int k = 0; k < 59; k++)
{
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].inventory[k].name, player.Index, (float)k, (float)Main.player[player.Index].inventory[k].prefix, 0f, 0);
}
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[0].name, player.Index, 59f, (float)Main.player[player.Index].armor[0].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[1].name, player.Index, 60f, (float)Main.player[player.Index].armor[1].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[2].name, player.Index, 61f, (float)Main.player[player.Index].armor[2].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[3].name, player.Index, 62f, (float)Main.player[player.Index].armor[3].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[4].name, player.Index, 63f, (float)Main.player[player.Index].armor[4].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[5].name, player.Index, 64f, (float)Main.player[player.Index].armor[5].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[6].name, player.Index, 65f, (float)Main.player[player.Index].armor[6].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[7].name, player.Index, 66f, (float)Main.player[player.Index].armor[7].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[8].name, player.Index, 67f, (float)Main.player[player.Index].armor[8].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[9].name, player.Index, 68f, (float)Main.player[player.Index].armor[9].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].armor[10].name, player.Index, 69f, (float)Main.player[player.Index].armor[10].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[0].name, player.Index, 70f, (float)Main.player[player.Index].dye[0].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[1].name, player.Index, 71f, (float)Main.player[player.Index].dye[1].prefix, 0f, 0);
NetMessage.SendData(5, player.Index, -1, Main.player[player.Index].dye[2].name, player.Index, 72f, (float)Main.player[player.Index].dye[2].prefix, 0f, 0);
NetMessage.SendData(4, -1, -1, Main.player[player.Index].name, player.Index, 0f, 0f, 0f, 0);
}
} }
public class NetItem public class NetItem

View file

@ -61,7 +61,7 @@ namespace TShockAPI
public static UserManager Users; public static UserManager Users;
public static ItemManager Itembans; public static ItemManager Itembans;
public static RememberedPosManager RememberedPos; public static RememberedPosManager RememberedPos;
public static InventoryManager InventoryDB; public static CharacterManager CharacterDB;
public static ConfigFile Config { get; set; } public static ConfigFile Config { get; set; }
public static IDbConnection DB; public static IDbConnection DB;
public static bool OverridePort; public static bool OverridePort;
@ -128,6 +128,8 @@ namespace TShockAPI
ConfigFile.ConfigRead += OnConfigRead; ConfigFile.ConfigRead += OnConfigRead;
FileTools.SetupConfig(); FileTools.SetupConfig();
Main.ServerSideCharacter = Config.ServerSideCharacter; //FYI, This cannot be disabled once flipped.
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
string logFilename; string logFilename;
string logPathSetupWarning = null; string logPathSetupWarning = null;
@ -219,7 +221,7 @@ namespace TShockAPI
Groups = new GroupManager(DB); Groups = new GroupManager(DB);
Itembans = new ItemManager(DB); Itembans = new ItemManager(DB);
RememberedPos = new RememberedPosManager(DB); RememberedPos = new RememberedPosManager(DB);
InventoryDB = new InventoryManager(DB); CharacterDB = new CharacterManager(DB);
RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort); RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort);
RestApi.Port = Config.RestApiPort; RestApi.Port = Config.RestApiPort;
RestManager = new RestManager(RestApi); RestManager = new RestManager(RestApi);
@ -610,7 +612,7 @@ namespace TShockAPI
LastCheck = DateTime.UtcNow; LastCheck = DateTime.UtcNow;
} }
if ((DateTime.UtcNow - LastSave).TotalMinutes >= Config.ServerSideInventorySave) if ((DateTime.UtcNow - LastSave).TotalMinutes >= Config.ServerSideCharacterSave)
{ {
foreach (TSPlayer player in Players) foreach (TSPlayer player in Players)
{ {
@ -618,7 +620,7 @@ namespace TShockAPI
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan) if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
{ {
InventoryDB.InsertPlayerData(player); CharacterDB.InsertPlayerData(player);
} }
} }
LastSave = DateTime.UtcNow; LastSave = DateTime.UtcNow;
@ -878,8 +880,8 @@ namespace TShockAPI
if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan) if (tsplr.IsLoggedIn && !tsplr.IgnoreActionsForClearingTrashCan)
{ {
tsplr.PlayerData.CopyInventory(tsplr); tsplr.PlayerData.CopyCharacter(tsplr);
InventoryDB.InsertPlayerData(tsplr); CharacterDB.InsertPlayerData(tsplr);
} }
if ((Config.RememberLeavePos) &&(!tsplr.LoginHarassed)) if ((Config.RememberLeavePos) &&(!tsplr.LoginHarassed))
@ -1055,10 +1057,10 @@ namespace TShockAPI
if (!player.IsLoggedIn) if (!player.IsLoggedIn)
{ {
if (Config.ServerSideInventory) if (Config.ServerSideCharacter)
{ {
player.SendMessage( player.SendMessage(
player.IgnoreActionsForInventory = "Server side inventory is enabled! Please /register or /login to play!", player.IgnoreActionsForInventory = "Server side characters is enabled! Please /register or /login to play!",
Color.Red); Color.Red);
player.LoginHarassed = true; player.LoginHarassed = true;
} }
@ -1607,141 +1609,6 @@ namespace TShockAPI
return check; return check;
} }
public static bool CheckInventory(TSPlayer player)
{
PlayerData playerData = player.PlayerData;
bool check = true;
if (player.TPlayer.statLifeMax > playerData.maxHealth)
{
player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server.",
Color.Cyan);
check = false;
}
Item[] inventory = player.TPlayer.inventory;
Item[] armor = player.TPlayer.armor;
Item[] dye = player.TPlayer.dye;
for (int i = 0; i < NetItem.maxNetInventory; i++)
{
if (i < NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots))
{
Item item = new Item();
Item serverItem = new Item();
if (inventory[i] != null && 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(player.IgnoreActionsForInventory = "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(player.IgnoreActionsForInventory = "Your item (" + item.name + ") needs to be deleted.",
Color.Cyan);
check = false;
}
else if (inventory[i].stack > playerData.inventory[i].stack)
{
item.netDefaults(inventory[i].netID);
item.Prefix(inventory[i].prefix);
item.AffixName();
player.SendMessage(
player.IgnoreActionsForInventory =
"Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have its stack size decreased to (" +
playerData.inventory[i].stack + ").", Color.Cyan);
check = false;
}
}
}
else if(i < (NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots)))
{
Item item = new Item();
Item serverItem = new Item();
var index = i - (NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots));
if (armor[index] != null && armor[index].netID != 0)
{
if (playerData.inventory[i].netID != armor[index].netID)
{
item.netDefaults(armor[index].netID);
item.Prefix(armor[index].prefix);
item.AffixName();
player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.",
Color.Cyan);
check = false;
}
else if (playerData.inventory[i].prefix != armor[index].prefix)
{
item.netDefaults(armor[index].netID);
item.Prefix(armor[index].prefix);
item.AffixName();
player.SendMessage(player.IgnoreActionsForInventory = "Your armor (" + item.name + ") needs to be deleted.",
Color.Cyan);
check = false;
}
else if (armor[index].stack > playerData.inventory[i].stack)
{
item.netDefaults(armor[index].netID);
item.Prefix(armor[index].prefix);
item.AffixName();
player.SendMessage(
player.IgnoreActionsForInventory =
"Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have its stack size decreased to (" +
playerData.inventory[i].stack + ").", Color.Cyan);
check = false;
}
}
}
else if(i < (NetItem.maxNetInventory - (NetItem.armorSlots + NetItem.dyeSlots)))
{
Item item = new Item();
Item serverItem = new Item();
var index = i - (NetItem.maxNetInventory - NetItem.dyeSlots);
if (dye[index] != null && dye[index].netID != 0)
{
if (playerData.inventory[i].netID != dye[index].netID)
{
item.netDefaults(dye[index].netID);
item.Prefix(dye[index].prefix);
item.AffixName();
player.SendMessage(player.IgnoreActionsForInventory = "Your dye (" + item.name + ") needs to be deleted.",
Color.Cyan);
check = false;
}
else if (playerData.inventory[i].prefix != dye[index].prefix)
{
item.netDefaults(dye[index].netID);
item.Prefix(dye[index].prefix);
item.AffixName();
player.SendMessage(player.IgnoreActionsForInventory = "Your dye (" + item.name + ") needs to be deleted.",
Color.Cyan);
check = false;
}
else if (dye[index].stack > playerData.inventory[i].stack)
{
item.netDefaults(dye[index].netID);
item.Prefix(dye[index].prefix);
item.AffixName();
player.SendMessage(
player.IgnoreActionsForInventory =
"Your dye (" + item.name + ") (" + inventory[i].stack + ") needs to have its stack size decreased to (" +
playerData.inventory[i].stack + ").", Color.Cyan);
check = false;
}
}
}
}
return check;
}
public static bool CheckIgnores(TSPlayer player) public static bool CheckIgnores(TSPlayer player)
{ {
return Config.PvPMode == "always" && !player.TPlayer.hostile || player.IgnoreActionsForInventory != "none" || player.IgnoreActionsForCheating != "none" || player.IgnoreActionsForDisabledArmor != "none" || player.IgnoreActionsForClearingTrashCan || !player.IsLoggedIn && Config.RequireLogin;; return Config.PvPMode == "always" && !player.TPlayer.hostile || player.IgnoreActionsForInventory != "none" || player.IgnoreActionsForCheating != "none" || player.IgnoreActionsForDisabledArmor != "none" || player.IgnoreActionsForClearingTrashCan || !player.IsLoggedIn && Config.RequireLogin;;

View file

@ -83,7 +83,7 @@
<Compile Include="Rest\RestPermissions.cs" /> <Compile Include="Rest\RestPermissions.cs" />
<Compile Include="SaveManager.cs" /> <Compile Include="SaveManager.cs" />
<Compile Include="DB\BanManager.cs" /> <Compile Include="DB\BanManager.cs" />
<Compile Include="DB\InventoryManager.cs" /> <Compile Include="DB\CharacterManager.cs" />
<Compile Include="DB\IQueryBuilder.cs" /> <Compile Include="DB\IQueryBuilder.cs" />
<Compile Include="DB\ItemManager.cs" /> <Compile Include="DB\ItemManager.cs" />
<Compile Include="DB\SqlColumn.cs" /> <Compile Include="DB\SqlColumn.cs" />
@ -183,7 +183,7 @@
</PropertyGroup> </PropertyGroup>
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" /> <UserProperties BuildVersion_IncrementBeforeBuild="False" BuildVersion_StartDate="2011/6/17" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_BuildAction="Both" BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" />
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View file

@ -571,10 +571,10 @@ namespace TShockAPI
/// <param name="reason">string reason (default: "Server shutting down!")</param> /// <param name="reason">string reason (default: "Server shutting down!")</param>
public void RestartServer(bool save = true, string reason = "Server shutting down!") public void RestartServer(bool save = true, string reason = "Server shutting down!")
{ {
if (TShock.Config.ServerSideInventory) if (TShock.Config.ServerSideCharacter)
foreach (TSPlayer player in TShock.Players) foreach (TSPlayer player in TShock.Players)
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan) if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
TShock.InventoryDB.InsertPlayerData(player); TShock.CharacterDB.InsertPlayerData(player);
StopServer(true, reason); StopServer(true, reason);
System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
@ -636,7 +636,7 @@ namespace TShockAPI
string playerName = player.Name; string playerName = player.Name;
player.SilentKickInProgress = silent; player.SilentKickInProgress = silent;
if (player.IsLoggedIn && saveSSI) if (player.IsLoggedIn && saveSSI)
player.SaveServerInventory(); player.SaveServerCharacter();
player.Disconnect(string.Format("Kicked: {0}", reason)); player.Disconnect(string.Format("Kicked: {0}", reason));
Log.ConsoleInfo(string.Format("Kicked {0} for : {1}", playerName, reason)); Log.ConsoleInfo(string.Format("Kicked {0} for : {1}", playerName, reason));
string verb = force ? "force " : ""; string verb = force ? "force " : "";