34#define MAX_SERVERLIST 128
113 cgi->NET_StreamFree(s);
117 const int cmd =
cgi->NET_ReadByte(
buf);
119 cgi->NET_StreamFree(s);
124 cgi->NET_ReadStringLine(
buf, str,
sizeof(str));
126 if (strncmp(str,
"info", 4) == 0) {
127 cgi->NET_ReadString(
buf, str,
sizeof(str));
140 }
else if (strncmp(str,
"print", 5) == 0) {
142 cgi->NET_ReadString(
buf, paramBuf,
sizeof(paramBuf));
145 cgi->NET_StreamFree(s);
157 cgi->Com_Printf(
"pinging failed [%s]:%s...\n", server->
node, server->
service);
162 cgi->NET_StreamSetData(s, server);
211 if (
cgi->NET_ReadString(msg, str,
sizeof(str)) == 0) {
214 cgi->UI_ExecuteConfunc(
"multiplayer_playerNumber 0");
215 cgi->Com_DPrintf(
DEBUG_CLIENT,
"GAME_MP_ParseTeamInfoMessage: No teaminfo string\n");
229 while (
cgi->NET_ReadString(msg, str,
sizeof(str)) > 0) {
238 cgi->LIST_AddString(&userList,
user);
240 cgi->LIST_AddString(&userTeam,
va(
_(
"Team %d"), team));
242 cgi->LIST_AddString(&userTeam,
_(
"No team"));
244 cgi->UI_ExecuteConfunc(
"multiplayer_playerIsReady %i %i", cnt, isReady);
251 cgi->UI_ExecuteConfunc(
"multiplayer_playerNumber %i", cnt);
260 cgi->Cvar_SetValue(
"mn_maxteams",
teamData.maxteams);
261 cgi->Cvar_SetValue(
"mn_maxplayersperteam",
teamData.maxPlayersPerTeam);
279 cgi->NET_ReadString(msg, str,
sizeof(str));
289 const char* users = strstr(str,
"\n");
290 if (users ==
nullptr) {
296 cgi->Cvar_Set(
"mn_mappic",
"maps/shots/default");
298 cgi->Cvar_Set(
"mn_server_need_password",
"1");
300 cgi->Cvar_Set(
"mn_server_need_password",
"0");
303 cgi->Cvar_Set(
"mn_server_ip",
"%s", hostname);
306 cgi->Cvar_Set(
"mn_svmapname",
"%s", value);
309 const char* token =
buf;
315 if (!
cgi->R_ImageExists(
"pics/maps/shots/%s", token)) {
317 cgi->Cvar_Set(
"mn_mappic",
"maps/shots/%s", token);
338 if (users ==
nullptr)
340 const int team = atoi(token);
342 if (users ==
nullptr)
347 cgi->UI_PushWindow(
"serverinfo");
358 cgi->NET_StreamFree(s);
361 const int cmd =
cgi->NET_ReadByte(
buf);
363 cgi->NET_StreamFree(s);
367 cgi->NET_ReadStringLine(
buf, str,
sizeof(str));
370 cgi->NET_StreamPeerToName(s, hostname,
sizeof(hostname),
true);
373 cgi->NET_StreamFree(s);
379 cgi->Com_Printf(
"Could not query masterserver\n");
383 const char* serverListBuf = responseBuf;
386 const char* token =
Com_Parse(&serverListBuf);
388 int num = atoi(token);
393 for (
int i = 0;
i < num;
i++) {
396 if (!*token || !serverListBuf) {
397 cgi->Com_Printf(
"Could not finish the masterserver response parsing\n");
404 if (token[0] ==
'\0' || !serverListBuf) {
405 cgi->Com_Printf(
"Could not finish the masterserver response parsing\n");
419 const char match[] =
"discovered";
420 if (
len ==
sizeof(match) && memcmp(
buf, match,
len) == 0) {
423 cgi->NET_SockaddrToStrings(s, from, node,
sizeof(node), service,
sizeof(service));
435 const char* newBookmark;
437 if (
cgi->Cmd_Argc() < 2) {
438 newBookmark =
cgi->Cvar_GetString(
"mn_server_ip");
440 cgi->Com_Printf(
"Usage: %s <ip>\n",
cgi->Cmd_Argv(0));
444 newBookmark =
cgi->Cmd_Argv(1);
448 const char* bookmark =
cgi->Cvar_GetString(
va(
"adr%i",
i));
449 if (bookmark[0] ==
'\0') {
450 cgi->Cvar_Set(
va(
"adr%i",
i),
"%s", newBookmark);
455 cgi->UI_Popup(
_(
"Notice"),
"%s",
_(
"All bookmark slots are used - please removed unused entries and repeat this step"));
466 switch (
cgi->Cmd_Argc()) {
468 host =
cgi->Cmd_Argv(1);
472 host =
cgi->Cmd_Argv(1);
480 host =
cgi->Cvar_GetString(
"mn_server_ip");
490 cgi->Com_Printf(
"Could not connect to %s %s\n", host,
port);
500 if (
cgi->Cmd_Argc() < 2) {
501 cgi->Com_Printf(
"Usage: %s <num>\n",
cgi->Cmd_Argv(0));
504 const int num = atoi(
cgi->Cmd_Argv(1));
524#define SERVERQUERYTIMEOUT 40000
536 if (
cgi->Cmd_Argc() == 2) {
557 const char buf[] =
"discover";
572 if (
cgi->Cmd_Argc() == 2 && !
Q_streq(
cgi->Cmd_Argv(1),
"local")) {
584 {
nullptr,
nullptr,
nullptr}
Shared game type headers.
Share stuff between the different cgame implementations.
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
const cgame_import_t * cgi
const char * Info_BoolForKey(const char *s, const char *key)
const char * Info_ValueForKey(const char *s, const char *key)
Searches the string for the given key and returns the associated value, or an empty string.
int Info_IntegerForKey(const char *s, const char *key)
Serverlist menu callbacks headers for multiplayer.
#define SERVERQUERYTIMEOUT
static serverList_t serverList[MAX_SERVERLIST]
static void GAME_MP_AddServerToList(const char *node, const char *service)
Adds a server to the serverlist cache.
void GAME_MP_ServerListShutdown(void)
void GAME_MP_PingServers_f(void)
The first function called when entering the multiplayer menu, then CL_Frame takes over.
static char serverInfoText[1024]
static void GAME_MP_ServerListDiscoveryCallback(struct datagram_socket *s, const char *buf, int len, struct sockaddr *from)
static void GAME_MP_BookmarkAdd_f(void)
Add a new bookmark.
serverList_t * selectedServer
static bool GAME_MP_ProcessPingReply(serverList_t *server, const char *msg)
Parsed the server ping response.
static const cmdList_t serverListCmds[]
static void GAME_MP_ServerListClick_f(void)
Callback for bookmark nodes in multiplayer menu (mp_bookmarks).
static void GAME_MP_QueryMasterServerThread(const char *responseBuf, void *userdata)
static void GAME_MP_ServerInfoCallback(struct net_stream *s)
static void GAME_MP_PingServerCallback(struct net_stream *s)
static char userInfoText[256]
static void GAME_MP_PingServer(serverList_t *server)
Pings all servers in serverList.
static int serverListLength
static cvar_t * cl_serverlist
static void GAME_MP_ServerInfo_f(void)
static int lastServerQuery
static struct datagram_socket * netDatagramSocket
static char serverText[1024]
static bool serversAlreadyQueried
static void GAME_MP_PrintServerList_f(void)
Prints all the servers on the list to game console.
static bool GAME_MP_ShowServer(const serverList_t *server)
Perform the server filtering.
static void GAME_MP_ParseServerInfoMessage(dbuffer *msg, const char *hostname)
Serverbrowser text.
void GAME_MP_ParseTeamInfoMessage(dbuffer *msg)
Team selection text.
void GAME_MP_ServerListInit(const cgame_import_t *import)
Serverlist management headers for multiplayer.
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Shared parsing functions.
QGL_EXTERN GLuint GLchar GLuint * len
bool Q_strnull(const char *string)
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
char sv_hostname[MAX_OSPATH]
Data and interface to share data.
@ TEXT_MULTIPLAYER_USERTEAM
@ TEXT_MULTIPLAYER_USERLIST