diff --git a/config/menus_multiplayer.cfg b/config/menus_multiplayer.cfg
index 7b5d07d7..b130dd7b 100644
--- a/config/menus_multiplayer.cfg
+++ b/config/menus_multiplayer.cfg
@@ -21,6 +21,7 @@ menuitem "Set mode/map..." "showmenu Gamemode"
menuitem "Kick/ban player..." "showmenu kick/ban"
menuitem "Adjust teams..." [ showmenu "Team adjustment" ]
menuitem "Download a demo..." [ listdemos; showmenu "Download demo" ]
+menuitem "Get additional server information" "showmenu [serverinfo]"
menuitem "" -1
menuitem "4Main menu..." [ closemenu In-game; showmenu main ]
menuitem "4Browse servers..." [ closemenu "In-game"; joinservermenu ]
@@ -124,6 +125,7 @@ menuitem "F1: Display this help menu" -1
menuitem "F3: Search for players by nickname..." [ showmenu "search player" ]
menuitem "F4: Edit favourites..." "showmenu [edit favourites]"
menuitem "F5: Update the serverlist from the masterserver" [updatefrommaster 1; closemenu "serverbrowser help"]
+menuitem "F9: Get additional server information" "showmenu [serverinfo]"
menuitem "" -1
menuitem "Options:" -1
menuitemcheckbox "F6: Reverse the sort order:" "$serversortdir" "serversortdir $arg1"
diff --git a/config/serverinfo_en.txt b/config/serverinfo_en.txt
new file mode 100644
index 00000000..10eec30c
--- /dev/null
+++ b/config/serverinfo_en.txt
@@ -0,0 +1,21 @@
+// extended serverinfo file
+// ========================
+// WARNING: You can NOT use CubeScript in here!!
+//
+// This text file is sent, whenever a client requests extended server information.
+// Comments are removed, also leading and trailing blanks and empty lines.
+// To send an intentionally left blank line, use a line with a single '.'
+//
+// Please use this file to provide contact information, especially for players
+// who are innocently affect by an IP range ban.
+// You can also use this page to advertize your clan or provide contact
+// information for recruiting.
+//
+// Don't use more than 80 characters per line. You can use colors and TABs.
+// The available colors are: 0: green, 1: blue, 2: yellow, 3: red, 4: gray, 5: white, 6: dark brown, 7: dark red
+//
+// Example:
+// BobsInstagibServer \f3play nicely!
+// contact me at a@b.c
+
+
diff --git a/docs/commandline.html b/docs/commandline.html
index 80384387..4b00288c 100644
--- a/docs/commandline.html
+++ b/docs/commandline.html
@@ -470,6 +470,17 @@
-Kconfig/nicknameblacklist.cfg
+
-oN
diff --git a/docs/server.html b/docs/server.html
index 83937519..a425cbcc 100644
--- a/docs/server.html
+++ b/docs/server.html
@@ -197,7 +197,7 @@
Important: do only use standard maps and maps from your packages/maps/servermaps folder!
- Blacklist
+ IP Blacklist
In the blacklist file specified on the command line (default:
diff --git a/source/src/main.cpp b/source/src/main.cpp
index 3fcd887d..cbeff9e8 100644
--- a/source/src/main.cpp
+++ b/source/src/main.cpp
@@ -660,17 +660,18 @@ int main(int argc, char **argv)
audiomgr.initsound();
initlog("cfg");
- extern void *scoremenu, *teammenu, *ctfmenu, *servmenu, *searchmenu, *kickmenu, *banmenu, *forceteammenu, *giveadminmenu, *docmenu, *applymenu;
- scoremenu = addmenu("score", "frags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
- teammenu = addmenu("team score", "frags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
- ctfmenu = addmenu("ctf score", "flags\tfrags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
- servmenu = addmenu("server", NULL, true, refreshservers, serverskey);
- searchmenu = addmenu("search", NULL, true, refreshservers, serverskey);
- kickmenu = addmenu("kick player", NULL, true, refreshsopmenu);
- banmenu = addmenu("ban player", NULL, true, refreshsopmenu);
- forceteammenu = addmenu("force team", NULL, true, refreshsopmenu);
- giveadminmenu = addmenu("give admin", NULL, true, refreshsopmenu);
- docmenu = addmenu("reference", NULL, true, renderdocmenu);
+ extern void *scoremenu, *teammenu, *ctfmenu, *servmenu, *searchmenu, *serverinfomenu, *kickmenu, *banmenu, *forceteammenu, *giveadminmenu, *docmenu, *applymenu;
+ scoremenu = addmenu("score", "frags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
+ teammenu = addmenu("team score", "frags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
+ ctfmenu = addmenu("ctf score", "flags\tfrags\tdeath\tratio\tpj\tping\tcn\tname", false, renderscores, NULL, false, true);
+ servmenu = addmenu("server", NULL, true, refreshservers, serverskey);
+ searchmenu = addmenu("search", NULL, true, refreshservers, serverskey);
+ serverinfomenu = addmenu("serverinfo", NULL, true, refreshservers, NULL);
+ kickmenu = addmenu("kick player", NULL, true, refreshsopmenu);
+ banmenu = addmenu("ban player", NULL, true, refreshsopmenu);
+ forceteammenu = addmenu("force team", NULL, true, refreshsopmenu);
+ giveadminmenu = addmenu("give admin", NULL, true, refreshsopmenu);
+ docmenu = addmenu("reference", NULL, true, renderdocmenu);
applymenu = addmenu("apply", "apply changes now?", true, refreshapplymenu);
exec("config/scontext.cfg");
diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp
index 41cb6257..4a50e2d7 100644
--- a/source/src/protocol.cpp
+++ b/source/src/protocol.cpp
@@ -159,6 +159,17 @@ void filterservdesc(char *dst, const char *src, int len)
*dst = '\0';
}
+void cutcolorstring(char *text, int len)
+{ // limit string length, ignore color codes
+ while(*text)
+ {
+ if(*text == '\f' && text[1]) text++;
+ else len--;
+ if(len < 0) { *text = '\0'; break; }
+ text++;
+ }
+}
+
const char *modefullnames[] =
{
"demo playback",
diff --git a/source/src/protocol.h b/source/src/protocol.h
index 2a5a6c0c..5a98711e 100644
--- a/source/src/protocol.h
+++ b/source/src/protocol.h
@@ -96,7 +96,7 @@ enum { DISC_NONE = 0, DISC_EOP, DISC_CN, DISC_MKICK, DISC_MBAN, DISC_TAGT, DISC_
#define EXT_PLAYERSTATS_RESP_STATS -11
enum { PONGFLAG_PASSWORD = 0, PONGFLAG_BANNED, PONGFLAG_BLACKLIST, PONGFLAG_MASTERMODE = 6, PONGFLAG_NUM };
-enum { EXTPING_NOP = 0, EXTPING_NAMELIST, EXTPING_NUM };
+enum { EXTPING_NOP = 0, EXTPING_NAMELIST, EXTPING_SERVERINFO, EXTPING_MAPROT, EXTPING_NUM };
enum
{
diff --git a/source/src/protos.h b/source/src/protos.h
index fb41a51d..b6b4b388 100644
--- a/source/src/protos.h
+++ b/source/src/protos.h
@@ -196,17 +196,21 @@ struct serverinfo
string sdesc;
string description;
string cmd;
- int mode, numplayers, maxclients, ping, protocol, minremain, resolved, port, lastpingmillis, pongflags, getnames, menuline_from, menuline_to;
+ int mode, numplayers, maxclients, ping, protocol, minremain, resolved, port, lastpingmillis, pongflags, getnames, getinfo, menuline_from, menuline_to;
ENetAddress address;
vector playernames;
uchar namedata[MAXTRANS];
+ vector infotexts;
+ uchar textdata[MAXTRANS];
+ char lang[3];
color *bgcolor;
int favcat, msweight, weight;
serverinfo()
- : mode(0), numplayers(0), maxclients(0), ping(9999), protocol(0), minremain(0), resolved(UNRESOLVED), port(-1), lastpingmillis(0), pongflags(0), getnames(0), bgcolor(NULL), favcat(-1), msweight(0), weight(0)
+ : mode(0), numplayers(0), maxclients(0), ping(9999), protocol(0), minremain(0), resolved(UNRESOLVED), port(-1), lastpingmillis(0), pongflags(0), getnames(0), getinfo(0), bgcolor(NULL), favcat(-1), msweight(0), weight(0)
{
name[0] = full[0] = map[0] = sdesc[0] = description[0] = '\0';
+ loopi(3) lang[i] = '\0';
}
};
@@ -685,6 +689,7 @@ extern void getstring(char *t, ucharbuf &p, int len = MAXTRANS);
extern void filtertext(char *dst, const char *src, int whitespace = 1, int len = sizeof(string)-1);
extern void filterrichtext(char *dst, const char *src, int len = sizeof(string)-1);
extern void filterservdesc(char *dst, const char *src, int len = sizeof(string)-1);
+extern void cutcolorstring(char *text, int len);
extern void startintermission();
extern void restoreserverstate(vector &ents);
extern uchar *retrieveservers(uchar *buf, int buflen);
@@ -722,7 +727,7 @@ extern bool logline(int level, const char *msg, ...);
struct servercommandline
{
int uprate, serverport, syslogfacility, filethres, syslogthres, maxdemos, maxclients, kickthreshold, banthreshold, verbose;
- const char *ip, *master, *logident, *serverpassword, *adminpasswd, *demopath, *maprot, *pwdfile, *blfile, *nbfile;
+ const char *ip, *master, *logident, *serverpassword, *adminpasswd, *demopath, *maprot, *pwdfile, *blfile, *nbfile, *infopath;
bool demoeverymatch, logtimestamp;
string motd, servdesc_full, servdesc_pre, servdesc_suf, voteperm, mapperm;
int clfilenesting;
@@ -732,6 +737,7 @@ struct servercommandline
maxclients(DEFAULTCLIENTS), kickthreshold(-5), banthreshold(-6), verbose(0),
ip(""), master(NULL), logident(""), serverpassword(""), adminpasswd(""), demopath(""),
maprot("config/maprot.cfg"), pwdfile("config/serverpwd.cfg"), blfile("config/serverblacklist.cfg"), nbfile("config/nicknameblacklist.cfg"),
+ infopath("config/serverinfo"),
demoeverymatch(true), logtimestamp(false),
clfilenesting(0)
{
@@ -744,7 +750,7 @@ struct servercommandline
const char *a = arg + 2 + strspn(arg + 2, " ");
int ai = atoi(a);
switch(arg[1])
- { // todo: egjlqEGHIJOQUYZ
+ { // todo: egjlqEGHJOQUYZ
case 'u': uprate = ai; break;
case 'f': if(ai > 0 && ai < 65536) serverport = ai; break;
case 'i': ip = a; break;
@@ -777,6 +783,7 @@ struct servercommandline
case 'X': pwdfile = a; break;
case 'B': blfile = a; break;
case 'K': nbfile = a; break;
+ case 'I': infopath = a; break;
case 'o': filterrichtext(motd, a); break;
case 'n':
{
diff --git a/source/src/server.cpp b/source/src/server.cpp
index ebd38525..123c8261 100644
--- a/source/src/server.cpp
+++ b/source/src/server.cpp
@@ -3793,6 +3793,80 @@ void extping_namelist(ucharbuf &p)
sendstring("", p);
}
+#define MAXINFOLINELEN 100 // including color codes
+
+const char *readserverinfo(const char *lang)
+{
+ s_sprintfd(fname)("%s_%s.txt", scl.infopath, lang);
+ path(fname);
+ int len, n;
+ char *c, *s, *t, *buf = loadfile(fname, &len);
+ if(!buf) return NULL;
+ char *nbuf = new char[len + 2];
+ for(t = nbuf, s = strtok(buf, "\n\r"); s; s = strtok(NULL, "\n\r"))
+ {
+ c = strstr(s, "//");
+ if(c) *c = '\0'; // strip comments
+ for(n = strlen(s) - 1; n >= 0 && s[n] == ' '; n--) s[n] = '\0'; // strip trailing blanks
+ filterrichtext(t, s + strspn(s, " "), MAXINFOLINELEN); // skip leading blanks
+ n = strlen(t);
+ if(n) t += n + 1;
+ }
+ *t = '\0';
+ delete[] buf;
+ if(!*nbuf) DELETEA(nbuf);
+ return nbuf;
+}
+
+struct serverinfotext { char lang[3]; const char *info; };
+vector serverinfotexts;
+
+const char *getserverinfo(const char *lang)
+{
+ if(!islower(lang[0]) || !islower(lang[1])) return NULL;
+ serverinfotext s;
+ loopi(3) s.lang[i] = lang[i];
+ loopv(serverinfotexts)
+ {
+ if(!strcmp(s.lang, serverinfotexts[i].lang) && serverinfotexts[i].info) return serverinfotexts[i].info;
+ }
+ s.info = readserverinfo(lang);
+ serverinfotexts.add(s);
+ return s.info;
+}
+
+void extping_serverinfo(ucharbuf &pi, ucharbuf &po)
+{
+ char lang[3];
+ lang[0] = tolower(getint(pi)); lang[1] = tolower(getint(pi)); lang[2] = '\0';
+ const char *reslang = lang, *buf = getserverinfo(lang); // try client language
+ if(!buf) buf = getserverinfo(reslang = "en"); // try english
+ sendstring(buf ? reslang : "", po);
+ if(buf)
+ {
+ for(const char *c = buf; *c && po.remaining() > MAXINFOLINELEN + 10; c += strlen(c) + 1) sendstring(c, po);
+ sendstring("", po);
+ }
+}
+
+void extping_maprot(ucharbuf &po)
+{
+ putint(po, CONFIG_MAXPAR);
+ string text;
+ bool abort = false;
+ loopv(configsets)
+ {
+ if(po.remaining() < 100) abort = true;
+ configset &c = configsets[i];
+ filtertext(text, c.mapname, 0);
+ text[30] = '\0';
+ sendstring(abort ? "-- list truncated --" : text, po);
+ loopi(CONFIG_MAXPAR) putint(po, c.par[i]);
+ if(abort) break;
+ }
+ sendstring("", po);
+}
+
void extinfo_cnbuf(ucharbuf &p, int cn)
{
if(cn == -1) // add all available player ids
@@ -3932,6 +4006,7 @@ void initserver(bool dedicated)
readpwdfile(scl.pwdfile);
readipblacklist(scl.blfile);
nbl.readnickblacklist(scl.nbfile);
+ getserverinfo("en"); // cache 'en' serverinfo
if(scl.demoeverymatch) logline(ACLOG_VERBOSE, "recording demo of every game (holding up to %d in memory)", scl.maxdemos);
if(scl.demopath[0]) logline(ACLOG_VERBOSE,"all recorded demos will be written to: \"%s\"", scl.demopath);
if(scl.voteperm[0]) logline(ACLOG_VERBOSE,"vote permission string: \"%s\"", scl.voteperm);
diff --git a/source/src/serverbrowser.cpp b/source/src/serverbrowser.cpp
index a3159d6f..9fb8c5cb 100644
--- a/source/src/serverbrowser.cpp
+++ b/source/src/serverbrowser.cpp
@@ -341,7 +341,7 @@ VAR(searchlan, 0, 1, 2);
#define PINGBUFSIZE 100
static int pingbuf[PINGBUFSIZE], curpingbuf = 0;
-void pingservers(bool issearch, bool onlyconnected)
+void pingservers(bool issearch, serverinfo *onlyconnected)
{
if(pingsock == ENET_SOCKET_NULL)
{
@@ -364,15 +364,19 @@ void pingservers(bool issearch, bool onlyconnected)
int baselen = p.length();
if(onlyconnected)
{
- serverinfo *si = getconnectedserverinfo();
- if(si)
+ serverinfo *si = onlyconnected;
+ //p.len = baselen;
+ if(si->getinfo)
{
- //p.len = baselen;
- putint(p, si->getnames || issearch ? EXTPING_NAMELIST : EXTPING_NOP);
- buf.data = ping;
- buf.dataLength = p.length();
- enet_socket_send(pingsock, &si->address, &buf, 1);
+ putint(p, EXTPING_SERVERINFO);
+ const char *lang = getalias("LANG");
+ if(!lang || strlen(lang) != 2) lang = "en";
+ loopi(2) putint(p, lang[i]);
}
+ else putint(p, si->getnames || issearch ? EXTPING_NAMELIST : EXTPING_NOP);
+ buf.data = ping;
+ buf.dataLength = p.length();
+ enet_socket_send(pingsock, &si->address, &buf, 1);
}
else if(searchlan < 2)
{
@@ -437,6 +441,8 @@ void checkresolver()
}
}
+#define MAXINFOLINELEN 100 // including color codes
+
void checkpings()
{
if(pingsock == ENET_SOCKET_NULL) return;
@@ -465,6 +471,12 @@ void checkpings()
int pingtm = pingbuf[(getint(p) - 1) % PINGBUFSIZE];
if(pingtm) si->ping = totalmillis - pingtm;
int query = getint(p);
+ switch(query)
+ { // cleanup additional query info
+ case EXTPING_SERVERINFO:
+ loopi(2) getint(p);
+ break;
+ }
si->protocol = getint(p);
if(si->protocol!=PROTOCOL_VERSION) si->ping = 9998;
si->mode = getint(p);
@@ -500,6 +512,53 @@ void checkpings()
}
break;
}
+ case EXTPING_SERVERINFO:
+ {
+ si->infotexts.setsizenodelete(0);
+ ucharbuf q(si->textdata, sizeof(si->textdata));
+ getstring(text, p);
+ si->getinfo = 0;
+ if(strlen(text) != 2)
+ {
+ si->infotexts.add((char *)si->textdata);
+ sendstring("this server does not provide additional information", q);
+ break;
+ }
+ strcpy(si->lang, text);
+ while(p.remaining())
+ {
+ getstring(text, p);
+ if(*text && !p.overread())
+ {
+ text[MAXINFOLINELEN] = '\0';
+ cutcolorstring(text, 80);
+ si->infotexts.add((char *)si->textdata + q.length());
+ sendstring(strcmp(text, ".") ? text : "", q);
+ }
+ else break;
+ }
+ break;
+ }
+ case EXTPING_MAPROT:
+ {
+ si->infotexts.setsizenodelete(0);
+ ucharbuf q(si->textdata, sizeof(si->textdata));
+ int n = getint(p);
+ si->getinfo = 0;
+ while(p.remaining())
+ {
+ getstring(text, p);
+ if(*text && !p.overread())
+ {
+ text[MAXINFOLINELEN] = '\0';
+ loopi(n) s_strcatf(text, ", %d", getint(p));
+ si->infotexts.add((char *)si->textdata + q.length());
+ sendstring(text , q);
+ }
+ else break;
+ }
+ break;
+ }
}
}
}
@@ -609,7 +668,7 @@ int sicompare(serverinfo **ap, serverinfo **bp)
else return -dir;
}
-void *servmenu = NULL, *searchmenu = NULL;
+void *servmenu = NULL, *searchmenu = NULL, *serverinfomenu = NULL;
vector namelists;
string cursearch, cursearchuc;
@@ -810,7 +869,10 @@ void refreshservers(void *menu, bool init)
static int servermenumillis;
static bool usedselect = false;
static string title;
+ static serverinfo *lastselectedserver = NULL;
bool issearch = menu == searchmenu;
+ bool isinfo = menu == serverinfomenu;
+ bool isscoreboard = menu == NULL;
serverinfo *curserver = getconnectedserverinfo(), *oldsel = NULL;
if(init)
@@ -826,11 +888,55 @@ void refreshservers(void *menu, bool init)
checkresolver();
checkpings();
- if((init && issearch) || totalmillis - lastinfo >= (servpingrate * (issearch ? 2 : 1))/(maxservpings ? (servers.length() + maxservpings - 1) / maxservpings : 1)) pingservers(issearch, menu == NULL);
- if(!init && menu && servers.inrange(((gmenu *)menu)->menusel) && (usedselect || ((gmenu *)menu)->menusel > 0))
+ if(isinfo)
{
- loopv(servers) if(servers[i]->menuline_from == ((gmenu *)menu)->menusel && servers[i]->menuline_to > servers[i]->menuline_from) { oldsel = servers[i]; break; }
+ if(lastselectedserver)
+ {
+ bool found = false;
+ loopv(servers) if(lastselectedserver == servers[i]) { found = true; break; }
+ if(!found) lastselectedserver = NULL;
+ }
+ menutitle(menu, "extended server information");
+ menureset(menu);
+ static string infotext;
+ static char dummy = '\0';
+ if(lastselectedserver)
+ {
+ serverinfo &si = *lastselectedserver;
+ s_sprintf(si.full)("%s:%d %s", si.name, si.port, si.sdesc);
+ menumanual(menu, si.full);
+ menumanual(menu, &dummy);
+ if(si.infotexts.length())
+ {
+ infotext[0] = '\0';
+ loopv(si.infotexts) menumanual(menu, si.infotexts[i]);
+ }
+ else
+ {
+ s_strcpy(infotext, "-- waiting for server response --");
+ si.getinfo = 1;
+ if(init || totalmillis - lastinfo >= servpingrate) pingservers(false, lastselectedserver);
+ }
+ }
+ else
+ s_strcpy(infotext, " -- no server selected --");
+ if(*infotext) menumanual(menu, infotext);
+ return;
}
+ if((init && issearch) || totalmillis - lastinfo >= (servpingrate * (issearch ? 2 : 1))/(maxservpings ? (servers.length() + maxservpings - 1) / maxservpings : 1))
+ pingservers(issearch, isscoreboard ? curserver : NULL);
+ if(!init && menu)// && servers.inrange(((gmenu *)menu)->menusel))
+ {
+ serverinfo *foundserver = NULL;
+ loopv(servers) if(servers[i]->menuline_from == ((gmenu *)menu)->menusel && servers[i]->menuline_to > servers[i]->menuline_from) { foundserver = servers[i]; break; }
+ if(foundserver)
+ {
+ if((usedselect || ((gmenu *)menu)->menusel > 0)) oldsel = foundserver;
+ lastselectedserver = foundserver;
+ }
+ }
+ if(isscoreboard) lastselectedserver = curserver;
+
bool showfavtag = (assignserverfavourites() || !serverbrowserhidefavtag) && serverbrowserhidefavtag != 2;
serversortprepare();
servers.sort(sicompare);
@@ -857,6 +963,7 @@ void refreshservers(void *menu, bool init)
loopv(servers)
{
serverinfo &si = *servers[i];
+ si.menuline_to = si.menuline_from = ((gmenu *)menu)->items.length();
if(!showallservers && si.lastpingmillis < servermenumillis) continue; // no pong yet
int banned = ((si.pongflags >> PONGFLAG_BANNED) & 1) | ((si.pongflags >> (PONGFLAG_BLACKLIST - 1)) & 2);
bool showthisone = !(banned && showonlygoodservers) && !(showonlyfavourites > 0 && si.favcat != showonlyfavourites - 1);
@@ -865,7 +972,6 @@ void refreshservers(void *menu, bool init)
bool isprivate = (si.pongflags >> PONGFLAG_MASTERMODE) > 0;
char basecolor = banned ? '4' : (curserver == servers[i] ? '1' : '5');
char plnumcolor = serverfull ? '2' : (needspasswd ? '3' : (isprivate ? '1' : basecolor));
- si.menuline_from = ((gmenu *)menu)->items.length();
if(si.address.host != ENET_HOST_ANY && si.ping != 9999)
{
if(si.protocol!=PROTOCOL_VERSION)
@@ -902,8 +1008,8 @@ void refreshservers(void *menu, bool init)
}
if(showthisone)
{
- si.full[94] = 0; // cut off too long server descriptions
- si.description[75] = 0;
+ cutcolorstring(si.full, 76); // cut off too long server descriptions
+ cutcolorstring(si.description, 76);
if(sbconnectexists)
{
filtertext(text, si.sdesc);
@@ -1016,6 +1122,10 @@ bool serverskey(void *menu, int code, bool isdown, int unicode)
case SDLK_F6:
serversortdir = serversortdir ? 0 : 1;
return true;
+
+ case SDLK_F9:
+ showmenu("serverinfo");
+ return true;
}
if(menu == searchmenu) return false;
switch(code)
diff --git a/source/src/serverms.cpp b/source/src/serverms.cpp
index 60958fcd..da54e95f 100644
--- a/source/src/serverms.cpp
+++ b/source/src/serverms.cpp
@@ -214,6 +214,20 @@ void serverms(int mode, int numplayers, int minremain, char *smapname, int milli
extping_namelist(po);
break;
}
+ case EXTPING_SERVERINFO:
+ {
+ extern void extping_serverinfo(ucharbuf &pi, ucharbuf &po);
+ putint(po, query);
+ extping_serverinfo(pi, po);
+ break;
+ }
+ case EXTPING_MAPROT:
+ {
+ extern void extping_maprot(ucharbuf &po);
+ putint(po, query);
+ extping_maprot(po);
+ break;
+ }
case EXTPING_NOP:
default:
putint(po, EXTPING_NOP);
|