Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
981 changes: 601 additions & 380 deletions src/game/client/neo/ui/neo_root.cpp

Large diffs are not rendered by default.

36 changes: 33 additions & 3 deletions src/game/client/neo/ui/neo_root.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,22 @@
#include <vgui_controls/EditablePanel.h>
#include "GameUI/IGameUI.h"
#include <steam/isteamhttp.h>

// GCC shipped on SteamRT3 giving false positive
#ifdef ACTUALLY_COMPILER_GCC
#pragma GCC diagnostic push
#if ((__GNUC__ >= 10) && (__GNUC__ <= 13))
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
#endif

#include <steam/steam_api.h>

#ifdef ACTUALLY_COMPILER_GCC
#pragma GCC diagnostic pop
#endif

#include "neo_ui.h"
#include "neo_root_serverbrowser.h"
#include "neo_root_settings.h"
Expand Down Expand Up @@ -139,6 +153,7 @@ class CNeoRoot : public vgui::EditablePanel, public CGameEventListener
void OnTick() final;
void FireGameEvent(IGameEvent *event) final;

void OnEnterServer(const gameserveritem_t gameServer, const char *pszServerPassword);
void OnMainLoop(const NeoUI::Mode eMode);

struct MainLoopParam
Expand Down Expand Up @@ -172,10 +187,10 @@ class CNeoRoot : public vgui::EditablePanel, public CGameEventListener
int m_iServerBrowserTab = 0;
CNeoServerList m_serverBrowser[GS__TOTAL];
CNeoServerPlayers m_serverPlayers;
ServerBrowserFilters m_sbFilters;
bool m_bSBFiltModified = false;
ServerBrowserFilters m_sbFilters = {};
NeoUI::TableHeaderModFlags m_headerModFlagsServerBrowser = 0;
bool m_bShowFilterPanel = false;
bool m_bSPlayersSortModified = false;
NeoUI::TableHeaderModFlags m_headerModFlagsPlayers = 0;
GameServerSortContext m_sortCtx = {};

wchar_t m_wszBindingText[128];
Expand Down Expand Up @@ -231,6 +246,21 @@ class CNeoRoot : public vgui::EditablePanel, public CGameEventListener
servernetadr_t m_favCacheNetAdr = {};
bool m_bFavCacheIsFav = false;
bool m_bAutoRefreshFav = false;

int m_iColsWideServerBrowser[GSIW__TOTAL] = {};
int m_iColsWideServerBlacklist[SBLIST_COL__TOTAL] = {};
int m_iColsWideDetailedPlayerList[GSPS__TOTAL] = {};

int m_iUpDownInitialServer = -1;
int m_iUpDownDirection = 0;

NeoUI::TabsState m_tabsStateSettings = {};
NeoUI::TabsState m_tabsStateServerBrowser = {};
NeoUI::TabsState m_tabsStateIFF = {};

float m_flAutoJoinLastAttempt = 0.0f;
CNeoServerPing m_serverPingAutoJoin = {};
CNeoServerPing m_serverPingEnter = {};
};

extern CNeoRoot *g_pNeoRoot;
64 changes: 57 additions & 7 deletions src/game/client/neo/ui/neo_root_serverbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,14 @@ void CNeoServerList::UpdateFilteredList()
}

gameserveritem_t curGsi;
if (IN_BETWEEN_AR(0, g_pNeoRoot->m_iSelectedServer, m_filteredServers.Count()))
if (IN_BETWEEN_AR(0, g_pNeoRoot->m_iSelectedServer, m_filteredServers.size()))
{
V_memcpy(&curGsi, &m_filteredServers[g_pNeoRoot->m_iSelectedServer], sizeof(gameserveritem_t));
}

m_filteredServers = m_servers;
if (m_filteredServers.IsEmpty())

if (m_filteredServers.empty())
{
g_pNeoRoot->m_iSelectedServer = -1;
return;
Expand Down Expand Up @@ -258,6 +259,10 @@ void CNeoServerList::UpdateFilteredList()
iLeft = gsiLeft.m_nPing;
iRight = gsiRight.m_nPing;
break;
case GSIW_IP_ADDRESS:
iLeft = gsiLeft.m_NetAdr.GetIP();
iRight = gsiRight.m_NetAdr.GetIP();
break;
case GSIW_NAME:
default:
// no-op, already assigned (default)
Expand All @@ -272,6 +277,7 @@ void CNeoServerList::UpdateFilteredList()
break;
case GSIW_PLAYERS:
case GSIW_PING:
case GSIW_IP_ADDRESS:
if (iLeft != iRight) return (m_pSortCtx->bDescending) ? iLeft < iRight : iLeft > iRight;
break;
default:
Expand All @@ -280,10 +286,10 @@ void CNeoServerList::UpdateFilteredList()
return (m_pSortCtx->bDescending) ? (V_strcmp(szRight, szLeft) > 0) : (V_strcmp(szLeft, szRight) > 0);
});

if (IN_BETWEEN_AR(0, g_pNeoRoot->m_iSelectedServer, m_filteredServers.Count()))
if (IN_BETWEEN_AR(0, g_pNeoRoot->m_iSelectedServer, m_filteredServers.size()))
{
g_pNeoRoot->m_iSelectedServer = -1;
for (int i = 0; i < m_filteredServers.Count(); ++i)
for (int i = 0; i < m_filteredServers.size(); ++i)
{
if (V_memcmp(&curGsi, &m_filteredServers[i], sizeof(gameserveritem_t)) == 0)
{
Expand All @@ -301,6 +307,8 @@ void CNeoServerList::RequestList()
return;
}

m_servers.clear();

static MatchMakingKeyValuePair_t mmFilters[] = {
{"gamedir", "neo"},
};
Expand Down Expand Up @@ -331,9 +339,26 @@ void CNeoServerList::ServerResponded(HServerListRequest hRequest, int iServer)

ISteamMatchmakingServers *steamMM = steamapicontext->SteamMatchmakingServers();
gameserveritem_t *pServerDetails = steamMM->GetServerDetails(hRequest, iServer);
if (pServerDetails)
if (pServerDetails && m_servers.size() < 1024)
{
m_servers.AddToTail(*pServerDetails);
wchar_t wszServerName[k_cbMaxGameServerName] = {};
g_pVGuiLocalize->ConvertANSIToUnicode(
pServerDetails->GetName(), wszServerName, sizeof(wszServerName));
const int iWszLen = V_wcslen(wszServerName);
// NEO TODO (nullsystem): Need to implement fallback fonts in NeoUI or otherwise
// without fallback unicode fonts can corrupt the memory on drawing the text somehow
for (int i = 0; i < iWszLen; ++i)
{
if (wszServerName[i] >= 256)
{
wszServerName[i] = L'?';
}
}
char szServerName[k_cbMaxGameServerName] = {};
g_pVGuiLocalize->ConvertUnicodeToANSI(wszServerName, szServerName, sizeof(szServerName));
Q_UnicodeRepair(szServerName);
pServerDetails->SetName(szServerName);
m_servers.push_back(*pServerDetails);
m_bModified = true;
}
}
Expand All @@ -350,7 +375,7 @@ void CNeoServerList::RefreshComplete(HServerListRequest hRequest, EMatchMakingSe
if (m_iType == GS_BLACKLIST || hRequest != m_hdlRequest) return;

m_bSearching = false;
if (response == eNoServersListedOnMasterServer && m_servers.IsEmpty())
if (response == eNoServersListedOnMasterServer && m_servers.empty())
{
m_bModified = true;
}
Expand Down Expand Up @@ -431,3 +456,28 @@ void CNeoServerPlayers::PlayersRefreshComplete()
{
m_hdlQuery = HSERVERQUERY_INVALID;
}

void CNeoServerPing::RequestPing()
{
auto *steamMM = steamapicontext->SteamMatchmakingServers();
if (m_hdlPing != HSERVERQUERY_INVALID)
{
steamMM->CancelServerQuery(m_hdlPing);
}
const uint32 unIP = m_serverInfo.m_NetAdr.GetIP();
const uint16 usPort = m_serverInfo.m_NetAdr.GetQueryPort();
m_hdlPing = steamMM->PingServer(unIP, usPort, this);
m_ePingState = PINGSTATE_NIL;
}

void CNeoServerPing::ServerResponded(gameserveritem_t &server)
{
m_serverInfo = server;
m_ePingState = PINGSTATE_SUCCESS;
}

void CNeoServerPing::ServerFailedToRespond()
{
m_ePingState = PINGSTATE_FAILED;
}

58 changes: 55 additions & 3 deletions src/game/client/neo/ui/neo_root_serverbrowser.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
#pragma once

#include <tier1/netadr.h>

// GCC shipped on SteamRT3 giving false positive
#ifdef ACTUALLY_COMPILER_GCC
#pragma GCC diagnostic push
#if ((__GNUC__ >= 10) && (__GNUC__ <= 13))
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
#endif

#include <steam/isteammatchmaking.h>

#ifdef ACTUALLY_COMPILER_GCC
#pragma GCC diagnostic pop
#endif

#include <utlvector.h>
#include <vector>

enum EServerBlacklistType
{
Expand Down Expand Up @@ -64,9 +80,11 @@ enum GameServerInfoW
GSIW_LOCKED = 0,
GSIW_VAC,
GSIW_NAME,
GSIW_IP_ADDRESS,
GSIW_MAP,
GSIW_PLAYERS,
GSIW_PING,
GSIW_TAGS,

GSIW__TOTAL,
};
Expand All @@ -80,6 +98,14 @@ enum AntiCheatMode
ANTICHEAT__TOTAL,
};

enum ETagsFilterMode
{
TAGSFILTER_INCLUDE = 0,
TAGSFILTER_EXCLUDE,

TAGSFILTER__TOTAL,
};

enum GameServerPlayerSort
{
GSPS_SCORE = 0,
Expand All @@ -101,16 +127,19 @@ struct GameServerSortContext

struct GameServerPlayerSortContext
{
GameServerPlayerSort col = GSPS_SCORE;
int col = GSPS_SCORE;
bool bDescending = true;
};

class CNeoServerList : public ISteamMatchmakingServerListResponse
{
public:
GameServerType m_iType;
CUtlVector<gameserveritem_t> m_servers;
CUtlVector<gameserveritem_t> m_filteredServers;

// NEO JANK (nullsystem): CUtlVector easily corrupts memory with
// gameserveritem_t results, so using std::vector instead
std::vector<gameserveritem_t> m_servers;
std::vector<gameserveritem_t> m_filteredServers;

void UpdateFilteredList();
void RequestList();
Expand Down Expand Up @@ -148,11 +177,34 @@ class CNeoServerPlayers : public ISteamMatchmakingPlayersResponse
GameServerPlayerSortContext m_sortCtx;
};

class CNeoServerPing : public ISteamMatchmakingPingResponse
{
public:
void RequestPing();
void ServerResponded(gameserveritem_t &server) final;
void ServerFailedToRespond() final;
HServerQuery m_hdlPing = HSERVERQUERY_INVALID;
gameserveritem_t m_serverInfo = {};

enum EPingState
{
PINGSTATE_NIL = 0, // Either pinging or inactive
PINGSTATE_SUCCESS,
PINGSTATE_FAILED,
};
EPingState m_ePingState = PINGSTATE_NIL;
};

struct ServerBrowserFilters
{
bool bServerNotFull = false;
bool bHasUsersPlaying = false;
bool bIsNotPasswordProtected = false;
int iAntiCheat = 0;
int iMaxPing = 0;
wchar_t wszMapFilter[k_cbMaxGameServerMapName] = {};
int iMaxPlayerCount = 0;
int iTagsFilterType = 0;
wchar_t wszTagsFilter[k_cbMaxGameServerTags] = {};
};

3 changes: 2 additions & 1 deletion src/game/client/neo/ui/neo_root_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,8 @@ void NeoSettings_HUD(NeoSettings *ns)

NeoUI::SetPerRowLayout(1);
NeoUI::Tabs(IFF_LABELS, iIFFLabelsSize, &optionChosen,
NeoUI::TABFLAG_NOSIDEKEYS | NeoUI::TABFLAG_NOSTATERESETS);
NeoUI::TABFLAG_NOSIDEKEYS | NeoUI::TABFLAG_NOSTATERESETS,
&g_pNeoRoot->m_tabsStateIFF);
NeoUI::SetPerRowLayout(2, NeoUI::ROWLAYOUT_TWOSPLIT);

// NEO TODO (Adam) Show what the marker looks like somewhere here
Expand Down
3 changes: 3 additions & 0 deletions src/game/client/neo/ui/neo_theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ void SetupNTRETheme(NeoUI::Context *pNeoUICtx)
pColors->sliderHotBg = COLOR_GREY;
pColors->sliderActiveBg = COLOR_BLACK;
pColors->tabHintsFg = COLOR_WHITE;
pColors->tableHeaderSortIndicatorBg = COLOR_WHITE;
pColors->headerDragNormalBg = COLOR_FADED_WHITE;
pColors->headerDragActiveBg = COLOR_DARK_RED;
}

Loading
Loading