Rcon with LuaSocket


(3Necromancer) #1

Hey,
I have zero knowledge about sending packets over the net so i need a little help.
Im trying to use Lua+LuaSocket to send commands to the ET server rcon without any success.

i’ve tried this


local host = "localhost"
local address = '127.0.0.1' -- ip adress
local port = 27960 -- port number
local password = "life" -- rcon password

-- load namespace
socket = require("socket")

-- create a new UDP object
udp = assert(socket.udp())
print (udp)

-- Associate this object with our server
udp:setpeername(address, port)
print (udp)

local s,err = (udp:send("\xFF\xFFrconpassword\x00".. password .. "\x00\x00"))
print (udp)
print(s)
print(err)
print (assert(udp:receive()))
print (udp)

udp:close() -- disconnect and free the socket


i’m not sure, maybe it needs to be coded somehow?
like here

<html> 
<body> 
<form action="rcon.php" method="post"> 
Command:<input type="text" name="command" /> 
<input type="submit" value="send command" /> 
</form> 
<?php 
function etrcon() { 
 $ip   = ""; //enter server ip between quotes 
 $port   = ""; //enter server port between quotes 
 $pass   = ""; //enter rcon password between quotes 
 $command  = $_POST['command']; 
 $fp    = fsockopen("udp://$ip",$port,$errno,$errstr, 2); 
// We don't need the preceding / since it's going straight over the network.. 
 $passinput = "\xFF\xFFrconpassword\x00". $pass . "\x00\x00"; //Input rcon pass In et console: rconpassword <password> 
 $cmdinput = "\xFF\xFFrcon\x00". $command . "\x00\x00"; //Input command: rcon <command> 
 fwrite($fp,$passinput/*second parameter is (optional) length*/); 
fwrite($fp, $cmdinput); 
} 
/* ?????? 
if(!$command) { 
 print("$errstr"); 
} else { 
*/ 
if(!empty($_POST['command'])) 
 etrcon(); 
// } ??? 
?> 
</html>

or
http://forums.warchest.com/showthread.php/32770-Little-C-RCON-Tool

all i need is for the server rcon to get my strings and if its possible to also catch the server’s replay that would be great.


(ETJump-Zero) #2

The protocol requires 4*"\xFF" in the beginning of every message. You shouldn’t be adding any \0’s in the middle of the message either.

I don’t have any experience with LUA so I’ll give you an example in python. Tested and it works just fine even with multiple arguments.

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(3.0)
sock.sendto("\xFF\xFF\xFF\xFFgetstatus", ("127.0.0.1", 27960))
# or sock.sendto("\xFF\xFF\xFF\xFFrcon password command", ("127.0.0.1", 27960))
response = sock.recvfrom(8196)[0]
print response[4:]

PS. Please, do NOT post any cheating sites on official forums…


(3Necromancer) #3

didn’t really noticed what site it was from, it came up when i googled and didn’t have anything cheat-related on that page.

The protocol require

is there documentation of the protocol somewhere?

i’ve tried your way with no success. the server console doesn’t indicate it received anything.
is there a way to check if the packets even being sent (and not blocked by somekind of firewall)?


(ETJump-Zero) #4

[QUOTE=3Necromancer;473144]didn’t really noticed what site it was from, it came up when i googled and didn’t have anything cheat-related on that page.

is there documentation of the protocol somewhere?

i’ve tried your way with no success. the server console doesn’t indicate it received anything.
is there a way to check if the packets even being sent (and not blocked by somekind of firewall)?[/QUOTE]
The URL has “aimbots” in it. :rolleyes: The author of the topic also mentioned he never tested it. Here is some information about the protocol. Not sure if it’s really useful in this case. You could download ET Engine source and look at it. Use Wireshark (with Quake 3 protocol filter) to see if you’re actually sending anything. Could you post what you tried, maybe I (or someone else) can spot what’s wrong.


(acQu) #5

The server usually prints something like “bad rcon from” to its local console. If the message arrived successful and is valid, the server will send to you back a \xFF\xFF\xFF\xFFprint <msg> (mostly).

For example if i want to change the map and my pw is “derp”, i send this:

\xFF\xFF\xFF\xFFrcon derp map oasis

(note: no \x00 in the message, maybe that is your problem currently).

Otherwise wireshark is a good idea :slight_smile:


(acQu) #6

The server usually prints something like “bad rcon from” to its local console. If the message arrived successful and is valid, the server will send to you back a \xFF\xFF\xFF\xFFprint <msg> (mostly). If the server does not know the message (misconstructed rcon message for example), it probably just silently drops the packet.

Otherwise wireshark is a good idea :slight_smile:


(3Necromancer) #7

thanks a lot for the help , theres little information on the subject.
unfortunately im out of town until sunday. i’ll be sure to test it with wireshark and post my connection script the moment im back.


(3Necromancer) #8

tried wireshark but it didn’t register anything but the servers attempts to connect to the master servers.
acQu, if i had any feedback from the server (bad rcon) or anything else i could work on it. but i got nothing and have no idea what to do.

As i said wireshark did not detect any communications when i ran the script. i disabled the windows firewall and my anti-virus (just to be on the safe side) but it didn’t help. not sure if windows has some other blocking mechanisms.
update: since the server and my script are both running locally on the same machine, maybe it never goes to the ‘internet’ and doesn’t pass through wireshark*

Lua forums are also unavailable for like a month now. i posted there about Lua and LuaSocket before it went down and i guess i shouldn’t hold my breath until they put it up again.
I tried contacting some ET mods devs but some i couldn’t find a way to contact, and others haven’t replied yet, i guess they don’t visit these sites anymore.

To whoever wants to give it a second look, heres what i did:
downloaded lua for windows (contains luaSocket and every other possible addon)
then i tested luaSocket by running listener.lua and talker.lua (its in the examples folder of the luaForWindows)

dolua('examples/luasocket/listener.lua')

and same for talker.lua and saw that the listener window would echo whatever i typed in talker.lua window.
so the TCP protocol worked.
then i did the same with echoclnt.lua and echosrvr.lua which is also located in the examples folder and test the UDP connection.

i then fired up my etpub server console, and tried to run my lua script to get some input from the etconsole, but nothing.
here’s my lua code

host = "localhost"
address = '10.100.x.x' -- ip adress
port = 27960 -- port number
password = "pass" -- rcon password

-- load namespace
socket = require("socket")

-- convert host name to ip address
--address = socket.dns.toip(host)


-- create a new UDP object
rcon = assert(socket.udp())
assert(rcon:setpeername(address, port))

print("Using remote host '" ..address.. "' and port " .. port .. "...")

--datagram = string.format("\255\255rcon\0%s\0%s\0", "pass", "") 
datagram = string.format("\xFF\xFF\xFF\xFFrcon %s %s", "pass", "") 
--datagram = "\xFF\xFF\xFF\xFFgetstatus"
assert(rcon:send(datagram))



udp = assert(socket.udp())
assert(udp:setsockname(host, port))
assert(udp:settimeout(1))
ip, port = udp:getsockname()
assert(ip, port)
print("Waiting packets on " .. ip .. ":" .. port .. "...")
for i=1,5,1 do
	dgram, ip, port = udp:receivefrom()
	if dgram then
		print("Echoing '" .. dgram .. "' to " .. ip .. ":" .. port)
		--udp:sendto(dgram, ip, port)
	else
        print(ip)
    end
end


rcon:close() -- disconnect and free the socket
udp:close()

removed the 2 last digits of the IP address. tried both with the actual IP address and ‘localhost’ = 127.0.01

*i was running wireshark the entire time, and it didn’t record any of the echoclnt.lua/echosrvr.lua packets either
so i think it doesn’t record packets that are sent locally from the same machine to the same machine.
maybe the OS is handling it locally without actually passing it to the network adapter and intercepted by wireshark?

i really want it to work, but im out of ideas.


(acQu) #9

Maybe the port is not right. I remember i once had to turn off my router NAT settings, because the port actually was not 29760, but something different. The server console said 27960 though, but as i checked my server ip on the masterlist, it was listed with a different port. Only a guess though. No clue how to do it with Lua sockets. Only C. The actual message (\xFF\xFF\xFF\xFFrcon %s %s") looks to be the right one though. Maybe someone else knows better.


(Mateos) #10

27960 commonly :slight_smile:


(ETJump-Zero) #11

Are you sure ETPub lua implementation supports sockets? You really should read the console output for possible errors.

Lua API: G_LuaStartVM error running lua script: [string "udp.lua"]:7: module 'socket' not found:

(ETJump-Zero) #12

Are you sure ETPub Lua supports sockets?

Clean ETPub installation with LUA support.

Lua API: Loading udp.lua
Lua API: G_LuaStartVM error running lua script: [string "udp.lua"]:7: module 'socket' not found:

Like I said I’m not really experienced with Lua and the documentation was terrible so I could’ve done something wrong. Looks like it’s not supported, though.


(ETJump-Zero) #13

Did you check if ETPub actually loaded your .lua? Or if there are any error messages. If you suspect Wireshark doesn’t register any of the local packets, just send your packets to some public server.


(3Necromancer) #14

nothing to do with etpub’s embedded lua.
im trying to write a 3rd party rcon tool that happens to be in Lua. like HLSW or ETadmin_mod etc. running it using the Lua interpreter, not ETpub. it just happens to be that my local server is etpub, but it doesn’t matter as i believe all mods use the same rcon interface.


(ETJump-Zero) #15

[QUOTE=3Necromancer;474942]nothing to do with etpub’s embedded lua.
im trying to write a 3rd party rcon tool that happens to be in Lua. like HLSW or ETadmin_mod etc. running it using the Lua interpreter, not ETpub. it just happens to be that my local server is etpub, but it doesn’t matter as i believe all mods use the same rcon interface.[/QUOTE]

Why Lua? Anyway, I just understood you were trying to send it from ingame. Yes the interface is the same.

Try to send it to an external server and see if a packet leaves your computer. If it doesn’t there’s something wrong with the sending part of the script. If it does but you don’t get a reply, make sure the format is correct. I managed to send UTF-8 or similarily encoded messages once, which were obviously incorrect and server didn’t know how to reply.

EDIT: I don’t have time to test it now but try binding the socket first, it could be that you get a reply before you’re actually ready to receive any packets -> OS just throws them away.


(3Necromancer) #16
  1. its simple language
  2. its easy to add LuaSocket and LuaSqlite3 to it to get network and database capabilities for this (rcon + gather statistics from the server into a database)
  3. it can compile and run source files at run time with the dolua(filename) function, meaning other people don’t need to download the entire source and all the dependencies and get it to compile to add/change something. simply drop in a file with your lua chunk and make the program execute it with dolua().

As i said im not running through ETpub’s embedded lua, i don’t even know if that one even has LuaSocket and LuaSqlite3 libraries added to it.
Im using the lua Interpreter from LuaForWindows to execute my lua code.

i just upgraded my system (new windows) so i need a few hours to get everything back into working order and then i’ll test network/wireshark with two different computers.


(3Necromancer) #17

sorry it took so long to report.
i ran a server on one machine, and client on another - wireshark picked up the packets.
so i then closed the client and tried running my script with the server’s address.
.10 - server
.2 - client/lua script
wireshark picked up the packets and recognized them as quake3 protocol. this is what wireshark got:


No.     Time            Source          Destination     Protocol  Length   Info
6855	494.196574000	10.100.102.2	10.100.102.10	QUAKE3	64	Game Client to Server
6856	494.199828000	10.100.102.10	10.100.102.2	QUAKE3	60	Connectionless Unknown

so it seems it sends something to the server, and the server replies. however nothing is printed on the server console (rcon from / bad rcon pass) and my script also doesn’t catch any replay from the server.
is the length fine?
anyone knows what it means?


(ETJump-Zero) #18

[QUOTE=3Necromancer;475473]sorry it took so long to report.
i ran a server on one machine, and client on another - wireshark picked up the packets.
so i then closed the client and tried running my script with the server’s address.
.10 - server
.2 - client/lua script
wireshark picked up the packets and recognized them as quake3 protocol. this is what wireshark got:


No.     Time            Source          Destination     Protocol  Length   Info
6855	494.196574000	10.100.102.2	10.100.102.10	QUAKE3	64	Game Client to Server
6856	494.199828000	10.100.102.10	10.100.102.2	QUAKE3	60	Connectionless Unknown

so it seems it sends something to the server, and the server replies. however nothing is printed on the server console (rcon from / bad rcon pass) and my script also doesn’t catch any replay from the server.
is the length fine?
anyone knows what it means?[/QUOTE]
Check the actual payload of both packets and paste them here. There’s clearly a problem with handling the packet on client side. Did you try binding the socket before sending packets?


(3Necromancer) #19

yes, the socket is bound to the IP and port. you can see it in the code i posted.


assert(udp:setsockname(host, port))

i then use send(text) instead of sendto(ip,port,text) function.
as i said im pretty noob at networking, where/how do i find that payload?

also - will the server stream everything once the connection is established?
or just responses to the commands you sent it?
how to make it stream everything? (like when you connect to the server using rcon tool you see everything that is printed in the console).


(ETJump-Zero) #20

[QUOTE=3Necromancer;475645]yes, the socket is bound to the IP and port. you can see it in the code i posted.


assert(udp:setsockname(host, port))

i then use send(text) instead of sendto(ip,port,text) function.
as i said im pretty noob at networking, where/how do i find that payload?

also - will the server stream everything once the connection is established?
or just responses to the commands you sent it?
how to make it stream everything? (like when you connect to the server using rcon tool you see everything that is printed in the console).[/QUOTE]

UDP is a “connectionless connection”. It means that it doesn’t actually open a “pipe” and throw packets in. UDP sends the packet and forgets about it. It will not make sure the packet is received or if the data is corrupted. TCP is a proper connection that requires a 3-way handshake in order to open up the connection. It makes sure the data is actually received and tries to make sure it is not corrupted. You can think of UDP as a letter and TCP as a phone line. All you need for a letter is the address. You send it and you will not know if it ever gets there. When you dial a phone, phone companies need to set up an actual connection from your phone to the other person’s phone. When the connection is set up you can talk back and forth and you will indeed know if the other person received what you sent.

Server usually responds with everything that a certain command caused to print. This was you will get the response of each command just by waiting for a reply from server. If you want to stream the console output you will actually have to modify the mod you’re using to allow a client to open a TCP-connection to the server and then write into the connection. Another possibility is to make another server-side application that reads W:ET logs and writes them to any open connections. That’s how ET Admin Mod’s control center works.

Payload of each packet can be found on Wireshark by clicking the packet. The highlighted text is the [payload](http://i.imgur.com/H0MraRB.png).

EDIT: Anyway, I would stick to a more popular programming language like Python for such things, especially if you’re not really familiar with networking in general. There are a lot of great tutorials for Python and the basic libraries such as socket should be available instantly.