From c8f34d229a93be82acab5a40577c2f06800a4910 Mon Sep 17 00:00:00 2001 From: Vari Date: Thu, 7 Mar 2024 22:17:41 +0100 Subject: [PATCH] Fixed file Put/Get endpoints being in the wrong routes file because of prefix. Implemented rotue where the host dleetes an user from the match if he didn't join. Added funktion that tries to fill open games that have missing players. --- .../Api/Matchmaking/MatchmakingController.php | 80 +++++++++++++++++-- dist/app/Models/Game/Matchmaking/Game.php | 5 ++ dist/routes/deathgardenApi.php | 4 +- dist/routes/web.php | 4 + 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/dist/app/Http/Controllers/Api/Matchmaking/MatchmakingController.php b/dist/app/Http/Controllers/Api/Matchmaking/MatchmakingController.php index ea62b04..0b6035d 100644 --- a/dist/app/Http/Controllers/Api/Matchmaking/MatchmakingController.php +++ b/dist/app/Http/Controllers/Api/Matchmaking/MatchmakingController.php @@ -109,6 +109,19 @@ public function seedFilePost(string $gameVersion, string $seed, string $mapName) return response('', 200); } + public function deleteUserFromMatch(string $matchId, string $userId) + { + $foundGame = Game::find($matchId); + $userToRemove = User::find($userId); + $requestUser = Auth::user(); + + // Block request if it doesn't come from the host + if($foundGame === null || $foundGame->creator != $requestUser) + return response('Action not allowed, you are not the creator of the match.', 403); + + $foundGame->players()->detach($userToRemove); + } + public function endOfMatch(EndOfMatchRequest $request) { $game = Game::find($request->matchId); @@ -264,12 +277,6 @@ protected function processQueue(): void if($availableMatchConfigs->isEmpty()) return; - $selectedConfig = MatchConfiguration::selectRandomConfigByWeight($availableMatchConfigs); - - // Should never happen, but just to be careful - if($selectedConfig === null) - return; - $runners = new Collection(); $hunters = new Collection(); @@ -281,6 +288,14 @@ protected function processQueue(): void $runners->add($player); }); + $this->tryFillOpenGames($hunters, $runners); + + $selectedConfig = MatchConfiguration::selectRandomConfigByWeight($availableMatchConfigs); + + // Should never happen, but just to be careful + if($selectedConfig === null) + return; + $hunterGroupsSet = $this->determineMatchingPlayers($hunters, $selectedConfig->hunters); $runnerGroupsSet = $this->determineMatchingPlayers($runners, $selectedConfig->runners); @@ -316,6 +331,59 @@ protected function processQueue(): void $newGame->determineHost(); } + protected function tryFillOpenGames(Collection|array &$hunters, Collection|array &$runners) + { + $openGames = Game::where('status', '=', MatchStatus::Opened->value)->get(); + + foreach ($openGames as $game) { + $neededPlayers = $game->remainingPlayerCount(); + + // game is full and doesn't need filling + if($neededPlayers->getTotal() == 0) + continue; + + if($neededPlayers->hunters > 0) { + $hunterGroupsSet = $this->determineMatchingPlayers($hunters, $neededPlayers->hunters); + + // see if there are any group combinations possible to fill the game + if(count($hunterGroupsSet) === 0) + continue; + + // use biggest groups first + rsort($hunterGroupsSet, SORT_NUMERIC); + + foreach ($hunterGroupsSet as $groupSize) { + $foundQueuedPlayerIndex = $hunters->search(function (QueuedPlayer $hunter) use ($groupSize) { + return ($hunter->following_users_count + 1) === $groupSize; + }); + + $foundHunter = $hunters->pull($foundQueuedPlayerIndex); + $game->addQueuedPlayer($foundHunter); + } + } + + if($neededPlayers->runners > 0) { + $runnerGroupSet = $this->determineMatchingPlayers($runners, $neededPlayers->runners); + + // see if there are any group combinations possible to fill the game + if(count($runnerGroupSet) === 0) + continue; + + // use biggest groups first + rsort($runnerGroupSet, SORT_NUMERIC); + + foreach ($runnerGroupSet as $groupSize) { + $foundQueuedPlayerIndex = $hunters->search(function (QueuedPlayer $hunter) use ($groupSize) { + return ($hunter->following_users_count + 1) === $groupSize; + }); + + $foundRunner = $hunters->pull($foundQueuedPlayerIndex); + $game->addQueuedPlayer($foundRunner); + } + } + } + } + protected function removeUserFromGame(User $user, Game $game) { $game->players()->detach($user); diff --git a/dist/app/Models/Game/Matchmaking/Game.php b/dist/app/Models/Game/Matchmaking/Game.php index becc9c3..60eddd0 100644 --- a/dist/app/Models/Game/Matchmaking/Game.php +++ b/dist/app/Models/Game/Matchmaking/Game.php @@ -66,6 +66,11 @@ public function determineHost(): void $this->save(); } + /** + * Get the number of needed players to fill the game. + * + * @return MatchmakingPlayerCount + */ public function remainingPlayerCount(): MatchmakingPlayerCount { $players = $this->players; diff --git a/dist/routes/deathgardenApi.php b/dist/routes/deathgardenApi.php index 91609ee..c4478d3 100644 --- a/dist/routes/deathgardenApi.php +++ b/dist/routes/deathgardenApi.php @@ -71,9 +71,7 @@ Route::put('match/{matchId}/Close', [MatchmakingController::class, 'close']); Route::put('match/{matchId}/Kill', [MatchmakingController::class, 'kill']); Route::put('match/{matchId}/Quit', [MatchmakingController::class, 'quit']); - - Route::post('file/{gameVersion}/{seed}/{mapName}', [MatchmakingController::class, 'seedFilePost']); - Route::get('file/{gameVersion}/{seed}/{mapName}', [MatchmakingController::class, 'seedFileGet']); + Route::delete('match/{matchId}/user/{$userId}', [MatchmakingController::class, 'deleteUserFromMatch']); }); diff --git a/dist/routes/web.php b/dist/routes/web.php index 3f1f71f..4ddb4ea 100644 --- a/dist/routes/web.php +++ b/dist/routes/web.php @@ -1,5 +1,6 @@