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.
This commit is contained in:
Vari
2024-03-07 22:17:41 +01:00
parent 3f9a257821
commit c8f34d229a
4 changed files with 84 additions and 9 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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']);
});

4
dist/routes/web.php vendored
View File

@@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Api\Matchmaking\MatchmakingController;
use App\Http\Controllers\Web\LoginController;
use Illuminate\Support\Facades\Route;
use Laravel\Socialite\Facades\Socialite;
@@ -49,6 +50,9 @@
});
Route::post('file/{gameVersion}/{seed}/{mapName}', [MatchmakingController::class, 'seedFilePost']);
Route::get('file/{gameVersion}/{seed}/{mapName}', [MatchmakingController::class, 'seedFileGet']);
Route::post('metrics/httplog/event', function () {
return response('', 200);