Add some rcon hooks to server

This commit is contained in:
ChillerDragon 2024-01-20 22:21:59 +08:00
parent c9cbbb7c0a
commit b49116e190
2 changed files with 60 additions and 4 deletions

View file

@ -88,7 +88,7 @@ class GameServer
context = Context.new(say, chunk:) context = Context.new(say, chunk:)
return if call_hook(:chat, context, msg).nil? return if call_hook(:chat, context, msg).nil?
puts msg.to_s puts msg
end end
def on_enter_game(_chunk, packet) def on_enter_game(_chunk, packet)
@ -108,8 +108,26 @@ class GameServer
def on_rcon_cmd(chunk, _packet) def on_rcon_cmd(chunk, _packet)
u = Unpacker.new(chunk.data[1..]) u = Unpacker.new(chunk.data[1..])
cmd = u.get_string command = u.get_string
puts "got rcon_cmd=#{cmd}" return if call_hook(:rcon_cmd, Context.new(nil, chunk:, packet:, command:)).nil?
return unless packet.client.authed?
puts "[server] ClientID=#{packet.client.player.id} rcon='#{command}'"
if command == 'shutdown'
@server.shutdown!
else
puts "[console] No such command: #{command}:"
end
end
def on_rcon_auth(chunk, packet)
u = Unpacker.new(chunk.data[1..])
password = u.get_string
return if call_hook(:rcon_auth, Context.new(nil, chunk:, packet:, password:)).nil?
# TODO: we accept any password lol
puts "[server] ClientID=#{packet.client.player.id} addr=#{packet.client.addr} authed (admin)"
packet.client.authed = true
end end
def on_input(chunk, packet) def on_input(chunk, packet)
@ -126,6 +144,12 @@ class GameServer
puts "'#{client.player.name}' left the game#{reason}" puts "'#{client.player.name}' left the game#{reason}"
end end
def on_shutdown
return if call_hook(:shutdown, Context.new(nil)).nil?
puts '[gameserver] shutting down ...'
end
def on_tick def on_tick
now = Time.now now = Time.now
timeout_ids = [] timeout_ids = []

View file

@ -16,6 +16,7 @@ require_relative 'models/token'
class Client class Client
attr_accessor :id, :addr, :vital_sent, :last_recv_time, :token, :player, :in_game attr_accessor :id, :addr, :vital_sent, :last_recv_time, :token, :player, :in_game
attr_accessor :authed
attr_reader :ack attr_reader :ack
def initialize(attr = {}) def initialize(attr = {})
@ -33,10 +34,15 @@ class Client
clan: '', clan: '',
country: -1 country: -1
) )
@authed = false
@token = attr[:token] @token = attr[:token]
SecurityToken.validate(@token) SecurityToken.validate(@token)
end end
def authed?
@authed
end
def in_game? def in_game?
@in_game @in_game
end end
@ -70,17 +76,39 @@ class TeeworldsServer
@current_game_tick = 0 @current_game_tick = 0
@last_snap_time = Time.now @last_snap_time = Time.now
@hooks = { @hooks = {
chat: [] chat: [],
rcon_auth: [],
rcon_cmd: [],
shutdown: []
} }
@thread_running = false @thread_running = false
@is_shutting_down = false
end
def shutdown!
@is_shutting_down = true
end end
def on_chat(&block) def on_chat(&block)
@hooks[:chat].push(block) @hooks[:chat].push(block)
end end
def on_rcon_auth(&block)
@hooks[:rcon_auth].push(block)
end
def on_rcon_cmd(&block)
@hooks[:rcon_cmd].push(block)
end
def on_shutdown(&block)
@hooks[:shutdown].push(block)
end
def main_loop def main_loop
loop do loop do
break if @is_shutting_down
tick tick
# TODO: proper tick speed sleep # TODO: proper tick speed sleep
# replace by blocking network read # replace by blocking network read
@ -123,6 +151,8 @@ class TeeworldsServer
else else
main_loop main_loop
end end
@game_server.on_shutdown
end end
def on_message(chunk, packet) def on_message(chunk, packet)
@ -154,6 +184,8 @@ class TeeworldsServer
@game_server.on_input(chunk, packet) @game_server.on_input(chunk, packet)
when NETMSG_RCON_CMD when NETMSG_RCON_CMD
@game_server.on_rcon_cmd(chunk, packet) @game_server.on_rcon_cmd(chunk, packet)
when NETMSG_RCON_AUTH
@game_server.on_rcon_auth(chunk, packet)
else else
puts "Unsupported system msg: #{chunk.msg}" puts "Unsupported system msg: #{chunk.msg}"
exit(1) exit(1)