Skip to content
Merged
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
3 changes: 2 additions & 1 deletion mp/src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,15 @@ if(OS_WINDOWS)
AVI_VIDEO
WMV_VIDEO
fopen=dont_use_fopen

PSAPI_VERSION=1
)

target_link_libraries(client
PRIVATE
legacy_stdio_definitions.lib
#winmm.lib
libz
Psapi.lib
)
endif()

Expand Down
13 changes: 13 additions & 0 deletions mp/src/game/client/c_playerresource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ BEGIN_PREDICTION_DATA( C_PlayerResource )

END_PREDICTION_DATA()

#ifdef NEO
extern ConVar neo_cl_streamermode;
#endif

C_PlayerResource *g_PR;

IGameResources * GameResources( void ) { return g_PR; }
Expand Down Expand Up @@ -187,6 +191,15 @@ const char *C_PlayerResource::GetPlayerName( int iIndex )
}

#ifdef NEO
if (neo_cl_streamermode.GetBool() && !IsLocalPlayer(iIndex))
{
[[maybe_unused]] uchar32 u32Out;
bool bError = false;
const int iSize = Q_UTF8ToUChar32(m_szName[iIndex], u32Out, bError);
if (!bError) V_memcpy(gStreamerModeNames[iIndex], m_szName[iIndex], iSize);
return gStreamerModeNames[iIndex];
}

const bool clientWantNeoName = C_NEO_Player::GetLocalNEOPlayer()->ClientWantNeoName();
const int dupeIdx = m_iNeoNameDupeIdx[iIndex];

Expand Down
73 changes: 73 additions & 0 deletions mp/src/game/client/cdll_client_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,19 @@ extern vgui::IInputInternal *g_InputInternal;
#include "neo_version.h"
#include "neo_mount_original.h"
#include "ui/neo_loading.h"
#include "neo_player_shared.h"
extern bool NeoRootCaptureESC();
extern CNeoLoading *g_pNeoLoading;
extern ConVar neo_cl_streamermode_autodetect_obs;
bool g_bOBSDetected = false;

#ifdef WIN32
#include <windows.h>
#include <tchar.h>
#include <psapi.h>
#include <tlhelp32.h>
#undef CreateEvent
#endif

#ifdef LINUX
#include "neo_fixup_glshaders.h"
Expand Down Expand Up @@ -1273,7 +1284,69 @@ void CHLClient::PostInit()
}

NeoToggleConsoleEnforce();

// Detect OBS - Only on startup
if (neo_cl_streamermode_autodetect_obs.GetBool())
{
g_bOBSDetected = false;
#ifdef LINUX
FileFindHandle_t findHdl;
for (const char *pszFilename = filesystem->FindFirst("/proc/*", &findHdl);
Comment thread
nullsystem marked this conversation as resolved.
pszFilename && !g_bOBSDetected;
pszFilename = filesystem->FindNext(findHdl))
{
if (!filesystem->FindIsDirectory(findHdl))
{
continue;
}

char szCmdlinePath[MAX_PATH];
V_sprintf_safe(szCmdlinePath, "/proc/%s/cmdline", pszFilename);
if (!filesystem->FileExists(szCmdlinePath))
{
continue;
}

// NEO NOTE (nullsystem): At this point, cannot just do filesystem->ReadFile
// as it won't output anything. Instead just cat the file and fetch the line.
char szCmdCat[sizeof(szCmdlinePath) + 16];
V_sprintf_safe(szCmdCat, "cat \"%s\"", szCmdlinePath);
FILE *fp = popen(szCmdCat, "r");
if (fp)
{
char szCmdline[512] = {};
if (fgets(szCmdline, sizeof(szCmdline), fp))
{
// NEO TODO (nullsystem): Check on OBS flatpak, snaps, nix, and appimage.
// Could they give out different cmdline?
g_bOBSDetected = (V_strcmp(szCmdline, "obs") == 0);
}
pclose(fp);
}
}
filesystem->FindClose(findHdl);
#else // WIN32
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 processInfo = {};
processInfo.dwSize = sizeof(PROCESSENTRY32);
while (!g_bOBSDetected && Process32Next(hSnapShot, &processInfo) != FALSE)
{
g_bOBSDetected = (V_strcmp(processInfo.szExeFile, "obs64.exe") == 0);
}
CloseHandle(hSnapShot);
}
#endif
ConVarRef("neo_cl_streamermode").SetValue(g_bOBSDetected);
}

// Initialize streamer mode names
for (int i = 0; i < MAX_PLAYERS + 1; ++i)
{
V_memset(gStreamerModeNames[i], '.', 5);
}
#endif // NEO
}

//-----------------------------------------------------------------------------
Expand Down
16 changes: 16 additions & 0 deletions mp/src/game/client/clientmode_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class CHudVote;

#ifdef NEO
static CDllDemandLoader g_gameUI("GameUI");
extern ConVar neo_cl_streamermode;
#endif

static vgui::HContext s_hVGuiContext = DEFAULT_VGUI_CONTEXT;
Expand Down Expand Up @@ -1064,6 +1065,13 @@ void ClientModeShared::FireGameEvent( IGameEvent *event )

if ( !IsInCommentaryMode() )
{
#ifdef NEO
if (neo_cl_streamermode.GetBool())
{
hudChat->Printf(CHAT_FILTER_JOINLEAVE, "Player connected");
return;
}
#endif
wchar_t wszLocalized[100];
wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
g_pVGuiLocalize->ConvertANSIToUnicode( event->GetString("name"), wszPlayerName, sizeof(wszPlayerName) );
Expand All @@ -1077,6 +1085,14 @@ void ClientModeShared::FireGameEvent( IGameEvent *event )
}
else if ( Q_strcmp( "player_disconnect", eventname ) == 0 )
{
#ifdef NEO
if (neo_cl_streamermode.GetBool())
{
hudChat->Printf(CHAT_FILTER_JOINLEAVE, "Player disconnected");
return;
}
#endif

C_BasePlayer *pPlayer = USERID2PLAYER( event->GetInt("userid") );

if ( !hudChat || !pPlayer )
Expand Down
25 changes: 24 additions & 1 deletion mp/src/game/client/hud_basechat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ Color g_ColorDarkGreen( 64, 255, 64, 255 );
Color g_ColorYellow( 255, 178, 0, 255 );
Color g_ColorGrey( 204, 204, 204, 255 );

#ifdef NEO
extern ConVar neo_cl_streamermode;
#endif

// removes all color markup characters, so Msg can deal with the string properly
// returns a pointer to str
Expand Down Expand Up @@ -833,6 +836,14 @@ void CBaseHudChat::MsgFunc_SayText2( bf_read &msg )
ReadLocalizedString( msg, szBuf[3], sizeof( szBuf[3] ), true );
ReadLocalizedString( msg, szBuf[4], sizeof( szBuf[4] ), true );

#ifdef NEO
if (neo_cl_streamermode.GetBool())
{
V_memset(szBuf[1], 0, sizeof(szBuf[1]));
g_pVGuiLocalize->ConvertANSIToUnicode(g_PR->GetPlayerName(client), szBuf[1], sizeof(szBuf[1]));
}
#endif

g_pVGuiLocalize->ConstructString( szBuf[5], sizeof( szBuf[5] ), msg_text, 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] );

char ansiString[512];
Expand Down Expand Up @@ -1841,6 +1852,18 @@ void CBaseHudChat::ChatPrintf( int iPlayerIndex, int iFilter, const char *fmt, .
return;
}

#ifdef NEO
if (neo_cl_streamermode.GetBool())
{
auto neoPlayer = static_cast<CNEO_Player *>(UTIL_PlayerByIndex(iPlayerIndex));
if (neoPlayer && !neoPlayer->IsLocalPlayer())
{
// Only print local player's chat in streamer mode
return;
}
}
#endif

// If a player is muted for voice, also mute them for text because jerks gonna jerk.
if ( cl_mute_all_comms.GetBool() && iPlayerIndex != 0 )
{
Expand Down Expand Up @@ -1943,4 +1966,4 @@ void CBaseHudChat::FireGameEvent( IGameEvent *event )
ChatPrintf( player->entindex(), CHAT_FILTER_NONE, "(SourceTV) %s", event->GetString( "text" ) );
}
#endif
}
}
18 changes: 17 additions & 1 deletion mp/src/game/client/neo/c_neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ USER_MESSAGE_REGISTER(IdleRespawnShowMenu);
ConVar cl_drawhud_quickinfo("cl_drawhud_quickinfo", "0", 0,
"Whether to display HL2 style ammo/health info near crosshair.",
true, 0.0f, true, 1.0f);
ConVar neo_cl_streamermode("neo_cl_streamermode", "0", FCVAR_ARCHIVE | FCVAR_USERINFO, "Streamer mode turns player names into generic names and hide avatars.", true, 0.0f, true, 1.0f);
ConVar neo_cl_streamermode_autodetect_obs("neo_cl_streamermode_autodetect_obs", "0", FCVAR_ARCHIVE, "Automatically turn neo_cl_streamermode on if OBS was detected on startup.", true, 0.0f, true, 1.0f);

class NeoLoadoutMenu_Cb : public ICommandCallback
{
Expand Down Expand Up @@ -553,7 +555,7 @@ int C_NEO_Player::GetAttackersScores(const int attackerIdx) const
return min(m_rfAttackersScores.Get(attackerIdx), 100);
}

const char *C_NEO_Player::GetNeoPlayerName() const
const char *C_NEO_Player::InternalGetNeoPlayerName() const
{
const int dupePos = m_szNameDupePos;
const bool localWantNeoName = GetLocalNEOPlayer()->ClientWantNeoName();
Expand Down Expand Up @@ -585,6 +587,20 @@ const char *C_NEO_Player::GetNeoPlayerName() const
return stndName;
}

const char *C_NEO_Player::GetNeoPlayerName() const
{
if (neo_cl_streamermode.GetBool() && !IsLocalPlayer())
{
[[maybe_unused]] uchar32 u32Out;
bool bError = false;
const char *pSzName = InternalGetNeoPlayerName();
const int iSize = Q_UTF8ToUChar32(pSzName, u32Out, bError);
if (!bError) V_memcpy(gStreamerModeNames[entindex()], pSzName, iSize);
return gStreamerModeNames[entindex()];
}
return InternalGetNeoPlayerName();
}

bool C_NEO_Player::ClientWantNeoName() const
{
return m_bClientWantNeoName;
Expand Down
1 change: 1 addition & 0 deletions mp/src/game/client/neo/c_neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class C_NEO_Player : public C_HL2MP_Player
int GetAttackersScores(const int attackerIdx) const;
int GetAttackerHits(const int attackerIdx) const;

const char *InternalGetNeoPlayerName() const;
Comment thread
nullsystem marked this conversation as resolved.
const char *GetNeoPlayerName() const;
bool ClientWantNeoName() const;

Expand Down
8 changes: 7 additions & 1 deletion mp/src/game/client/neo/ui/neo_hud_round_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ ConVar neo_cl_squad_hud_original("neo_cl_squad_hud_original", "0", FCVAR_ARCHIVE

ConVar neo_cl_squad_hud_star_scale("neo_cl_squad_hud_star_scale", "0", FCVAR_ARCHIVE, "Scaling to apply from 1080p, 0 disables scaling");
extern ConVar neo_sv_dm_win_xp;
extern ConVar neo_cl_streamermode;

namespace {
constexpr int Y_POS = 2;
Expand Down Expand Up @@ -775,13 +776,18 @@ void CNEOHud_RoundState::UpdatePlayerAvatar(int playerIndex)

void CNEOHud_RoundState::SetTextureToAvatar(int playerIndex)
{
if (neo_cl_streamermode.GetBool())
{
return;
}

player_info_t pi;
if (!engine->GetPlayerInfo(playerIndex, &pi))
return;

if (!pi.friendsID)
return;

CSteamID steamIDForPlayer(pi.friendsID, 1, steamapicontext->SteamUtils()->GetConnectedUniverse(), k_EAccountTypeIndividual);
const int mapIndex = m_mapAvatarsToImageList.Find(steamIDForPlayer);
if ((mapIndex == m_mapAvatarsToImageList.InvalidIndex()))
Expand Down
42 changes: 26 additions & 16 deletions mp/src/game/client/neo/ui/neo_root.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static CDllDemandLoader g_GameUIDLL("GameUI");

extern ConVar neo_name;
extern ConVar cl_onlysteamnick;
extern ConVar neo_cl_streamermode;

CNeoRoot *g_pNeoRoot = nullptr;
void NeoToggleconsole();
Expand Down Expand Up @@ -646,15 +647,18 @@ void CNeoRoot::MainLoopRoot(const MainLoopParam param)
int iStatusTall = 0;
if (eCurStatus != k_EPersonaStateMax)
{
const wchar_t *wszState = WSZ_PERSONA_STATES[static_cast<int>(eCurStatus)];
wchar_t wszStatusTotal[48];
const int iStatusTotalSize = V_swprintf_safe(wszStatusTotal, L"%ls%ls",
WSZ_PERSONA_STATES[static_cast<int>(eCurStatus)],
neo_cl_streamermode.GetBool() ? L" [Streamer mode on]" : L"");
const int iStatusTextStartPosY = g_uiCtx.iMarginY + iMainTextHeight + g_uiCtx.iMarginY;

[[maybe_unused]] int iStatusWide;
surface()->DrawSetTextFont(g_uiCtx.fonts[NeoUI::FONT_NTNORMAL].hdl);
surface()->GetTextSize(g_uiCtx.fonts[NeoUI::FONT_NTNORMAL].hdl, wszState, iStatusWide, iStatusTall);
surface()->GetTextSize(g_uiCtx.fonts[NeoUI::FONT_NTNORMAL].hdl, wszStatusTotal, iStatusWide, iStatusTall);
surface()->DrawSetTextPos(iSteamPlaceXStart + iMainTextStartPosX,
iRightSideYStart + iStatusTextStartPosY);
surface()->DrawPrintText(wszState, V_wcslen(wszState));
surface()->DrawPrintText(wszStatusTotal, iStatusTotalSize);
}

// Put the news title in either from avatar or text end Y position
Expand Down Expand Up @@ -1202,12 +1206,15 @@ void CNeoRoot::MainLoopServerDetails(const MainLoopParam param)
wchar_t wszText[128];
if (bP) g_pVGuiLocalize->ConvertANSIToUnicode(gameServer->GetName(), wszText, sizeof(wszText));
NeoUI::Label(L"Name:", wszText);
if (bP) g_pVGuiLocalize->ConvertANSIToUnicode(gameServer->m_NetAdr.GetConnectionAddressString(), wszText, sizeof(wszText));
NeoUI::Label(L"Address:", wszText);
if (!neo_cl_streamermode.GetBool())
{
if (bP) g_pVGuiLocalize->ConvertANSIToUnicode(gameServer->m_NetAdr.GetConnectionAddressString(), wszText, sizeof(wszText));
NeoUI::Label(L"Address:", wszText);
}
if (bP) g_pVGuiLocalize->ConvertANSIToUnicode(gameServer->m_szMap, wszText, sizeof(wszText));
NeoUI::Label(L"Map:", wszText);
if (bP) V_swprintf_safe(wszText, L"%d/%d", gameServer->m_nPlayers, gameServer->m_nMaxPlayers);
NeoUI::Label(L"Ping:", wszText);
NeoUI::Label(L"Players:", wszText);
if (bP) V_swprintf_safe(wszText, L"%ls", gameServer->m_bSecure ? L"Enabled" : L"Disabled");
NeoUI::Label(L"VAC:", wszText);
if (bP) V_swprintf_safe(wszText, L"%d", gameServer->m_nPing);
Expand All @@ -1220,18 +1227,21 @@ void CNeoRoot::MainLoopServerDetails(const MainLoopParam param)
g_uiCtx.dPanel.tall = (iTallTotal - g_uiCtx.iRowTall) - g_uiCtx.dPanel.tall;
NeoUI::BeginSection();
{
if (m_serverPlayers.m_players.IsEmpty())
if (!neo_cl_streamermode.GetBool())
{
g_uiCtx.eLabelTextStyle = NeoUI::TEXTSTYLE_CENTER;
NeoUI::Label(L"There are no players in the server.");
g_uiCtx.eLabelTextStyle = NeoUI::TEXTSTYLE_LEFT;
}
else
{
for (const auto &player : m_serverPlayers.m_players)
if (m_serverPlayers.m_players.IsEmpty())
{
g_uiCtx.eLabelTextStyle = NeoUI::TEXTSTYLE_CENTER;
NeoUI::Label(L"There are no players in the server.");
g_uiCtx.eLabelTextStyle = NeoUI::TEXTSTYLE_LEFT;
}
else
{
NeoUI::Label(player.wszName);
// TODO
for (const auto &player : m_serverPlayers.m_players)
{
NeoUI::Label(player.wszName);
// TODO
}
}
}
}
Expand Down
Loading