/* =========================================================================== Copyright (C) 2015 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 "../gamespy/goaceng.h" #include "../gamespy/sv_gamespy.h" #include "../gamespy/common/gsPlatformSocket.h" Event EV_FAKKServerList_Connect( "connect", EV_DEFAULT, NULL, NULL, "Connect to the specified server" ); Event EV_FAKKServerList_RefreshServerList( "refreshserverlist", EV_DEFAULT, NULL, NULL, "Refresh the serverlist" ); Event EV_FAKKServerList_RefreshLANServerList( "refreshlanserverlist", EV_DEFAULT, NULL, NULL, "Refresh the LAN serverlist" ); Event EV_FAKKServerList_CancelRefresh( "cancelrefresh", EV_DEFAULT, NULL, NULL, "Cancel serverlist Refresh" ); Event EV_FAKKServerList_LANListing( "lanlisting", EV_DEFAULT, NULL, NULL, "Makes this server list to LAN stuff when there's a choice between Internet & LAN servers" ); Event EV_FAKKServerList_UpdateServer( "updateserver", EV_DEFAULT, NULL, NULL, "Update the selected server" ); struct ServerListInstance { int iServerType; UIFAKKServerList* serverList; }; class FAKKServerListItem : public UIListCtrlItem { UIFAKKServerList* m_parent; // Added in OPM str m_strings[6]; str m_sVersion; bool m_bDifferentVersion; bool m_bFavorite; bool m_bQueryDone; bool m_bQueryFailed; int m_iNumPlayers; public: str m_sIP; unsigned int m_uiRealIP; int m_iPort; int m_iGameSpyPort; public: FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver); griditemtype_t getListItemType(int index) const override; int getListItemValue(int i) const override; str getListItemString(int i) const override; void setListItemString(int i, str sNewString); void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont* pFont) override; qboolean IsHeaderEntry() const override; bool IsQueried() const; void SetQueried(bool bIsQueried); bool IfQueryFailed() const; void SetQueryFailed(bool bFailed); void SetNumPlayers(int iNum); bool IsFavorite() const; void SetFavorite(bool bIsFavorite); str GetListItemVersion() const; void SetListItemVersion(str sNewVer); void SetDifferentVersion(bool bIsDifferentVersion); bool IsDifferentVersion() const; }; static int g_iTotalNumPlayers; qboolean g_bNumericSort = qfalse; qboolean g_bReverseSort = qfalse; qboolean g_NeedAdditionalLANSearch = qfalse; qboolean g_bDoneUpdating[2]; ServerListInstance g_ServerListInst[2]; void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, void* param1, void* param2); static void AddFilter(char* filter, const char* value); FAKKServerListItem::FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver) { m_parent = parent; m_strings[0] = string1; m_strings[1] = string2; m_strings[2] = string3; m_strings[3] = string4; m_strings[4] = string5; m_strings[5] = string6; m_sVersion = ver; m_bFavorite = false; m_bQueryDone = false; m_bQueryFailed = false; m_iNumPlayers = 0; } griditemtype_t FAKKServerListItem::getListItemType(int index) const { return griditemtype_t::TYPE_OWNERDRAW; } int FAKKServerListItem::getListItemValue(int i) const { return atoi(m_strings[i]); } str FAKKServerListItem::getListItemString(int i) const { return m_strings[i]; } void FAKKServerListItem::setListItemString(int i, str sNewString) { m_strings[i] = sNewString; } void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont* pFont) { static cvar_t *pColoringType = Cvar_Get("cl_browserdetailedcolors", "0", CVAR_ARCHIVE); UIRect2D newRect = drawRect; vec2_t virtualScale = { 1.f, 1.f }; /* if (m_parent->isVirtual()) { virtualScale[0] = uid.vidWidth / 640.f; virtualScale[1] = uid.vidHeight / 480.f; newRect.size.width *= uid.vidWidth / 1024; newRect.size.height *= uid.vidHeight / 768; } */ virtualScale[0] = m_parent->getHighResScale()[0]; virtualScale[1] = m_parent->getHighResScale()[1]; if (!pColoringType->integer) { if (IfQueryFailed() || (IsDifferentVersion() && IsQueried())) { if (bSelected) { DrawBox(newRect, UColor(0.2f, 0.0f, 0.0f), 1.0); pFont->setColor(UColor(0.9f, 0.0f, 0.0f)); } else { DrawBox(newRect, UColor(0.1f, 0.0f, 0.0f), 1.0); pFont->setColor(UColor(0.55f, 0.0f, 0.0f)); } } else if (IsQueried()) { if (bSelected) { DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0); pFont->setColor(UColor(0.9f, 0.8f, 0.6f)); } else { DrawBox(newRect, UColor(0.02f, 0.07f, 0.004f), 1.0); pFont->setColor(UHudColor); } } else { if (bSelected) { DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0); pFont->setColor(UColor(0.6f, 0.7f, 0.8f)); } else { DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0); pFont->setColor(UColor(0.05f, 0.5f, 0.6f)); } } pFont->Print( newRect.pos.x / virtualScale[0] + 1.0, newRect.pos.y / virtualScale[1], getListItemString(iColumn).c_str(), -1, virtualScale ); } else { if (IsDifferentVersion()) { if (IsQueried()) { if (bSelected) { DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0); pFont->setColor(UColor(0.0f, 0.5f, 0.0f)); } else { DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0); pFont->setColor(UColor(0.0f, 0.35f, 0.0f)); } } else { if (bSelected) { DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0); pFont->setColor(UColor(0.5f, 0.6f, 0.7f)); } else { DrawBox(newRect, UColor(0.15f, 0.0f, 0.0f), 1.0); pFont->setColor(UColor(0.05f, 0.4f, 0.5f)); } } } else if (IsQueried()) { if (bSelected) { DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0); pFont->setColor(UColor(0.9f, 0.8f, 0.6f)); } else { DrawBox(newRect, UColor(0.02f, 0.07f, 0.005f), 1.0); pFont->setColor(UHudColor); } } else { if (bSelected) { DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0); pFont->setColor(UColor(0.6f, 0.7f, 0.8f)); } else { DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0); pFont->setColor(UColor(0.05f, 0.5f, 0.6f)); } if (IfQueryFailed()) { DrawBox( UIRect2D( newRect.pos.x, newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y, newRect.size.width, newRect.size.height * 0.5 - 1.0 + newRect.pos.y ), URed, 0.3f ); } pFont->Print( newRect.pos.x / virtualScale[0] + 1.0, newRect.pos.y / virtualScale[1], getListItemString(iColumn).c_str(), -1, virtualScale ); if (IsDifferentVersion()) { DrawBox( UIRect2D( newRect.pos.x, newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y, newRect.size.width, 1.0 ), URed, 0.3f ); } } } } qboolean FAKKServerListItem::IsHeaderEntry() const { return m_bFavorite; } bool FAKKServerListItem::IsQueried() const { return m_bQueryDone; } void FAKKServerListItem::SetQueried(bool bIsQueried) { m_bQueryDone = bIsQueried; if (m_bQueryDone) { m_bQueryFailed = false; } else { SetNumPlayers(0); } } bool FAKKServerListItem::IfQueryFailed() const { return m_bQueryFailed; } void FAKKServerListItem::SetQueryFailed(bool bFailed) { m_bQueryFailed = bFailed; } void FAKKServerListItem::SetNumPlayers(int iNum) { if (m_iNumPlayers) { g_iTotalNumPlayers -= m_iNumPlayers; } m_iNumPlayers = iNum; g_iTotalNumPlayers += iNum; Cvar_Set("dm_playercount", va("%d", g_iTotalNumPlayers)); } bool FAKKServerListItem::IsFavorite() const { return m_bFavorite; } void FAKKServerListItem::SetFavorite(bool bIsFavorite) { m_bFavorite = bIsFavorite; } str FAKKServerListItem::GetListItemVersion() const { return m_sVersion; } void FAKKServerListItem::SetListItemVersion(str sNewVer) { m_sVersion = sNewVer; } void FAKKServerListItem::SetDifferentVersion(bool bIsDifferentVersion) { m_bDifferentVersion = bIsDifferentVersion; } bool FAKKServerListItem::IsDifferentVersion() const { return m_bDifferentVersion; } CLASS_DECLARATION( UIListCtrl, UIFAKKServerList, NULL ) { { &EV_UIListBase_ItemSelected, &UIFAKKServerList::SelectServer }, { &EV_UIListBase_ItemDoubleClicked, &UIFAKKServerList::ConnectServer }, { &EV_FAKKServerList_RefreshServerList, &UIFAKKServerList::RefreshServerList }, { &EV_FAKKServerList_RefreshLANServerList, &UIFAKKServerList::RefreshLANServerList }, { &EV_FAKKServerList_CancelRefresh, &UIFAKKServerList::CancelRefresh }, { &EV_FAKKServerList_Connect, &UIFAKKServerList::ConnectServer }, { &EV_FAKKServerList_LANListing, &UIFAKKServerList::MakeLANListing }, { &EV_FAKKServerList_UpdateServer, &UIFAKKServerList::UpdateServer }, { NULL, NULL } }; UIFAKKServerList::UIFAKKServerList() { setBackgroundColor(UWhite, true); Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked); Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected); AllowActivate(true); setHeaderFont("facfont-20"); m_serverList[0] = NULL; m_serverList[1] = NULL; m_bHasList = false; m_bGettingList[0] = false; m_bGettingList[1] = false; m_bUpdatingList = false; m_bLANListing = false; m_iLastSortColumn = 2; } void UIFAKKServerList::SelectServer( Event *ev ) { } void UIFAKKServerList::ConnectServer( Event *ev ) { const FAKKServerListItem* pItem; if (getCurrentItem() <= 0) { return; } pItem = static_cast(GetItem(getCurrentItem())); if (pItem->IsDifferentVersion()) { const char* message; float neededVersion = com_target_version->value; float serverVersion = atof(pItem->GetListItemVersion().c_str()); // Tolerate patch version if (fabs(neededVersion - serverVersion) >= 0.1) { UI_SetReturnMenuToCurrent(); message = va("Server is version %s, you are targeting %s", pItem->GetListItemVersion().c_str(), com_target_version->string); Cvar_Set("com_errormessage", message); UI_PushMenu("wrongversion"); } else { message = va("Can not connect to v%s server, you are targeting v%s", pItem->GetListItemVersion().c_str(), com_target_version->string); Cvar_Set("dm_serverstatus", message); } } else { char cmdString[256]; UI_SetReturnMenuToCurrent(); Com_sprintf(cmdString, sizeof(cmdString), "connect %s\n", pItem->getListItemString(1).c_str()); Cbuf_AddText(cmdString); ServerListHalt(m_serverList[0]); } } qboolean UIFAKKServerList::KeyEvent( int key, unsigned int time ) { switch (key) { case K_ENTER: case K_KP_ENTER: ConnectServer(NULL); return qtrue; case K_UPARROW: if (getCurrentItem() > 1) { TrySelectItem(getCurrentItem() - 1); SelectServer(NULL); return qtrue; } else { return qfalse; } break; case K_DOWNARROW: if (getCurrentItem() < getNumItems()) { TrySelectItem(getCurrentItem() + 1); SelectServer(NULL); return qtrue; } else { return qfalse; } break; case 'u': case 'U': if (getCurrentItem() > 0) { const FAKKServerListItem* pItem = static_cast(GetItem(getCurrentItem())); ServerListAuxUpdate(m_serverList[0], pItem->m_sIP.c_str(), pItem->m_iGameSpyPort, true, GQueryType::qt_status); } return UIListCtrl::KeyEvent(key, time); case 'c': case 'C': ServerListHalt(m_serverList[0]); return qtrue; case 'i': case 'I': { int i, j; const FAKKServerListItem* pServerItem1; const FAKKServerListItem* pServerItem2; int iNumErrors = 0; for (i = 1; i <= getNumItems(); i++) { pServerItem1 = static_cast(GetItem(i)); for (j = i + 1; j <= getNumItems(); j++) { pServerItem2 = static_cast(GetItem(j)); if (!str::icmp(pServerItem1->m_sIP.c_str(), pServerItem2->m_sIP.c_str())) { if (pServerItem1->m_iPort == pServerItem2->m_iPort) { Com_DPrintf("*#*#* Duplicate server address: %s:%i\n", pServerItem1->m_sIP.c_str(), pServerItem1->m_iPort); iNumErrors++; } if (pServerItem1->m_iGameSpyPort == pServerItem2->m_iGameSpyPort) { Com_DPrintf("*#*#* servers at IP %s sharing GameSpy port %i\n", pServerItem1->m_sIP.c_str(), pServerItem1->m_iGameSpyPort); iNumErrors++; } } } } Com_DPrintf("*#*#* %i problems detected\n", iNumErrors); } return qtrue; default: return UIListCtrl::KeyEvent(key, time); } } void UIFAKKServerList::UpdateUIElement( void ) { float width; RemoveAllColumns(); width = getClientFrame().size.width; AddColumn("Server Name", 0, width * 0.31f, false, false); AddColumn("Map", 5, width * 0.135f, false, false); AddColumn("Players", 3, width * 0.085f, true, true); AddColumn("Gametype", 4, width * 0.18f, false, false); AddColumn("Ping", 2, width * 0.05f, true, false); AddColumn("IP", 1, width * 0.23f, false, false); uWinMan.ActivateControl(this); } void UIFAKKServerList::RefreshServerList( Event *ev ) { int i; FAKKServerListItem* pNewServerItem; for (i = 1; i <= getNumItems(); i++) { pNewServerItem = static_cast(GetItem(i)); pNewServerItem->SetQueried(false); pNewServerItem->SetNumPlayers(0); pNewServerItem->SetQueryFailed(false); } if (m_serverList[0]) { ServerListClear(m_serverList[0]); ServerListFree(m_serverList[0]); m_serverList[0] = NULL; } if (m_serverList[1]) { ServerListClear(m_serverList[1]); ServerListFree(m_serverList[1]); m_serverList[1] = NULL; } if (!m_serverList[0]) { NewServerList(); } g_bDoneUpdating[0] = false; g_bDoneUpdating[1] = false; Cvar_Set("dm_playercount", "0"); { char filter[2048] = { 0 }; static cvar_t* dm_max_players = Cvar_Get("dm_max_players", "0", CVAR_ARCHIVE); static cvar_t* dm_min_players = Cvar_Get("dm_min_players", "0", CVAR_ARCHIVE); static cvar_t* dm_show_demo_servers = Cvar_Get("dm_show_demo_servers", "1", CVAR_ARCHIVE); static cvar_t* dm_realism_mode = Cvar_Get("dm_realism_mode", "0", CVAR_ARCHIVE); static cvar_t* dm_filter_listen = Cvar_Get("dm_filter_listen", "1", CVAR_ARCHIVE); static cvar_t* dm_filter_empty = Cvar_Get("dm_filter_empty", "0", CVAR_ARCHIVE); static cvar_t* dm_filter_full = Cvar_Get("dm_filter_full", "0", CVAR_ARCHIVE); if (dm_min_players->integer) { AddFilter(filter, va("numplayers >= %d", dm_min_players->integer)); } if (dm_max_players->integer) { AddFilter(filter, va("numplayers <= %d", dm_max_players->integer)); } if (dm_show_demo_servers && !dm_show_demo_servers->integer) { AddFilter(filter, "gamever not like 'd%'"); } if (dm_realism_mode && dm_realism_mode->integer == 1) { AddFilter(filter, "realism=1"); } if (dm_filter_listen->integer == 1) { AddFilter(filter, "dedicated=1"); } if (dm_filter_empty && dm_filter_empty->integer) { AddFilter(filter, "numplayers > 0 "); } if (dm_filter_full && dm_filter_full->integer == 1) { AddFilter(filter, "numplayers < maxplayers"); } ServerListUpdate2(m_serverList[0], true, filter, GQueryType::qt_status); if (m_serverList[1]) { ServerListUpdate2(m_serverList[1], true, filter, GQueryType::qt_status); } } m_bUpdatingList = true; } void UIFAKKServerList::RefreshLANServerList( Event *ev ) { int i; FAKKServerListItem* pNewServerItem; for (i = 1; i <= getNumItems(); i++) { pNewServerItem = static_cast(GetItem(i)); pNewServerItem->SetQueried(false); pNewServerItem->SetNumPlayers(0); pNewServerItem->SetQueryFailed(false); } if (m_serverList[1]) { ServerListClear(m_serverList[1]); } if (m_serverList[0]) { ServerListClear(m_serverList[0]); } else { NewServerList(); } g_bDoneUpdating[0] = false; g_bDoneUpdating[1] = false; g_NeedAdditionalLANSearch = true; Cvar_Set("dm_playercount", "0"); // Search all LAN servers from port 12300 to 12316 ServerListLANUpdate(m_serverList[0], true, 12300, 12316, 1); if (m_serverList[1]) { // If another game is supported search for it ServerListLANUpdate(m_serverList[1], true, 12300, 12316, 1); } } static void AddFilter(char* filter, const char* value) { if (*filter) { strcat(filter, va(" and %s", value)); } else { strcpy(filter, value); } } void UIFAKKServerList::CancelRefresh( Event *ev ) { ServerListHalt(m_serverList[0]); if (m_serverList[1]) { ServerListHalt(m_serverList[1]); } } void UIFAKKServerList::NewServerList( void ) { int iNumConcurrent; const char* secret_key; const char* game_name; cvar_t* pRateCvar = Cvar_Get("rate", "5000", CVAR_ARCHIVE | CVAR_USERINFO); if (pRateCvar->integer <= 3000) { iNumConcurrent = 4; } else if (pRateCvar->integer <= 5000) { iNumConcurrent = 6; } else if (pRateCvar->integer <= 25000) { iNumConcurrent = 10; } else { iNumConcurrent = 15; } if (com_target_game->integer < target_game_e::TG_MOHTT) { game_name = GS_GetCurrentGameName(); secret_key = GS_GetCurrentGameKey(); // standard mohaa server g_ServerListInst[0].iServerType = com_target_game->integer; g_ServerListInst[0].serverList = this; m_serverList[0] = ServerListNew( game_name, game_name, secret_key, iNumConcurrent, (void*)&UpdateServerListCallBack, 1, (void*)&g_ServerListInst[0] ); m_serverList[1] = NULL; } else { static cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", 1); game_name = GS_GetGameName(target_game_e::TG_MOHTT); secret_key = GS_GetGameKey(target_game_e::TG_MOHTT); g_ServerListInst[0].iServerType = target_game_e::TG_MOHTT; g_ServerListInst[0].serverList = this; m_serverList[0] = ServerListNew( game_name, game_name, secret_key, iNumConcurrent, (void*)&UpdateServerListCallBack, 1, (void*)&g_ServerListInst[0] ); if (!dm_omit_spearhead->integer) { // Since mohtt is compatible with mohta // Search for both type of servers game_name = GS_GetGameName(target_game_e::TG_MOHTA); secret_key = GS_GetGameKey(target_game_e::TG_MOHTA); g_ServerListInst[1].iServerType = target_game_e::TG_MOHTA; g_ServerListInst[1].serverList = this; m_serverList[1] = ServerListNew( game_name, game_name, secret_key, iNumConcurrent, (void*)&UpdateServerListCallBack, 1, (void*)&g_ServerListInst[1] ); } } } void UIFAKKServerList::MakeLANListing( Event *ev ) { m_bLANListing = true; } void UIFAKKServerList::UpdateServer( Event *ev ) { if (m_currentItem <= 0) { return; } FAKKServerListItem* item = (FAKKServerListItem*)GetItem(getCurrentItem()); ServerListAuxUpdate(m_serverList[0], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status); if (com_target_game->integer >= target_game_e::TG_MOHTT) { const cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", CVAR_ARCHIVE); // check for Spearhead if (!dm_omit_spearhead->integer) { ServerListAuxUpdate(m_serverList[1], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status); } } } int UIFAKKServerList::ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname ) { int iCompResult; int val1, val2; const FAKKServerListItem* fi1 = static_cast(i1); const FAKKServerListItem* fi2 = static_cast(i2); if (fi1->IsFavorite() != fi2->IsFavorite()) { if (fi1->IsFavorite()) { iCompResult = -1; } else { iCompResult = 1; } if (g_bReverseSort) iCompResult = -iCompResult; } else if (fi1->IsQueried() != fi2->IsQueried()) { if (fi1->IsQueried()) { iCompResult = -1; } else { iCompResult = 1; } if (g_bReverseSort) iCompResult = -iCompResult; } else if (fi1->IsDifferentVersion() != fi2->IsDifferentVersion()) { if (fi1->IsDifferentVersion()) { iCompResult = 1; } else { iCompResult = -1; } if (g_bReverseSort) iCompResult = -iCompResult; } else if (fi1->IfQueryFailed() != fi2->IfQueryFailed()) { if (fi1->IfQueryFailed()) { iCompResult = 1; } else { iCompResult = -1; } if (g_bReverseSort) iCompResult = -iCompResult; } else if (g_bNumericSort) { val1 = fi1->getListItemValue(columnname); val2 = fi2->getListItemValue(columnname); if (val1 < val2) { iCompResult = -1; } else if (val1 > val2) { iCompResult = 1; } else { iCompResult = 0; } } else { iCompResult = str::icmp(fi1->getListItemString(columnname), fi2->getListItemString(columnname)); } if (!iCompResult) { if (columnname != -2) { val1 = fi1->getListItemValue(2); val2 = fi2->getListItemValue(2); if (val1 < val2) { iCompResult = -1; } else if (val1 > val2) { iCompResult = 1; } else { iCompResult = 0; } } if (!iCompResult) { if (columnname != 4) { iCompResult = str::icmp(fi1->getListItemString(4), fi2->getListItemString(4)); } } if (!iCompResult) { if (columnname != 5) { iCompResult = str::icmp(fi1->getListItemString(5), fi2->getListItemString(5)); } } if (!iCompResult) { if (columnname != 3) { val1 = fi1->getListItemValue(3); val2 = fi2->getListItemValue(3); if (val1 < val2) { iCompResult = 1; } else if (val1 > val2) { iCompResult = -1; } else { iCompResult = 0; } } } if (!iCompResult) { if (columnname != 0) { iCompResult = str::icmp(fi1->getListItemString(0), fi2->getListItemString(0)); } } if (!iCompResult) { if (columnname != -1) { iCompResult = str::icmp(fi1->getListItemString(1), fi2->getListItemString(1)); } } if (g_bReverseSort) iCompResult = -iCompResult; } return iCompResult; } void UIFAKKServerList::Draw( void ) { if (m_serverList[0]) { GServerListState listState[2]; ServerListThink(m_serverList[0]); if (m_serverList[1]) { ServerListThink(m_serverList[1]); } listState[0] = ServerListState(m_serverList[0]); listState[1] = m_serverList[1] ? ServerListState(m_serverList[1]) : GServerListState::sl_idle; if (listState[0] != GServerListState::sl_idle || listState[1] != GServerListState::sl_idle) { menuManager.PassEventToWidget("refresh", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("cancelrefresh", new Event(EV_Widget_Enable)); } else { menuManager.PassEventToWidget("refresh", new Event(EV_Widget_Enable)); menuManager.PassEventToWidget("cancelrefresh", new Event(EV_Widget_Disable)); } } else if (!m_bHasList) { if (m_bLANListing) { RefreshLANServerList(NULL); } else { RefreshServerList(NULL); } m_bHasList = true; menuManager.PassEventToWidget("refresh", new Event(EV_Widget_Enable)); menuManager.PassEventToWidget("cancelrefresh", new Event(EV_Widget_Disable)); if (g_NeedAdditionalLANSearch) { g_NeedAdditionalLANSearch = false; ServerListLANUpdate(m_serverList[0], true, 12201, 12233, 1); if (m_serverList[1]) { ServerListLANUpdate(m_serverList[1], true, 12201, 12233, 1); } } } UIListCtrl::Draw(); } void UIFAKKServerList::SortByColumn( int column ) { int i; bool exists = 0; bool numeric = 0; bool reverse = 0; UIListCtrlItem* selected = NULL; bool selvisible = false; for (i = 1; i <= m_columnlist.NumObjects(); i++) { const columndef_t& def = m_columnlist.ObjectAt(i); if (def.name == column) { // found one numeric = def.numeric; reverse = def.reverse_sort; exists = true; break; } } if (!exists) { m_iLastSortColumn = 0; return; } m_iLastSortColumn = column; s_qsortcolumn = column; s_qsortobject = this; s_qsortreverse = reverse; g_bNumericSort = numeric; g_bReverseSort = reverse; if (getCurrentItem()) { selected = m_itemlist.ObjectAt(getCurrentItem()); if (GetScrollBar()) { selvisible = getCurrentItem() >= GetScrollBar()->getTopItem() + 1 && getCurrentItem() <= GetScrollBar()->getPageHeight() + GetScrollBar()->getTopItem(); } else { selvisible = getCurrentItem() > 0; } } setCompareFunction(&UIFAKKServerList::ServerCompareFunction); if (m_itemlist.NumObjects()) { m_itemlist.Sort(&UIListCtrl::QsortCompare); } if (selected) { if (selvisible) { TrySelectItem(FindItem(selected)); } else { m_currentItem = FindItem(selected); } } } void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, void* param1, void* param2) { int i, j; int iPort, iGameSpyPort; unsigned int iRealIP; str sAddress; GServer server; FAKKServerListItem* pNewServerItem; static int iServerQueryCount = 0; static int iServerTotalCount = 0; UIFAKKServerList* uiServerList; int iServerType; // filters static cvar_t* dm_filter_empty = Cvar_Get("dm_filter_empty", "0", CVAR_ARCHIVE); static cvar_t* dm_filter_full = Cvar_Get("dm_filter_full", "0", CVAR_ARCHIVE); static cvar_t* dm_filter_pure = Cvar_Get("dm_filter_pure", "0", CVAR_ARCHIVE); static cvar_t* dm_max_ping = Cvar_Get("dm_max_ping", "0", CVAR_ARCHIVE); static cvar_t* dm_free_for_all = Cvar_Get("dm_free_for_all", "1", CVAR_ARCHIVE); static cvar_t* dm_objective_match = Cvar_Get("dm_objective_match", "1", CVAR_ARCHIVE); static cvar_t* dm_round_based_match = Cvar_Get("dm_round_based_match", "1", CVAR_ARCHIVE); static cvar_t* dm_team_match = Cvar_Get("dm_team_match", "1", CVAR_ARCHIVE); static cvar_t* dm_tow_match = Cvar_Get("dm_tow_match", "1", CVAR_ARCHIVE); static cvar_t* dm_liberation_match = Cvar_Get("dm_liberation_match", "1", CVAR_ARCHIVE); static cvar_t* dm_run_fast = Cvar_Get("dm_run_fast", "1", CVAR_ARCHIVE); static cvar_t* dm_run_normal = Cvar_Get("dm_run_normal", "1", CVAR_ARCHIVE); static cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", CVAR_ARCHIVE); iServerType = ((ServerListInstance*)instance)->iServerType; uiServerList = ((ServerListInstance*)instance)->serverList; pNewServerItem = NULL; server = (GServer)param1; if (param2) { if (msg == LIST_PROGRESS && param2 == (void*)-1) { iRealIP = inet_addr(ServerGetAddress(server)); ServerGetIntValue(server, "hostport", PORT_SERVER); iGameSpyPort = ServerGetQueryPort(server); for (i = 1; i <= uiServerList->getNumItems(); i++) { pNewServerItem = static_cast(uiServerList->GetItem(i)); if (pNewServerItem->m_uiRealIP == iRealIP && pNewServerItem->m_iGameSpyPort == iGameSpyPort) { break; } } if (i <= uiServerList->getNumItems() && pNewServerItem) { pNewServerItem->SetQueryFailed(true); } return; } Cvar_Set("dm_serverstatusbar", va("%i", (int)(uintptr_t)param2)); } if (msg == LIST_PROGRESS) { const char* pszHostName; bool bDiffVersion; bool bIsDemo; str sServerName; str sPlayers; const char* pszGameVer; const char* pszGameVerNumber; pszHostName = ServerGetStringValue(server, "hostname", "(NONE)"); bDiffVersion = false; bIsDemo = false; pszGameVer = ServerGetStringValue(server, "gamever", "1.00"); pszGameVerNumber = pszGameVer; if (pszGameVerNumber[0] == 'd') { // demo server pszGameVerNumber++; bIsDemo = true; } if (com_target_game->integer >= target_game_e::TG_MOHTT) { if (iServerType == target_game_e::TG_MOHTT) { //if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) { // bDiffVersion = true; //} if (fabs(atof(pszGameVerNumber)) < 2.3f) { bDiffVersion = true; } } else { //if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.3f) { // bDiffVersion = true; //} if (fabs(atof(pszGameVerNumber)) < 2.1f) { bDiffVersion = true; } } } else { if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) { bDiffVersion = true; } } // always show the version if (!bIsDemo) { sServerName = va(" (%s) %s", pszGameVerNumber, pszHostName); } else { sServerName = va(" (d%s) %s", pszGameVerNumber, pszHostName); } iRealIP = inet_addr(ServerGetAddress(server)); iPort = ServerGetIntValue(server, "hostport", PORT_SERVER); iGameSpyPort = ServerGetQueryPort(server); sAddress = va("%s:%i", ServerGetAddress(server), iPort); sPlayers = va("%d/%d", ServerGetIntValue(server, "numplayers", 0), ServerGetIntValue(server, "maxplayers", 0)); for (i = 1; i <= uiServerList->getNumItems(); i++) { pNewServerItem = static_cast(uiServerList->GetItem(i)); if (pNewServerItem->m_uiRealIP == iRealIP && pNewServerItem->m_iGameSpyPort == iGameSpyPort) { break; } } if (i > uiServerList->getNumItems() || !pNewServerItem) { pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?"); pNewServerItem->m_sIP = ServerGetAddress(server); pNewServerItem->m_uiRealIP = iRealIP; pNewServerItem->m_iGameSpyPort = iGameSpyPort; uiServerList->AddItem(pNewServerItem); } pNewServerItem->m_iPort = iPort; pNewServerItem->setListItemString(0, sServerName); pNewServerItem->setListItemString(1, sAddress); pNewServerItem->setListItemString(2, va("%d", ServerGetPing(server))); pNewServerItem->setListItemString(3, sPlayers.c_str()); pNewServerItem->setListItemString(4, ServerGetStringValue(server, "gametype", "(NONE)")); pNewServerItem->setListItemString(5, ServerGetStringValue(server, "mapname", "(NONE)")); pNewServerItem->SetListItemVersion(pszGameVer); pNewServerItem->SetDifferentVersion(bDiffVersion); pNewServerItem->SetQueried(true); pNewServerItem->SetNumPlayers(ServerGetIntValue(server, "numplayers", 0)); iServerQueryCount++; Cvar_Set("dm_servercount", va("%d/%d", iServerQueryCount, iServerTotalCount)); uiServerList->SortByLastSortColumn(); } else if (msg == LIST_STATECHANGED) { switch (ServerListState(serverlist)) { case GServerListState::sl_idle: if (com_target_game->integer >= target_game_e::TG_MOHTT) { if (iServerType == target_game_e::TG_MOHTT) { g_bDoneUpdating[0] = true; } else if (iServerType == target_game_e::TG_MOHTA || dm_omit_spearhead->integer) { g_bDoneUpdating[1] = true; } } else { g_bDoneUpdating[0] = true; g_bDoneUpdating[1] = true; } if (g_bDoneUpdating[0] && g_bDoneUpdating[1]) { Cvar_Set("dm_serverstatus", "Done Updating."); Cvar_Set("dm_serverstatusbar", "0"); uiServerList->m_bUpdatingList = false; Cvar_Set("dm_servercount", va("%d", uiServerList->getNumItems())); uiServerList->SortByLastSortColumn(); } break; case GServerListState::sl_listxfer: Cvar_Set("dm_serverstatus", "Getting List."); if (com_target_game->integer >= target_game_e::TG_MOHTT) { if (iServerType == target_game_e::TG_MOHTT) uiServerList->m_bGettingList[0] = true; if (iServerType == target_game_e::TG_MOHTA) uiServerList->m_bGettingList[1] = true; } else { uiServerList->m_bGettingList[0] = true; uiServerList->m_bGettingList[1] = false; } uiServerList->m_bUpdatingList = true; iServerQueryCount = 0; return; case GServerListState::sl_lanlist: Cvar_Set("dm_serverstatus", "Searching LAN."); uiServerList->m_bUpdatingList = true; break; case GServerListState::sl_querying: Cvar_Set("dm_serverstatus", "Querying Servers."); uiServerList->m_bUpdatingList = true; iServerQueryCount = 0; iServerTotalCount = 0; break; default: break; } if (!uiServerList->m_bGettingList[0] && !uiServerList->m_bGettingList[1]) { return; } iServerTotalCount += ServerListCount(serverlist); // Removed in 2.0 // Only add entries for servers that are queried successfully // it avoids unnecessary entries #if 0 for (j = 0; j < ServerListCount(serverlist); j++) { GServer arrayServer = ServerListGetServer(serverlist, j); iRealIP = inet_addr(ServerGetAddress(arrayServer)); iGameSpyPort = ServerGetQueryPort(arrayServer); for (i = 1; i <= uiServerList->getNumItems(); i++) { pNewServerItem = static_cast(uiServerList->GetItem(i)); if (pNewServerItem->m_uiRealIP == iRealIP && pNewServerItem->m_iGameSpyPort == iGameSpyPort) { break; } } if (i <= uiServerList->getNumItems() && pNewServerItem) { continue; } pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?"); pNewServerItem->m_sIP = ServerGetAddress(arrayServer); pNewServerItem->m_uiRealIP = iRealIP; pNewServerItem->m_iPort = PORT_SERVER; pNewServerItem->m_iGameSpyPort = iGameSpyPort; pNewServerItem->SetDifferentVersion(false); pNewServerItem->SetQueried(false); uiServerList->AddItem(pNewServerItem); } #endif /* for (i = 1; i <= uiServerList->getNumItems(); i++) { pNewServerItem = static_cast(uiServerList->GetItem(i)); if (!pNewServerItem->IsFavorite()) { for (j = 0; j < ServerListCount(serverlist); j++) { GServer arrayServer = ServerListGetServer(serverlist, j); iRealIP = inet_addr(ServerGetAddress(arrayServer)); iGameSpyPort = ServerGetQueryPort(arrayServer); if (pNewServerItem->m_uiRealIP == iRealIP && pNewServerItem->m_iGameSpyPort == iGameSpyPort) { break; } } if (j == ServerListCount(serverlist)) { uiServerList->DeleteItem(j); j--; } } } */ } }