⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bloodservershell.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	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 + -