/
dieoska
/
ddnet
Обзор
Документация
Войти
/
dieoska
/
ddnet
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/test/gameworld_test.cpp
312 строк
9 KB
KebsCS
Add TEAM_GAME, IsValidTeam, Remove ClampTeam
26 ноя 2025, 00:24
Не верифицирован
26 ноя 2025, 00:24
6a29b5b
Код
Авторство
О чём код?
#include "test.h" #include <base/logger.h> #include <base/system.h> #include <base/types.h> #include <engine/engine.h> #include <engine/kernel.h> #include <engine/server/databases/connection.h> #include <engine/server/databases/connection_pool.h> #include <engine/server/register.h> #include <engine/server/server.h> #include <engine/server/server_logger.h> #include <engine/shared/assertion_logger.h> #include <engine/shared/config.h> #include <generated/protocol.h> #include <game/server/entities/character.h> #include <game/server/gamecontext.h> #include <game/server/gamecontroller.h> #include <game/server/gameworld.h> #include <game/server/player.h> #include <game/version.h> #include <gtest/gtest.h> #include <memory> #include <thread> bool IsInterrupted() { return false; } std::vector<std::string> FakeQueue; std::vector<std::string> FetchAndroidServerCommandQueue() { return FakeQueue; } class CTestGameWorld : public ::testing::Test { public: IGameServer *m_pGameServer = nullptr; CServer *m_pServer = nullptr; std::unique_ptr<IKernel> m_pKernel; CTestInfo m_TestInfo; std::unique_ptr<IStorage> m_pStorage; CGameContext *GameServer() { return (CGameContext *)m_pGameServer; } CTestGameWorld() { CServer *pServer = CreateServer(); m_pServer = pServer; m_pKernel = std::unique_ptr<IKernel>(IKernel::Create()); m_pKernel->RegisterInterface(m_pServer); IEngine *pEngine = CreateTestEngine(GAME_NAME); m_pKernel->RegisterInterface(pEngine); m_TestInfo.m_DeleteTestStorageFilesOnSuccess = true; m_pStorage = m_TestInfo.CreateTestStorage(); EXPECT_NE(m_pStorage, nullptr); m_pKernel->RegisterInterface(m_pStorage.get(), false); IConsole *pConsole = CreateConsole(CFGFLAG_SERVER | CFGFLAG_ECON).release(); m_pKernel->RegisterInterface(pConsole); IConfigManager *pConfigManager = CreateConfigManager(); m_pKernel->RegisterInterface(pConfigManager); IEngineMap *pEngineMap = CreateEngineMap(); m_pKernel->RegisterInterface(pEngineMap); m_pKernel->RegisterInterface(static_cast<IMap *>(pEngineMap), false); IEngineAntibot *pEngineAntibot = CreateEngineAntibot(); m_pKernel->RegisterInterface(pEngineAntibot); m_pKernel->RegisterInterface(static_cast<IAntibot *>(pEngineAntibot), false); m_pGameServer = CreateGameServer(); m_pKernel->RegisterInterface(m_pGameServer); pEngine->Init(); pConsole->Init(); pConfigManager->Init(); m_pServer->RegisterCommands(); EXPECT_NE(m_pServer->LoadMap("coverage"), 0); m_pServer->m_RunServer = CServer::RUNNING; m_pServer->m_AuthManager.Init(); { int Size = GameServer()->PersistentClientDataSize(); for(auto &Client : m_pServer->m_aClients) { Client.m_HasPersistentData = false; Client.m_pPersistentData = malloc(Size); } } m_pServer->m_pPersistentData = malloc(GameServer()->PersistentDataSize()); EXPECT_NE(m_pServer->LoadMap("coverage"), 0); if(!pServer->m_Http.Init(std::chrono::seconds{2})) { log_error("server", "Failed to initialize the HTTP client."); } pServer->m_NetServer.SetCallbacks( CServer::NewClientCallback, CServer::NewClientNoAuthCallback, CServer::ClientRejoinCallback, CServer::DelClientCallback, pServer); pServer->m_Econ.Init(pServer->Config(), pServer->Console(), &pServer->m_ServerBan); pServer->m_Fifo.Init(pServer->Console(), pServer->Config()->m_SvInputFifo, CFGFLAG_SERVER); m_pServer->Antibot()->Init(); GameServer()->OnInit(nullptr); pServer->ReadAnnouncementsFile(); pServer->InitMaplist(); } ~CTestGameWorld() override { m_pServer->m_Econ.Shutdown(); m_pServer->m_Fifo.Shutdown(); m_pGameServer->OnShutdown(nullptr); m_pServer->m_pMap->Unload(); m_pServer->DbPool()->OnShutdown(); } }; TEST_F(CTestGameWorld, ClosestCharacter) { CNetObj_PlayerInput Input = {}; CCharacter *pChr1 = new(0) CCharacter(&GameServer()->m_World, Input); pChr1->m_Pos = vec2(0, 0); GameServer()->m_World.InsertEntity(pChr1); CCharacter *pChr2 = new(1) CCharacter(&GameServer()->m_World, Input); pChr2->m_Pos = vec2(10, 10); GameServer()->m_World.InsertEntity(pChr2); CCharacter *pClosest = GameServer()->m_World.ClosestCharacter(vec2(1, 1), 20, nullptr); EXPECT_EQ(pClosest, pChr1); } TEST_F(CTestGameWorld, IntersectEntity) { CNetObj_PlayerInput Input = {}; CCharacter *pChrLeft = new(0) CCharacter(&GameServer()->m_World, Input); pChrLeft->m_Pos = vec2(15, 10); GameServer()->m_World.InsertEntity(pChrLeft); CCharacter *pChrRight = new(1) CCharacter(&GameServer()->m_World, Input); pChrRight->m_Pos = vec2(16, 10); GameServer()->m_World.InsertEntity(pChrRight); float Radius = 5.0f; vec2 IntersectAt; CCharacter *pIntersectedChar; // both tees are exactly on the line // if we go intersect left to right we find the left one pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(10, 10), // intersect from vec2(20, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, nullptr, // pNotThis -1, // CollideWith nullptr /* pThisOnly */); EXPECT_EQ(pIntersectedChar, pChrLeft); // if we intersect right to left we find the right one pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(20, 10), // intersect from vec2(10, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, nullptr, // pNotThis -1, // CollideWith nullptr /* pThisOnly */); EXPECT_EQ(pIntersectedChar, pChrRight); // but not if we ignore the right one pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(20, 10), // intersect from vec2(10, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, pChrRight, // pNotThis -1, // CollideWith nullptr /* pThisOnly */); EXPECT_EQ(pIntersectedChar, pChrLeft); // or we force find the left one pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(20, 10), // intersect from vec2(10, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, nullptr, // pNotThis -1, // CollideWith pChrLeft /* pThisOnly */); EXPECT_EQ(pIntersectedChar, pChrLeft); // pNotThis == pThisOnly => nullptr pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(20, 10), // intersect from vec2(10, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, pChrLeft, // pNotThis -1, // CollideWith pChrLeft /* pThisOnly */); EXPECT_EQ(pIntersectedChar, nullptr); // the tee closer to the start of the intersection line // will not be matched if it is further than Radius away // from the line vec2 CloserToFromButTooFarFromLine = vec2(11, 11 + Radius + pChrLeft->GetProximityRadius()); pChrLeft->SetPosition(CloserToFromButTooFarFromLine); pChrLeft->m_Pos = CloserToFromButTooFarFromLine; pIntersectedChar = (CCharacter *)GameServer()->m_World.IntersectEntity( vec2(10, 10), // intersect from vec2(20, 10), // intersect to Radius, CGameWorld::ENTTYPE_CHARACTER, IntersectAt, nullptr, // pNotThis -1, // CollideWith nullptr /* pThisOnly */); EXPECT_EQ(pIntersectedChar, pChrRight); } TEST_F(CTestGameWorld, BasicTick) { int ClientId = 0; bool Afk = true; int LastWhisperTo = -1; const int StartTeam = GameServer()->m_pController->GetAutoTeam(ClientId); GameServer()->CreatePlayer(ClientId, StartTeam, Afk, LastWhisperTo); GameServer()->OnTick(); } TEST_F(CTestGameWorld, CharacterEmote) { int ClientId = 0; bool Afk = true; int LastWhisperTo = -1; GameServer()->CreatePlayer(ClientId, TEAM_GAME, Afk, LastWhisperTo); CPlayer *pPlayer = GameServer()->m_apPlayers[ClientId]; pPlayer->ForceSpawn(vec2(0, 0)); CCharacter *pChr = pPlayer->GetCharacter(); ASSERT_NE(pChr, nullptr); // afk pPlayer->SetAfk(true); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_BLINK); // not afk pPlayer->SetAfk(false); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_NORMAL); // frozen pChr->Freeze(10); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_BLINK); // frozen and paused pPlayer->Pause(CPlayer::PAUSE_PAUSED, true); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_NORMAL); // ninja jetpack pPlayer->Pause(CPlayer::PAUSE_NONE, true); pChr->UnFreeze(); pPlayer->m_NinjaJetpack = true; pChr->m_NinjaJetpack = true; pChr->SetJetpack(true); pChr->SetActiveWeapon(WEAPON_GUN); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_HAPPY); // /emote angry 3 chat command pChr->SetEmote(EMOTE_ANGRY, GameServer()->Server()->Tick() + GameServer()->Server()->TickSpeed() * 3); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_ANGRY); // /emote angry 3 chat command and frozen pChr->Freeze(10); ASSERT_EQ(pChr->DetermineEyeEmote(), EMOTE_ANGRY); }