diff --git a/src/network.zig b/src/network.zig index 54c2309ba5..8355cd4003 100644 --- a/src/network.zig +++ b/src/network.zig @@ -1599,11 +1599,13 @@ pub const Connection = struct { // MARK: Connection pub fn receive(self: *Connection, data: []const u8) void { self.tryReceive(data) catch |err| { - std.log.err("Got error while processing received network data: {s}", .{@errorName(err)}); - if (@errorReturnTrace()) |trace| { - std.log.info("{f}", .{std.debug.FormatStackTrace{.stack_trace = trace.*, .tty_config = .no_color}}); + if (err != error.Denied) { + std.log.err("Got error while processing received network data: {s}", .{@errorName(err)}); + if (@errorReturnTrace()) |trace| { + std.log.info("{f}", .{std.debug.FormatStackTrace{.stack_trace = trace.*, .tty_config = .no_color}}); + } + std.log.debug("Packet data: {any}", .{data}); } - std.log.debug("Packet data: {any}", .{data}); self.disconnect(); }; } diff --git a/src/network/protocols.zig b/src/network/protocols.zig index 304851ae6a..9a90202840 100644 --- a/src/network/protocols.zig +++ b/src/network/protocols.zig @@ -58,7 +58,9 @@ pub fn onReceive(conn: *Connection, protocolIndex: u8, data: []const u8) !void { } else { var reader = utils.BinaryReader.init(data); protocolReceive(conn, &reader) catch |err| { - std.log.debug("Got error while executing protocol {} with data {any}", .{protocolIndex, data}); + if (err != error.Denied) { + std.log.debug("Got error while executing protocol {} with data {any}", .{protocolIndex, data}); + } return err; }; } @@ -189,6 +191,8 @@ pub const handShake = struct { // MARK: handShake const keys = zon.getChild("keys"); try conn.user.?.identifyFromKeysAndName(name, keys); + conn.user.?.initPlayer(); + if (!main.server.world.?.playerMayJoin(conn.user.?)) return error.Denied; var writer: utils.BinaryWriter = .init(main.stackAllocator); defer writer.deinit(); diff --git a/src/server/server.zig b/src/server/server.zig index ef365885ad..761e21c294 100644 --- a/src/server/server.zig +++ b/src/server/server.zig @@ -116,6 +116,7 @@ pub const User = struct { // MARK: User gamemode: std.atomic.Value(main.game.Gamemode) = .init(.creative), spawnPos: Vec3d = .{0, 0, 0}, worldEditData: WorldEditData = undefined, + mayJoin: ServerWorld.mayJoinState = undefined, playerIndex: usize = undefined, @@ -720,7 +721,6 @@ pub fn connect(user: *User) void { } pub fn connectInternal(user: *User) void { - user.initPlayer(); main.network.protocols.handShake.sendServerPlayerData(user.conn); // TODO: addEntity(player); const userList = getUserListAndIncreaseRefCount(main.stackAllocator); diff --git a/src/server/world.zig b/src/server/world.zig index 03cccde000..a06ab0b71e 100644 --- a/src/server/world.zig +++ b/src/server/world.zig @@ -449,6 +449,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld playerDatabase: std.StringHashMapUnmanaged(usize) = .{}, nextPlayerIndex: std.atomic.Value(usize) = .init(0), + whitelisted: bool = undefined, biomeChecksum: i64 = 0, @@ -497,6 +498,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld errdefer main.assets.unloadAssets(); const worldData = try dir.readToZon(arena, "world.zig.zon"); + self.whitelisted = worldData.get(bool, "whitelisted", false); try self.loadWorldConfig(arena, dir, worldData); try self.loadPlayerLoginInfo(dir); @@ -635,6 +637,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld worldData.put("name", self.name); worldData.put("lastUsedTime", (try std.Io.Clock.Timestamp.now(main.io, .real)).raw.toMilliseconds()); worldData.put("tickSpeed", self.tickSpeed.load(.monotonic)); + worldData.put("whitelisted", self.whitelisted); try files.cubyzDir().writeZon(path, worldData); } @@ -959,6 +962,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld user.handInventory = loadPlayerInventory(1, playerData.get([]const u8, "hand", ""), .{.hand = user.id}, path); user.spawnPos = playerData.get(Vec3d, "playerSpawnPos", @as(Vec3d, @floatFromInt(self.spawn))); + user.mayJoin = playerData.get(mayJoinState, "mayJoin", .default); } fn loadPlayerInventory(size: usize, base64EncodedData: []const u8, source: main.items.Inventory.Source, playerDataFilePath: []const u8) main.items.Inventory.InventoryId { @@ -1021,6 +1025,7 @@ pub const ServerWorld = struct { // MARK: ServerWorld } playerZon.put("playerSpawnPos", user.spawnPos); + playerZon.put("mayJoin", user.mayJoin); const playerPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/players", .{self.path}) catch unreachable; defer main.stackAllocator.free(playerPath); @@ -1085,6 +1090,19 @@ pub const ServerWorld = struct { // MARK: ServerWorld } } + pub const mayJoinState = enum { default, whitelisted, blacklisted }; + + pub fn playerMayJoin(self: *ServerWorld, user: *main.server.User) bool { + if (user.isLocal) return true; + + const mayJoin = user.mayJoin; + return switch (mayJoin) { + .default => !self.whitelisted, + .whitelisted => true, + .blacklisted => false, + }; + } + pub fn update(self: *ServerWorld) void { // MARK: update() const newTime = main.timestamp(); var deltaTime = @as(f32, @floatFromInt(self.lastUpdateTime.durationTo(newTime).toNanoseconds()))/1.0e9;