Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

489 lines
12 KiB

//++ BulliT
#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_state.h"
#include "cl_entity.h"
#include "event_api.h"
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "com_weapons.h"
#include "parsemsg.h"
#include "demo.h"
#include "demo_api.h"
#include "agglobal.h"
#include "aghudglobal.h"
#include "agmodelcheck.h"
#ifdef AG_USE_CHEATPROTECTION
#include "agwallhack.h"
#include "agcrc32enforcer.h"
#endif
#include "agvariablechecker.h"
//#include "vgui_TeamFortressViewport.h"
//#include "vgui_ScorePanel.h"
//#include "AgVGuiMapBrowser.h"
//#include "AgDownload.h"
DECLARE_MESSAGE(m_Global, PlaySound )
DECLARE_MESSAGE(m_Global, CheatCheck )
DECLARE_MESSAGE(m_Global, WhString )
DECLARE_MESSAGE(m_Global, SpikeCheck )
DECLARE_MESSAGE(m_Global, Gametype )
DECLARE_MESSAGE(m_Global, AuthID )
DECLARE_MESSAGE(m_Global, MapList )
DECLARE_MESSAGE(m_Global, CRC32 )
DECLARE_COMMAND(m_Global, Winamp);
DECLARE_COMMAND(m_Global, ToggleWinamp);
DECLARE_COMMAND(m_Global, ToggleMapBrowser);
DECLARE_COMMAND(m_Global, LoadAuthID);
DECLARE_COMMAND(m_Global, UnloadAuthID);
DECLARE_COMMAND(m_Global, AgRecord);
int g_iPure = 1;
unsigned char g_GameType = STANDARD;
int iNumberOfTeamColors = 5;
extern int iTeamColors[5][3];
typedef map<int, AgString, less<int> > AgPlayerToAuthID;
typedef map<AgString, AgString, less<AgString> > AgAuthIDToRealName;
static AgPlayerToAuthID s_mapAuthID;
static AgAuthIDToRealName s_mapRealName;
static int s_iCheckWallhack = 0;
extern cvar_t* g_pcl_scores;
int AgHudGlobal::Init(void)
{
m_iFlags = 0;
gHUD.AddHudElem(this);
HOOK_MESSAGE( PlaySound );
HOOK_MESSAGE( CheatCheck );
HOOK_MESSAGE( WhString );
HOOK_MESSAGE( SpikeCheck );
HOOK_MESSAGE( Gametype );
HOOK_MESSAGE( AuthID );
HOOK_MESSAGE( MapList );
HOOK_MESSAGE( CRC32 );
HOOK_COMMAND("winamp",Winamp);
HOOK_COMMAND("togglewinamp",ToggleWinamp);
HOOK_COMMAND("togglemapbrowser",ToggleMapBrowser);
HOOK_COMMAND("loadauthid",LoadAuthID);
HOOK_COMMAND("unloadauthid",UnloadAuthID);
HOOK_COMMAND("agrecord",AgRecord);
return 1;
};
int AgHudGlobal::VidInit(void)
{
if (!gEngfuncs.pDemoAPI->IsRecording())
s_mapAuthID.clear();
return 1;
};
void AgHudGlobal::Reset(void)
{
m_iFlags |= HUD_ACTIVE;
m_fCheckColor = 0;
}
int iOverLay = 0;
int AgHudGlobal::Draw( float fTime )
{
if( m_fCheckColor < gHUD.m_flTime )
{
AgUpdateHudColor();
m_fCheckColor = gHUD.m_flTime + 1; //every second
}
if( g_pcl_scores->value < 1 )
return 1;
int i, j, xpos, ypos, r, g, b;
xpos = 30;
ypos = 50;
sscanf( CVAR_GET_STRING( "cl_scores_pos" ), "%i %i", &xpos, &ypos );
if( gHUD.m_Teamplay )
{
// clear out team scores
for( i = 1; i <= gHUD.m_Scoreboard.m_iNumTeams; i++ )
{
g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0;
g_TeamInfo[i].already_drawn = FALSE;
}
// recalc the team scores, then draw them
for( i = 1; i < MAX_PLAYERS; i++ )
{
if( g_PlayerExtraInfo[i].teamname[0] == 0 )
continue; // skip over players who are not in a team
// find what team this player is in
for( j = 1; j <= gHUD.m_Scoreboard.m_iNumTeams; j++ )
{
if( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) )
break;
}
if( j > gHUD.m_Scoreboard.m_iNumTeams ) // player is not in a team, skip to the next guy
continue;
g_TeamInfo[j].frags += g_PlayerExtraInfo[i].frags;
g_TeamInfo[j].deaths += g_PlayerExtraInfo[i].deaths;
}
}
else
gHUD.m_Scoreboard.GetAllPlayersInfo();
for( int iRow = 0, iLines = 0; iLines < g_pcl_scores->value; iRow++ )
{
if( gHUD.m_Teamplay )
{
int highest_frags = -99999; int lowest_deaths = 99999;
int best_team = 0;
for( i = 1; i <= gHUD.m_Scoreboard.m_iNumTeams; i++ )
{
if( g_TeamInfo[i].players < 0 )
continue;
if( !g_TeamInfo[i].already_drawn && g_TeamInfo[i].frags >= highest_frags )
{
if( g_TeamInfo[i].frags > highest_frags || g_TeamInfo[i].deaths < lowest_deaths )
{
best_team = i;
lowest_deaths = g_TeamInfo[i].deaths;
highest_frags = g_TeamInfo[i].frags;
}
}
}
// draw the best team on the scoreboard
if( !best_team )
break;
char szScore[64];
team_info_t *team_info = &g_TeamInfo[best_team];
sprintf( szScore, "%-5i %s", team_info->frags, team_info->name );
r = iTeamColors[best_team % iNumberOfTeamColors][0];
g = iTeamColors[best_team % iNumberOfTeamColors][1];
b = iTeamColors[best_team % iNumberOfTeamColors][2];
FillRGBA( xpos - 10, ypos + 2 , iOverLay, gHUD.m_scrinfo.iCharHeight * 0.9, r, g, b, 20 );
ScaleColors( r, g, b, 135 );
int ixposnew = gHUD.DrawHudString( xpos, ypos, ScreenWidth, szScore, r, g, b );
iOverLay = max( ixposnew - xpos + 20, iOverLay );
ypos += gHUD.m_scrinfo.iCharHeight * 0.9;
g_TeamInfo[best_team].already_drawn = TRUE;
iLines++;
}
else
{
int highest_frags = -99999;
int lowest_deaths = 99999;
int best_player = 0;
for( i = 1; i < MAX_PLAYERS; i++ )
{
if( g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags )
{
extra_player_info_t *pl_info = &g_PlayerExtraInfo[i];
if( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths )
{
best_player = i;
lowest_deaths = pl_info->deaths;
highest_frags = pl_info->frags;
}
}
}
if( !best_player )
break;
char szScore[64];
hud_player_info_t *pl_info = &g_PlayerInfoList[best_player];
extra_player_info_t *pl_info_extra = &g_PlayerExtraInfo[best_player];
sprintf( szScore, "%-5i %s",pl_info_extra->frags,pl_info->name );
r = iTeamColors[pl_info_extra->teamnumber % iNumberOfTeamColors][0];
g = iTeamColors[pl_info_extra->teamnumber % iNumberOfTeamColors][1];
b = iTeamColors[pl_info_extra->teamnumber % iNumberOfTeamColors][2];
FillRGBA( xpos - 10, ypos + 2, iOverLay, gHUD.m_scrinfo.iCharHeight * 0.9, r, g, b, 10 );
ScaleColors( r, g, b, 135 );
int ixposnew = gHUD.DrawHudString( xpos, ypos, ScreenWidth, szScore, r, g, b );
iOverLay = max( ixposnew - xpos + 20,iOverLay );
ypos += gHUD.m_scrinfo.iCharHeight * 0.9;
pl_info->name = NULL; // set the name to be NULL, so this client won't get drawn again
iLines++;
}
}
return 1;
}
int AgHudGlobal::MsgFunc_PlaySound(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
vec3_t origin;
/*int iPlayer = */READ_BYTE();
for ( int i = 0 ; i < 3 ; i++)
origin[i] = READ_COORD();
char* pszSound = READ_STRING();
gEngfuncs.pfnPlaySoundByName( pszSound, 1);
//this does not work - gEngfuncs.pfnPlaySoundByNameAtLocation( pszSound, 1, origin);
//gEngfuncs.pEventAPI->EV_PlaySound( -1, origin, 0, pszName, 1.0, ATTN_NORM, 0, PITCH_NORM );
return 1;
}
extern bool AgCRC32EnforceFiles();
int AgHudGlobal::MsgFunc_CheatCheck(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
int iPure = READ_BYTE();
g_iPure = iPure;
#ifdef AG_USE_CHEATPROTECTION
if (0 < g_iPure)
AgCRC32EnforceFiles();
g_VariableChecker.Activate();
#ifdef _DEBUG
DWORD dwTime = GetTickCount();
AgLog( "Checking for spikes\n" );
#endif //_DEBUG
if (!g_ModelCheck.Check())
return 1;
if (s_iCheckWallhack)
{
#if defined(AG_USE_CHEATPROTECTION) && defined(_WIN32)
#ifdef _DEBUG
AgLog( "Checking for wallhack\n" );
#endif //_DEBUG
if (!g_Wallhack.Check())
return 1;
#endif
}
#ifdef _DEBUG
char szTime[64];
sprintf(szTime,"Cheat check took %dms\n",int((GetTickCount() - dwTime)));
ConsolePrint(szTime);
AgLog(szTime);
#endif
#endif //AG_USE_CHEATPROTECTION
return 1;
}
int AgHudGlobal::MsgFunc_WhString(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
#if defined(AG_USE_CHEATPROTECTION) && defined(_WIN32)
g_Wallhack.AddBadStrings(READ_STRING());
#else
READ_STRING();
#endif
s_iCheckWallhack = 1;
return 1;
}
int AgHudGlobal::MsgFunc_SpikeCheck(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
#ifdef AG_USE_CHEATPROTECTION
g_ModelCheck.CheckOne(READ_STRING());
#else
READ_STRING();
#endif
return 1;
}
int AgHudGlobal::MsgFunc_Gametype(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
g_GameType = READ_BYTE();
return 1;
}
int AgHudGlobal::MsgFunc_AuthID(const char *pszName, int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
int iPlayer = READ_BYTE();
AgString sAuthID = READ_STRING();
int iCutId = sAuthID.find("_");
if (-1 != iCutId)
sAuthID = sAuthID.substr(iCutId+1);
AgPlayerToAuthID::iterator itrAuthID = s_mapAuthID.find(iPlayer);
if (itrAuthID == s_mapAuthID.end())
s_mapAuthID.insert(AgPlayerToAuthID::value_type(iPlayer,sAuthID));
else
(*itrAuthID).second = sAuthID;
return 1;
}
int AgHudGlobal::MsgFunc_MapList( const char *pszName, int iSize, void *pbuf )
{
//if (gViewPort && gViewPort->m_pMapBrowser)
//return gViewPort->m_pMapBrowser->MsgFunc_MapList( pszName, iSize, pbuf );
return 1;
}
int AgHudGlobal::MsgFunc_CRC32( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int iCheckSum = READ_LONG();
#ifdef AG_USE_CHEATPROTECTION
AgCRC32EnforceFile(READ_STRING(), iCheckSum);
#else
READ_STRING();
#endif
return 1;
}
void AgHudGlobal::UserCmd_Winamp()
{
//gViewPort->UserCmd_Winamp();
}
void AgHudGlobal::UserCmd_ToggleWinamp()
{
//gViewPort->ToggleWinamp();
}
void AgHudGlobal::UserCmd_ToggleMapBrowser()
{
//gViewPort->ToggleMapBrowser();
}
void AgHudGlobal::UserCmd_LoadAuthID()
{
char* pszFileName = "realnames.txt";
if (gEngfuncs.Cmd_Argc() == 2)
{
char szSaveAs[MAX_PATH];
AgString sUrl = gEngfuncs.Cmd_Argv(1);
sprintf(szSaveAs,"%s/%s",AgGetDirectory(),pszFileName);
sUrl = "http://" + sUrl;
//AgDownload download;
//download.DownloadFile(sUrl.c_str(), szSaveAs);
}
int iFilePos = 0, iFileSize = 0;
char* pFile = (char*)gEngfuncs.COM_LoadFile(pszFileName, 5, NULL);
if (!pFile)
{
char szMessage[256];
sprintf(szMessage, "Could not load file %s\n", pszFileName);
ConsolePrint(szMessage);
return;
}
AgString sRealNames(pFile);
gEngfuncs.COM_FreeFile(pFile);
int iPosNewLine = sRealNames.find_first_of("\n");
while (-1 != iPosNewLine)
{
AgString sAuthID, sRealName;
int iPosRealName = sRealNames.find_first_of(" \t");
sAuthID = sRealNames.substr(0,iPosRealName);
sRealName = sRealNames.substr(iPosRealName+1,min(32,iPosNewLine - iPosRealName));
AgTrim(sAuthID);
AgTrim(sRealName);
if ("//" != sAuthID.substr(0,2))
{
if (sAuthID.size() && sRealName.size())
s_mapRealName.insert(AgAuthIDToRealName::value_type(sAuthID, sRealName));
}
else
{
AgString sComment = sRealNames.substr(2,iPosNewLine-2);
AgTrim(sComment);
sComment += "\n";
ConsolePrint(sComment.c_str());
}
sRealNames = sRealNames.substr(iPosNewLine+1);
iPosNewLine = sRealNames.find_first_of("\n");
}
char szCount[64];
sprintf(szCount,"Loaded auth id's - %d\n",(int)s_mapRealName.size());
ConsolePrint(szCount);
}
void AgHudGlobal::UserCmd_UnloadAuthID()
{
ConsolePrint("Unloaded all auth id's\n");
s_mapRealName.clear();
}
AgString AgGetAuthID(int iPlayer)
{
AgPlayerToAuthID::iterator itrAuthID = s_mapAuthID.find(iPlayer);
if (itrAuthID != s_mapAuthID.end())
{
return (*itrAuthID).second;
}
return "";
}
AgString AgGetRealName(int iPlayer)
{
if (s_mapRealName.size())
{
AgString sRealName;
AgPlayerToAuthID::iterator itrAuthID = s_mapAuthID.find(iPlayer);
if (itrAuthID != s_mapAuthID.end())
{
AgAuthIDToRealName::iterator itrRealName = s_mapRealName.find((*itrAuthID).second);
if (itrRealName != s_mapRealName.end())
return (*itrRealName).second;
}
}
return g_PlayerInfoList[iPlayer].name;
}
void AgHudGlobal::UserCmd_AgRecord()
{
time_t t_now;
time(&t_now);
struct tm* now = localtime(&t_now);
now->tm_year += 1900;
char szExtra[128];
if (gEngfuncs.Cmd_Argc() == 2)
sprintf(szExtra, "_%s",gEngfuncs.Cmd_Argv(1));
else
szExtra[0] = '\0';
char szCMD[128];
sprintf(szCMD, "record %04d%02d%02d_%02d%02d%02d_%s%s\n",now->tm_year, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, AgMapname().c_str(), szExtra);
ClientCmd(szCMD);
}
//-- Martin Webrant