-
Notifications
You must be signed in to change notification settings - Fork 0
/
GameRoomManager.cpp
141 lines (120 loc) · 4.46 KB
/
GameRoomManager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
// Created by floweryclover on 2024-01-30.
//
#include "GameRoomManager.h"
#include "GameData.h"
#include "BattleGameServer.h"
#include "ClientManager.h"
#include <iostream>
GameRoomManager::GameRoomManager() noexcept : mNewRoomId(ROOM_MAINMENU+1)
{
mGameRooms.emplace(ROOM_MAINMENU, std::make_unique<MainMenuRoom>(ROOM_MAINMENU));
}
void GameRoomManager::Tick()
{
// 매치메이킹
if (mMatchMakingQueue.size() >= 2)
{
auto playerA = mMatchMakingQueue.front();
mMatchMakingQueue.pop();
if (mMatchMakingSet.contains(playerA))
{
mMatchMakingSet.erase(playerA);
auto playerB = mMatchMakingQueue.front();
mMatchMakingQueue.pop();
if (mMatchMakingSet.contains(playerB))
{
mMatchMakingSet.erase(playerB);
mGameRooms.emplace(mNewRoomId, std::make_unique<OneVsOneGameRoom>(mNewRoomId, playerA, playerB));
JoinPlayer(playerA, mNewRoomId);
JoinPlayer(playerB, mNewRoomId);
mNewRoomId++;
}
else // 플레이어 A는 실제로 매치메이킹 중이지만, B는 매치메이킹중이지 않음. A를 다시 큐에 넣음
{
mMatchMakingQueue.emplace(playerA);
mMatchMakingSet.emplace(playerA);
}
}
}
// 삭제할 방이 mRoomDestoryQueue에 있다면 삭제
if (!mRoomDestroyQueue.empty())
{
auto room = mRoomDestroyQueue.front();
mRoomDestroyQueue.pop();
if (!mGameRooms.contains(room) || room == ROOM_MAINMENU)
{std::cerr << "존재하지 않는 방 또는 메인메뉴용 방을 삭제하려고 시도했습니다." << std::endl;}
else
{
auto pPlayerCountableRoom = dynamic_cast<IPlayerCountable*>(mGameRooms.at(room).get());
if (pPlayerCountableRoom != nullptr)
{
auto players = pPlayerCountableRoom->GetAllPlayers();
for (auto player : players)
{ JoinPlayer(player, ROOM_MAINMENU);}
}
mGameRooms.erase(room);
}
}
// 모든 게임방 틱
for (auto iter = mGameRooms.begin(); iter != mGameRooms.end(); iter++)
{
auto pTickable = dynamic_cast<ITickable*>(iter->second.get());
//auto pTickable = dynamic_cast<ITickable*>(dynamic_cast<OneVsOneGameRoom*>(iter->second.get()));
if (pTickable != nullptr)
{pTickable->Tick();}
}
}
void GameRoomManager::JoinPlayer(ClientId clientId, GameRoomId roomId)
{
if (!mRoomOfPlayers.contains(clientId)
|| !mGameRooms.contains(roomId))
{return;}
auto pPreviousRoom = mGameRooms.at(mRoomOfPlayers.at(clientId)).get();
if (pPreviousRoom != nullptr)
{pPreviousRoom->OnPlayerLeft(clientId);}
auto pNewRoom = mGameRooms.at(roomId).get();
if (pNewRoom != nullptr)
{pNewRoom->OnPlayerJoined(clientId);}
else
{std::cerr << "클라이언트 " << clientId << "을 " << roomId << "번 게임으로 이동하려 했으나 존재하지 않았습니다." << std::endl; }
mRoomOfPlayers.at(clientId) = roomId;
}
void GameRoomManager::StartMatchMaking(ClientId clientId)
{
if (!mRoomOfPlayers.contains(clientId)
|| mRoomOfPlayers.at(clientId) != ROOM_MAINMENU)
{return;}
mMatchMakingQueue.emplace(clientId);
mMatchMakingSet.emplace(clientId);
}
void GameRoomManager::StopMatchMaking(ClientId clientId)
{mMatchMakingSet.erase(clientId);}
void GameRoomManager::OnPlayerConnected(ClientId clientId)
{
mRoomOfPlayers.emplace(clientId, ROOM_MAINMENU);
JoinPlayer(clientId, ROOM_MAINMENU);
}
void GameRoomManager::OnPlayerDisconnected(ClientId clientId)
{
auto roomId = mRoomOfPlayers.at(clientId);
mRoomOfPlayers.erase(clientId);
mGameRooms.at(roomId)->OnPlayerLeft(clientId);
}
std::optional<GameRoomId> GameRoomManager::GetPlayerJoinedRoomId(ClientId clientId) const noexcept
{
if (!mRoomOfPlayers.contains(clientId))
{return std::nullopt;}
return mRoomOfPlayers.at(clientId);
}
BaseRoom* GameRoomManager::GetGameRoom(GameRoomId roomId) noexcept
{return const_cast<BaseRoom*>(this->GetConstGameRoom(roomId));}
const BaseRoom* GameRoomManager::GetConstGameRoom(GameRoomId roomId) const noexcept
{
if (!mGameRooms.contains(roomId)
|| roomId == ROOM_MAINMENU)
{return nullptr;}
return mGameRooms.at(roomId).get();
}
void GameRoomManager::DestroyRoom(GameRoomId roomId) noexcept
{mRoomDestroyQueue.emplace(roomId);}