Implement player persistence
This saves your health, inventory, position, and look values.
This commit is contained in:
parent
f84538b9c6
commit
74849b0b56
@ -19,6 +19,8 @@ namespace TrueCraft.API.Networking
|
||||
IMultiplayerServer Server { get; }
|
||||
bool EnableLogging { get; set; }
|
||||
|
||||
bool Load();
|
||||
void Save();
|
||||
void QueuePacket(IPacket packet);
|
||||
void SendMessage(string message);
|
||||
void Log(string message, params object[] parameters);
|
||||
|
@ -22,6 +22,7 @@ namespace TrueCraft.API.Windows
|
||||
/// Gets an array of all slots in this window. Suitable for sending to clients over the network.
|
||||
/// </summary>
|
||||
ItemStack[] GetSlots();
|
||||
void SetSlots(ItemStack[] slots);
|
||||
/// <summary>
|
||||
/// Adds the specified item stack to this window, merging with established slots as neccessary.
|
||||
/// </summary>
|
||||
|
@ -14,7 +14,6 @@ namespace TrueCraft.Core.Entities
|
||||
public PlayerEntity(string username) : base()
|
||||
{
|
||||
Username = username;
|
||||
Food = 20;
|
||||
}
|
||||
|
||||
public const double Width = 0.6;
|
||||
@ -100,39 +99,6 @@ namespace TrueCraft.Core.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected short _Food;
|
||||
public short Food
|
||||
{
|
||||
get { return _Food; }
|
||||
set
|
||||
{
|
||||
_Food = value;
|
||||
OnPropertyChanged("Food");
|
||||
}
|
||||
}
|
||||
|
||||
protected float _FoodSaturation;
|
||||
public float FoodSaturation
|
||||
{
|
||||
get { return _FoodSaturation; }
|
||||
set
|
||||
{
|
||||
_FoodSaturation = value;
|
||||
OnPropertyChanged("FoodSaturation");
|
||||
}
|
||||
}
|
||||
|
||||
protected float _FoodExhaustion;
|
||||
public float FoodExhaustion
|
||||
{
|
||||
get { return _FoodExhaustion; }
|
||||
set
|
||||
{
|
||||
_FoodExhaustion = value;
|
||||
OnPropertyChanged("FoodExhaustion");
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<EntityEventArgs> PickUpItem;
|
||||
public void OnPickUpItem(ItemEntity item)
|
||||
{
|
||||
|
@ -95,6 +95,12 @@ namespace TrueCraft.Core.Windows
|
||||
return slots;
|
||||
}
|
||||
|
||||
public virtual void SetSlots(ItemStack[] slots)
|
||||
{
|
||||
foreach (var windowArea in WindowAreas)
|
||||
Array.Copy(slots, windowArea.StartIndex, windowArea.Items, 0, windowArea.Length);
|
||||
}
|
||||
|
||||
public virtual ItemStack this[int index]
|
||||
{
|
||||
get
|
||||
|
@ -35,15 +35,19 @@ namespace TrueCraft.Handlers
|
||||
client.World = server.Worlds[0];
|
||||
client.ChunkRadius = 2;
|
||||
|
||||
if (!client.Load())
|
||||
client.Entity.Position = client.World.SpawnPoint;
|
||||
|
||||
// Send setup packets
|
||||
client.QueuePacket(new LoginResponsePacket(0, 0, Dimension.Overworld));
|
||||
client.UpdateChunks();
|
||||
client.QueuePacket(new WindowItemsPacket(0, client.Inventory.GetSlots()));
|
||||
client.Entity.Position = client.World.SpawnPoint;
|
||||
client.QueuePacket(new SpawnPositionPacket((int)client.Entity.Position.X,
|
||||
(int)client.Entity.Position.Y, (int)client.Entity.Position.Z));
|
||||
client.QueuePacket(new SetPlayerPositionPacket(client.Entity.Position.X, client.Entity.Position.Y,
|
||||
client.Entity.Position.Y + client.Entity.Size.Height, client.Entity.Position.Z, 0, 0, true));
|
||||
client.QueuePacket(new SetPlayerPositionPacket(client.Entity.Position.X,
|
||||
client.Entity.Position.Y + 1,
|
||||
client.Entity.Position.Y + client.Entity.Size.Height + 1,
|
||||
client.Entity.Position.Z, client.Entity.Yaw, client.Entity.Pitch, true));
|
||||
client.QueuePacket(new TimeUpdatePacket(client.World.Time));
|
||||
|
||||
// Start housekeeping for this client
|
||||
|
@ -216,6 +216,7 @@ namespace TrueCraft
|
||||
GetEntityManagerForWorld(client.World).DespawnEntity(client.Entity);
|
||||
GetEntityManagerForWorld(client.World).FlushDespawns();
|
||||
}
|
||||
client.Save();
|
||||
client.Disconnected = true;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ using TrueCraft.Core.Windows;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using TrueCraft.Core.Entities;
|
||||
using System.IO;
|
||||
using fNbt;
|
||||
|
||||
namespace TrueCraft
|
||||
{
|
||||
@ -25,7 +27,7 @@ namespace TrueCraft
|
||||
public RemoteClient(IMultiplayerServer server, NetworkStream stream)
|
||||
{
|
||||
NetworkStream = stream;
|
||||
MinecraftStream = new MinecraftStream(new BufferedStream(NetworkStream));
|
||||
MinecraftStream = new MinecraftStream(new TrueCraft.Core.Networking.BufferedStream(NetworkStream));
|
||||
PacketQueue = new ConcurrentQueue<IPacket>();
|
||||
LoadedChunks = new List<Coordinates2D>();
|
||||
Server = server;
|
||||
@ -117,6 +119,50 @@ namespace TrueCraft
|
||||
}
|
||||
}
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "players", Username + ".nbt");
|
||||
if (!File.Exists(path))
|
||||
return false;
|
||||
try
|
||||
{
|
||||
var nbt = new NbtFile(path);
|
||||
Entity.Position = new Vector3(
|
||||
nbt.RootTag["position"][0].DoubleValue,
|
||||
nbt.RootTag["position"][1].DoubleValue,
|
||||
nbt.RootTag["position"][2].DoubleValue);
|
||||
Inventory.SetSlots(((NbtList)nbt.RootTag["inventory"]).Select(t => ItemStack.FromNbt(t as NbtCompound)).ToArray());
|
||||
(Entity as PlayerEntity).Health = nbt.RootTag["health"].ShortValue;
|
||||
Entity.Yaw = nbt.RootTag["yaw"].FloatValue;
|
||||
Entity.Pitch = nbt.RootTag["pitch"].FloatValue;
|
||||
}
|
||||
catch { /* Who cares */ }
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "players", Username + ".nbt");
|
||||
if (!Directory.Exists(Path.GetDirectoryName(path)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
var nbt = new NbtFile(new NbtCompound("player", new NbtTag[]
|
||||
{
|
||||
new NbtString("username", Username),
|
||||
new NbtList("position", new[]
|
||||
{
|
||||
new NbtDouble(Entity.Position.X),
|
||||
new NbtDouble(Entity.Position.Y),
|
||||
new NbtDouble(Entity.Position.Z)
|
||||
}),
|
||||
new NbtList("inventory", Inventory.GetSlots().Select(s => s.ToNbt())),
|
||||
new NbtShort("health", (Entity as PlayerEntity).Health),
|
||||
new NbtFloat("yaw", Entity.Yaw),
|
||||
new NbtFloat("pitch", Entity.Pitch),
|
||||
}
|
||||
));
|
||||
nbt.SaveToFile(path, NbtCompression.ZLib);
|
||||
}
|
||||
|
||||
public void OpenWindow(IWindow window)
|
||||
{
|
||||
CurrentWindow = window;
|
||||
|
Loading…
x
Reference in New Issue
Block a user