diff --git a/lib/game_server.rb b/lib/game_server.rb index ba8d824..ab31bcd 100644 --- a/lib/game_server.rb +++ b/lib/game_server.rb @@ -106,7 +106,7 @@ def on_enter_game(_chunk, packet) puts "'#{packet.client.player.name}' joined the game" end - def on_rcon_cmd(chunk, _packet) + def on_rcon_cmd(chunk, packet) u = Unpacker.new(chunk.data[1..]) command = u.get_string return if call_hook(:rcon_cmd, Context.new(nil, chunk:, packet:, command:)).nil? @@ -114,7 +114,7 @@ def on_rcon_cmd(chunk, _packet) puts "[server] ClientID=#{packet.client.player.id} rcon='#{command}'" if command == 'shutdown' - @server.shutdown! + @server.shutdown!('Server shutdown') else puts "[console] No such command: #{command}:" end @@ -128,6 +128,7 @@ def on_rcon_auth(chunk, packet) # TODO: we accept any password lol puts "[server] ClientID=#{packet.client.player.id} addr=#{packet.client.addr} authed (admin)" packet.client.authed = true + @server.send_rcon_auth_on(packet.client) end def on_input(chunk, packet) @@ -147,6 +148,10 @@ def on_client_drop(client, reason = nil) def on_shutdown return if call_hook(:shutdown, Context.new(nil)).nil? + puts '[gameserver] disconnecting all clients ...' + @server.clients.each do |id, client| + @server.send_ctrl_close(client, @server.shutdown_reason) + end puts '[gameserver] shutting down ...' end diff --git a/lib/teeworlds_server.rb b/lib/teeworlds_server.rb index d2c1122..1bed3ff 100644 --- a/lib/teeworlds_server.rb +++ b/lib/teeworlds_server.rb @@ -65,7 +65,7 @@ def seq class TeeworldsServer attr_accessor :clients - attr_reader :hooks + attr_reader :hooks, :shutdown_reason def initialize(options = {}) @verbose = options[:verbose] || false @@ -83,10 +83,12 @@ def initialize(options = {}) } @thread_running = false @is_shutting_down = false + @shutdown_reason = '' end - def shutdown! + def shutdown!(reason) @is_shutting_down = true + @shutdown_reason = reason end def on_chat(&block) @@ -260,6 +262,12 @@ def send_map(client) @netbase.send_packet(msg, chunks: 1, client:) end + def send_rcon_auth_on(client) + msg = NetChunk.create_header(vital: true, size: 1, client:) + + [pack_msg_id(NETMSG_RCON_AUTH_ON, system: true)] + @netbase.send_packet(msg, chunks: 1, client:) + end + def send_ready(client) msg = NetChunk.create_header(vital: true, size: 1, client:) + [pack_msg_id(NETMSG_CON_READY, system: true)]