Skip to content

Commit 7c92c0a

Browse files
use kick inside manage player window (#2798)
Closes #2724 Changes: - Rename manage players window to just players window - On client only instances the players window uses the kick command - Put the players window directly into the pause window instead of having it inside the invite window - Show the manage player window to client only instances One difference between the windows is still that the player opening the window is not shown for the client-side only version, while for the client-server version the player is in the list. I would be ok with both versions that's why I take the question to the reviewers. --------- Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>
1 parent 3613616 commit 7c92c0a

6 files changed

Lines changed: 126 additions & 83 deletions

File tree

src/client/Entity.zig

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ rot: Vec3f = undefined,
3030

3131
id: u32,
3232
name: []const u8,
33-
playerIndex: usize, // TODO extract into own component #2760
33+
playerIndex: ?usize, // TODO extract into own component #2760
3434

3535
pub fn init(self: *@This(), zon: ZonElement, allocator: NeverFailingAllocator) void {
3636
self.* = @This(){
3737
.id = zon.get(u32, "id", std.math.maxInt(u32)),
3838
.width = zon.get(f64, "width", 1),
3939
.height = zon.get(f64, "height", 1),
4040
.name = allocator.dupe(u8, zon.get([]const u8, "name", "")),
41-
.playerIndex = zon.get(usize, "playerIndex", std.math.maxInt(usize)),
41+
.playerIndex = zon.get(?usize, "playerIndex", null),
4242
};
4343
self._interpolationPos = [_]f64{
4444
self.pos[0],
@@ -75,9 +75,14 @@ pub fn update(self: *@This(), time: i16, lastTime: i16) void {
7575
}
7676

7777
pub fn format(self: *const @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
78-
if (main.settings.showPlayerIndexWithName) {
79-
try writer.print("{s}@{d}", .{self.name, self.playerIndex});
78+
if (main.settings.showPlayerIndexWithName and self.playerIndex != null) {
79+
try self.formatWithPlayerIndex(writer);
8080
} else {
8181
try writer.print("{s}", .{self.name});
8282
}
8383
}
84+
85+
pub fn formatWithPlayerIndex(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
86+
std.debug.assert(self.playerIndex != null);
87+
try writer.print("{s}@{d}", .{self.name, self.playerIndex.?});
88+
}

src/gui/windows/_windowlist.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub const inventory = @import("inventory.zig");
2121
pub const inventory_crafting = @import("inventory_crafting.zig");
2222
pub const invite = @import("invite.zig");
2323
pub const main = @import("main.zig");
24-
pub const manage_players = @import("manage_players.zig");
24+
pub const players = @import("players.zig");
2525
pub const multiplayer = @import("multiplayer.zig");
2626
pub const notification = @import("notification.zig");
2727
pub const pause = @import("pause.zig");

src/gui/windows/invite.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ pub fn onOpen() void {
7474
ipAddressEntry.obfuscated = main.settings.streamerMode;
7575
list.add(ipAddressEntry);
7676
list.add(Button.initText(.{0, 0}, 100, "Invite", .init(invite)));
77-
list.add(Button.initText(.{0, 0}, 100, "Manage Players", gui.openWindowCallback("manage_players")));
7877
list.add(CheckBox.init(.{0, 0}, width, "Allow anyone to join (requires a publicly visible IP address+port which may need some configuration in your router)", main.server.connectionManager.allowNewConnections.load(.monotonic), &makePublic));
7978
list.finish(.center);
8079
window.rootComponent = list.toComponent();

src/gui/windows/manage_players.zig

Lines changed: 0 additions & 77 deletions
This file was deleted.

src/gui/windows/pause.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn reorderHudCallbackFunction() void {
2121
}
2222
pub fn onOpen() void {
2323
const list = VerticalList.init(.{padding, 16 + padding}, 300, 16);
24+
list.add(Button.initText(.{0, 0}, 128, "Players", gui.openWindowCallback("players")));
2425
if (main.server.world != null) {
2526
list.add(Button.initText(.{0, 0}, 128, "Invite Player", gui.openWindowCallback("invite")));
2627
}

src/gui/windows/players.zig

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
const std = @import("std");
2+
3+
const main = @import("main");
4+
const ConnectionManager = main.network.ConnectionManager;
5+
const settings = main.settings;
6+
const Vec2f = main.vec.Vec2f;
7+
8+
const gui = @import("../gui.zig");
9+
const GuiComponent = gui.GuiComponent;
10+
const GuiWindow = gui.GuiWindow;
11+
const Button = @import("../components/Button.zig");
12+
const Label = @import("../components/Label.zig");
13+
const TextInput = @import("../components/TextInput.zig");
14+
const VerticalList = @import("../components/VerticalList.zig");
15+
const HorizontalList = @import("../components/HorizontalList.zig");
16+
17+
pub var window = GuiWindow{
18+
.contentSize = Vec2f{128, 256},
19+
.closeIfMouseIsGrabbed = true,
20+
};
21+
22+
const padding: f32 = 8;
23+
var userList: []*main.server.User = &.{};
24+
var entityCount: u32 = 0;
25+
26+
fn kickbyConnection(conn: *main.network.Connection) void {
27+
conn.disconnect();
28+
}
29+
30+
fn kickByPlayerIndex(playerIndex: usize) void {
31+
const command = std.fmt.allocPrint(main.globalAllocator.allocator, "kick @{d}", .{playerIndex}) catch unreachable;
32+
main.sync.ClientSide.executeCommand(.{.chatCommand = .{.message = command}});
33+
}
34+
35+
pub fn onOpen() void {
36+
const list = VerticalList.init(.{padding, 16 + padding}, 300, 16);
37+
if (main.server.world == null) blk: {
38+
entityCount = main.client.entity_manager.entities.len;
39+
if (entityCount == 0) {
40+
list.add(Label.init(.{0, 0}, 200, "No other players", .left));
41+
break :blk;
42+
}
43+
44+
for (main.client.entity_manager.entities.items()) |ent| {
45+
if (ent.playerIndex == null) continue;
46+
const row = HorizontalList.init();
47+
48+
const string = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{std.fmt.alt(ent, .formatWithPlayerIndex)}) catch unreachable;
49+
defer main.stackAllocator.free(string);
50+
row.add(Label.init(.{0, 0}, 200, string, .left));
51+
row.add(Button.initText(.{0, 0}, 100, "Kick", .initWithInt(kickByPlayerIndex, ent.playerIndex.?)));
52+
list.add(row);
53+
}
54+
} else {
55+
main.server.connectionManager.mutex.lock();
56+
defer main.server.connectionManager.mutex.unlock();
57+
std.debug.assert(userList.len == 0);
58+
userList = main.globalAllocator.alloc(*main.server.User, main.server.connectionManager.connections.items.len);
59+
for (main.server.connectionManager.connections.items, 0..) |connection, i| {
60+
userList[i] = connection.user.?;
61+
userList[i].increaseRefCount();
62+
if (userList[i].id == main.game.Player.id and connection.isConnected()) continue;
63+
const row = HorizontalList.init();
64+
if (connection.handShakeState.load(.monotonic) == .complete) {
65+
const string = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{connection.user.?}) catch unreachable;
66+
defer main.stackAllocator.free(string);
67+
row.add(Label.init(.{0, 0}, 200, string, .left));
68+
row.add(Button.initText(.{0, 0}, 100, "Kick", .initWithPtr(kickbyConnection, connection)));
69+
} else {
70+
const ip = std.fmt.allocPrint(main.stackAllocator.allocator, "{f}", .{connection.remoteAddress}) catch unreachable;
71+
defer main.stackAllocator.free(ip);
72+
row.add(Label.init(.{0, 0}, 200, ip, .left));
73+
row.add(Button.initText(.{0, 0}, 100, "Cancel", .initWithPtr(kickbyConnection, connection)));
74+
}
75+
list.add(row);
76+
}
77+
if (userList.len == 1) {
78+
list.add(Label.init(.{0, 0}, 200, "No other players", .left));
79+
}
80+
}
81+
list.finish(.center);
82+
window.rootComponent = list.toComponent();
83+
window.contentSize = window.rootComponent.?.pos() + window.rootComponent.?.size() + @as(Vec2f, @splat(padding));
84+
gui.updateWindowPositions();
85+
}
86+
87+
pub fn onClose() void {
88+
if (main.server.world != null) {
89+
for (userList) |user| {
90+
user.decreaseRefCount();
91+
}
92+
main.globalAllocator.free(userList);
93+
userList = &.{};
94+
}
95+
if (window.rootComponent) |*comp| {
96+
comp.deinit();
97+
}
98+
}
99+
100+
pub fn update() void {
101+
if (main.server.world == null) {
102+
if (main.client.entity_manager.entities.len != entityCount) {
103+
onClose();
104+
onOpen();
105+
}
106+
} else {
107+
main.server.connectionManager.mutex.lock();
108+
const serverListLen = main.server.connectionManager.connections.items.len;
109+
main.server.connectionManager.mutex.unlock();
110+
if (userList.len != serverListLen) {
111+
onClose();
112+
onOpen();
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)