mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-18 19:00:21 +02:00
Rework the version string. - Make the original game version appear first in the `version` variable. - Use `com_target_shortversion` for the short version number. - Use `com_target_version` for the original game version. Some software, such as HLSW, as well as certain mods, check if the version string begins with "Medal of Honor ....". This commit makes these changes to ensure most software properly handles the game version.
641 lines
19 KiB
C++
641 lines
19 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2025 the OpenMoHAA team
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
or (at your option) any later version.
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "cl_ui.h"
|
|
#include "cl_instantAction.h"
|
|
#include "cl_uiserverlist.h"
|
|
#include "../gamespy/sv_gamespy.h"
|
|
|
|
Event EV_UIInstantAction_AcceptServer
|
|
(
|
|
"acceptserver",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Connect to the current server"
|
|
);
|
|
|
|
Event EV_UIInstantAction_RejectServer
|
|
(
|
|
"rejectserver",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Reject the current server"
|
|
);
|
|
|
|
Event EV_UIInstantAction_Cancel
|
|
(
|
|
"ia_cancel",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"cancel the server update"
|
|
);
|
|
|
|
Event EV_UIInstantAction_Refresh
|
|
(
|
|
"ia_refresh",
|
|
EV_DEFAULT,
|
|
NULL,
|
|
NULL,
|
|
"Refresh the server list"
|
|
);
|
|
|
|
CLASS_DECLARATION(UIWidget, UIInstantAction, NULL) {
|
|
{&EV_UIInstantAction_AcceptServer, &UIInstantAction::Connect },
|
|
{&EV_UIInstantAction_RejectServer, &UIInstantAction::Reject },
|
|
{&EV_UIInstantAction_Cancel, &UIInstantAction::CancelRefresh},
|
|
{&EV_UIInstantAction_Refresh, &UIInstantAction::Refresh },
|
|
{NULL, NULL }
|
|
};
|
|
|
|
struct ServerListInstance {
|
|
int iServerType;
|
|
UIInstantAction *pServerList;
|
|
};
|
|
|
|
ServerListInstance g_IAServerListInst[2];
|
|
|
|
UIInstantAction::UIInstantAction()
|
|
{
|
|
state = IA_INITIALIZE;
|
|
numFoundServers = 0;
|
|
numServers = 0;
|
|
minPlayers = 3;
|
|
startingMaxPing = 100;
|
|
endingMaxPing = 1500;
|
|
maxServers = -1;
|
|
servers = NULL;
|
|
doneList[0] = false;
|
|
doneList[1] = false;
|
|
serverList[0] = NULL;
|
|
serverList[1] = NULL;
|
|
|
|
ReadIniFile();
|
|
EnableServerInfo(false);
|
|
|
|
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Disable));
|
|
}
|
|
|
|
UIInstantAction::~UIInstantAction()
|
|
{
|
|
CleanUp();
|
|
}
|
|
|
|
void UIInstantAction::CleanUp()
|
|
{
|
|
if (serverList[0]) {
|
|
ServerListFree(serverList[0]);
|
|
serverList[0] = NULL;
|
|
}
|
|
|
|
if (serverList[1]) {
|
|
ServerListFree(serverList[1]);
|
|
serverList[1] = NULL;
|
|
}
|
|
|
|
if (servers) {
|
|
delete[] servers;
|
|
servers = NULL;
|
|
}
|
|
}
|
|
|
|
void UIInstantAction::Init()
|
|
{
|
|
const char *secret_key;
|
|
const char *game_name;
|
|
|
|
static const unsigned int iNumConcurrent = 10;
|
|
|
|
numFoundServers = 0;
|
|
numServers = 0;
|
|
doneList[0] = false;
|
|
doneList[1] = false;
|
|
|
|
EnableServerInfo(false);
|
|
|
|
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_noserverfound", new Event(EV_Widget_Disable));
|
|
|
|
Cvar_Set("ia_search_percentage", va("%d %%", 0));
|
|
|
|
if (com_target_game->integer < target_game_e::TG_MOHTT) {
|
|
g_IAServerListInst[0].iServerType = com_target_game->integer;
|
|
g_IAServerListInst[0].pServerList = this;
|
|
|
|
game_name = GS_GetGameName(com_target_game->integer);
|
|
secret_key = GS_GetGameKey(com_target_game->integer);
|
|
|
|
serverList[0] = ServerListNew(
|
|
game_name,
|
|
game_name,
|
|
secret_key,
|
|
iNumConcurrent,
|
|
(void *)&IAServerListCallBack,
|
|
1,
|
|
(void *)&g_IAServerListInst[0]
|
|
);
|
|
|
|
ServerListClear(serverList[0]);
|
|
} else {
|
|
g_IAServerListInst[0].iServerType = target_game_e::TG_MOHTT;
|
|
g_IAServerListInst[0].pServerList = this;
|
|
|
|
game_name = GS_GetGameName(target_game_e::TG_MOHTT);
|
|
secret_key = GS_GetGameKey(target_game_e::TG_MOHTT);
|
|
|
|
serverList[0] = ServerListNew(
|
|
game_name,
|
|
game_name,
|
|
secret_key,
|
|
iNumConcurrent,
|
|
(void *)&IAServerListCallBack,
|
|
1,
|
|
(void *)&g_IAServerListInst[0]
|
|
);
|
|
|
|
ServerListClear(serverList[0]);
|
|
|
|
g_IAServerListInst[1].iServerType = target_game_e::TG_MOHTA;
|
|
g_IAServerListInst[1].pServerList = this;
|
|
|
|
game_name = GS_GetGameName(target_game_e::TG_MOHTA);
|
|
secret_key = GS_GetGameKey(target_game_e::TG_MOHTA);
|
|
|
|
serverList[1] = ServerListNew(
|
|
game_name,
|
|
game_name,
|
|
secret_key,
|
|
iNumConcurrent,
|
|
(void *)&IAServerListCallBack,
|
|
1,
|
|
(void *)&g_IAServerListInst[1]
|
|
);
|
|
|
|
ServerListClear(serverList[1]);
|
|
}
|
|
|
|
state = IA_WAITING;
|
|
numFoundServers = 0;
|
|
|
|
ServerListUpdate(serverList[0], true);
|
|
|
|
if (serverList[1]) {
|
|
ServerListUpdate(serverList[1], true);
|
|
}
|
|
|
|
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("searchstatus", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("searchstatuslable", new Event(EV_Widget_Enable));
|
|
}
|
|
|
|
int UIInstantAction::GetServerIndex(int maxPing, int gameType)
|
|
{
|
|
int bestPing = 1500;
|
|
int bestServer = -1;
|
|
int i;
|
|
|
|
for (i = 0; i < numFoundServers; i++) {
|
|
const IAServer_t& IAServer = servers[i];
|
|
|
|
char *gameVer;
|
|
float fGameVer;
|
|
int ping;
|
|
int numPlayers;
|
|
|
|
if (IAServer.rejected) {
|
|
continue;
|
|
}
|
|
|
|
// Skip servers that don't match the provided game type
|
|
if (ServerGetIntValue(IAServer.server, "g_gametype_i", 1) != gameType) {
|
|
continue;
|
|
}
|
|
|
|
// Skip servers with high ping
|
|
ping = ServerGetPing(IAServer.server);
|
|
if (ping > maxPing) {
|
|
continue;
|
|
}
|
|
|
|
gameVer = ServerGetStringValue(IAServer.server, "gamever", "1.00");
|
|
if (com_target_demo->integer && *gameVer != 'd') {
|
|
// Skip retail servers on demo game
|
|
continue;
|
|
} else if (!com_target_demo->integer && *gameVer == 'd') {
|
|
// Skip demo servers on retail game
|
|
continue;
|
|
}
|
|
|
|
// Skip incompatible servers
|
|
fGameVer = atof(gameVer);
|
|
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
|
if (IAServer.serverGame.serverType == target_game_e::TG_MOHTT) {
|
|
if (fabs(fGameVer) < 2.3f) {
|
|
continue;
|
|
}
|
|
} else {
|
|
if (fabs(fGameVer) < 2.1f) {
|
|
continue;
|
|
}
|
|
}
|
|
} else {
|
|
if (fabs(fGameVer - com_target_shortversion->value) > 0.1f) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Skip servers with a password
|
|
if (ServerGetIntValue(IAServer.server, "password", 0)) {
|
|
continue;
|
|
}
|
|
|
|
// Skip servers that don't match the minimum number of players
|
|
numPlayers = ServerGetIntValue(IAServer.server, "numplayers", 0);
|
|
if (numPlayers < minPlayers) {
|
|
continue;
|
|
}
|
|
|
|
// Skip full servers
|
|
if (numPlayers == ServerGetIntValue(IAServer.server, "maxplayers", 0)) {
|
|
continue;
|
|
}
|
|
|
|
// Skip servers with an higher ping than the best one
|
|
if (ping >= bestPing) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Found a potential server
|
|
//
|
|
|
|
bestPing = ping;
|
|
bestServer = i;
|
|
}
|
|
|
|
return bestServer;
|
|
}
|
|
|
|
void UIInstantAction::ReadIniFile()
|
|
{
|
|
char *buffer;
|
|
const char *p;
|
|
const char *pVal;
|
|
int intValue;
|
|
char value[32];
|
|
|
|
if (!FS_ReadFileEx("iaction.ini", (void **)&buffer, qtrue)) {
|
|
return;
|
|
}
|
|
|
|
for (p = buffer; p; p = strstr(pVal, "\n")) {
|
|
if (sscanf(p, "%31s", value) != 1) {
|
|
break;
|
|
}
|
|
|
|
pVal = strstr(p, "=");
|
|
if (!pVal) {
|
|
break;
|
|
}
|
|
|
|
pVal++;
|
|
|
|
if (sscanf(pVal, "%d", &intValue) != 1) {
|
|
break;
|
|
}
|
|
|
|
if (!Q_stricmpn(value, "MinPlayers", 10)) {
|
|
minPlayers = intValue;
|
|
}
|
|
|
|
if (!Q_stricmpn(value, "StartingMaxPing", 15)) {
|
|
startingMaxPing = intValue;
|
|
}
|
|
|
|
if (!Q_stricmpn(value, "EndingMaxPing", 13)) {
|
|
endingMaxPing = intValue;
|
|
}
|
|
|
|
if (!Q_stricmpn(value, "MaxServers", 10)) {
|
|
maxServers = intValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void UIInstantAction::FindServer()
|
|
{
|
|
int ping;
|
|
int i;
|
|
|
|
currentServer = -1;
|
|
state = IA_NONE;
|
|
|
|
for (ping = startingMaxPing; ping < endingMaxPing; ping += 100) {
|
|
//
|
|
// Find the best server starting from FFA gametype first
|
|
//
|
|
for (i = 1; i < 7; i++) {
|
|
currentServer = GetServerIndex(ping, i);
|
|
if (currentServer >= 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (currentServer >= 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("searchstatus", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("searchstatuslable", new Event(EV_Widget_Disable));
|
|
|
|
if (currentServer < 0) {
|
|
EnableServerInfo(false);
|
|
|
|
menuManager.PassEventToWidget("ia_noserverfound", new Event(EV_Widget_Enable));
|
|
return;
|
|
}
|
|
|
|
const IAServer_t& IAServer = servers[currentServer];
|
|
const char *hostname = ServerGetStringValue(IAServer.server, "hostname", "(NONE)");
|
|
const char *gametype = ServerGetStringValue(IAServer.server, "gametype", "(NONE)");
|
|
int numplayers = ServerGetIntValue(IAServer.server, "numplayers", 0);
|
|
int maxplayers = ServerGetIntValue(IAServer.server, "maxplayers", 0);
|
|
ping = ServerGetPing(IAServer.server);
|
|
|
|
Cvar_Set("ia_servername", va(" %s", hostname));
|
|
Cvar_Set("ia_ping", va("%d", ping));
|
|
Cvar_Set("ia_gametype", va("%s", gametype));
|
|
Cvar_Set("ia_players", va("%d", numplayers));
|
|
Cvar_Set("ia_maxplayers", va("%d", maxplayers));
|
|
|
|
EnableServerInfo(true);
|
|
}
|
|
|
|
void UIInstantAction::Connect(Event *ev)
|
|
{
|
|
char *gameVer;
|
|
float fGameVer;
|
|
bool bDiffVersion;
|
|
char command[256];
|
|
|
|
if (currentServer < 0 || currentServer < numServers) {
|
|
return;
|
|
}
|
|
|
|
const IAServer_t& IAServer = servers[currentServer];
|
|
|
|
gameVer = ServerGetStringValue(IAServer.server, "gamever", "1.00");
|
|
if (gameVer[0] == 'd') {
|
|
gameVer++;
|
|
}
|
|
|
|
// Skip incompatible servers
|
|
fGameVer = atof(gameVer);
|
|
bDiffVersion = false;
|
|
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
|
|
if (IAServer.serverGame.serverType == target_game_e::TG_MOHTT) {
|
|
if (fabs(fGameVer) < 2.3f) {
|
|
bDiffVersion = true;
|
|
}
|
|
} else {
|
|
if (fabs(fGameVer) < 2.1f) {
|
|
bDiffVersion = true;
|
|
}
|
|
}
|
|
} else {
|
|
if (fabs(fGameVer - com_target_shortversion->value) > 0.1f) {
|
|
bDiffVersion = true;
|
|
}
|
|
}
|
|
|
|
if (bDiffVersion) {
|
|
if (fGameVer - com_target_shortversion->value > 0) {
|
|
// Older version
|
|
UI_SetReturnMenuToCurrent();
|
|
Cvar_Set("com_errormessage", va("Server is version %s, you are using %s", gameVer, "2.40"));
|
|
UI_PushMenu("wrongversion");
|
|
} else {
|
|
// Server version is newer
|
|
Cvar_Set("dm_serverstatus", va("Can not connect to v%s server, you are using v%s", gameVer, "2.40"));
|
|
}
|
|
}
|
|
|
|
UI_SetReturnMenuToCurrent();
|
|
Cvar_Set("g_servertype", va("%d", servers[currentServer].serverGame.serverType));
|
|
|
|
Com_sprintf(
|
|
command,
|
|
sizeof(command),
|
|
"connect %s:%i\n",
|
|
ServerGetAddress(IAServer.server),
|
|
ServerGetIntValue(IAServer.server, "hostport", PORT_SERVER)
|
|
);
|
|
Cbuf_AddText(command);
|
|
}
|
|
|
|
void UIInstantAction::Reject(Event *ev)
|
|
{
|
|
servers[currentServer].rejected = 1;
|
|
FindServer();
|
|
}
|
|
|
|
void UIInstantAction::Draw()
|
|
{
|
|
switch (state) {
|
|
case IA_INITIALIZE:
|
|
Init();
|
|
break;
|
|
case IA_UPDATE:
|
|
Update();
|
|
break;
|
|
case IA_FINISHED:
|
|
FindServer();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (serverList[0]) {
|
|
ServerListThink(serverList[0]);
|
|
}
|
|
|
|
if (serverList[1]) {
|
|
ServerListThink(serverList[1]);
|
|
}
|
|
}
|
|
|
|
void UIInstantAction::Update()
|
|
{
|
|
numFoundServers = 0;
|
|
|
|
// count the total number of servers from both server list
|
|
numServers = ServerListCount(serverList[0]);
|
|
if (serverList[1]) {
|
|
numServers += ServerListCount(serverList[1]);
|
|
}
|
|
|
|
state = IA_FINISHED;
|
|
servers = new IAServer_t[numServers];
|
|
|
|
ServerListHalt(serverList[0]);
|
|
if (serverList[1]) {
|
|
ServerListHalt(serverList[1]);
|
|
}
|
|
|
|
ServerListThink(serverList[0]);
|
|
if (serverList[1]) {
|
|
ServerListThink(serverList[1]);
|
|
}
|
|
|
|
state = IA_SEARCHING;
|
|
|
|
// Start updating the first list
|
|
doneList[0] = false;
|
|
ServerListClear(serverList[0]);
|
|
ServerListUpdate(serverList[0], true);
|
|
|
|
// Update the second optional list
|
|
if (serverList[1]) {
|
|
doneList[1] = false;
|
|
ServerListClear(serverList[1]);
|
|
ServerListUpdate(serverList[1], true);
|
|
}
|
|
}
|
|
|
|
int UIInstantAction::AddServer(GServer server, const ServerGame_t& serverGame)
|
|
{
|
|
servers[numFoundServers].server = server;
|
|
servers[numFoundServers].serverGame = serverGame;
|
|
servers[numFoundServers].rejected = false;
|
|
numFoundServers++;
|
|
|
|
return numFoundServers;
|
|
}
|
|
|
|
void UIInstantAction::CancelRefresh(Event *ev)
|
|
{
|
|
state = IA_FINISHED;
|
|
ServerListHalt(serverList[0]);
|
|
ServerListHalt(serverList[1]);
|
|
}
|
|
|
|
void UIInstantAction::Refresh(Event *ev)
|
|
{
|
|
state = IA_INITIALIZE;
|
|
}
|
|
|
|
void UIInstantAction::EnableServerInfo(bool enable)
|
|
{
|
|
if (enable) {
|
|
menuManager.PassEventToWidget("iaservername_label", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_servername_field", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_ping_label", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_ping_field", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_gametype_label", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_gametype_field", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_players_label", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_players_field", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_maxplayers_label", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("ia_maxplayers_field", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("acceptserver", new Event(EV_Widget_Enable));
|
|
menuManager.PassEventToWidget("rejectserver", new Event(EV_Widget_Enable));
|
|
} else {
|
|
menuManager.PassEventToWidget("iaservername_label", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_servername_field", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_ping_label", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_ping_field", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_gametype_label", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_gametype_field", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_players_label", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_players_field", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_maxplayers_label", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("ia_maxplayers_field", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("acceptserver", new Event(EV_Widget_Disable));
|
|
menuManager.PassEventToWidget("rejectserver", new Event(EV_Widget_Disable));
|
|
}
|
|
}
|
|
|
|
void UIInstantAction::IAServerListCallBack(GServerList serverlist, int msg, void *instance, void *param1, void *param2)
|
|
{
|
|
const ServerListInstance *pInstance = (const ServerListInstance *)instance;
|
|
UIInstantAction *pServerList = pInstance->pServerList;
|
|
|
|
if (msg == LIST_PROGRESS) {
|
|
if (pServerList->state == IA_WAITING) {
|
|
if (pInstance->iServerType == com_target_game->integer) {
|
|
pServerList->doneList[0] = true;
|
|
}
|
|
|
|
if (com_target_game->integer >= target_game_e::TG_MOHTT && pInstance->iServerType == target_game_e::TG_MOHTA) {
|
|
pServerList->doneList[1] = true;
|
|
}
|
|
|
|
if (pServerList->doneList[0] && (!pServerList->serverList[1] || pServerList->doneList[1])) {
|
|
pServerList->state = IA_UPDATE;
|
|
}
|
|
} else if (pServerList->state == IA_SEARCHING) {
|
|
ServerGame_t serverGame;
|
|
serverGame.serverType = pInstance->iServerType;
|
|
const int serverIndex = pServerList->AddServer((GServer)param1, serverGame);
|
|
|
|
Cvar_Set("ia_search_percentage", va("%d %%", 100 * serverIndex / pServerList->numServers));
|
|
|
|
if (pServerList->maxServers >= 0 && serverIndex >= pServerList->maxServers) {
|
|
// Reached the maximum number of servers, stop there
|
|
pServerList->doneList[0] = true;
|
|
ServerListHalt(pServerList->serverList[0]);
|
|
|
|
if (pServerList->serverList[1]) {
|
|
pServerList->doneList[1] = true;
|
|
ServerListHalt(pServerList->serverList[1]);
|
|
}
|
|
|
|
pServerList->state = IA_FINISHED;
|
|
}
|
|
}
|
|
} else if (msg == LIST_STATECHANGED && ServerListState(serverlist) == GServerListState::sl_idle) {
|
|
if (pInstance->iServerType == com_target_game->integer) {
|
|
pServerList->doneList[0] = true;
|
|
}
|
|
|
|
if (com_target_game->integer >= target_game_e::TG_MOHTT && pInstance->iServerType == target_game_e::TG_MOHTA) {
|
|
pServerList->doneList[1] = true;
|
|
}
|
|
|
|
if (pServerList->doneList[0] && (!pServerList->serverList[1] || pServerList->doneList[1])) {
|
|
if (pServerList->state == IA_WAITING) {
|
|
pServerList->state = IA_UPDATE;
|
|
}
|
|
if (pServerList->state == IA_SEARCHING) {
|
|
pServerList->state = IA_FINISHED;
|
|
}
|
|
}
|
|
}
|
|
}
|