📄 bloodservershell.cpp
字号:
return(DTRUE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::UpdateBlood2Server
//
// PURPOSE: Updates a stand-alone server with game info if necessary
//
// ----------------------------------------------------------------------- //
DBOOL CBloodServerShell::UpdateBlood2Server()
{
// Check if we need to update...
if (!m_bUpdateBlood2Serv)
{
return(DFALSE);
}
m_bUpdateBlood2Serv = FALSE;
// Make sure we are actually being hosted via ShogoServ...
if (!m_bBlood2ServHosted)
{
return(DFALSE);
}
// Get the current base level name...
char sCurLevel[128];
_mbscpy((unsigned char*)sCurLevel, (const unsigned char*)m_GameInfo.m_sLevels[m_nCurLevel]);
// Get the next base level name...
char sNextLevel[128];
int i = m_nCurLevel + 1;
if (i >= m_GameInfo.m_byNumLevels) i = 0;
_mbscpy((unsigned char*)sNextLevel, (const unsigned char*)m_GameInfo.m_sLevels[i]);
// Declare the string...
static char sInfo[4096];
sInfo[0] = '\0';
// Flag that this is a standard update message...
Sparam_Add(sInfo, "GMSG", NGM_STANDARDUPDATE);
// Add the levels...
Sparam_Add(sInfo, NST_CURLEVEL, sCurLevel);
Sparam_Add(sInfo, NST_NEXTLEVEL, sNextLevel);
// Add info for each player...
int count = 0;
for (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(sInfo, sBase, pName);
sprintf(sBase, "%s%i", NST_PLRFRAG_BASE, count);
Sparam_Add(sInfo, sBase, pPlayer->GetFrags());
HCLIENT hClient = pPlayer->GetClient();
if (hClient)
{
sprintf(sBase, "%s%i", NST_PLRID_BASE, count);
Sparam_Add(sInfo, sBase, g_pServerDE->GetClientID(hClient));
}
}
}
Sparam_Add(sInfo, NST_PLRCOUNT, count);
// Pass this info to the Shogo Server...
g_pServerDE->SendToServerApp(sInfo);
// All done...
return(DTRUE);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::UpdateMultiplayer
//
// PURPOSE: Determine if it is time to change levels
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::UpdateMultiplayer()
{
if (!g_pServerDE || GetGameType() == GAMETYPE_SINGLE) return;
DBOOL bStartLevel = DFALSE;
if (m_GameInfo.m_byEnd == NGE_TIME ||
m_GameInfo.m_byEnd == NGE_FRAGSANDTIME)
{
DFLOAT fEndLevelTime = (m_GameInfo.m_dwEndTime * 60.0f);
DFLOAT fTime = g_pServerDE->GetTime();
if (fTime >= fEndLevelTime)
{
bStartLevel = DTRUE;
}
}
if ( !bStartLevel &&
(m_GameInfo.m_byEnd == NGE_FRAGS ||
m_GameInfo.m_byEnd == NGE_FRAGSANDTIME) )
{
if (IsMultiplayerTeamBasedGame())
{
CTeam* pTeam = m_TeamMgr.GetFirstTeam();
while (pTeam)
{
if (pTeam->GetFrags() >= (int)m_GameInfo.m_dwEndFrags)
{
bStartLevel = DTRUE;
break;
}
pTeam = m_TeamMgr.GetNextTeam(pTeam);
}
}
else
{
for (int i = 0; i < MAX_CLIENTS; i++)
{
CPlayerObj* pPlayer = GetPlayerFromClientList(m_aClients[i]);
if (pPlayer)
{
if (pPlayer->GetFrags() >= (int)m_GameInfo.m_dwEndFrags)
{
bStartLevel = DTRUE;
break;
}
}
}
}
}
if (g_bWaitToStartNextLevel)
{
if(g_pServerDE->GetTime() - g_fWaitTimeForNextLevel > WAIT_TIME_FOR_LEVEL_SWITCH)
{
g_bWaitToStartNextLevel = DFALSE;
StartNextMultiplayerLevelAck();
}
return;
}
if (g_bNextLevel)
{
bStartLevel = DTRUE;
}
if (bStartLevel)
{
StartNextMultiplayerLevel();
g_bNextLevel = DFALSE;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::StartNextMultiplayerLevel
//
// PURPOSE: Start the next multiplayer level
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::StartNextMultiplayerLevel()
{
// Tell the server that we're changing the level...
/*
char sInfo[1024];
sInfo[0] = '\0';
Sparam_Add(sInfo, NST_GENERICMESSAGE, NGM_LEVELCHANGING);
g_pServerDE->SendToServerApp(sInfo);
*/
// Tell all clients we're changing levels...
HMESSAGEWRITE hWrite = g_pServerDE->StartMessage(DNULL, SMSG_MP_CHANGING_LEVELS);
g_pServerDE->EndMessage(hWrite);
g_bWaitToStartNextLevel = DTRUE;
g_fWaitTimeForNextLevel = g_pServerDE->GetTime();
// Clear player frags...
/*
for (int i = 0; i < MAX_CLIENTS; i++)
{
CPlayerObj* pPlayer = GetPlayerFromClientList(m_aClients[i]);
if (pPlayer)
{
pPlayer->SetFrags(0);
}
}
// Stop voice mgr stuff...
m_VoiceMgr.StopAll();
// Create the transition team id list so we can properly restore the teams...
m_TeamMgr.CreateTeamTransIDs();
// Load the next level...
if (++m_nCurLevel >= m_GameInfo.m_byNumLevels)
{
m_nCurLevel = 0;
}
char* pLevelName = m_GameInfo.m_sLevels[m_nCurLevel];
if (pLevelName)
{
g_pServerDE->LoadWorld(pLevelName, LOADWORLD_LOADWORLDOBJECTS | LOADWORLD_RUNWORLD);
}
else
{
g_pServerDE->BPrint("ERROR CAN'T START NEXT MULTIPLAYER LEVEL!");
}
// Tell the shogo server that we changed the level...
sInfo[0] = '\0';
Sparam_Add(sInfo, NST_GENERICMESSAGE, NGM_LEVELCHANGED);
char sCurLevel[128];
_mbscpy((unsigned char*)sCurLevel, (const unsigned char*)m_GameInfo.m_sLevels[m_nCurLevel]);
char sNextLevel[128];
i = m_nCurLevel + 1;
if (i >= m_GameInfo.m_byNumLevels) i = 0;
_mbscpy((unsigned char*)sNextLevel, (const unsigned char*)m_GameInfo.m_sLevels[i]);
Sparam_Add(sInfo, NST_CURLEVEL, sCurLevel);
Sparam_Add(sInfo, NST_NEXTLEVEL, sNextLevel);
g_pServerDE->SendToServerApp(sInfo);*/
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::StartNextMultiplayerLevelAck
//
// PURPOSE: Start the next multiplayer level
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::StartNextMultiplayerLevelAck()
{
// Tell the shogo server that we're changing the level...
char sInfo[1024];
sInfo[0] = '\0';
Sparam_Add(sInfo, NST_GENERICMESSAGE, NGM_LEVELCHANGING);
g_pServerDE->SendToServerApp(sInfo);
// Clear player frags...
for (int i = 0; i < MAX_CLIENTS; i++)
{
CPlayerObj* pPlayer = GetPlayerFromClientList(m_aClients[i]);
if (pPlayer)
pPlayer->SetFrags(0);
}
// Stop voice mgr stuff...
m_VoiceMgr.StopAll();
// Create the transition team id list so we can properly restore the teams...
m_TeamMgr.CreateTeamTransIDs();
// Load the next level...
if (++m_nCurLevel >= m_GameInfo.m_byNumLevels)
m_nCurLevel = 0;
char* pLevelName = m_GameInfo.m_sLevels[m_nCurLevel];
if (pLevelName)
g_pServerDE->LoadWorld(pLevelName, LOADWORLD_LOADWORLDOBJECTS | LOADWORLD_RUNWORLD);
else
g_pServerDE->BPrint("ERROR CAN'T START NEXT MULTIPLAYER LEVEL!");
// Tell the shogo server that we changed the level...
sInfo[0] = '\0';
Sparam_Add(sInfo, NST_GENERICMESSAGE, NGM_LEVELCHANGED);
char sCurLevel[128];
_mbscpy((unsigned char*)sCurLevel, (const unsigned char*)m_GameInfo.m_sLevels[m_nCurLevel]);
char sNextLevel[128];
i = m_nCurLevel + 1;
if (i >= m_GameInfo.m_byNumLevels) i = 0;
_mbscpy((unsigned char*)sNextLevel, (const unsigned char*)m_GameInfo.m_sLevels[i]);
Sparam_Add(sInfo, NST_CURLEVEL, sCurLevel);
Sparam_Add(sInfo, NST_NEXTLEVEL, sNextLevel);
g_pServerDE->SendToServerApp(sInfo);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::ServerAppMessageFn
//
// PURPOSE: Server app message function
//
// ----------------------------------------------------------------------- //
DRESULT CBloodServerShell::ServerAppMessageFn(char* sMsg)
{
// Sanity checks...
if (!sMsg) return(LT_OK);
// Check for "GAMEINIT" message...
if (_mbscmp((const unsigned char*)sMsg, (const unsigned char*)"GAMEINIT") == 0)
{
SetupGameInfo();
}
else if (_mbscmp((const unsigned char*)sMsg, (const unsigned char*)"NEXTLEVEL") == 0)
{
StartNextMultiplayerLevel();
}
else if (_mbscmp((const unsigned char*)sMsg, (const unsigned char*)"SERVHOST") == 0)
{
m_bBlood2ServHosted = DTRUE;
}
// All done...
return(LT_OK);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::SendBlood2ServConsoleMessage
//
// PURPOSE: Sends a string to be displayed in the ShogoServ console
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::SendBlood2ServConsoleMessage(char* sMsg)
{
if (!sMsg || !m_bBlood2ServHosted) return;
char sInfo[1024];
sInfo[0] = '\0';
Sparam_Add(sInfo, NST_GENERICMESSAGE, NGM_CONSOLEMSG);
Sparam_Add(sInfo, NST_CONSOLEMESSAGE, sMsg);
g_pServerDE->SendToServerApp(sInfo);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::FindClient
//
// PURPOSE: Goes through the client list and checks for a player
// represented by hObject. Returns the HCLIENT if it's still an
// active player.
//
// ----------------------------------------------------------------------- //
HCLIENT CBloodServerShell::FindClient(HOBJECT hObject)
{
if (!g_pServerDE) return DFALSE;
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (m_aClients[i])
{
CPlayerObj *pObj = (CPlayerObj*)g_pServerDE->GetClientUserData(m_aClients[i]);
if (pObj && pObj->m_hObject == hObject)
return m_aClients[i];
}
}
return DNULL;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::UpdateClientPingTimes
//
// PURPOSE: Updates each client with all client ping times
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::UpdateClientPingTimes()
{
HMESSAGEWRITE hWrite;
float ping;
DDWORD clientID;
HCLIENT hClient;
ServerDE *pServerDE = g_pServerDE;
if(!pServerDE) return;
static DFLOAT fPingUpdateCounter = 0.0f;
fPingUpdateCounter += pServerDE->GetFrameTime();
if(fPingUpdateCounter > CLIENT_PING_UPDATE_RATE)
{
hWrite = pServerDE->StartMessage(DNULL, SMSG_PINGTIMES);
hClient = DNULL;
while(hClient = pServerDE->GetNextClient(hClient))
{
clientID = pServerDE->GetClientID(hClient);
pServerDE->GetClientPing(hClient, ping);
pServerDE->WriteToMessageWord(hWrite, (D_WORD)clientID);
pServerDE->WriteToMessageWord(hWrite, (D_WORD)(ping * 1000.0f));
}
pServerDE->WriteToMessageWord(hWrite, 0xFFFF);
pServerDE->EndMessage2(hWrite, MESSAGE_NAGGLE);
fPingUpdateCounter = 0.0f;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: CBloodServerShell::DoLevelChangeCharacterCheck
//
// PURPOSE: Updates each client with all client ping times
//
// ----------------------------------------------------------------------- //
void CBloodServerShell::DoLevelChangeCharacterCheck(char* sLevel)
{
g_bLevelChangeCharacter = DFALSE;
#ifndef _ADDON
return;
#endif
char sUpr[256];
strncpy(sUpr, sLevel, 255);
strupr(sUpr);
if (strstr(sUpr, "_AO")) // is this an add-on level?
{
if (strstr(sUpr, "_CC_C")) // switch to caleb?
{
g_bLevelChangeCharacter = DTRUE;
g_nLevelChangeCharacter = CHARACTER_CALEB;
}
else if (strstr(sUpr, "_CC_I")) // switch to ishmael?
{
g_bLevelChangeCharacter = DTRUE;
g_nLevelChangeCharacter = CHARACTER_ISHMAEL;
}
else if (strstr(sUpr, "_CC_O")) // switch to ophelia?
{
g_bLevelChangeCharacter = DTRUE;
g_nLevelChangeCharacter = CHARACTER_OPHELIA;
}
else if (strstr(sUpr, "_CC_G")) // switch to gabby?
{
g_bLevelChangeCharacter = DTRUE;
g_nLevelChangeCharacter = CHARACTER_GABREILLA;
}
// check for the last level...
if (strstr(sUpr, "ENDBOSS_CC_C")) // check for final caleb nightmare level
{
g_bLevelChangeCharacter = DFALSE;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -