Forum

> > CS2D > General > Get player count JSON
Forums overviewCS2D overviewGeneral overviewLog in to reply

English Get player count JSON

61 replies
Page
To the start Previous 1 2 3 4 Next To the start

old Re: Get player count JSON

MikuAuahDark
User Off Offline

Quote
If you're stuck with pure CS2D Lua (not LuaJIT) then your only option is to use cs2d lua cmd reqhttp requesting to UnrealSoftware server as user Avo said.

However, if you have atleast JIT and LuaSocket, then you can create your own UDP socket then parse the response as shown in https://github.com/Austinb/GameQ/blob/v3/src/GameQ/Protocols/Cs2d.php#L189

1. Send "\x01\x00\xFB\x01" to the server
2. Server will send you back "\x01\x00\xFB\x01" followed by any data that's according to the link above.

old Re: Get player count JSON

The Dark Shadow
User Off Offline

Quote
@user Mami Tomoe: You are doing something that you don't know how to complete it successfully, Just copying and pasting them. You won't be success if you keep going this way my man. Ask everything about it that you don't know, Search on Google, Then you'll finally understand how actually it does work, Afterall you can make it on your own

old Re: Get player count JSON

Avo
User Off Offline

Quote
user DC has written
The recommended approach would be to get the server details directly from the server via UDP.

@user DC: By the way, is there any kind of specification of the communication protocol between client and server? Or any hint how does the protocol look like?

Or one would need to figure it out with wireshark, tcpdump, etc?

---
user MikuAuahDark has written
If you're stuck with pure CS2D Lua (not LuaJIT) then your only option is to use cs2d lua cmd reqhttp requesting to UnrealSoftware server as user Avo said.

Oh, I was not aware of existence of reqhttp function! That's the way to go if you want to ask /serverinfo.php for data in the most simple manner (not the fastest tho).

old Re: Get player count JSON

Mami Tomoe
User Off Offline

Quote
Okay well I just need simple instructions on how to use Lua to get info from another server.

Such as:

Get LuaJIT
Install socket thingy
Use req hook to do x things
etc

old Re: Get player count JSON

The Dark Shadow
User Off Offline

Quote
Why are you still asking for LuaJIT, LuaSocket while there is
dgram
in nodeJS, You can use nodeJS itself to request data, You don't need to install anything if you use my way. LuaSocket does the same thing as mine even if I compare them mine is simpler. It requests data from the server to the client directly. If you want to use it, Just run the code I've posted yesterday then you're done that's all you have to do.

old Re: Get player count JSON

MikuAuahDark
User Off Offline

Quote
user The Dark Shadow has written
Why are you still asking for LuaJIT, LuaSocket while there is
dgram
in nodeJS, You can use nodeJS itself to request data, You don't need to install anything if you use my way. LuaSocket does the same thing as mine even if I compare them mine is simpler. It requests data from the server to the client directly. If you want to use it, Just run the code I've posted yesterday then you're done that's all you have to do.

@user The Dark Shadow, Node.JS has nothing to do in here.
user TrialAndError has written
@user Mami Tomoe Are you using pure lua or CS2D

user Mami Tomoe has written
CS2D Lua, I want to have a server specifically for doing file downloading and stuff


If you want a simple approach, you can use something like this

1
2
3
4
5
6
7
8
9
10
11
12
local reqID

addhook("httpdata", "httpdata")
function httpadata(requestID, state, data)
	if requestID == reqID and state == 1 then
		-- Now "data" has the HTTP data as Avo said before, see below.
		-- Do your processing to the data here to retrieve what you need.
	end
end

-- Somewhere
reqID = reqhttp("unrealsoftware.de", "/inc_pub/serverinfo.php?i="..server_ip.."&p="..server_port.."&g=0")

user Avo has written
I made a little investigation of http://www.unrealsoftware.de/usgn.php?s=cs2d and find out that you can make a GET call to
www.unrealsoftware.de/inc_pub/serverinfo.php

For example:
http://www.unrealsoftware.de/inc_pub/serverinfo.php?i=85.25.143.56&p=36955&g=0&123

returned
Name:	[Q][GamersCentral.de][Public]
Map:	de_dust2
Players:	2 / 32 (Bots: 0)
Password:	None
U.S.G.N. only:	Off
Fog of War:	On
Friendly Fire:	Off
Lua:	Uses Lua Scripts!
Game Mode:	Standard
(visible content only, HTML tags omitted)

It's not JSON, but I guess you can use parse it and make use of that. It's simple HTML with table tags.

Parameters of a call:
http://www.unrealsoftware.de/inc_pub/serverinfo.php?i=<IP>&p=<PORT>&g=<GAME ID, 0 for CS2D>&<SOME RANDOM NUMBER>

Spoiler >


Fragments of HTML and JS code that helped me to figure it out >


Edit: For anyone stumble upon this solution, this no longer works under CS2D as UnrealSoftware sites now enforces HSTS!
edited 1×, last 27.06.20 01:46:23 pm

old Re: Get player count JSON

Devil-Thanh
GAME BANNED Off Offline

Quote
MikuAuahDark has written
Edit: it seems that random number is optional.


That random number is not optional, it's used to prevent the GET request from being cached.

old Re: Get player count JSON

DC
Admin Off Offline

Quote
Using the same number every time is equal to not using it at all. It won't prevent caching.
The best value would be a unix timestamp of the current time.

(not sure why I used a random number when I implemented that stuff years ago. It's an "ok" approach but of course there's still a chance that you get the same number twice, rendering the anti caching mechanism usless)
edited 1×, last 08.05.20 05:30:42 pm

old Re: Get player count JSON

DC
Admin Off Offline

Quote
No it does not have any limit. In fact it's entirely ignored by the script which is called. Its only purpose is to alter the URL to prevent browsers from caching the call.

It's probably not even an entirely valid request string syntax (not sure, didn't check the URI RFCs). Normally you would have to put a variable name at that point. The script doesn't care though because the value is not relevant.

So instead of appending
&123
you could also append something like
&t=12345678912345679
. Makes no difference.

Btw: I would appreciate if you could just host the PHP stuff on your own server. That would perform better anyway (for you). Of course the requirement would be to run a webserver with PHP.

This is the code I'm using.
Pasted together and stripped some things like a caching mechanism. I hope it works anyway.
Please don't judge me. This is some ooold shit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<?php
/*
Quick & dirty library to read/extract BlitzMax compatible data types from raw input data (files/UDP).

Globals:
- $d: holds the data to read (d for Data)
- $dOS: read offset in bytes (dOS for Data OffSet)

- the normal functions manipulate $d (which is slow), they do not use $dOS
- the fast functions use $dOS to keep track of the read offset, they do not manipulate $d (faster)
*/

function readLine(){
	global $d;
	$line='';
	do {
		$char=ord(substr($d,0,1));
		$line.=chr($char);
		$d=substr($d,1);
	} while ($char!=13);
	$d=substr($d,1);
	return substr($line,0,strlen($line)-1);
}

function readString(){
	global $d;
	$length=ord(substr($d,0,1));
	$string=substr($d,1,$length);
	$d=substr($d,$length+1);
	return $string;
}

function readByte(){
	global $d;
	$byte=ord(substr($d,0,1));
	$d=substr($d,1);
	return $byte;
}

function readShort(){
	global $d;
	$short=substr($d,0,2);
	$d=substr($d,2);
	$r=unpack('S',$short);
	return $r[1];
}

function readInt(){
	global $d;
	$int=substr($d,0,4);
	$d=substr($d,4);
	$r=unpack('l',$int);
	return $r[1];
}

function readFloat(){
	global $d;
	$float=ord(substr($d,0,4));
	$d=substr($d,4);
	$r=unpack('f',$float);
	return $r[1];
}

// Fast versions using an offset ($dOS) instead of manipulating $d

function readLineFast(){
	global $d;
	global $dOS;
	$line='';
	do {
		$char=ord(substr($d,$dOS,1));
		$line.=chr($char);
		$dOS++;
	} while ($char!=13);
	$dOS++;
	return substr($line,0,strlen($line)-1);
}

function readStringFast(){
	global $d;
	global $dOS;
	$length=ord(substr($d,$dOS,1));
	$string=substr($d,$dOS+1,$length);
	$dOS+=($length+1);
	return $string;
}

function readByteFast(){
	global $d;
	global $dOS;
	$byte=ord(substr($d,$dOS,1));
	$dOS++;
	return $byte;
}

function readShortFast(){
	global $d;
	global $dOS;
	$short=substr($d,$dOS,2);
	$dOS+=2;
	$r=unpack('S',$short);
	return $r[1];
}

function readIntFast(){
	global $d;
	global $dOS;
	$int=substr($d,$dOS,4);
	$dOS+=4;
	$r=unpack('l',$int);
	return $r[1];
}

function readFloatFast(){
	global $d;
	global $dOS;
	$float=ord(substr($d,$dOS,4));
	$dOS+=4;
	$r=unpack('f',$float);
	return $r[1];
}


function utf8_htmlentities($t,$q=ENT_COMPAT,$char='UTF-8',$denc=TRUE){
	return htmlentities($t,$q,$char,$denc);
}

// Send request with specified payload data
function sendRequest($data){
	global $fp;
	global $d;
	
	// Use cached data
	if (isset($d)) {
		return;
	}
	
	// Send Request
	fwrite($fp, $data);
	
	// Set Timeout
	stream_set_timeout($fp, 5);
	
	// Read Data (try to read up to 256 bytes)
	$d = fread($fp, 256);
	
	// Meta data implies timeout
	$md = stream_get_meta_data($fp);
	if ($md['timed_out'] == 1){
		die('timeout');
	}
	
	// Empty package implies timeout
	if (ord(substr($d, 0, 1)) == 0){
		die('timeout');
	}
}

//-------------------------------------------------------------------------

// Validate IP
if (!filter_var($_GET['i'], FILTER_VALIDATE_IP)) {
	die('bad IP (format)');
}
if (strpos($_GET['i'], '127') === 0) {
	die('bad IP (local)');
}
$_GET['p'] = (int)$_GET['p'];
if ($_GET['p'] < 1 || $_GET['p'] > 65535) {
	die('bad port');
}

// Connect (with 5 secs timeout)
if (!isset($d)) {
	$fp = @fsockopen('udp://'.$_GET['i'], $_GET['p'], $errno, $errstr, 5);
}
if (isset($d) || $fp) {
	switch ((int)$_GET['g']){
		// Game 0 - CS2D
		case 0:
			sendRequest(chr(1).chr(0).chr(251).chr(1));				//Send Request
			
			// Read UDP packet header
			$b0=readByte();
			$b1=readByte();
			$b2=readByte();
			$b3=readByte();
			
			if ($b0==0) {
				echo('timeout');
				break;
			}
			
			// Check if header is valid
			if ($b0==1 && $b1==0 && $b2=251 && $b3==1){
				//Get Data
				$mode=readByte();									//Mode Bit Flags
				$name=readString();									//Server Name
				$map=readString();									//Map
				$players=min(readByte(),32);						//Players
				$players_max=min(readByte(),32);					//Players Max
				if ($mode & 32){ $gmi=readByte(); }else{ $gmi=0; }	//Game Mode
				$bots=readByte();
				
				// Print General Data
				echo '<table>';
				echo '<tr><td>Name:</td><td>',utf8_htmlentities($name),'</td></tr>';
				echo '<tr><td>Map:</td><td>',utf8_htmlentities($map),'</td></tr>';
				echo '<tr><td>Players:</td><td>',$players,' / ',$players_max,' (Bots: ',$bots,')</td></tr>';
				// Print Mode Flag Stuff
				if ($mode & 1){ $t='Password protected!'; }else{ $t='None'; } echo '<tr><td>Password:</td><td>',$t,'</td></tr>';
				if ($mode & 2){ $t='On'; }else{ $t='Off'; } echo '<tr><td>U.S.G.N. only:</td><td>',$t,'</td></tr>';
				if ($mode & 4){ $t='On'; }else{ $t='Off'; } echo '<tr><td>Fog of War:</td><td>',$t,'</td></tr>';	
				if ($mode & 8){ $t='On'; }else{ $t='Off'; } echo '<tr><td>Friendly Fire:</td><td>',$t,'</td></tr>';
				if ($mode & 64){ $t='Uses Lua Scripts!'; }else{ $t='None'; } echo '<tr><td>Lua:</td><td>',$t,'</td></tr>';
				// Print Game Mode
				switch ($gmi){
					case 0: $gm='Standard'; break;
					case 1: $gm='Deathmatch'; break;
					case 2: $gm='Team Deathmatch'; break;
					case 3: $gm='Construction'; break;
					case 4: $gm='Zombies'; break;
					default: $gm='Unknown ('.$gmi.')';
				}
				echo '<tr><td>Game Mode:</td><td>',$gm,'</td></tr>';
				echo '</table>';
				
			}else{
				echo 'unexpected server reply (',$b0,',',$b1,',',$b2,',',$b3,') - expected (1,0,251,1)';
			}
			break;
		// Game 1 - Carnage Contest
		case 1:
			// NOT RELEVANT 4 U BOY!
			break;
		// Unknown
		default:
			echo 'unknown request';
	}
	
	// Close socket
	if (isset($fp)) {
		fclose($fp);   
	} else {
		echo '<br /><span style="font-size:9px; color:#AAA">(cached values, new every 10 sec)</span>';
	}
}else{
	echo 'failed to open socket to server! please try again later!';
}
edited 3×, last 08.05.20 05:48:49 pm

old Re: Get player count JSON

Mami Tomoe
User Off Offline

Quote
I'd love to just connect directly to the server but I don't know anything web related, all the programming I do is non-web stuff sadly...

old Re: Get player count JSON

Avo
User Off Offline

Quote
@user Mami Tomoe: try it, then. It's totally worth it to know how network-related stuff works in general. All of these things such as TCP, UDP, sockets, HTTP, REST etc.
To the start Previous 1 2 3 4 Next To the start
Log in to replyGeneral overviewCS2D overviewForums overview