@@ -158,64 +158,70 @@ Match::DisconnectedPlayer(PlayerSocket& player)
158158 default :
159159 throw MutexError (" WinXP::Match::DisconnectedPlayer(): An error occured waiting for mutex: " + std::to_string (GetLastError ()));
160160 }
161-
162- RemovePlayer (player);
163-
164- // End the match on no players, marking it as to-be-removed from MatchManager
165- if (m_players.empty ())
166- {
167- m_state = STATE_ENDED;
168- }
169- else if (m_state == STATE_WAITINGFORPLAYERS)
170- {
171- MsgServerStatus msgServerStatus;
172- msgServerStatus.playersWaiting = static_cast <int >(m_players.size ());
173- BroadcastGenericMessage<MessageServerStatus>(msgServerStatus);
174- }
175- // Originally, servers replaced players who have left the game with computer (AI) players.
176- // Based on the game, either replace with computer player, or end the game directly by disconnecting everyone.
177- else if (m_state == STATE_PLAYING || m_state == STATE_GAMEOVER)
161+ try
178162 {
179- if ((g_config.allowSinglePlayer || m_players.size () > 1 ) && SupportsComputerPlayers ())
163+ RemovePlayer (player);
164+
165+ // End the match on no players, marking it as to-be-removed from MatchManager
166+ if (m_players.empty ())
167+ {
168+ m_state = STATE_ENDED;
169+ }
170+ else if (m_state == STATE_WAITINGFORPLAYERS)
180171 {
181- const uint32 userID = std::uniform_int_distribution<uint32>{}(g_rng);
172+ MsgServerStatus msgServerStatus;
173+ msgServerStatus.playersWaiting = static_cast <int >(m_players.size ());
174+ BroadcastGenericMessage<MessageServerStatus>(msgServerStatus);
175+ }
176+ // Originally, servers replaced players who have left the game with computer (AI) players.
177+ // Based on the game, either replace with computer player, or end the game directly by disconnecting everyone.
178+ else if (m_state == STATE_PLAYING || m_state == STATE_GAMEOVER)
179+ {
180+ if ((g_config.allowSinglePlayer || m_players.size () > 1 ) && SupportsComputerPlayers ())
181+ {
182+ const uint32 userID = std::uniform_int_distribution<uint32>{}(g_rng);
182183
183- MsgPlayerReplaced msgPlayerReplaced;
184- msgPlayerReplaced.userIDOld = player.GetID ();
185- msgPlayerReplaced.userIDNew = userID;
186- BroadcastGenericMessage<MessagePlayerReplaced>(msgPlayerReplaced);
184+ MsgPlayerReplaced msgPlayerReplaced;
185+ msgPlayerReplaced.userIDOld = player.GetID ();
186+ msgPlayerReplaced.userIDNew = userID;
187+ BroadcastGenericMessage<MessagePlayerReplaced>(msgPlayerReplaced);
187188
188- m_playerSeatsComputer[player.m_seat ] = true ;
189- m_playerComputerIDs[player.m_seat ] = userID;
189+ m_playerSeatsComputer[player.m_seat ] = true ;
190+ m_playerComputerIDs[player.m_seat ] = userID;
190191
191- OnReplacePlayer (player, userID);
192- }
192+ OnReplacePlayer (player, userID);
193+ }
193194#if not MATCH_NO_DISCONNECT_ON_PLAYER_LEAVE
194- else
195- {
196- SessionLog () << " [MATCH] " << m_guid << " : A player left, closing match!" << std::endl;
197-
198- for (PlayerSocket* p : m_players)
195+ else
199196 {
200- try
201- {
202- p->OnMatchDisconnect ();
203- }
204- catch (const std::exception& err)
197+ SessionLog () << " [MATCH] " << m_guid << " : A player left, closing match!" << std::endl;
198+
199+ for (PlayerSocket* p : m_players)
205200 {
206- SessionLog () << " [MATCH] " << m_guid
207- << " : Couldn't disconnect socket from this match! Disconnecting from server instead. Error: "
208- << err.what () << std::endl;
209- p->Disconnect ();
201+ try
202+ {
203+ p->OnMatchDisconnect ();
204+ }
205+ catch (const std::exception& err)
206+ {
207+ SessionLog () << " [MATCH] " << m_guid
208+ << " : Couldn't disconnect socket from this match! Disconnecting from server instead. Error: "
209+ << err.what () << std::endl;
210+ p->Disconnect ();
211+ }
210212 }
211- }
212- m_players.clear ();
213+ m_players.clear ();
213214
214- m_state = STATE_ENDED;
215- }
215+ m_state = STATE_ENDED;
216+ }
216217#endif
218+ }
219+ }
220+ catch (...)
221+ {
222+ ReleaseMutex (m_mutex);
223+ throw ;
217224 }
218-
219225 if (!ReleaseMutex (m_mutex))
220226 throw MutexError (" WinXP::Match::DisconnectedPlayer(): Couldn't release mutex: " + std::to_string (GetLastError ()));
221227}
@@ -228,23 +234,44 @@ Match::Update()
228234 {
229235 case STATE_WAITINGFORPLAYERS:
230236 {
231- // Start the game, if all players are waiting for opponents
232- if (m_players.size () == GetRequiredPlayerCount () &&
233- std::all_of (m_players.begin (), m_players.end (),
234- [](const auto & player) { return player->GetState () == PlayerSocket::STATE_WAITINGFOROPPONENTS; }))
237+ switch (WaitForSingleObject (m_mutex, MATCH_MUTEX_TIMEOUT_MS))
238+ {
239+ case WAIT_OBJECT_0: // Acquired ownership of the mutex
240+ break ;
241+ case WAIT_TIMEOUT:
242+ throw MutexError (" WinXP::Match::Update(): Timed out waiting for mutex: " + std::to_string (GetLastError ()));
243+ case WAIT_ABANDONED: // Acquired ownership of an abandoned mutex
244+ throw MutexError (" WinXP::Match::Update(): Got ownership of an abandoned mutex: " + std::to_string (GetLastError ()));
245+ default :
246+ throw MutexError (" WinXP::Match::Update(): An error occured waiting for mutex: " + std::to_string (GetLastError ()));
247+ }
248+ try
235249 {
236- // Distribute unique IDs for each player, starting from 0
237- const int playerCount = static_cast <int >(m_players.size ());
238- const std::vector<int > seats = GenerateUniqueRandomNums (0 , playerCount - 1 );
239- for (int i = 0 ; i < playerCount; i++)
240- const_cast <int16&>(m_players[i]->m_seat ) = seats[i];
250+ // Start the game, if all players are waiting for opponents
251+ if (m_players.size () == GetRequiredPlayerCount () &&
252+ std::all_of (m_players.begin (), m_players.end (),
253+ [](const auto & player) { return player->GetState () == PlayerSocket::STATE_WAITINGFOROPPONENTS; }))
254+ {
255+ // Distribute unique IDs for each player, starting from 0
256+ const int playerCount = static_cast <int >(m_players.size ());
257+ const std::vector<int > seats = GenerateUniqueRandomNums (0 , playerCount - 1 );
258+ for (int i = 0 ; i < playerCount; i++)
259+ const_cast <int16&>(m_players[i]->m_seat ) = seats[i];
241260
242- for (PlayerSocket* p : m_players)
243- p->OnGameStart (m_players);
261+ for (PlayerSocket* p : m_players)
262+ p->OnGameStart (m_players);
244263
245- SessionLog () << " [MATCH] " << m_guid << " : Started match!" << std::endl;
246- m_state = STATE_PLAYING;
264+ SessionLog () << " [MATCH] " << m_guid << " : Started match!" << std::endl;
265+ m_state = STATE_PLAYING;
266+ }
267+ }
268+ catch (...)
269+ {
270+ ReleaseMutex (m_mutex);
271+ throw ;
247272 }
273+ if (!ReleaseMutex (m_mutex))
274+ throw MutexError (" WinXP::Match::Update(): Couldn't release mutex: " + std::to_string (GetLastError ()));
248275 break ;
249276 }
250277 case STATE_PLAYING:
0 commit comments