From 1f7fe6692c96f624b45c4572d8c8a437937f712c Mon Sep 17 00:00:00 2001
From: Chris <2648373+QuiCM@users.noreply.github.com>
Date: Wed, 3 Jun 2020 17:25:42 +0930
Subject: [PATCH 1/5] Create a bunch of new SSC classes Begin rewriting the old
implementation
---
TShockAPI/GetDataHandlers.cs | 2 +-
TShockAPI/Net/NetItem.cs | 332 ++++++++++++++++++
TShockAPI/NetItem.cs | 188 ----------
TShockAPI/PlayerData.cs | 9 +
.../ServerSideCharacters/ServerSideConfig.cs | 5 +
.../ServerSideCoordinator.cs | 43 +++
.../ServerSideInventory.cs | 161 +++++++++
.../ServerSidePlayerData.cs | 46 +++
.../ServerSideCharacters/ServerSideSpawn.cs | 18 +
.../ServerSideCharacters/ServerSideStats.cs | 52 +++
.../ServerSideCharacters/ServerSideVanity.cs | 80 +++++
TShockAPI/TSPlayer.cs | 3 +-
TShockAPI/TShock.cs | 2 +-
TShockAPI/TShockAPI.csproj | 10 +-
14 files changed, 758 insertions(+), 193 deletions(-)
create mode 100644 TShockAPI/Net/NetItem.cs
delete mode 100644 TShockAPI/NetItem.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSideCoordinator.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSideInventory.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSidePlayerData.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSideSpawn.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSideStats.cs
create mode 100644 TShockAPI/ServerSideCharacters/ServerSideVanity.cs
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index cf13e396c..0c3f0e4fc 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -3632,7 +3632,7 @@ private static bool HandlePlayerKillMeV2(GetDataHandlerArgs args)
if (args.TPlayer.difficulty == 2 && Main.ServerSideCharacter && args.Player.IsLoggedIn)
{
- if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID))
+ if (TShock.CharacterDB.DeletePlayerData(args.Player.Account.ID))
{
TShock.Log.ConsoleDebug("GetDataHandlers / HandlePlayerKillMeV2 ssc delete {0} {1}", args.Player.Name, args.TPlayer.difficulty);
args.Player.SendErrorMessage("You have fallen in hardcore mode, and your items have been lost forever.");
diff --git a/TShockAPI/Net/NetItem.cs b/TShockAPI/Net/NetItem.cs
new file mode 100644
index 000000000..1a49a6601
--- /dev/null
+++ b/TShockAPI/Net/NetItem.cs
@@ -0,0 +1,332 @@
+/*
+TShock, a server mod for Terraria
+Copyright (C) 2011-2019 Pryaxis & TShock Contributors
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json;
+using Terraria;
+
+namespace TShockAPI.Net
+{
+ ///
+ /// Helper class to group inventory indexes.
+ /// Contains the starting index of an inventory group, and the number of items in the group
+ ///
+ public class InventoryGrouping
+ {
+ ///
+ /// The starting index of the inventory group
+ ///
+ public int Start;
+ ///
+ /// The number of items in the group
+ ///
+ public int Count;
+
+ ///
+ /// Creates a new grouping with the given start and count
+ ///
+ ///
+ ///
+ public InventoryGrouping(int start, int count)
+ {
+ Start = start;
+ Count = count;
+ }
+
+ ///
+ /// Creates a new grouping using the given previous grouping to determine the start of this grouping
+ ///
+ ///
+ ///
+ public InventoryGrouping(InventoryGrouping previous, int count)
+ {
+ Start = previous.Start + previous.Count;
+ Count = count;
+ }
+ }
+
+ ///
+ /// Represents an item.
+ ///
+ [JsonObject(MemberSerialization.OptIn)]
+ public struct NetItem
+ {
+ ///
+ /// The maximum number of slots in the main inventory. This does not include coins, ammo, or the held item
+ ///
+ public static readonly int InventorySlots = 50;
+ ///
+ /// The maximum number of coin slots
+ ///
+ public static readonly int CoinSlots = 4;
+ ///
+ /// The maximum number of ammo slots
+ ///
+ public static readonly int AmmoSlots = 4;
+ ///
+ /// The maximum number of held item slots
+ ///
+ public static readonly int HeldItemSlots = 1;
+
+ ///
+ /// The maximum number of armor slots
+ ///
+ public static readonly int ArmorSlots = 3;
+ ///
+ /// The maximum number of accessory slots
+ ///
+ public static readonly int AccessorySlots = 7;
+
+ ///
+ /// The maximum number of armor vanity slots
+ ///
+ public static readonly int ArmorVanitySlots = ArmorSlots;
+ ///
+ /// The maximum number of accessory vanity slots
+ ///
+ public static readonly int AccessoryVanitySlots = AccessorySlots;
+
+ ///
+ /// The maximum number of armor dye slots
+ ///
+ public static readonly int ArmorDyeSlots = ArmorVanitySlots;
+ ///
+ /// The maximum number of accessory dye slots
+ ///
+ public static readonly int AccessoryDyeSlots = AccessoryVanitySlots;
+
+ ///
+ /// The maximum number of misc equipment slots. This is the mount/hook/etc equipment
+ ///
+ public static readonly int MiscEquipSlots = 5;
+ ///
+ /// The maximum number of misc dye slots
+ ///
+ public static readonly int MiscDyeSlots = MiscEquipSlots;
+
+ ///
+ /// The maximum number of slots in a piggy bank
+ ///
+ public static readonly int PiggySlots = 40;
+
+ ///
+ /// The maximum number of slots in the trash can
+ ///
+ public static readonly int TrashSlots = 1;
+
+ ///
+ /// The maximum number of slots in a safe
+ ///
+ public static readonly int SafeSlots = PiggySlots;
+
+ ///
+ /// The maximum number of slots in a defender's forge
+ ///
+ public static readonly int ForgeSlots = SafeSlots;
+
+ ///
+ /// The maximum numbert of slots in a void bank
+ ///
+ public static readonly int VoidSlots = ForgeSlots;
+
+ ///
+ /// The total number of slots available across the entire inventory
+ ///
+ public static readonly int MaxInventory =
+ InventorySlots + CoinSlots + AmmoSlots + HeldItemSlots +
+ ArmorSlots + AccessorySlots +
+ ArmorVanitySlots + AccessoryVanitySlots +
+ ArmorDyeSlots + AccessoryDyeSlots +
+ MiscEquipSlots + MiscDyeSlots +
+ PiggySlots +
+ TrashSlots +
+ SafeSlots +
+ ForgeSlots +
+ VoidSlots;
+
+ ///
+ /// Groups the main inventory slots
+ ///
+ public static readonly InventoryGrouping MainInventoryGroup = new InventoryGrouping(0, InventorySlots);
+ ///
+ /// Groups the coin slots
+ ///
+ public static readonly InventoryGrouping CoinGroup = new InventoryGrouping(MainInventoryGroup, CoinSlots);
+ ///
+ /// Groups the ammo slots
+ ///
+ public static readonly InventoryGrouping AmmoGroup = new InventoryGrouping(CoinGroup, AmmoSlots);
+ ///
+ /// Groups the held item slot
+ ///
+ public static readonly InventoryGrouping HeldItemGroup = new InventoryGrouping(AmmoGroup, HeldItemSlots);
+
+ ///
+ /// Groups the armor slots
+ ///
+ public static readonly InventoryGrouping ArmorGroup = new InventoryGrouping(HeldItemGroup, ArmorSlots);
+ ///
+ /// Groups the accessory slots
+ ///
+ public static readonly InventoryGrouping AccessoryGroup = new InventoryGrouping(ArmorGroup, AccessorySlots);
+
+ ///
+ /// Groups the armor vanity slots
+ ///
+ public static readonly InventoryGrouping ArmorVanityGroup = new InventoryGrouping(AccessoryGroup, ArmorVanitySlots);
+ ///
+ /// Groups the accessory vanity slots
+ ///
+ public static readonly InventoryGrouping AccessoryVanityGroup = new InventoryGrouping(ArmorVanityGroup, AccessoryVanitySlots);
+
+ ///
+ /// Groups the armor dye slots
+ ///
+ public static readonly InventoryGrouping ArmorDyeGroup = new InventoryGrouping(AccessoryVanityGroup, ArmorDyeSlots);
+ ///
+ /// Groups the accessory dye slots
+ ///
+ public static readonly InventoryGrouping AccessoryDyeGroup = new InventoryGrouping(ArmorDyeGroup, AccessoryDyeSlots);
+
+ ///
+ /// Groups the misc equipment slots
+ ///
+ public static readonly InventoryGrouping MiscEquipGroup = new InventoryGrouping(AccessoryDyeGroup, MiscEquipSlots);
+ ///
+ /// Groups the misc dye slots
+ ///
+ public static readonly InventoryGrouping MiscDyeGroup = new InventoryGrouping(MiscEquipGroup, MiscDyeSlots);
+
+ ///
+ /// Groups the piggy bank slots
+ ///
+ public static readonly InventoryGrouping PiggyGroup = new InventoryGrouping(MiscDyeGroup, PiggySlots);
+
+ ///
+ /// Groups the trash item slot
+ ///
+ public static readonly InventoryGrouping TrashGroup = new InventoryGrouping(PiggyGroup, TrashSlots);
+
+ ///
+ /// Groups the safe item slots
+ ///
+ public static readonly InventoryGrouping SafeGroup = new InventoryGrouping(TrashGroup, SafeSlots);
+
+ ///
+ /// Groups the defender's forge item slots
+ ///
+ public static readonly InventoryGrouping ForgeGroup = new InventoryGrouping(SafeGroup, ForgeSlots);
+
+ ///
+ /// Groups the void bank item slots
+ ///
+ public static readonly InventoryGrouping VoidGroup = new InventoryGrouping(ForgeGroup, VoidSlots);
+
+
+ [JsonProperty("netID")]
+ private int _netId;
+ [JsonProperty("prefix")]
+ private byte _prefixId;
+ [JsonProperty("stack")]
+ private int _stack;
+
+ ///
+ /// Gets the net ID.
+ ///
+ public int NetId
+ {
+ get { return _netId; }
+ }
+
+ ///
+ /// Gets the prefix.
+ ///
+ public byte PrefixId
+ {
+ get { return _prefixId; }
+ }
+
+ ///
+ /// Gets the stack.
+ ///
+ public int Stack
+ {
+ get { return _stack; }
+ }
+
+ ///
+ /// Creates a new .
+ ///
+ /// The net ID.
+ /// The stack.
+ /// The prefix ID.
+ public NetItem(int netId, int stack, byte prefixId)
+ {
+ _netId = netId;
+ _stack = stack;
+ _prefixId = prefixId;
+ }
+
+ ///
+ /// Converts the to a string.
+ ///
+ ///
+ public override string ToString()
+ {
+ return String.Format("{0},{1},{2}", _netId, _stack, _prefixId);
+ }
+
+ ///
+ /// Converts a string into a .
+ ///
+ /// The string.
+ ///
+ ///
+ ///
+ public static NetItem Parse(string str)
+ {
+ if (str == null)
+ throw new ArgumentNullException("str");
+
+ string[] comp = str.Split(',');
+ if (comp.Length != 3)
+ throw new FormatException("String does not contain three sections.");
+
+ int netId = Int32.Parse(comp[0]);
+ int stack = Int32.Parse(comp[1]);
+ byte prefixId = Byte.Parse(comp[2]);
+
+ return new NetItem(netId, stack, prefixId);
+ }
+
+ ///
+ /// Converts an into a .
+ ///
+ /// The .
+ ///
+ public static explicit operator NetItem(Item item)
+ {
+ return item == null
+ ? new NetItem()
+ : new NetItem(item.netID, item.stack, item.prefix);
+ }
+ }
+}
diff --git a/TShockAPI/NetItem.cs b/TShockAPI/NetItem.cs
deleted file mode 100644
index 13ac0989c..000000000
--- a/TShockAPI/NetItem.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-TShock, a server mod for Terraria
-Copyright (C) 2011-2019 Pryaxis & TShock Contributors
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
- using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Newtonsoft.Json;
-using Terraria;
-
-namespace TShockAPI
-{
- ///
- /// Represents an item.
- ///
- [JsonObject(MemberSerialization.OptIn)]
- public struct NetItem
- {
- ///
- /// 40 - The number of slots in a piggy bank
- ///
- public static readonly int PiggySlots = 40;
-
- ///
- /// 40 - The number of slots in a safe
- ///
- public static readonly int SafeSlots = PiggySlots;
-
- ///
- /// 40 - The number of slots in a forge
- ///
- public static readonly int ForgeSlots = SafeSlots;
-
- ///
- /// 40 - The number of slots in a void vault
- ///
- public static readonly int VoidSlots = ForgeSlots;
-
- ///
- /// 59 - The size of the player's inventory (inventory, coins, ammo, held item)
- ///
- public static readonly int InventorySlots = 59;
-
- ///
- /// 20 - The number of armor slots.
- ///
- public static readonly int ArmorSlots = 20;
-
- ///
- /// 5 - The number of other equippable items
- ///
- public static readonly int MiscEquipSlots = 5;
-
- ///
- /// 10 - The number of dye slots.
- ///
- public static readonly int DyeSlots = 10;
-
- ///
- /// 5 - The number of other dye slots (for )
- ///
- public static readonly int MiscDyeSlots = MiscEquipSlots;
-
- ///
- /// 1 - The number of trash can slots.
- ///
- public static readonly int TrashSlots = 1;
-
- ///
- /// 180 - The inventory size (inventory, held item, armour, dies, coins, ammo, piggy, safe, and trash)
- ///
- public static readonly int MaxInventory = InventorySlots + ArmorSlots + DyeSlots + MiscEquipSlots + MiscDyeSlots + PiggySlots + SafeSlots + ForgeSlots + VoidSlots + 1;
-
- public static readonly Tuple InventoryIndex = new Tuple(0, InventorySlots);
- public static readonly Tuple ArmorIndex = new Tuple(InventoryIndex.Item2, InventoryIndex.Item2 + ArmorSlots);
- public static readonly Tuple DyeIndex = new Tuple(ArmorIndex.Item2, ArmorIndex.Item2 + DyeSlots);
- public static readonly Tuple MiscEquipIndex = new Tuple(DyeIndex.Item2, DyeIndex.Item2 + MiscEquipSlots);
- public static readonly Tuple MiscDyeIndex = new Tuple(MiscEquipIndex.Item2, MiscEquipIndex.Item2 + MiscDyeSlots);
- public static readonly Tuple PiggyIndex = new Tuple(MiscDyeIndex.Item2, MiscDyeIndex.Item2 + PiggySlots);
- public static readonly Tuple SafeIndex = new Tuple(PiggyIndex.Item2, PiggyIndex.Item2 + SafeSlots);
- public static readonly Tuple TrashIndex = new Tuple(SafeIndex.Item2, SafeIndex.Item2 + TrashSlots);
- public static readonly Tuple ForgeIndex = new Tuple(TrashIndex.Item2, TrashIndex.Item2 + ForgeSlots);
- public static readonly Tuple VoidIndex = new Tuple(ForgeIndex.Item2, ForgeIndex.Item2 + VoidSlots);
-
- [JsonProperty("netID")]
- private int _netId;
- [JsonProperty("prefix")]
- private byte _prefixId;
- [JsonProperty("stack")]
- private int _stack;
-
- ///
- /// Gets the net ID.
- ///
- public int NetId
- {
- get { return _netId; }
- }
-
- ///
- /// Gets the prefix.
- ///
- public byte PrefixId
- {
- get { return _prefixId; }
- }
-
- ///
- /// Gets the stack.
- ///
- public int Stack
- {
- get { return _stack; }
- }
-
- ///
- /// Creates a new .
- ///
- /// The net ID.
- /// The stack.
- /// The prefix ID.
- public NetItem(int netId, int stack, byte prefixId)
- {
- _netId = netId;
- _stack = stack;
- _prefixId = prefixId;
- }
-
- ///
- /// Converts the to a string.
- ///
- ///
- public override string ToString()
- {
- return String.Format("{0},{1},{2}", _netId, _stack, _prefixId);
- }
-
- ///
- /// Converts a string into a .
- ///
- /// The string.
- ///
- ///
- ///
- public static NetItem Parse(string str)
- {
- if (str == null)
- throw new ArgumentNullException("str");
-
- string[] comp = str.Split(',');
- if (comp.Length != 3)
- throw new FormatException("String does not contain three sections.");
-
- int netId = Int32.Parse(comp[0]);
- int stack = Int32.Parse(comp[1]);
- byte prefixId = Byte.Parse(comp[2]);
-
- return new NetItem(netId, stack, prefixId);
- }
-
- ///
- /// Converts an into a .
- ///
- /// The .
- ///
- public static explicit operator NetItem(Item item)
- {
- return item == null
- ? new NetItem()
- : new NetItem(item.netID, item.stack, item.prefix);
- }
- }
-}
diff --git a/TShockAPI/PlayerData.cs b/TShockAPI/PlayerData.cs
index d6540e34a..5ad43e777 100644
--- a/TShockAPI/PlayerData.cs
+++ b/TShockAPI/PlayerData.cs
@@ -23,9 +23,11 @@ You should have received a copy of the GNU General Public License
using Terraria.GameContent.NetModules;
using Terraria.Net;
using Terraria.ID;
+using TShockAPI.Net;
namespace TShockAPI
{
+ [System.Obsolete("", true)]
public class PlayerData
{
public NetItem[] inventory = new NetItem[NetItem.MaxInventory];
@@ -50,6 +52,7 @@ public class PlayerData
public bool[] hideVisuals;
public int questsCompleted;
+ [System.Obsolete("", true)]
public PlayerData(TSPlayer player)
{
for (int i = 0; i < NetItem.MaxInventory; i++)
@@ -71,6 +74,8 @@ public PlayerData(TSPlayer player)
///
///
///
+
+ [System.Obsolete("", true)]
public void StoreSlot(int slot, int netID, byte prefix, int stack)
{
if (slot > (this.inventory.Length - 1)) //if the slot is out of range then dont save
@@ -85,6 +90,8 @@ public void StoreSlot(int slot, int netID, byte prefix, int stack)
/// Copies a characters data to this object
///
///
+
+ [System.Obsolete("", true)]
public void CopyCharacter(TSPlayer player)
{
this.health = player.TPlayer.statLife > 0 ? player.TPlayer.statLife : 1;
@@ -193,6 +200,8 @@ public void CopyCharacter(TSPlayer player)
/// Restores a player's character to the state stored in the database
///
///
+
+ [System.Obsolete("", true)]
public void RestoreCharacter(TSPlayer player)
{
// Start ignoring SSC-related packets! This is critical so that we don't send or receive dirty data!
diff --git a/TShockAPI/ServerSideCharacters/ServerSideConfig.cs b/TShockAPI/ServerSideCharacters/ServerSideConfig.cs
index 31d5caac7..566deaa58 100644
--- a/TShockAPI/ServerSideCharacters/ServerSideConfig.cs
+++ b/TShockAPI/ServerSideCharacters/ServerSideConfig.cs
@@ -23,11 +23,15 @@ You should have received a copy of the GNU General Public License
using System.Linq;
using System.Text;
using Newtonsoft.Json;
+using TShockAPI.Net;
namespace TShockAPI.ServerSideCharacters
{
public class ServerSideConfig
{
+ // Disable the 'Missing XML comment for publicly visible type or member' for these fields as they have
+ // description attributes
+#pragma warning disable CS1591
[Description("Enable server side characters, This stops the client from saving character data! EXPERIMENTAL!!!!!")]
public bool Enabled = false;
@@ -45,6 +49,7 @@ public class ServerSideConfig
[Description("The starting default inventory for new SSC.")]
public List StartingInventory = new List();
+#pragma warning restore CS1591
public static ServerSideConfig Read(string path)
{
diff --git a/TShockAPI/ServerSideCharacters/ServerSideCoordinator.cs b/TShockAPI/ServerSideCharacters/ServerSideCoordinator.cs
new file mode 100644
index 000000000..c6317ce2a
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSideCoordinator.cs
@@ -0,0 +1,43 @@
+using System;
+using Terraria;
+using TShockAPI.Hooks;
+
+namespace TShockAPI.ServerSideCharacters
+{
+ public class ServerSideCoordinator
+ {
+ public ServerSideCoordinator()
+ {
+ PlayerHooks.PlayerPostLogin += OnPlayerPostLogin;
+ PlayerHooks.PlayerLogout += OnPlayerLogout;
+ }
+
+ private void OnPlayerPostLogin(PlayerPostLoginEventArgs e)
+ {
+ if (!Main.ServerSideCharacter)
+ {
+ return;
+ }
+
+ if (e.Player.HasPermission(Permissions.bypassssc))
+ {
+ // Do bypass stuff?
+ return;
+ }
+
+ if (TShock.CharacterDB.HasPlayerData(e.Player))
+ {
+ // Retrieve & apply existing data
+ return;
+ }
+
+ // Create a new SSC data set
+ ServerSidePlayerData player = ServerSidePlayerData.CreateDefaultFor(e.Player.TPlayer);
+ }
+
+ private void OnPlayerLogout(PlayerLogoutEventArgs e)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/TShockAPI/ServerSideCharacters/ServerSideInventory.cs b/TShockAPI/ServerSideCharacters/ServerSideInventory.cs
new file mode 100644
index 000000000..59f583375
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSideInventory.cs
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Generic;
+using TShockAPI.Net;
+
+namespace TShockAPI.ServerSideCharacters
+{
+ ///
+ /// Contains a server side player's inventory
+ ///
+ public class ServerSideInventory
+ {
+ ///
+ /// Array of all items in the player's inventory
+ ///
+ internal NetItem[] Items = new NetItem[NetItem.MaxInventory];
+
+ ///
+ /// Items in the player's main inventory slots
+ ///
+ public ArraySegment Inventory =>
+ new ArraySegment(Items, NetItem.MainInventoryGroup.Start, NetItem.MainInventoryGroup.Count);
+
+ ///
+ /// Items in the player's coin slots
+ ///
+ public ArraySegment Coins =>
+ new ArraySegment(Items, NetItem.CoinGroup.Start, NetItem.CoinGroup.Count);
+
+ ///
+ /// Items in the player's ammo slots
+ ///
+ public ArraySegment Ammo =>
+ new ArraySegment(Items, NetItem.AmmoGroup.Start, NetItem.AmmoGroup.Count);
+
+ ///
+ /// Items in the player's held item slot
+ ///
+ public ArraySegment HeldItem =>
+ new ArraySegment(Items, NetItem.HeldItemGroup.Start, NetItem.HeldItemGroup.Count);
+
+ ///
+ /// Armor equipped by the player
+ ///
+ public ArraySegment Armor =>
+ new ArraySegment(Items, NetItem.ArmorGroup.Start, NetItem.ArmorGroup.Count);
+
+ ///
+ /// Accessories equipped by the player
+ ///
+ public ArraySegment Accessory =>
+ new ArraySegment(Items, NetItem.AccessoryGroup.Start, NetItem.AccessoryGroup.Count);
+
+ ///
+ /// Vanity armor equipped by the player
+ ///
+ public ArraySegment ArmorVanity =>
+ new ArraySegment(Items, NetItem.ArmorVanityGroup.Start, NetItem.ArmorVanityGroup.Count);
+
+ ///
+ /// Vanity accessories equipped by the player
+ ///
+ public ArraySegment AccessoryVanity =>
+ new ArraySegment(Items, NetItem.AccessoryVanityGroup.Start, NetItem.AccessoryVanityGroup.Count);
+
+ ///
+ /// Armor dyes equipped by the player
+ ///
+ public ArraySegment ArmorDye =>
+ new ArraySegment(Items, NetItem.ArmorDyeGroup.Start, NetItem.ArmorDyeGroup.Count);
+
+ ///
+ /// Vanity dyes equipped by the player
+ ///
+ public ArraySegment AccessoryDye =>
+ new ArraySegment(Items, NetItem.AccessoryDyeGroup.Start, NetItem.AccessoryDyeGroup.Count);
+
+ ///
+ /// Miscellanious items equipped by the player. This is the Mount/Hook/etc section of the inventory
+ ///
+ public ArraySegment MiscEquips =>
+ new ArraySegment(Items, NetItem.MiscEquipGroup.Start, NetItem.MiscEquipGroup.Count);
+
+ ///
+ /// Dyes for the miscellanious items sections equipped by the player
+ ///
+ public ArraySegment MiscEquipDyes =>
+ new ArraySegment(Items, NetItem.MiscDyeGroup.Start, NetItem.MiscDyeGroup.Count);
+
+ ///
+ /// Items in the player's piggy bank
+ ///
+ public ArraySegment PiggyBank =>
+ new ArraySegment(Items, NetItem.PiggyGroup.Start, NetItem.PiggyGroup.Count);
+
+ ///
+ /// Items in the player's safe
+ ///
+ public ArraySegment SafeBank =>
+ new ArraySegment(Items, NetItem.SafeGroup.Start, NetItem.SafeGroup.Count);
+
+ ///
+ /// Items in the player's trash slot
+ ///
+ public ArraySegment TrashSlot =>
+ new ArraySegment(Items, NetItem.TrashGroup.Start, NetItem.TrashGroup.Count);
+
+ ///
+ /// Items in the player's defender's forge
+ ///
+ public ArraySegment ForgeBank =>
+ new ArraySegment(Items, NetItem.ForgeGroup.Start, NetItem.ForgeGroup.Count);
+
+ ///
+ /// Items in the player's void bank
+ ///
+ public ArraySegment VoidBank =>
+ new ArraySegment(Items, NetItem.VoidGroup.Start, NetItem.VoidGroup.Count);
+
+ ///
+ /// Creates a default inventory using the items listed in
+ ///
+ ///
+ public static ServerSideInventory CreateDefault()
+ {
+ ServerSideInventory inventory = new ServerSideInventory();
+
+ // First fill as much of the inventory as possible with items from the SSC Config
+ for (int i = 0; i < TShock.ServerSideCharacterConfig.StartingInventory.Count; i++)
+ {
+ inventory.Items[i] = TShock.ServerSideCharacterConfig.StartingInventory[i];
+ }
+
+ // Then fill the rest with empty items
+ for (int i = TShock.ServerSideCharacterConfig.StartingInventory.Count; i < NetItem.MaxInventory; i++)
+ {
+ inventory.Items[i] = new NetItem();
+ }
+
+ return inventory;
+ }
+
+ ///
+ /// Creates an inventory from an enumerable of NetItems
+ ///
+ ///
+ ///
+ public static ServerSideInventory FromNetItems(IEnumerable items)
+ {
+ ServerSideInventory inventory = new ServerSideInventory();
+
+ int index = 0;
+ foreach (NetItem item in items)
+ {
+ inventory.Items[index] = item;
+ index++;
+ }
+
+ return inventory;
+ }
+ }
+}
diff --git a/TShockAPI/ServerSideCharacters/ServerSidePlayerData.cs b/TShockAPI/ServerSideCharacters/ServerSidePlayerData.cs
new file mode 100644
index 000000000..a38e40f86
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSidePlayerData.cs
@@ -0,0 +1,46 @@
+using Terraria;
+
+namespace TShockAPI.ServerSideCharacters
+{
+ ///
+ /// Contains information about the server side state of a player
+ ///
+ public class ServerSidePlayerData
+ {
+ ///
+ /// Contains the server side player's stats
+ ///
+ public ServerSideStats Stats { get; set; }
+
+ ///
+ /// Contains the server side player's vanity values
+ ///
+ public ServerSideVanity Vanity { get; set; }
+
+ ///
+ /// Contains the server side player's inventory values
+ ///
+ public ServerSideInventory Inventory { get; set; }
+
+ ///
+ /// Contains the server side player's spawn information
+ ///
+ public ServerSideSpawn Spawn { get; set; }
+
+ ///
+ /// Creates a basic server side player using inventory and stat defaults from the config, and vanity from the player
+ ///
+ ///
+ public static ServerSidePlayerData CreateDefaultFor(Player player)
+ {
+ ServerSidePlayerData data = new ServerSidePlayerData
+ {
+ Stats = ServerSideStats.CreateDefault(),
+ Inventory = ServerSideInventory.CreateDefault(),
+ Vanity = ServerSideVanity.CreateFrom(player)
+ };
+
+ return data;
+ }
+ }
+}
diff --git a/TShockAPI/ServerSideCharacters/ServerSideSpawn.cs b/TShockAPI/ServerSideCharacters/ServerSideSpawn.cs
new file mode 100644
index 000000000..bb6d70a9e
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSideSpawn.cs
@@ -0,0 +1,18 @@
+namespace TShockAPI.ServerSideCharacters
+{
+ ///
+ /// Contains details about a server side player's spawn location
+ ///
+ public class ServerSideSpawn
+ {
+ ///
+ /// The tile coordinate x position the player will spawn at
+ ///
+ public int TileX { get; set; }
+
+ ///
+ /// The tile coordinate y position the player will spawn at
+ ///
+ public int TileY { get; set; }
+ }
+}
diff --git a/TShockAPI/ServerSideCharacters/ServerSideStats.cs b/TShockAPI/ServerSideCharacters/ServerSideStats.cs
new file mode 100644
index 000000000..d1a384ea6
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSideStats.cs
@@ -0,0 +1,52 @@
+namespace TShockAPI.ServerSideCharacters
+{
+ ///
+ /// Contains a server side player's stats
+ ///
+ public class ServerSideStats
+ {
+ ///
+ /// The player's current health
+ ///
+ public int Health { get; set; }
+ ///
+ /// The player's maximum health
+ ///
+ public int MaxHealth { get; set; }
+ ///
+ /// The player's current mana
+ ///
+ public int Mana { get; set; }
+ ///
+ /// The player's maximum mana
+ ///
+ public int MaxMana { get; set; }
+ ///
+ /// Whether or not the player has unlocked extra slots
+ ///
+ public bool HasExtraSlot { get; set; }
+ ///
+ /// The number of angler quests completed by the player
+ ///
+ public int QuestsCompleted { get; set; }
+
+ ///
+ /// Creates a default set of stats using the settings
+ ///
+ ///
+ public static ServerSideStats CreateDefault()
+ {
+ ServerSideStats stats = new ServerSideStats
+ {
+ Health = TShock.ServerSideCharacterConfig.StartingHealth,
+ MaxHealth = TShock.ServerSideCharacterConfig.StartingHealth,
+ Mana = TShock.ServerSideCharacterConfig.StartingMana,
+ MaxMana = TShock.ServerSideCharacterConfig.StartingMana,
+ HasExtraSlot = 0,
+ QuestsCompleted = 0
+ };
+
+ return stats;
+ }
+ }
+}
diff --git a/TShockAPI/ServerSideCharacters/ServerSideVanity.cs b/TShockAPI/ServerSideCharacters/ServerSideVanity.cs
new file mode 100644
index 000000000..6e3b1beb0
--- /dev/null
+++ b/TShockAPI/ServerSideCharacters/ServerSideVanity.cs
@@ -0,0 +1,80 @@
+using Microsoft.Xna.Framework;
+using Terraria;
+
+namespace TShockAPI.ServerSideCharacters
+{
+ ///
+ /// Contains a server side player's vanity display
+ ///
+ public class ServerSideVanity
+ {
+ ///
+ /// Player's skin variant
+ ///
+ public int SkinVariant { get; set; }
+ ///
+ /// Player's hair type
+ ///
+ public int Hair { get; set; }
+ ///
+ /// Hair dye applied to the player's hair
+ ///
+ public byte HairDye { get; set; }
+ ///
+ /// Player's hair color
+ ///
+ public Color? HairColor { get; set; }
+ ///
+ /// Player's pants color
+ ///
+ public Color? PantsColor { get; set; }
+ ///
+ /// Player's shirt color
+ ///
+ public Color? ShirtColor { get; set; }
+ ///
+ /// Player's undershirt color
+ ///
+ public Color? UnderShirtColor { get; set; }
+ ///
+ /// Player's shoe color
+ ///
+ public Color? ShoeColor { get; set; }
+ ///
+ /// Player's skin color
+ ///
+ public Color? SkinColor { get; set; }
+ ///
+ /// Player's eye color
+ ///
+ public Color? EyeColor { get; set; }
+ ///
+ /// Player's hidden accessories
+ ///
+ public bool[] HideVisuals { get; set; }
+
+ ///
+ /// Creates server side vanity for the given player
+ ///
+ ///
+ ///
+ public static ServerSideVanity CreateFrom(Player player)
+ {
+ ServerSideVanity vanity = new ServerSideVanity
+ {
+ Hair = player.hair,
+ HairDye = player.hairDye,
+ HairColor = player.hairColor,
+ PantsColor = player.pantsColor,
+ ShirtColor = player.shirtColor,
+ UnderShirtColor = player.underShirtColor,
+ ShoeColor = player.shoeColor,
+ SkinColor = player.skinColor,
+ EyeColor = player.eyeColor,
+ HideVisuals = player.hideVisibleAccessory
+ };
+
+ return vanity;
+ }
+ }
+}
diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index ade162346..9d0fd58aa 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -368,6 +368,7 @@ public bool HasHackedItemStacks(bool shouldWarnPlayer = false)
Item[] voidVault = TPlayer.bank4.item;
Item trash = TPlayer.trashItem;
+ /*
for (int i = 0; i < NetItem.MaxInventory; i++)
{
if (i < NetItem.InventoryIndex.Item2)
@@ -576,7 +577,7 @@ public bool HasHackedItemStacks(bool shouldWarnPlayer = false)
}
}
-
+ */
return check;
}
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index 74e356360..428ceaa21 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -508,7 +508,7 @@ private void OnPlayerLogin(PlayerPostLoginEventArgs args)
/// args - The AccountDeleteEventArgs object.
private void OnAccountDelete(Hooks.AccountDeleteEventArgs args)
{
- CharacterDB.RemovePlayer(args.Account.ID);
+ CharacterDB.DeletePlayerData(args.Account.ID);
}
/// OnAccountCreate - Internal hook fired on account creation.
diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj
index 495127c83..2862efc20 100644
--- a/TShockAPI/TShockAPI.csproj
+++ b/TShockAPI/TShockAPI.csproj
@@ -111,9 +111,15 @@
-
+
+
+
+
+
+
+
@@ -223,7 +229,7 @@
-
+