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,
|
||||
}
|
||||
const inventory = ServerInventory.init(len, typ, source);
|
||||
|
||||
switch (source) {
|
||||
.sharedTestingInventory => {},
|
||||
.playerInventory => {
|
||||
.playerInventory, .hand => {
|
||||
const dest: []u8 = main.stackAllocator.alloc(u8, std.base64.url_safe.Encoder.calcSize(user.name.len));
|
||||
defer main.stackAllocator.free(dest);
|
||||
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;
|
||||
defer playerData.deinit(main.stackAllocator);
|
||||
|
||||
const inventoryZon = playerData.getChild("inventory");
|
||||
const inventoryZon = playerData.getChild(@tagName(source));
|
||||
|
||||
inventory.inv.loadFromZon(inventoryZon);
|
||||
},
|
||||
@ -352,10 +352,10 @@ pub const Sync = struct { // MARK: Sync
|
||||
return inventories.items[serverId].inv;
|
||||
}
|
||||
|
||||
pub fn getInventoryFromSource(source: SourceType) ?Inventory {
|
||||
pub fn getInventoryFromSource(source: Source) ?Inventory {
|
||||
main.utils.assertLocked(&mutex);
|
||||
for(inventories.items) |inv| {
|
||||
if (inv.source == source) {
|
||||
if (std.meta.eql(inv.source, source)) {
|
||||
return inv.inv;
|
||||
}
|
||||
}
|
||||
@ -1059,8 +1059,14 @@ pub const Command = struct { // MARK: Command
|
||||
std.mem.writeInt(usize, data.addMany(8)[0..8], self.inv._items.len, .big);
|
||||
data.append(@intFromEnum(self.inv.type));
|
||||
data.append(@intFromEnum(self.source));
|
||||
switch (self.source) {
|
||||
.playerInventory, .hand => |val| {
|
||||
std.mem.writeInt(u32, data.addMany(4)[0..4], val, .big);
|
||||
},
|
||||
else => {}
|
||||
}
|
||||
switch(self.source) {
|
||||
.playerInventory, .sharedTestingInventory, .other => {},
|
||||
.playerInventory, .sharedTestingInventory, .hand, .other => {},
|
||||
.alreadyFreed => unreachable,
|
||||
}
|
||||
}
|
||||
@ -1073,8 +1079,9 @@ pub const Command = struct { // MARK: Command
|
||||
const typ: Inventory.Type = @enumFromInt(data[12]);
|
||||
const sourceType: SourceType = @enumFromInt(data[13]);
|
||||
const source: Source = switch(sourceType) {
|
||||
.playerInventory => .{.playerInventory = {}},
|
||||
.playerInventory => .{.playerInventory = std.mem.readInt(u32, data[14..18], .big)},
|
||||
.sharedTestingInventory => .{.sharedTestingInventory = {}},
|
||||
.hand => .{.hand = std.mem.readInt(u32, data[14..18], .big)},
|
||||
.other => .{.other = {}},
|
||||
.alreadyFreed => unreachable,
|
||||
};
|
||||
@ -1647,12 +1654,14 @@ const SourceType = enum(u8) {
|
||||
alreadyFreed = 0,
|
||||
playerInventory = 1,
|
||||
sharedTestingInventory = 2,
|
||||
hand = 3,
|
||||
other = 0xff, // TODO: List every type separately here.
|
||||
};
|
||||
const Source = union(SourceType) {
|
||||
alreadyFreed: void,
|
||||
playerInventory: void,
|
||||
playerInventory: u32,
|
||||
sharedTestingInventory: void,
|
||||
hand: u32,
|
||||
other: void,
|
||||
};
|
||||
|
||||
@ -1691,7 +1700,13 @@ fn _init(allocator: NeverFailingAllocator, _size: usize, _type: Type, side: Side
|
||||
}
|
||||
|
||||
pub fn deinit(self: Inventory, allocator: NeverFailingAllocator) void {
|
||||
Sync.ClientSide.executeCommand(.{.close = .{.inv = self, .allocator = allocator}});
|
||||
if (main.game.world.?.connected) {
|
||||
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 {
|
||||
|
10
src/game.zig
10
src/game.zig
@ -583,6 +583,7 @@ pub const World = struct { // MARK: World
|
||||
milliTime: i64,
|
||||
gameTime: Atomic(i64) = .init(0),
|
||||
spawn: Vec3f = undefined,
|
||||
connected: bool = true,
|
||||
blockPalette: *assets.Palette = undefined,
|
||||
biomePalette: *assets.Palette = undefined,
|
||||
itemDrops: ClientItemDropManager = undefined,
|
||||
@ -595,6 +596,7 @@ pub const World = struct { // MARK: World
|
||||
.name = "client",
|
||||
.milliTime = std.time.milliTimestamp(),
|
||||
};
|
||||
|
||||
self.itemDrops.init(main.globalAllocator, self);
|
||||
network.Protocols.handShake.clientSide(self.conn, settings.playerName);
|
||||
|
||||
@ -607,15 +609,17 @@ pub const World = struct { // MARK: World
|
||||
}
|
||||
|
||||
pub fn deinit(self: *World) void {
|
||||
self.conn.deinit();
|
||||
|
||||
self.connected = false;
|
||||
|
||||
// TODO: Close all world related guis.
|
||||
main.gui.inventory.deinit();
|
||||
main.gui.deinit();
|
||||
main.gui.init();
|
||||
|
||||
Player.inventory.deinit(main.globalAllocator);
|
||||
|
||||
main.threadPool.clear();
|
||||
self.conn.deinit();
|
||||
self.itemDrops.deinit();
|
||||
self.blockPalette.deinit();
|
||||
self.biomePalette.deinit();
|
||||
@ -642,7 +646,7 @@ pub const World = struct { // MARK: World
|
||||
try assets.loadWorldAssets("serverAssets", self.blockPalette, self.biomePalette);
|
||||
Player.loadFrom(zon.getChild("player"));
|
||||
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 {
|
||||
|
@ -593,7 +593,7 @@ pub const inventory = struct { // MARK: inventory
|
||||
var initialized: bool = false;
|
||||
|
||||
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);
|
||||
rightClickSlots = .init(main.globalAllocator);
|
||||
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 {
|
||||
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);
|
||||
std.debug.assert(self.inventoryClientToServerIdMap.count() == 0); // leak
|
||||
self.inventoryClientToServerIdMap.deinit();
|
||||
|
@ -815,8 +815,12 @@ pub const ServerWorld = struct { // MARK: ServerWorld
|
||||
{
|
||||
main.items.Inventory.Sync.ServerSide.mutex.lock();
|
||||
defer main.items.Inventory.Sync.ServerSide.mutex.unlock();
|
||||
if (main.items.Inventory.Sync.ServerSide.getInventoryFromSource(.playerInventory)) |inv| {
|
||||
playerZon.put("inventory", inv.save(main.stackAllocator));
|
||||
if (main.items.Inventory.Sync.ServerSide.getInventoryFromSource(.{.playerInventory = user.id})) |inv| {
|
||||
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