📄 bloodservershell.cpp
字号:
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::RestoreGame()
//
// PURPOSE: Restores a saved game
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::RestoreGame(DBYTE bySaveType)
{
if (!g_pServerDE)
return DFALSE;
char szSavePath[MAX_PATH];
_mbscpy((unsigned char*)szSavePath, (const unsigned char*)g_szSavePath);
if (bySaveType == SAVETYPE_CURRENT)
_mbscat((unsigned char*)szSavePath, (const unsigned char*)g_szCurrentSaveFile);
else if (bySaveType == SAVETYPE_AUTO)
_mbscat((unsigned char*)szSavePath, (const unsigned char*)g_szAutoSaveFile);
else
return DFALSE;
if (g_pServerDE->RestoreObjects(szSavePath, 0, RESTOREOBJECTS_RESTORETIME) != DE_OK)
return DFALSE;
return DTRUE;
}
/*
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::BuildSavePath()
//
// PURPOSE: Builds a path for a save file given a world file
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::BuildSavePath(char *pBuffer, char *pFilename)
{
if (!pBuffer && !pFilename)
return DFALSE;
// Build the filename path..
// Remove leading slashes..
while(*pFilename == '\\' || *pFilename == '/')
pFilename++;
_mbscpy((unsigned char*)pBuffer, (const unsigned char*)g_szSavePath);
// Keep track of the position that the filename will be appended to
char *pEnd = (char *)(pBuffer + _mbstrlen(pBuffer));
_mbscat((unsigned char*)pBuffer, (const unsigned char*)pFilename);
// Replace slashes in the filename with underscores.
char *pSlash;
while (pSlash = _mbschr((const unsigned char*)pEnd, (unsigned int)'\\'))
*pSlash = '_';
// ..and tack on the extension.
_mbscat((unsigned char*)pBuffer, (const unsigned char*)".sav");
return DTRUE;
}
*/
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::KeepAliveSave()
//
// PURPOSE: Saves the state of player objects between levels
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::KeepAliveSave()
{
DBOOL bRet = DFALSE;
if (!g_pServerDE) return bRet;
char szSavePath[MAX_PATH];
#ifndef _DEMO
_mbscpy((unsigned char*)szSavePath, (const unsigned char*)g_szSavePath);
_mbscat((unsigned char*)szSavePath, (const unsigned char*)"Keep.sav");
#else
_mbscpy((unsigned char*)szSavePath, (const unsigned char*)"Keep.sav");
#endif
// Make a list of savable objects
ObjectList* pObjectList = g_pServerDE->CreateObjectList();
HCLASS hPlayerTest = g_pServerDE->GetClass("CPlayerObj");
HOBJECT hObj = g_pServerDE->GetNextObject(DNULL);
while (hObj)
{
if (IsPlayer(hObj))
{
ObjectLink *ol = g_pServerDE->AddObjectToList(pObjectList, hObj);
ol->m_hObject = hObj;
}
hObj = g_pServerDE->GetNextObject(hObj);
}
if (g_pServerDE->SaveObjects(szSavePath, pObjectList, 1, 0 ) == DE_OK)
bRet = DTRUE;
g_pServerDE->RelinquishList(pObjectList);
return bRet;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::KeepAliveLoad()
//
// PURPOSE: Restores player data saved when switching levels
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::KeepAliveLoad()
{
if (!g_pServerDE) return DFALSE;
char szSavePath[MAX_PATH];
#ifndef _DEMO
_mbscpy((unsigned char*)szSavePath, (const unsigned char*)g_szSavePath);
_mbscat((unsigned char*)szSavePath, (const unsigned char*)"Keep.sav");
#else
_mbscpy((unsigned char*)szSavePath, (const unsigned char*)"Keep.sav");
#endif
if (g_pServerDE->RestoreObjects(szSavePath, 1, 0) != DE_OK)
return DFALSE;
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::SetGameDifficulty()
//
// PURPOSE: Sets game info console vars for difficulty level
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::SetGameInfo(DBYTE nGameType, DBYTE nDifficulty)
{
if (!g_pServerDE) return;
char szValue[20];
_itoa(nGameType, szValue, 10);
g_pServerDE->SetGameConVar(g_szVarGameType, szValue);
_itoa(nDifficulty, szValue, 10);
g_pServerDE->SetGameConVar(g_szVarDifficulty, szValue);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::CacheFiles()
//
// PURPOSE: Cache files that are used often
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::CacheFiles()
{
// Cache models...
for (int i=0; i < NUM_CACHED_MODELS; i++)
{
g_pServerDE->CacheFile(FT_MODEL, g_pCachedModels[i]);
}
// Cache textures...
for (i=0; i < NUM_CACHED_TEXTURES; i++)
{
g_pServerDE->CacheFile(FT_TEXTURE, g_pCachedTextures[i]);
}
// Cache sprites...
for (i=0; i < NUM_CACHED_SPRITES; i++)
{
g_pServerDE->CacheFile(FT_SPRITE, g_pCachedSprite[i]);
}
// Cache sounds...
for (i=0; i < NUM_CACHED_SOUNDS_LOCAL; i++)
{
g_pServerDE->CacheFile(FT_SOUND, g_pCachedSoundLocal[i]);
}
for (i=0; i < NUM_CACHED_SOUNDS_AMBIENT; i++)
{
g_pServerDE->CacheFile(FT_SOUND, g_pCachedSoundAmbient[i]);
}
for (i=0; i < NUM_CACHED_SOUNDS_3D; i++)
{
g_pServerDE->CacheFile(FT_SOUND, g_pCachedSound3D[i]);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::AddClientToList
//
// PURPOSE: Adds the given client handle to our local list
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::AddClientToList(HCLIENT hClient)
{
// Sanity checks...
if (!hClient) return(DFALSE);
// Make sure this client isn't already in our list...
if (IsClientInList(hClient))
{
return(DTRUE);
}
// Add this client handle to our array...
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (m_aClients[i] == DNULL)
{
m_aClients[i] = hClient;
return(DTRUE);
}
}
// If we get here, there wasn't any space left in the array...
return(DFALSE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::RemoveClientFromList
//
// PURPOSE: Adds the given client handle to our local list
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::RemoveClientFromList(HCLIENT hClient)
{
// Sanity checks...
if (!hClient) return(DFALSE);
// Remove this client handle from our array...
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (m_aClients[i] == hClient)
{
m_aClients[i] = DNULL;
return(DTRUE);
}
}
// If we get here, we didn't find the given client handle in the array...
return(DFALSE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::IsClientInList
//
// PURPOSE: Determines if the given client handle is in our list
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::IsClientInList(HCLIENT hClient)
{
// Sanity checks...
if (!hClient) return(DFALSE);
// Look for this client handle in our array...
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (m_aClients[i] == hClient)
{
return(DTRUE);
}
}
// If we get here, we didn't find the given client handle in the array...
return(DFALSE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::GetPlayerFromClientList
//
// PURPOSE: Adds the given client handle to our local list
//
// ----------------------------------------------------------------------- //
CPlayerObj* CBloodServerShell::GetPlayerFromClientList(HCLIENT hClient)
{
// Sanity checks...
if (!hClient) return(DNULL);
if (!g_pServerDE) return(DNULL);
// Remove this client handle from our array...
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (m_aClients[i] == hClient)
{
CPlayerObj* pPlayer = (CPlayerObj*)g_pServerDE->GetClientUserData(hClient);
return(pPlayer);
}
}
// If we get here, we didn't find the given client handle in the array...
return(DNULL);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::SetupGameInfo
//
// PURPOSE: Setup game info
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::SetupGameInfo()
{
if (g_pServerDE)
{
NetGame* pGameInfo;
DDWORD dwLen = sizeof(NetGame);
g_pServerDE->GetGameInfo((void**)&pGameInfo, &dwLen);
if (pGameInfo)
{
memcpy(&m_GameInfo, pGameInfo, sizeof(NetGame));
}
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::Update
//
// PURPOSE: Update servier stuff periodically
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::Update(DFLOAT timeElapsed)
{
// Sanity checks...
if (!g_pServerDE || GetGameType() == GAMETYPE_SINGLE) return;
// Update the client ping times...
UpdateClientPingTimes();
// Check for a say message...
if (!g_SayTrack.IsInitted())
{
g_SayTrack.Init(g_pServerDE, "Say", "", 0.0f);
}
else
{
char *sSay = g_SayTrack.GetStr("");
if (sSay && sSay[0] != 0)
{
char sMsg[512];
sprintf(sMsg, "HOST: %s", sSay);
HMESSAGEWRITE hMessage = g_pServerDE->StartMessage(DNULL, SMSG_CONSOLEMESSAGE_ALL);
g_pServerDE->WriteToMessageString(hMessage, sMsg);
g_pServerDE->EndMessage2(hMessage, MESSAGE_NAGGLE);
g_SayTrack.SetStr("");
}
}
// Setup a static timer for session name updates...
static DFLOAT timerUpdateName = 5;
// Update our time and see if it's time to update the session name...
if (timeElapsed < timerUpdateName)
{
timerUpdateName -= timeElapsed;
}
else
{
timerUpdateName = 10;
UpdateSessionName();
}
// Update shogo server info...
UpdateBlood2Server();
// Update multiplayer stuff...
UpdateMultiplayer();
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::UpdateSessionName
//
// PURPOSE: Updates the name of the session with current game info
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::UpdateSessionName()
{
// Get the current session name...
static char sSession[4096];
DRESULT dr = g_pServerDE->GetSessionName(sSession, 4096);
if (dr != LT_OK) return(DFALSE);
// Extract the info we want to keep...
char sName[NML_NAME];
if (!Sparam_Get(sName, sSession, NST_GAMENAME)) return(DFALSE);
char sHost[NML_HOST];
if (!Sparam_Get(sHost, sSession, NST_GAMEHOST)) return(DFALSE);
char sType[32];
if (!Sparam_Get(sType, sSession, NST_GAMETYPE)) return(DFALSE);
// Get the base level name...
char sLevel[128];
_mbscpy((unsigned char*)sLevel, (const unsigned char*)m_GameInfo.m_sLevels[m_nCurLevel]);
// Clear the session string now that we have the info we want from it...
sSession[0] = '\0';
// Add the info we kept...
Sparam_Add(sSession, NST_GAMENAME, sName);
Sparam_Add(sSession, NST_GAMEHOST, sHost);
Sparam_Add(sSession, NST_GAMELEVEL, sLevel);
Sparam_Add(sSession, NST_GAMETYPE, sType);
// Add info for each player...
int count = 0;
for (int i = 0; i < MAX_CLIENTS; i++)
{
CPlayerObj* pPlayer = GetPlayerFromClientList(m_aClients[i]);
if (pPlayer)
{
HSTRING hstrName = pPlayer->GetPlayerName();
char* pName = hstrName ? g_pServerDE->GetStringData(hstrName) : "";
count++;
char sBase[32];
sprintf(sBase, "%s%i", NST_PLRNAME_BASE, count);
Sparam_Add(sSession, sBase, pName);
sprintf(sBase, "%s%i", NST_PLRFRAG_BASE, count);
Sparam_Add(sSession, sBase, pPlayer->GetFrags());
}
}
Sparam_Add(sSession, NST_PLRCOUNT, count);
// Update the session name...
g_pServerDE->UpdateSessionName(sSession);
// All done...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -