mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
hopefully save the hand and also when the player leaves or server closes (#943)
* hopefully save the hand and also when the player leaves or server closes * fixes * change it to check the user id * fix * check pointers * fix compilation error * fix other bugs * put player id in source * fix error * remove one line of code * fix serialization * revert < 22 to < 14 * change * fix error where inventory not saved on alt f4 * change connected to a regular bool * remove isConnected function
This commit is contained in:
parent
fabc5c1aef
commit
1de5efbf6e
@ -310,14 +310,14 @@ pub const Sync = struct { // MARK: Sync
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.playerInventory, .other => {},
|
.playerInventory, .hand, .other => {},
|
||||||
.alreadyFreed => unreachable,
|
.alreadyFreed => unreachable,
|
||||||
}
|
}
|
||||||
const inventory = ServerInventory.init(len, typ, source);
|
const inventory = ServerInventory.init(len, typ, source);
|
||||||
|
|
||||||
switch (source) {
|
switch (source) {
|
||||||
.sharedTestingInventory => {},
|
.sharedTestingInventory => {},
|
||||||
.playerInventory => {
|
.playerInventory, .hand => {
|
||||||
const dest: []u8 = main.stackAllocator.alloc(u8, std.base64.url_safe.Encoder.calcSize(user.name.len));
|
const dest: []u8 = main.stackAllocator.alloc(u8, std.base64.url_safe.Encoder.calcSize(user.name.len));
|
||||||
defer main.stackAllocator.free(dest);
|
defer main.stackAllocator.free(dest);
|
||||||
const hashedName = std.base64.url_safe.Encoder.encode(dest, user.name);
|
const hashedName = std.base64.url_safe.Encoder.encode(dest, user.name);
|
||||||
@ -328,7 +328,7 @@ pub const Sync = struct { // MARK: Sync
|
|||||||
const playerData = main.files.readToZon(main.stackAllocator, path) catch .null;
|
const playerData = main.files.readToZon(main.stackAllocator, path) catch .null;
|
||||||
defer playerData.deinit(main.stackAllocator);
|
defer playerData.deinit(main.stackAllocator);
|
||||||
|
|
||||||
const inventoryZon = playerData.getChild("inventory");
|
const inventoryZon = playerData.getChild(@tagName(source));
|
||||||
|
|
||||||
inventory.inv.loadFromZon(inventoryZon);
|
inventory.inv.loadFromZon(inventoryZon);
|
||||||
},
|
},
|
||||||
@ -352,10 +352,10 @@ pub const Sync = struct { // MARK: Sync
|
|||||||
return inventories.items[serverId].inv;
|
return inventories.items[serverId].inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getInventoryFromSource(source: SourceType) ?Inventory {
|
pub fn getInventoryFromSource(source: Source) ?Inventory {
|
||||||
main.utils.assertLocked(&mutex);
|
main.utils.assertLocked(&mutex);
|
||||||
for(inventories.items) |inv| {
|
for(inventories.items) |inv| {
|
||||||
if (inv.source == source) {
|
if (std.meta.eql(inv.source, source)) {
|
||||||
return inv.inv;
|
return inv.inv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1060,7 +1060,13 @@ pub const Command = struct { // MARK: Command
|
|||||||
data.append(@intFromEnum(self.inv.type));
|
data.append(@intFromEnum(self.inv.type));
|
||||||
data.append(@intFromEnum(self.source));
|
data.append(@intFromEnum(self.source));
|
||||||
switch (self.source) {
|
switch (self.source) {
|
||||||
.playerInventory, .sharedTestingInventory, .other => {},
|
.playerInventory, .hand => |val| {
|
||||||
|
std.mem.writeInt(u32, data.addMany(4)[0..4], val, .big);
|
||||||
|
},
|
||||||
|
else => {}
|
||||||
|
}
|
||||||
|
switch(self.source) {
|
||||||
|
.playerInventory, .sharedTestingInventory, .hand, .other => {},
|
||||||
.alreadyFreed => unreachable,
|
.alreadyFreed => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1073,8 +1079,9 @@ pub const Command = struct { // MARK: Command
|
|||||||
const typ: Inventory.Type = @enumFromInt(data[12]);
|
const typ: Inventory.Type = @enumFromInt(data[12]);
|
||||||
const sourceType: SourceType = @enumFromInt(data[13]);
|
const sourceType: SourceType = @enumFromInt(data[13]);
|
||||||
const source: Source = switch(sourceType) {
|
const source: Source = switch(sourceType) {
|
||||||
.playerInventory => .{.playerInventory = {}},
|
.playerInventory => .{.playerInventory = std.mem.readInt(u32, data[14..18], .big)},
|
||||||
.sharedTestingInventory => .{.sharedTestingInventory = {}},
|
.sharedTestingInventory => .{.sharedTestingInventory = {}},
|
||||||
|
.hand => .{.hand = std.mem.readInt(u32, data[14..18], .big)},
|
||||||
.other => .{.other = {}},
|
.other => .{.other = {}},
|
||||||
.alreadyFreed => unreachable,
|
.alreadyFreed => unreachable,
|
||||||
};
|
};
|
||||||
@ -1647,12 +1654,14 @@ const SourceType = enum(u8) {
|
|||||||
alreadyFreed = 0,
|
alreadyFreed = 0,
|
||||||
playerInventory = 1,
|
playerInventory = 1,
|
||||||
sharedTestingInventory = 2,
|
sharedTestingInventory = 2,
|
||||||
|
hand = 3,
|
||||||
other = 0xff, // TODO: List every type separately here.
|
other = 0xff, // TODO: List every type separately here.
|
||||||
};
|
};
|
||||||
const Source = union(SourceType) {
|
const Source = union(SourceType) {
|
||||||
alreadyFreed: void,
|
alreadyFreed: void,
|
||||||
playerInventory: void,
|
playerInventory: u32,
|
||||||
sharedTestingInventory: void,
|
sharedTestingInventory: void,
|
||||||
|
hand: u32,
|
||||||
other: void,
|
other: void,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1691,7 +1700,13 @@ fn _init(allocator: NeverFailingAllocator, _size: usize, _type: Type, side: Side
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: Inventory, allocator: NeverFailingAllocator) void {
|
pub fn deinit(self: Inventory, allocator: NeverFailingAllocator) void {
|
||||||
|
if (main.game.world.?.connected) {
|
||||||
Sync.ClientSide.executeCommand(.{.close = .{.inv = self, .allocator = allocator}});
|
Sync.ClientSide.executeCommand(.{.close = .{.inv = self, .allocator = allocator}});
|
||||||
|
} else {
|
||||||
|
Sync.ClientSide.mutex.lock();
|
||||||
|
defer Sync.ClientSide.mutex.unlock();
|
||||||
|
self._deinit(allocator, .client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _deinit(self: Inventory, allocator: NeverFailingAllocator, side: Side) void {
|
fn _deinit(self: Inventory, allocator: NeverFailingAllocator, side: Side) void {
|
||||||
|
10
src/game.zig
10
src/game.zig
@ -583,6 +583,7 @@ pub const World = struct { // MARK: World
|
|||||||
milliTime: i64,
|
milliTime: i64,
|
||||||
gameTime: Atomic(i64) = .init(0),
|
gameTime: Atomic(i64) = .init(0),
|
||||||
spawn: Vec3f = undefined,
|
spawn: Vec3f = undefined,
|
||||||
|
connected: bool = true,
|
||||||
blockPalette: *assets.Palette = undefined,
|
blockPalette: *assets.Palette = undefined,
|
||||||
biomePalette: *assets.Palette = undefined,
|
biomePalette: *assets.Palette = undefined,
|
||||||
itemDrops: ClientItemDropManager = undefined,
|
itemDrops: ClientItemDropManager = undefined,
|
||||||
@ -595,6 +596,7 @@ pub const World = struct { // MARK: World
|
|||||||
.name = "client",
|
.name = "client",
|
||||||
.milliTime = std.time.milliTimestamp(),
|
.milliTime = std.time.milliTimestamp(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.itemDrops.init(main.globalAllocator, self);
|
self.itemDrops.init(main.globalAllocator, self);
|
||||||
network.Protocols.handShake.clientSide(self.conn, settings.playerName);
|
network.Protocols.handShake.clientSide(self.conn, settings.playerName);
|
||||||
|
|
||||||
@ -607,15 +609,17 @@ pub const World = struct { // MARK: World
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *World) void {
|
pub fn deinit(self: *World) void {
|
||||||
|
self.conn.deinit();
|
||||||
|
|
||||||
|
self.connected = false;
|
||||||
|
|
||||||
// TODO: Close all world related guis.
|
// TODO: Close all world related guis.
|
||||||
main.gui.inventory.deinit();
|
main.gui.inventory.deinit();
|
||||||
main.gui.deinit();
|
main.gui.deinit();
|
||||||
main.gui.init();
|
main.gui.init();
|
||||||
|
|
||||||
Player.inventory.deinit(main.globalAllocator);
|
Player.inventory.deinit(main.globalAllocator);
|
||||||
|
|
||||||
main.threadPool.clear();
|
main.threadPool.clear();
|
||||||
self.conn.deinit();
|
|
||||||
self.itemDrops.deinit();
|
self.itemDrops.deinit();
|
||||||
self.blockPalette.deinit();
|
self.blockPalette.deinit();
|
||||||
self.biomePalette.deinit();
|
self.biomePalette.deinit();
|
||||||
@ -642,7 +646,7 @@ pub const World = struct { // MARK: World
|
|||||||
try assets.loadWorldAssets("serverAssets", self.blockPalette, self.biomePalette);
|
try assets.loadWorldAssets("serverAssets", self.blockPalette, self.biomePalette);
|
||||||
Player.loadFrom(zon.getChild("player"));
|
Player.loadFrom(zon.getChild("player"));
|
||||||
Player.id = zon.get(u32, "player_id", std.math.maxInt(u32));
|
Player.id = zon.get(u32, "player_id", std.math.maxInt(u32));
|
||||||
Player.inventory = Inventory.init(main.globalAllocator, 32, .normal, .playerInventory);
|
Player.inventory = Inventory.init(main.globalAllocator, 32, .normal, .{.playerInventory = Player.id});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(self: *World) void {
|
pub fn update(self: *World) void {
|
||||||
|
@ -593,7 +593,7 @@ pub const inventory = struct { // MARK: inventory
|
|||||||
var initialized: bool = false;
|
var initialized: bool = false;
|
||||||
|
|
||||||
pub fn init() void {
|
pub fn init() void {
|
||||||
carried = Inventory.init(main.globalAllocator, 1, .normal, .other);
|
carried = Inventory.init(main.globalAllocator, 1, .normal, .{.hand = main.game.Player.id});
|
||||||
leftClickSlots = .init(main.globalAllocator);
|
leftClickSlots = .init(main.globalAllocator);
|
||||||
rightClickSlots = .init(main.globalAllocator);
|
rightClickSlots = .init(main.globalAllocator);
|
||||||
carriedItemSlot = ItemSlot.init(.{0, 0}, carried, 0, .default, .normal);
|
carriedItemSlot = ItemSlot.init(.{0, 0}, carried, 0, .default, .normal);
|
||||||
|
@ -70,6 +70,12 @@ pub const User = struct { // MARK: User
|
|||||||
|
|
||||||
pub fn deinit(self: *User) void {
|
pub fn deinit(self: *User) void {
|
||||||
std.debug.assert(self.refCount.load(.monotonic) == 0);
|
std.debug.assert(self.refCount.load(.monotonic) == 0);
|
||||||
|
|
||||||
|
world.?.savePlayer(self) catch |err| {
|
||||||
|
std.log.err("Failed to save player: {s}", .{@errorName(err)});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
main.items.Inventory.Sync.ServerSide.disconnectUser(self);
|
main.items.Inventory.Sync.ServerSide.disconnectUser(self);
|
||||||
std.debug.assert(self.inventoryClientToServerIdMap.count() == 0); // leak
|
std.debug.assert(self.inventoryClientToServerIdMap.count() == 0); // leak
|
||||||
self.inventoryClientToServerIdMap.deinit();
|
self.inventoryClientToServerIdMap.deinit();
|
||||||
|
@ -815,8 +815,12 @@ pub const ServerWorld = struct { // MARK: ServerWorld
|
|||||||
{
|
{
|
||||||
main.items.Inventory.Sync.ServerSide.mutex.lock();
|
main.items.Inventory.Sync.ServerSide.mutex.lock();
|
||||||
defer main.items.Inventory.Sync.ServerSide.mutex.unlock();
|
defer main.items.Inventory.Sync.ServerSide.mutex.unlock();
|
||||||
if (main.items.Inventory.Sync.ServerSide.getInventoryFromSource(.playerInventory)) |inv| {
|
if (main.items.Inventory.Sync.ServerSide.getInventoryFromSource(.{.playerInventory = user.id})) |inv| {
|
||||||
playerZon.put("inventory", inv.save(main.stackAllocator));
|
playerZon.put("playerInventory", inv.save(main.stackAllocator));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (main.items.Inventory.Sync.ServerSide.getInventoryFromSource(.{.hand = user.id})) |inv| {
|
||||||
|
playerZon.put("hand", inv.save(main.stackAllocator));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user