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

📄 bloodservershell.cpp

📁 Blood 2全套源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// ----------------------------------------------------------------------- //
//
//	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 + -