English Get player count JSON

61 replies
Goto Page
To the start Previous 1 2 3 4 Next To the start
07.05.20 01:05:31 pm
Up
MikuAuahDark
User
Offline Off
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.
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
07.05.20 01:10:17 pm
Up
Mami Tomoe
User
Offline Off
So can I use your LuaJIT dedicated server? And how would I get that socket thing?
fish
07.05.20 01:20:35 pm
Up
MikuAuahDark
User
Offline Off
If you can handle the consequence like slight script difference and stability (although from my testing server running with it for 1 week, it's stable). Then to use socket:

user Avo has written:
user Mami Tomoe has written:
Okay and how do I download a file with Lua?
socket.http
doesn't seem to exist.

You might want to see file us [Lua 5.1] LuaSocket 3.0 x86 Windows/Linux/MacOS (6).
edited 1×, last 07.05.20 01:22:14 pm
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
07.05.20 01:22:04 pm
Up
Mami Tomoe
User
Offline Off
So I need LuaJIT to use that socket thing?
fish
07.05.20 01:39:16 pm
Up
The Dark Shadow
User
Offline Off
@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
07.05.20 02:17:33 pm
Up
Mami Tomoe
User
Offline Off
This is my learning process.
fish
07.05.20 05:25:22 pm
Up
Avo
User
Offline Off
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).
Trust me, I'm an engineer | user DC approved file cs2d Super extra mod for CS2D (64), yeah!
07.05.20 06:09:59 pm
Up
Mami Tomoe
User
Offline Off
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
fish
07.05.20 06:39:35 pm
Up
The Dark Shadow
User
Offline Off
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.
07.05.20 08:16:31 pm
Up
Mami Tomoe
User
Offline Off
Well, how do I use nodeJS?
fish
08.05.20 06:28:10 am
Up
MikuAuahDark
User
Offline Off
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

Code:
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
Code:
www.unrealsoftware.de/inc_pub/serverinfo.php

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

returned
Code:
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:
Code:
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
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
08.05.20 03:48:19 pm
Up
Devil-Thanh
GAME BANNED
Offline Off
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.
08.05.20 04:02:41 pm
Up
Mami Tomoe
User
Offline Off
What is the right way to use the cached number then?
fish
08.05.20 04:03:42 pm
Up
Gaios
Security Supporter
Offline Off
@user Mami Tomoe: You can randomize.
08.05.20 04:28:51 pm
Up
Mami Tomoe
User
Offline Off
@user Gaios: Is using the same one every time bad?
fish
08.05.20 05:27:03 pm
Up
DC
Admin
Offline Off
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
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
08.05.20 05:30:41 pm
Up
Mami Tomoe
User
Offline Off
Does the number have a limit? Like is it int, long, or what?
fish
08.05.20 05:32:03 pm
Up
DC
Admin
Offline Off
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.
Code:
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
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
08.05.20 05:50:36 pm
Up
Mami Tomoe
User
Offline Off
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...
fish
08.05.20 08:32:15 pm
Up
Avo
User
Offline Off
@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.
Trust me, I'm an engineer | user DC approved file cs2d Super extra mod for CS2D (64), yeah!
To the start Previous 1 2 3 4 Next To the start