Forum

> > CS2D > General > CS2D Manager
Forums overviewCS2D overviewGeneral overviewLog in to reply

English CS2D Manager

9 replies
To the start Previous 1 Next To the start

old CS2D Manager

Manny
User Off Offline

Quote
Hello, I'd like to make CS2D Manager because "Server RCon/Viewer Tool by kog (Alpha Version, for dedicated servers)" is not enough for me and nothing better exists, so i decided to make it on my own.

I've got problem. Does anybody know what is format for sending command to server? For example if i wanna kick somebody?

I saw this function in PHP:
1
2
3
4
5
6
7
function send_command($ip,$port,$rcon,$command) {
	$fp = @fsockopen("udp://".$ip, $port, $errno, $errstr);
	if ($fp){
		$request = chr(1).chr(0).chr(242).chr(strlen($rcon)).$rcon.pack("S",strlen($command)).$command;
		fwrite($fp, $request);
	}
}

I'm trying to make application in Lazarus (FreePascal) but all i need is to know format of packet to send... i have tried this:
1
myFormat := chr(1)+chr(0)+chr(242)+chr(1) + chr(Length(rcon)) + rcon + chr(Length(cmd)) + cmd;
... but CS2D dedicated server returned:
1
2
WARNING: Failed RCon attempt from 127.0.0.1:53130 (cmd: )
NET: Received unknown or damaged msg (118, 127.0.0.1:53130)
edited 2×, last 21.07.11 12:09:05 pm

old Re: CS2D Manager

Lee
Moderator Off Offline

Quote
cmd can theoretically be over 0xff bytes long, so its length header is a short not a byte.

1
chr(Length(cmd))

If pascal has pointers and static casting, then it's possible to use this idiom: (Note: C code)

1
2
3
typedef unsigned char byte;
#define short(i) ((byte*)&(i))[0], ((byte*)&(i))[1]
char* packed = {short(strlen(cmd))};

Which offers the nice property that the endianness of the machine is preserved.

The more verbose solution is to use an AND mask for lo and a shift of one byte ( 8 ) for hi. C idiom:

1
2
3
4
typedef unsigned char byte;
short c; // assume 16 bits
byte byte1 = c & 0xff; //We mask all but 0b11111111
byte byte2 = (c >> 8) & 0xff; // shift by 8 then mask to hide overflow from certain machines

Now since cs2d standardized all of its data to be packed in small endian, our task becomes much simpler. We just concatenate the two as such:

1
2
3
short c;
...
byte* packed = {(c >> 8) & 0xff, c & 0xff};

Note that byte2 comes before byte1.

old Re: CS2D Manager

Manny
User Off Offline

Quote
Excuse me if I'm wrong, so problem is that "cmd" is not in binary format?

old Re: CS2D Manager

DannyDeth
User Off Offline

Quote
I doubt that would be the problem. What Lee is trying to point out ( at least what I think he is saying ) is that the length of cmd is supposed to be 16-bits wide instead of 8-bits, so using chr(length(cmd)) would be too short ( 1 byte wide snstead of 2 ).

old Re: CS2D Manager

Lee
Moderator Off Offline

Quote
Quote
Excuse me if I'm wrong, so problem is that "cmd" is not in binary format?


Danny's right, whenever CS2D sends out raw text, it must also be able to tell how many bytes of that text must be read in. So for the cmd parameter, you can have a string of text well over 256 characters long. Since a byte can hold an integer only up to 255 (0-255), we need two bytes to denote the length of the text.

Pascal's function chr only returns the most significant byte. This means that chr(1024) = chr(1024%256) = chr(0) = "\x00" , not "\x00" "\x04" as it should be.

And even if the number is less than 256, CS2D expects a short, which means two bytes, so "a" would require a header of "\x01" "\x00"

old Re: CS2D Manager

Manny
User Off Offline

Quote
What's the solution of this? I though it would be simple like in PHP but it seems it's more complex. Now, i know where is the problem but i don't have skills for this. I don't want to stuck at the beginning.

old Re: CS2D Manager

Lee
Moderator Off Offline

Quote
As per my previous post, the solution is to simply do the following:

byte byte1 = c & 0xff; //We mask all but 0b11111111
byte byte2 = (c >> & 0xff; // shift by 8 then mask to hide overflow from certain machines
where byte2 concat byte1 gives you the correct string.

1
2
3
4
function short(len : integer) : string;
begin
	short := chr((len shr 8) and 255) + chr(len and 255);
end

1
myFormat := chr(1)+chr(0)+chr(242)+chr(1) + chr(Length(rcon)) + rcon + short(Length(cmd)) + cmd;

For reference, here's what the shr and the and operators do: http://www.freepascal.org/docs-html/ref/refsu37.html

I'm not 100% familiar with the semantics of pascal grammar so the code may not run as is, but the gist is there.

old Re: CS2D Manager

Manny
User Off Offline

Quote
Lee, thank you very much for your interest in my problem. I used your function but the result is still the same, CS2D dedicated server returned:
1
2
WARNING: Failed RCon attempt from 127.0.0.1:49874 (cmd: )
NET: Received unknown or damaged msg (118, 127.0.0.1:49874)

old Re: CS2D Manager

Lee
Moderator Off Offline

Quote
oops, small endian does LSB first and not the other way around.

1
2
3
4
function short(len : integer) : string;
begin
	short :=  chr(len and 255) + chr((len shr 8) and 255);
end

at the same time, you added in an extra character into the packet right after the 242

1
myFormat := chr(1)+chr(0)+chr(242) + chr(Length(rcon)) + rcon + short(Length(cmd)) + cmd;

I just did a quick test over python and this scheme works correctly.

1
2
3
4
def short(len):
	return chr(len&0xff)+chr((len>>8)&0xff)

sock.sendto(chr(1)+chr(0)+chr(242) + chr(len(rcon)) + rcon + short(len(cmd)) + cmd, ("localhost", 36963))

Be sure to do a recvfrom on the socket, you will essentially get a packet that looks something like this:

1
2
(hexadecimal)
01 00 f0 00 03 nn nn msg

Since pascal strings are nice to work with, you can simply do a substring of this packet from index 6 (or 7 depending on how pascal handles substring).

The nn nn parameter in the return packet tells you how many bytes the message should be, but since you have only sent a single request to the server from your address, CS2D will not collate several different responses into a single packet so you can be assured that everything from index 6 onwards to the end of the string will contain only characters from the response message.

Edit:
If rcon fails authentication, the third byte of the returned packet will be ordinal 242.
edited 1×, last 21.07.11 11:01:08 pm

old Re: CS2D Manager

Manny
User Off Offline

Quote
Lee, thank you very much for you time to help me from the darkness It works like a charm!
To the start Previous 1 Next To the start
Log in to replyGeneral overviewCS2D overviewForums overview