1
This commit is contained in:
281
game/shared/motd.cpp
Normal file
281
game/shared/motd.cpp
Normal file
@ -0,0 +1,281 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: motd: Handles a list of message of the day entries
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "motd.h"
|
||||
#include "schemainitutils.h"
|
||||
#include "rtime.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace GCSDK;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CMOTDEntryDefinition::CMOTDEntryDefinition( void )
|
||||
{
|
||||
m_pKVMOTD = NULL;
|
||||
m_PostTime = 0;
|
||||
m_ChangedTime = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMOTDEntryDefinition::BInitFromKV( KeyValues *pKVMOTD, CUtlVector<CUtlString> *pVecErrors )
|
||||
{
|
||||
m_pKVMOTD = pKVMOTD->MakeCopy();
|
||||
|
||||
const char *pszTime = m_pKVMOTD->GetString( "post_time", NULL );
|
||||
m_PostTime = (pszTime && pszTime[0]) ? CRTime::RTime32FromString(pszTime) : 0;
|
||||
|
||||
pszTime = m_pKVMOTD->GetString( "last_changed_time", NULL );
|
||||
m_ChangedTime = (pszTime && pszTime[0]) ? CRTime::RTime32FromString(pszTime) : 0;
|
||||
|
||||
return SCHEMA_INIT_SUCCESS();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CMOTDEntryDefinition::GetTitle( ELanguage eLang )
|
||||
{
|
||||
if ( m_pKVMOTD )
|
||||
{
|
||||
// See if we have a localised block for the specified language.
|
||||
const char *pszLanguage = GetLanguageShortName( eLang );
|
||||
if ( pszLanguage && pszLanguage[0] )
|
||||
{
|
||||
const char *pszText = m_pKVMOTD->GetString( CFmtStr( "title_%s", pszLanguage ), NULL );
|
||||
if ( pszText && pszText[0] )
|
||||
return pszText;
|
||||
}
|
||||
|
||||
// Fall back to english
|
||||
return m_pKVMOTD->GetString( "title_english", "No Title" );
|
||||
}
|
||||
|
||||
return "No Title";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CMOTDEntryDefinition::GetText( ELanguage eLang )
|
||||
{
|
||||
if ( m_pKVMOTD )
|
||||
{
|
||||
// See if we have a localised block for the specified language.
|
||||
const char *pszLanguage = GetLanguageShortName( eLang );
|
||||
if ( pszLanguage && pszLanguage[0] )
|
||||
{
|
||||
const char *pszText = m_pKVMOTD->GetString( CFmtStr( "text_%s", pszLanguage ), NULL );
|
||||
if ( pszText && pszText[0] )
|
||||
return pszText;
|
||||
}
|
||||
|
||||
// Fall back to english
|
||||
return m_pKVMOTD->GetString( "text_english", "No text" );
|
||||
}
|
||||
|
||||
return "No text";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CMOTDEntryDefinition::GetHeaderTitle( ELanguage eLang )
|
||||
{
|
||||
if ( m_pKVMOTD )
|
||||
{
|
||||
// See if we have a localised block for the specified language.
|
||||
const char *pszLanguage = GetLanguageShortName( eLang );
|
||||
if ( pszLanguage && pszLanguage[0] )
|
||||
{
|
||||
const char *pszText = m_pKVMOTD->GetString( CFmtStr( "header_%s", pszLanguage ), NULL );
|
||||
if ( pszText && pszText[0] )
|
||||
return pszText;
|
||||
}
|
||||
|
||||
// Fall back to english
|
||||
return m_pKVMOTD->GetString( "header_english", "News" );
|
||||
}
|
||||
|
||||
return "News";
|
||||
}
|
||||
|
||||
// Sort by ID
|
||||
int MOTDEntriesListLess( const CMOTDEntryDefinition *pLhs, const CMOTDEntryDefinition *pRhs )
|
||||
{
|
||||
// This is stupid, sort by the KeyID instead
|
||||
return ( pLhs->GetNameInt() > pRhs->GetNameInt() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initializes the loot lists section of the schema
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMOTDManager::BInitMOTDEntries( KeyValues *pKVMOTDEntries, CUtlVector<CUtlString> *pVecErrors )
|
||||
{
|
||||
m_vecMOTDEntries.RemoveAll();
|
||||
|
||||
RTime32 iPrevTime = 0;
|
||||
|
||||
if ( NULL != pKVMOTDEntries )
|
||||
{
|
||||
FOR_EACH_TRUE_SUBKEY( pKVMOTDEntries, pKVEntry )
|
||||
{
|
||||
const char *listName = pKVEntry->GetName();
|
||||
|
||||
SCHEMA_INIT_CHECK( listName != NULL, "All MOTD entries must have titles." );
|
||||
|
||||
int idx = m_vecMOTDEntries.AddToTail();
|
||||
SCHEMA_INIT_SUBSTEP( m_vecMOTDEntries[idx].BInitFromKV( pKVEntry, pVecErrors ) );
|
||||
|
||||
// Make sure the dates all move forward
|
||||
SCHEMA_INIT_CHECK( m_vecMOTDEntries[idx].GetPostTime() > iPrevTime , "MOTD entry '%s' occurs prior to the previous entry.", m_vecMOTDEntries[idx].GetName() );
|
||||
iPrevTime = m_vecMOTDEntries[idx].GetPostTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Then sort all the MOTDs in order of their changed times, so we can easily send them
|
||||
m_vecMOTDEntries.Sort( MOTDEntriesListLess );
|
||||
|
||||
return SCHEMA_INIT_SUCCESS();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the number of MOTD entries we've got after the specified time
|
||||
//-----------------------------------------------------------------------------
|
||||
int CMOTDManager::GetNumMOTDAfter( RTime32 iTime )
|
||||
{
|
||||
FOR_EACH_VEC( m_vecMOTDEntries, i )
|
||||
{
|
||||
if ( m_vecMOTDEntries[i].GetChangedTime() > iTime )
|
||||
{
|
||||
// We've hit the first MOTD entry after this time. All following posts are assumed after.
|
||||
return (m_vecMOTDEntries.Count() - i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Remove all unused MOTD: Save memory and whatever
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMOTDManager::PurgeUnusedMOTDEntries( KeyValues *pKVMOTDEntries )
|
||||
{
|
||||
// Find the latest entry name and remove all others
|
||||
int iLargest = -1;
|
||||
FOR_EACH_VEC_BACK( m_vecMOTDEntries, i )
|
||||
{
|
||||
int iMOTDindex = m_vecMOTDEntries[i].GetNameInt();
|
||||
if ( iMOTDindex > iLargest )
|
||||
{
|
||||
iLargest = iMOTDindex;
|
||||
}
|
||||
}
|
||||
|
||||
FOR_EACH_VEC_BACK( m_vecMOTDEntries, i )
|
||||
{
|
||||
int iMOTDindex = m_vecMOTDEntries[i].GetNameInt();
|
||||
if ( iMOTDindex < iLargest )
|
||||
{
|
||||
if ( pKVMOTDEntries )
|
||||
{
|
||||
KeyValues *pKey = pKVMOTDEntries->FindKey( m_vecMOTDEntries[i].GetName() );
|
||||
if ( pKey )
|
||||
{
|
||||
pKVMOTDEntries->RemoveSubKey( pKey );
|
||||
}
|
||||
}
|
||||
m_vecMOTDEntries.Remove( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns the definition for the next blog post after the specified time
|
||||
//-----------------------------------------------------------------------------
|
||||
CMOTDEntryDefinition *CMOTDManager::GetNextMOTDAfter( RTime32 iTime )
|
||||
{
|
||||
FOR_EACH_VEC( m_vecMOTDEntries, i )
|
||||
{
|
||||
if ( m_vecMOTDEntries[i].GetChangedTime() > iTime )
|
||||
return &m_vecMOTDEntries[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMOTDEntryDefinition *CMOTDManager::GetMOTDByIndex( int iIndex )
|
||||
{
|
||||
if ( iIndex < 0 || iIndex > m_vecMOTDEntries.Count() )
|
||||
return NULL;
|
||||
return &m_vecMOTDEntries[iIndex];
|
||||
}
|
||||
|
||||
|
||||
#ifdef GC_DLL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle MOTD requests job.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CGCMOTDRequest : public CGCGameBaseJob
|
||||
{
|
||||
public:
|
||||
CGCMOTDRequest( CGCGameBase *pGC ) : CGCGameBaseJob( pGC ) { }
|
||||
bool BYieldingRunJobFromMsg( GCSDK::IMsgNetPacket *pNetPacket );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Responds to requests from the client for the current MOTD list
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CGCMOTDRequest::BYieldingRunJobFromMsg( IMsgNetPacket *pNetPacket )
|
||||
{
|
||||
CGCMsg< MsgGCMOTDRequest_t > msg( pNetPacket );
|
||||
ELanguage eLang = (ELanguage)msg.Body().m_eLanguage;
|
||||
RTime32 iMOTDTime = msg.Body().m_nLastMOTDRequest;
|
||||
|
||||
// Send the response to the client
|
||||
GCSDK::CGCMsg<MsgGCMOTDRequestResponse_t> msg_response( k_EMsgGCMOTDRequestResponse );
|
||||
|
||||
int iEntries = 0;
|
||||
CMOTDEntryDefinition *pMOTD = m_pGCGameBase->GetMOTDManager().GetNextMOTDAfter( iMOTDTime );
|
||||
while ( pMOTD )
|
||||
{
|
||||
// Stuff this MOTD into the message.
|
||||
msg_response.AddStrData( pMOTD->GetName() );
|
||||
msg_response.AddUintData( pMOTD->GetPostTime() );
|
||||
msg_response.AddStrData( pMOTD->GetTitle( eLang ) );
|
||||
msg_response.AddStrData( pMOTD->GetText( eLang ) );
|
||||
msg_response.AddStrData( pMOTD->GetURL() );
|
||||
msg_response.AddStrData( pMOTD->GetImage() );
|
||||
msg_response.AddIntData( pMOTD->GetHeaderType() );
|
||||
msg_response.AddStrData( pMOTD->GetHeaderTitle( eLang ) );
|
||||
msg_response.AddStrData( pMOTD->GetHeaderIcon() );
|
||||
iEntries++;
|
||||
|
||||
// Move on to the next message.
|
||||
iMOTDTime = pMOTD->GetChangedTime();
|
||||
pMOTD = m_pGCGameBase->GetMOTDManager().GetNextMOTDAfter( iMOTDTime );
|
||||
}
|
||||
msg_response.Body().m_nEntries = iEntries;
|
||||
|
||||
GGCEcon()->BSendGCMsgToClient( msg.Hdr().m_ulSteamID, msg_response );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GC_REG_JOB( CGCGameBase, CGCMOTDRequest, "CGCMOTDRequest", k_EMsgGCMOTDRequest, k_EServerTypeGC );
|
||||
|
||||
#endif // GC_DLL
|
Reference in New Issue
Block a user