Add rcon support
This commit is contained in:
parent
2db8b7058d
commit
ffbc433b67
3
.github/workflows/integration.yml
vendored
3
.github/workflows/integration.yml
vendored
|
@ -29,3 +29,6 @@ jobs:
|
|||
- name: Test reconnect
|
||||
run: |
|
||||
./integration_test/run.sh reconnect
|
||||
- name: Test rcon
|
||||
run: |
|
||||
./integration_test/run.sh rcon
|
|
@ -20,5 +20,5 @@ Signal.trap('INT') do
|
|||
client.disconnect
|
||||
end
|
||||
|
||||
# connect and detach thread
|
||||
# connect and block main thread
|
||||
client.connect('localhost', 8303, detach: false)
|
||||
|
|
18
examples/07_rcon.rb
Executable file
18
examples/07_rcon.rb
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../lib/teeworlds-client'
|
||||
|
||||
client = TeeworldsClient.new
|
||||
|
||||
client.on_connected do |_|
|
||||
client.rcon_auth(password: '123')
|
||||
client.rcon('shutdown')
|
||||
end
|
||||
|
||||
client.on_rcon_line do |ctx|
|
||||
puts "[rcon] #{ctx.data[:line]}"
|
||||
end
|
||||
|
||||
# connect and block main thread
|
||||
client.connect('localhost', 8303, detach: false)
|
18
integration_test/rcon_shutdown.rb
Executable file
18
integration_test/rcon_shutdown.rb
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../lib/teeworlds-client'
|
||||
|
||||
client = TeeworldsClient.new
|
||||
|
||||
client.on_connected do |_|
|
||||
client.rcon_auth(password: 'rcon')
|
||||
client.rcon('shutdown')
|
||||
end
|
||||
|
||||
client.on_rcon_line do |ctx|
|
||||
puts "[rcon] #{ctx.data[:line]}"
|
||||
end
|
||||
|
||||
# connect and block main thread
|
||||
client.connect('localhost', 8377, detach: false)
|
|
@ -3,10 +3,12 @@
|
|||
cd "$(dirname "$0")" || exit 1
|
||||
|
||||
twbin=teeworlds_srv
|
||||
rubybin=send_chat_hello.rb
|
||||
srvcfg='sv_rcon_password rcon;sv_port 8377;killme'
|
||||
|
||||
function cleanup() {
|
||||
echo "[*] shutting down server ..."
|
||||
pkill -f "$twbin sv_port 8377;killme"
|
||||
pkill -f "$twbin $srvcfg"
|
||||
[[ "$_timout_pid" != "" ]] && kill "$_timout_pid" &> /dev/null
|
||||
}
|
||||
|
||||
|
@ -15,32 +17,47 @@ trap cleanup EXIT
|
|||
function timeout() {
|
||||
local seconds="$1"
|
||||
sleep "$seconds"
|
||||
pkill -f 'send_chat_hello.rb'
|
||||
pkill -f "$rubybin"
|
||||
echo "killing: $rubybin"
|
||||
echo "Error: timeouted"
|
||||
}
|
||||
|
||||
if [[ -x "$(command -v teeworlds_srv)" ]]
|
||||
then
|
||||
teeworlds_srv "sv_port 8377;killme" &> server.txt &
|
||||
teeworlds_srv "$srvcfg" &> server.txt &
|
||||
elif [[ -x "$(command -v teeworlds-server)" ]]
|
||||
then
|
||||
teeworlds-server "sv_port 8377;killme" &> server.txt &
|
||||
teeworlds-server "$srvcfg" &> server.txt &
|
||||
twbin='teeworlds-server'
|
||||
elif [[ -x "$(command -v teeworlds-srv)" ]]
|
||||
then
|
||||
teeworlds-srv "sv_port 8377;killme" &> server.txt &
|
||||
teeworlds-srv "$srvcfg" &> server.txt &
|
||||
twbin='teeworlds-srv'
|
||||
else
|
||||
echo "Error: please install a teeworlds_srv"
|
||||
exit 1
|
||||
fi
|
||||
timeout 3 killme &
|
||||
_timout_pid=$!
|
||||
|
||||
testname="${1:-chat}"
|
||||
|
||||
echo "[*] running test '$testname' ..."
|
||||
|
||||
if [ "$testname" == "chat" ]
|
||||
then
|
||||
rubybin=send_chat_hello.rb
|
||||
elif [ "$testname" == "reconnect" ]
|
||||
then
|
||||
rubybin=reconnect.rb
|
||||
elif [ "$testname" == "rcon" ]
|
||||
then
|
||||
rubybin=rcon_shutdown.rb
|
||||
else
|
||||
echo "Error: unkown test '$testname'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
timeout 3 killme &
|
||||
_timout_pid=$!
|
||||
|
||||
function fail() {
|
||||
local msg="$1"
|
||||
tail client.txt
|
||||
|
@ -51,7 +68,7 @@ function fail() {
|
|||
|
||||
if [ "$testname" == "chat" ]
|
||||
then
|
||||
ruby ./send_chat_hello.rb &> client.txt
|
||||
ruby "$rubybin" &> client.txt
|
||||
|
||||
if ! grep -q 'hello world' server.txt
|
||||
then
|
||||
|
@ -59,16 +76,24 @@ then
|
|||
fi
|
||||
elif [ "$testname" == "reconnect" ]
|
||||
then
|
||||
ruby ./reconnect.rb &> client.txt
|
||||
ruby "$rubybin" &> client.txt
|
||||
|
||||
if ! grep -q 'bar' server.txt
|
||||
then
|
||||
fail "Error: did not find 2nd chat message in server log"
|
||||
fi
|
||||
elif [ "$testname" == "rcon" ]
|
||||
then
|
||||
ruby "$rubybin" &> client.txt
|
||||
|
||||
if pgrep -f "$twbin $srvcfg"
|
||||
then
|
||||
fail "Error: server still running rcon shutdown failed"
|
||||
fi
|
||||
else
|
||||
echo "Error: unkown test '$testname'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[+] Test passed client sent chat message to server"
|
||||
echo "[+] Test passed"
|
||||
|
||||
|
|
|
@ -106,6 +106,15 @@ class GameClient
|
|||
@client.send_msg_startinfo
|
||||
end
|
||||
|
||||
def on_rcon_line(chunk)
|
||||
u = Unpacker.new(chunk.data[1..])
|
||||
context = Context.new(
|
||||
@client,
|
||||
line: u.get_string
|
||||
)
|
||||
@client.hooks[:rcon_line]&.call(context)
|
||||
end
|
||||
|
||||
def on_emoticon(chunk); end
|
||||
|
||||
def on_map_change(chunk)
|
||||
|
|
|
@ -73,6 +73,10 @@ class TeeworldsClient
|
|||
@hooks[:connected] = block
|
||||
end
|
||||
|
||||
def on_rcon_line(&block)
|
||||
@hooks[:rcon_line] = block
|
||||
end
|
||||
|
||||
def send_chat(str)
|
||||
@netbase.send_packet(
|
||||
NetChunk.create_vital_header({ vital: true }, 4 + str.length) +
|
||||
|
@ -170,6 +174,42 @@ class TeeworldsClient
|
|||
@netbase.send_packet(msg, 1)
|
||||
end
|
||||
|
||||
def rcon_auth(name, password = nil)
|
||||
if name.instance_of?(Hash)
|
||||
password = name[:password]
|
||||
name = name[:name]
|
||||
end
|
||||
if password.nil?
|
||||
raise "Error: password can not be empty\n" \
|
||||
" provide two strings: name, password\n" \
|
||||
" or a hash with the key :password\n" \
|
||||
"\n" \
|
||||
" rcon_auth('', '123')\n" \
|
||||
" rcon_auth(password: '123')\n"
|
||||
end
|
||||
data = []
|
||||
if name.nil? || name == ''
|
||||
data += Packer.pack_str(password)
|
||||
else # ddnet auth using name, password and some int?
|
||||
data += Packer.pack_str(name)
|
||||
data += Packer.pack_str(password)
|
||||
data += Packer.pack_int(1)
|
||||
end
|
||||
msg = NetChunk.create_vital_header({ vital: true }, data.size + 1) +
|
||||
[pack_msg_id(NETMSG_RCON_AUTH, system: true)] +
|
||||
data
|
||||
@netbase.send_packet(msg, 1)
|
||||
end
|
||||
|
||||
def rcon(command)
|
||||
data = []
|
||||
data += Packer.pack_str(command)
|
||||
msg = NetChunk.create_vital_header({ vital: true }, data.size + 1) +
|
||||
[pack_msg_id(NETMSG_RCON_CMD, system: true)] +
|
||||
data
|
||||
@netbase.send_packet(msg, 1)
|
||||
end
|
||||
|
||||
def send_msg_startinfo
|
||||
data = []
|
||||
|
||||
|
@ -289,6 +329,8 @@ class TeeworldsClient
|
|||
@game_client.on_connected
|
||||
when NETMSG_NULL
|
||||
# should we be in alert here?
|
||||
when NETMSG_RCON_LINE
|
||||
@game_client.on_rcon_line(chunk)
|
||||
else
|
||||
puts "Unsupported system msg: #{chunk.msg}"
|
||||
exit(1)
|
||||
|
|
Loading…
Reference in a new issue