Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion src/Inventory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub const client = struct { // MARK: client
serverToClientMap.deinit();
}

fn nextId() InventoryId {
pub fn nextId() InventoryId {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
if (freeIdList.popOrNull()) |id| {
Expand Down Expand Up @@ -88,6 +88,42 @@ pub const client = struct { // MARK: client
}
return null;
}

var pendingChestOpen: ?ClientInventory = null;

fn buildFromResponse(clientId: InventoryId, source: Source, len: usize, reader: *BinaryReader) Inventory {
const inv: Inventory = .{
._items = main.globalAllocator.alloc(ItemStack, len),
.id = clientId,
.source = source,
.callbacks = .{},
};
for (inv._items) |*item| item.* = .{};
inv.fromBytes(reader);
return inv;
}

pub fn receiveChestOpenResponse(clientId: InventoryId, pos: Vec3i, serverId: InventoryId, reader: *BinaryReader) void {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
const inv = buildFromResponse(clientId, .{.blockInventory = pos}, main.block_entity.BlockEntityTypes.@"cubyz:chest".inventorySize, reader);
mapServerId(serverId, inv);
pendingChestOpen = .{.super = inv, .type = .serverShared};
}

pub fn cancelChestOpen(clientId: InventoryId) void {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
freeId(clientId);
std.log.err("Server rejected request to open chest.", .{});
}

pub fn takePendingChestOpen() ?ClientInventory {
main.sync.client.mutex.lock();
defer main.sync.client.mutex.unlock();
defer pendingChestOpen = null;
return pendingChestOpen;
}
};

pub const server = struct { // MARK: server
Expand Down
7 changes: 2 additions & 5 deletions src/callbacks/block/client/open_chest.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@ pub fn run(_: *anyopaque, params: main.callbacks.ClientBlockCallback.Params) mai
}
main.network.protocols.blockEntityUpdate.sendClientDataUpdateToServer(main.game.world.?.conn, params.blockPos);

const inventory = main.items.Inventory.ClientInventory.init(main.globalAllocator, main.block_entity.BlockEntityTypes.@"cubyz:chest".inventorySize, .serverShared, .{.blockInventory = params.blockPos}, .{});

main.gui.windowlist.chest.setInventory(inventory);
main.gui.openWindow("chest");
main.Window.setMouseGrabbed(false);
const clientId = main.items.Inventory.client.nextId();
main.network.protocols.chestOpen.sendRequest(main.game.world.?.conn, clientId, params.blockPos);

return .handled;
}
2 changes: 2 additions & 0 deletions src/game.zig
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ pub fn update(deltaTime: f64) void { // MARK: update()
restart();
}

main.gui.windowlist.chest.checkPendingOpen();

physics.calculateVolumeProperties(.client, &Player.volumeProperties, Player.super.pos, Player.outerBoundingBox, physics.playerAirTerminalVelocity);
if (Player.isFlying.load(.monotonic)) {
Player.friction = .{.current = 20, .mobile = 20};
Expand Down
7 changes: 7 additions & 0 deletions src/gui/windows/chest.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ pub fn setInventory(selectedInventory: main.items.Inventory.ClientInventory) voi
openInventory = selectedInventory;
}

pub fn checkPendingOpen() void {
const inv = main.items.Inventory.client.takePendingChestOpen() orelse return;
setInventory(inv);
main.gui.openWindow("chest");
main.Window.setMouseGrabbed(false);
}

pub fn onOpen() void {
const list = VerticalList.init(.{padding, padding + 16}, 300, 0);

Expand Down
66 changes: 66 additions & 0 deletions src/network/protocols.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1105,3 +1105,69 @@ pub const EntityComponentUpdate = struct { // MARK: EntityComponentUpdate
conn.send(.secure, id, writer.data.items);
}
};

pub const chestOpen = struct {
pub const id: u8 = 16;

fn clientReceive(_: *Connection, reader: *utils.BinaryReader) !void {
const InventoryId = items.Inventory.InventoryId;
const success = try reader.readInt(u8);
const clientId = try reader.readEnum(InventoryId);
if (success == 0) {
items.Inventory.client.cancelChestOpen(clientId);
return;
}
const pos = try reader.readVec(Vec3i);
const serverId = try reader.readEnum(InventoryId);
items.Inventory.client.receiveChestOpenResponse(clientId, pos, serverId, reader);
}
fn serverReceive(conn: *Connection, reader: *utils.BinaryReader) !void {
const user = conn.user.?;
user.receiveChestOpenRequest(reader.remaining);
}

pub fn sendRequest(conn: *Connection, clientId: items.Inventory.InventoryId, pos: Vec3i) void {
std.debug.assert(conn.user == null);
var writer = utils.BinaryWriter.initCapacity(main.stackAllocator, 16);
defer writer.deinit();
writer.writeEnum(items.Inventory.InventoryId, clientId);
writer.writeVec(Vec3i, pos);
conn.send(.secure, id, writer.data.items);
}

pub fn process(user: *main.server.User, reader: *utils.BinaryReader) void {
const InventoryId = items.Inventory.InventoryId;
const clientId = reader.readEnum(InventoryId) catch return;
const pos = reader.readVec(Vec3i) catch return;
main.items.Inventory.server.createInventory(user, clientId, main.block_entity.BlockEntityTypes.@"cubyz:chest".inventorySize, .{.blockInventory = pos}) catch {
sendFailure(user.conn, clientId);
return;
};
const inv = main.items.Inventory.server.getInventory(user, clientId) orelse {
sendFailure(user.conn, clientId);
return;
};
sendResponse(user.conn, clientId, pos, inv);
}

fn sendResponse(conn: *Connection, clientId: items.Inventory.InventoryId, pos: Vec3i, inv: items.Inventory) void {
std.debug.assert(conn.isServerSide());
var writer = utils.BinaryWriter.initCapacity(main.stackAllocator, 32);
defer writer.deinit();
writer.writeInt(u8, 1);
writer.writeEnum(items.Inventory.InventoryId, clientId);
writer.writeVec(Vec3i, pos);
writer.writeEnum(items.Inventory.InventoryId, inv.id);
inv.toBytes(&writer);
conn.send(.secure, id, writer.data.items);
}

fn sendFailure(conn: *Connection, clientId: items.Inventory.InventoryId) void {
std.debug.assert(conn.isServerSide());
var writer = utils.BinaryWriter.initCapacity(main.stackAllocator, 8);
defer writer.deinit();
writer.writeInt(u8, 0);
writer.writeEnum(items.Inventory.InventoryId, clientId);
conn.send(.secure, id, writer.data.items);
}
};
20 changes: 20 additions & 0 deletions src/server/server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ pub const User = struct { // MARK: User
mutex: main.utils.Mutex = .{},

inventoryCommands: main.List([]const u8) = .empty,
chestOpenRequests: main.List([]const u8) = .empty,

pub const State = enum { awaitingKeyVerification, connectedVerified, awaitingReloadVerified };

Expand Down Expand Up @@ -229,6 +230,10 @@ pub const User = struct { // MARK: User
main.globalAllocator.free(commandData);
}
self.inventoryCommands.deinit(main.globalAllocator);
for (self.chestOpenRequests.items) |requestData| {
main.globalAllocator.free(requestData);
}
self.chestOpenRequests.deinit(main.globalAllocator);

self.jobQueue.deinit();
}
Expand Down Expand Up @@ -496,6 +501,9 @@ pub const User = struct { // MARK: User
const commands = self.inventoryCommands;
defer commands.deinit(main.globalAllocator);
self.inventoryCommands = .empty;
const chestOpenRequests = self.chestOpenRequests;
defer chestOpenRequests.deinit(main.globalAllocator);
self.chestOpenRequests = .empty;
self.mutex.unlock();

for (commands.items) |commandData| {
Expand All @@ -512,6 +520,12 @@ pub const User = struct { // MARK: User
};
}

for (chestOpenRequests.items) |requestData| {
defer main.globalAllocator.free(requestData);
var reader: BinaryReader = .init(requestData);
main.network.protocols.chestOpen.process(self, &reader);
}

self.mutex.lock();
defer self.mutex.unlock();
var time = @as(i16, @truncate(main.timestamp().toMilliseconds())) -% main.settings.entityLookback;
Expand All @@ -536,6 +550,12 @@ pub const User = struct { // MARK: User
self.inventoryCommands.append(main.globalAllocator, main.globalAllocator.dupe(u8, commandData));
}

pub fn receiveChestOpenRequest(self: *User, requestData: []const u8) void {
self.mutex.lock();
defer self.mutex.unlock();
self.chestOpenRequests.append(main.globalAllocator, main.globalAllocator.dupe(u8, requestData));
}

pub fn receiveData(self: *User, reader: *BinaryReader) !void {
self.mutex.lock();
defer self.mutex.unlock();
Expand Down
Loading