Skip to content

Commit 0ceea9f

Browse files
alexp8Sneer-ra2
andauthored
Develop to main (#458)
* add more logs and update secondsInQueue (#456) Co-authored-by: Sneer-ra2 <[email protected]> * set AutoSaveInterval to 0 --------- Co-authored-by: Sneer-ra2 <[email protected]>
1 parent 1a4573a commit 0ceea9f

File tree

3 files changed

+144
-58
lines changed

3 files changed

+144
-58
lines changed

cncnet-api/app/Extensions/Qm/Matchup/TeamMatchupHandler.php

Lines changed: 140 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ public function matchup(): void
2020
// Check if current player is an observer
2121
if ($this->qmPlayer->isObserver())
2222
{
23-
// If yes, then we skip the matchup because we don't want to compare
24-
// observer with other actual players to find a match.
25-
// Observer will be added to the match later on.
23+
Log::debug("TeamMatchup ** {$playerInQueue} is an observer, skipping matchup process. Will be added to match when other players form one.");
2624
return;
2725
}
2826

@@ -31,21 +29,44 @@ public function matchup(): void
3129
->filter(function($entry) {
3230
return $entry->id !== $this->qmQueueEntry->id;
3331
})->values();
34-
$count = $opponents->count() + 1;
32+
33+
$totalInQueue = $opponents->count() + 1;
3534
$timeInQueue = $this->qmQueueEntry->secondsinQueue();
36-
Log::debug("FindOpponent ** inQueue={$playerInQueue}, players in q: {$count}, for ladder={$ladder->abbreviation}, seconds in Queue: {$timeInQueue}");
35+
$waitTimeBonus = $timeInQueue * $ladderRules->points_per_second;
36+
$effectiveRange = $ladderRules->max_points_difference + $waitTimeBonus;
37+
38+
Log::info("=== TeamMatchup START for {$playerInQueue} ===");
39+
Log::info(" Player: {$playerInQueue} | Points: {$this->qmQueueEntry->points} | Ladder: {$ladder->abbreviation}");
40+
Log::info(" Time in queue: {$timeInQueue}s | Wait bonus: +{$waitTimeBonus} pts | Effective range: {$effectiveRange} pts");
41+
Log::info(" Total players in queue: {$totalInQueue} (including {$playerInQueue})");
42+
43+
$allPlayerNames = $opponents->map(fn($e) => $e->qmPlayer?->player?->username ?? 'Unknown')->implode(', ');
44+
Log::debug(" All players in queue: {$playerInQueue}, {$allPlayerNames}");
3745

3846
// Find opponents in same tier with current player.
47+
$beforeTierFilter = $opponents->count();
3948
$matchableOpponents = $this->quickMatchService->getEntriesInSameTier($ladder, $this->qmQueueEntry, $opponents);
49+
$afterTierFilter = $matchableOpponents->count();
50+
51+
if ($afterTierFilter < $beforeTierFilter) {
52+
$filtered = $beforeTierFilter - $afterTierFilter;
53+
Log::debug(" Tier filter: {$filtered} players filtered out ({$afterTierFilter} remain in same tier)");
54+
}
4055

41-
// Find opponents that can be matched with current player.
56+
// Find opponents that can be matched with current player based on points.
4257
$matchableOpponents = $this->getEntriesInPointRange2v2($this->qmQueueEntry, $matchableOpponents);
4358

4459
$opponentCount = $matchableOpponents->count();
4560
$matchableNames = $matchableOpponents->map(function($entry) {
4661
return $entry->qmPlayer?->player?->username ?? 'Unknown';
4762
})->implode(', ');
48-
Log::debug("FindOpponent ** inQueue={$playerInQueue}, amount of matchable opponent after point filter: {$opponentCount} of {$count}. Names: [{$matchableNames}]");
63+
64+
if ($opponentCount > 0) {
65+
Log::info(" ✅ Point filter passed: {$opponentCount} matchable opponents found");
66+
Log::debug(" Matchable players: [{$matchableNames}]");
67+
} else {
68+
Log::info(" ❌ Point filter: No matchable opponents found after point range validation");
69+
}
4970

5071
// Count the number of players we need to start a match
5172
// Excluding current player
@@ -55,64 +76,84 @@ public function matchup(): void
5576
$matchableOpponentsCount = $matchableOpponents->count();
5677
if ($matchableOpponentsCount < $numberOfOpponentsNeeded)
5778
{
58-
Log::debug("FindOpponent ** inQueue={$playerInQueue}, Team matchup handler ** Not enough players for match yet ($matchableOpponentsCount of $numberOfOpponentsNeeded)");
79+
Log::info(" ❌ MATCH FAILED: Not enough players ({$matchableOpponentsCount}/{$numberOfOpponentsNeeded} needed)");
80+
Log::info("=== TeamMatchup END for {$playerInQueue} - NO MATCH ===\n");
5981
$this->qmPlayer->touch();
6082
return;
6183
}
6284

85+
Log::debug(" ✅ Sufficient players found, attempting to form teams...");
86+
6387
[$teamAPlayers, $teamBPlayers, $stats] = $this->quickMatchService->getBestMatch2v2ForPlayer(
6488
$this->qmQueueEntry,
6589
$matchableOpponents,
6690
$this->history
6791
);
6892

69-
Log::debug("FindOpponent ** TEAMS : "
70-
. json_encode($teamAPlayers) . ' VS'
71-
. json_encode($teamBPlayers));
72-
7393
// Log player names and their team
7494
$teamALog = $teamAPlayers->map(function($entry) {
75-
return $entry->qmPlayer?->player?->username ?? 'Unknown';
95+
$pts = $entry->points;
96+
$name = $entry->qmPlayer?->player?->username ?? 'Unknown';
97+
return "{$name} ({$pts} pts)";
7698
})->implode(', ');
7799
$teamBLog = $teamBPlayers->map(function($entry) {
78-
return $entry->qmPlayer?->player?->username ?? 'Unknown';
100+
$pts = $entry->points;
101+
$name = $entry->qmPlayer?->player?->username ?? 'Unknown';
102+
return "{$name} ({$pts} pts)";
79103
})->implode(', ');
80-
Log::debug("Team A (" . $teamAPlayers->count() . "): " . $teamALog);
81-
Log::debug("Team B (" . $teamBPlayers->count() . "): " . $teamBLog);
104+
105+
Log::info(" Teams formed:");
106+
Log::info(" Team A ({$teamAPlayers->count()}): {$teamALog}");
107+
Log::info(" Team B ({$teamBPlayers->count()}): {$teamBLog}");
82108

83109
// Ensure both teams have exactly two players
84110
if ($teamAPlayers->count() !== 2 || $teamBPlayers->count() !== 2) {
85-
Log::warning("Team size error: Team A has {$teamAPlayers->count()} players, Team B has {$teamBPlayers->count()} players. Expected 2 each.");
111+
Log::warning(" ⚠️ Team size error: Team A has {$teamAPlayers->count()} players, Team B has {$teamBPlayers->count()} players. Expected 2 each.");
86112
}
87113

88114
$players = $teamAPlayers->merge($teamBPlayers);
89115

90116
$commonQmMaps = $this->quickMatchService->getCommonMapsForPlayers($ladder, $players);
117+
$mapCount = count($commonQmMaps);
91118

92-
if (count($commonQmMaps) < 1)
119+
if ($mapCount < 1)
93120
{
94-
Log::info("FindOpponent ** No common maps available");
121+
Log::info(" ❌ MATCH FAILED: No common maps available between all players");
122+
Log::info("=== TeamMatchup END for {$playerInQueue} - NO MATCH ===\n");
95123
$this->qmPlayer->touch();
96124
return;
97125
}
98126

127+
Log::debug(" ✅ Map validation: {$mapCount} common maps available");
128+
99129
// Add observers to the match if there is any (maximum of one observer per match)
100130
// Prioritize observers who have been waiting the longest
101-
$observers = $opponents
102-
->filter(fn(QmQueueEntry $qmQueueEntry) => $qmQueueEntry->qmPlayer?->isObserver())
103-
->sortBy('created_at')
104-
->take(1);
105-
if ($observers->count() > 0)
106-
{
131+
$allObservers = $opponents->filter(fn(QmQueueEntry $qmQueueEntry) => $qmQueueEntry->qmPlayer?->isObserver());
132+
$observers = $allObservers->sortBy('created_at')->take(1);
133+
134+
if ($observers->count() > 0) {
107135
$this->matchHasObservers = true;
136+
$observerName = $observers->first()->qmPlayer?->player?->username ?? 'Unknown';
137+
$observerWait = $observers->first()->secondsinQueue();
138+
Log::info(" 👁 Observer added: {$observerName} (waited {$observerWait}s)");
139+
140+
if ($allObservers->count() > 1) {
141+
$remainingCount = $allObservers->count() - 1;
142+
Log::debug(" {$remainingCount} other observer(s) remain in queue");
143+
}
144+
} else {
145+
Log::debug(" No observers in queue");
108146
}
109147

110148
// Throw exception if team sizes are not exactly two
111149
if ($teamAPlayers->count() !== 2 || $teamBPlayers->count() !== 2) {
112-
Log::warning("Team size error: Team A has {$teamAPlayers->count()} players, Team B has {$teamBPlayers->count()} players. Expected 2 each.");
150+
Log::error(" ❌ MATCH FAILED: Invalid team sizes - Team A: {$teamAPlayers->count()}, Team B: {$teamBPlayers->count()}");
113151
throw new \RuntimeException("Team size error: Team A has {$teamAPlayers->count()} players, Team B has {$teamBPlayers->count()} players. Expected 2 each.");
114152
}
115153

154+
Log::info(" ✅ MATCH CREATED: All validations passed, creating match...");
155+
Log::info("=== TeamMatchup END for {$playerInQueue} - MATCH CREATED ===\n");
156+
116157
// Start the match with all other players and other observers if there is any
117158
$this->createTeamMatch($commonQmMaps, $teamAPlayers, $teamBPlayers, $observers, $stats);
118159
}
@@ -156,32 +197,46 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
156197
{
157198
$rules = $currentQmQueueEntry->ladderHistory->ladder->qmLadderRules;
158199
$playerName = $currentQmQueueEntry->qmPlayer?->player?->username ?? 'Unknown';
200+
$playerPoints = $currentQmQueueEntry->points;
201+
$playerWaitTime = $currentQmQueueEntry->secondsinQueue();
202+
$waitBonus = $playerWaitTime * $rules->points_per_second;
159203

160-
Log::debug("2v2 Search start: queueEntry={$currentQmQueueEntry->id}, name={$playerName}, opponentsInQueue=" . count($opponents));
204+
Log::debug(" --- 2v2 Point Range Search for {$playerName} ({$playerPoints} pts, +{$waitBonus} wait bonus) ---");
161205

162206
// Filter opponents to those that pass point range check with the current player
163207
$potentialOpponents = $this->filterOpponentsInRange($currentQmQueueEntry, $opponents, $rules)
164208
->filter(function($opponent) use ($currentQmQueueEntry) {
165209
return $opponent->id !== $currentQmQueueEntry->id;
166210
})->values();
167211

168-
Log::debug($potentialOpponents->count() . " potential opponents for {$playerName}: " . $potentialOpponents->pluck('qmPlayer.player.username')->implode(', '));
212+
$potentialCount = $potentialOpponents->count();
213+
$potentialNames = $potentialOpponents->map(function($e) {
214+
return $e->qmPlayer?->player?->username . ' (' . $e->points . ' pts)';
215+
})->implode(', ');
216+
217+
Log::debug(" Initial filter: {$potentialCount} potential opponents pass 1-on-1 range check");
218+
if ($potentialCount > 0) {
219+
Log::debug(" Potential: {$potentialNames}");
220+
}
169221

170222
if ($potentialOpponents->count() < 3)
171223
{
172-
Log::debug("Not enough valid opponents for {$playerName} to form a 2v2 match: " . $potentialOpponents->count() . "/3");
224+
Log::debug(" ❌ Not enough opponents for 2v2: {$potentialCount}/3 needed");
173225
return collect();
174226
}
175227

176228
// Sort opponents by a combination of point difference and time in queue bonus
177229
$pointsPerSecond = $rules->points_per_second;
178230
$sortedOpponents = $potentialOpponents->sortBy(function ($opponent) use ($currentQmQueueEntry, $pointsPerSecond) {
179231
$pointDiff = abs($currentQmQueueEntry->points - $opponent->points);
180-
$waitTimeBonus = (strtotime($opponent->updated_at) - strtotime($opponent->created_at)) * $pointsPerSecond;
232+
$waitTimeBonus = $opponent->secondsinQueue() * $pointsPerSecond;
181233
return $pointDiff - $waitTimeBonus;
182234
})->values();
183235

236+
Log::debug(" Sorted opponents by closeness (considering wait time)");
237+
184238
// Try all possible 3-player combinations (since the current player makes 4)
239+
$combinationsTried = 0;
185240
foreach ($this->getCombinations($sortedOpponents, 3) as $threeOthers)
186241
{
187242
$matchPlayers = collect([$currentQmQueueEntry])->merge($threeOthers)->unique('id')->values();
@@ -190,17 +245,19 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
190245
continue;
191246
}
192247

248+
$combinationsTried++;
249+
$comboNames = $matchPlayers->pluck('qmPlayer.player.username')->implode(', ');
250+
193251
if ($this->allPlayersInRange($matchPlayers, $rules))
194252
{
195-
Log::debug(
196-
"✅ Found valid 2v2 match for {$playerName}: " .
197-
$matchPlayers->pluck('qmPlayer.player.username')->implode(', ')
198-
);
253+
Log::debug(" ✅ Found valid 2v2 match after trying {$combinationsTried} combination(s)");
254+
Log::debug(" Match: {$comboNames}");
199255
return $matchPlayers;
200256
}
201257
}
202258

203-
Log::debug("❌ No valid 2v2 match found for {$playerName}");
259+
Log::debug(" ❌ No valid 2v2 match found after trying {$combinationsTried} combination(s)");
260+
Log::debug(" Reason: All combinations failed cross-player range validation");
204261
return collect();
205262
}
206263

@@ -214,21 +271,12 @@ public function getEntriesInPointRange2v2(QmQueueEntry $currentQmQueueEntry, Col
214271
private function getCombinations(Collection $items, int $size): Collection
215272
{
216273
$array = $items->all();
217-
$allNames = collect($array)->map(function($entry) {
218-
return $entry->qmPlayer?->player?->username ?? 'Unknown';
219-
})->implode(', ');
220-
Log::debug("getCombinations called with items: [{$allNames}] and size: {$size}");
221274
$results = [];
222275

223276
$recurse = function ($arr, $size, $start = 0, $current = []) use (&$results, &$recurse)
224277
{
225278
if (count($current) === $size)
226279
{
227-
// Debug log the combination
228-
$names = collect($current)->map(function($entry) {
229-
return $entry->qmPlayer?->player?->username ?? 'Unknown';
230-
})->implode(', ');
231-
Log::debug("getCombinations: [{$names}]");
232280
$results[] = $current;
233281
return;
234282
}
@@ -258,8 +306,10 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
258306
$pointsPerSecond = $rules->points_per_second;
259307
$maxPointsDifference = $rules->max_points_difference;
260308
$currentPointFilter = $current->qmPlayer->player->user->userSettings->disabledPointFilter;
309+
$currentPlayer = $current->qmPlayer?->player?->username ?? 'Unknown';
261310

262311
$matchable = collect();
312+
$filtered = collect();
263313

264314
foreach ($opponents as $opponent)
265315
{
@@ -268,10 +318,12 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
268318
continue;
269319
}
270320

321+
$opponentName = $opponent->qmPlayer?->player?->username ?? 'Unknown';
271322
$diff = abs($current->points - $opponent->points);
272-
$waitTimeBonus = (strtotime($current->updated_at) - strtotime($current->created_at)) * $pointsPerSecond;
323+
$waitTimeBonus = $current->secondsinQueue() * $pointsPerSecond;
324+
$effectiveRange = $waitTimeBonus + $maxPointsDifference;
273325

274-
$inNormalRange = $waitTimeBonus + $maxPointsDifference > $diff;
326+
$inNormalRange = $effectiveRange > $diff;
275327
$inDisabledFilterRange = $currentPointFilter
276328
&& $opponent->qmPlayer->player->user->userSettings->disabledPointFilter
277329
&& $diff < 1000
@@ -282,6 +334,22 @@ private function filterOpponentsInRange(QmQueueEntry $current, Collection $oppon
282334
{
283335
$matchable->push($opponent);
284336
}
337+
else
338+
{
339+
$filtered->put($opponentName, [
340+
'points' => $opponent->points,
341+
'diff' => $diff,
342+
'range' => $effectiveRange,
343+
'reason' => $diff > $effectiveRange ? 'Points too far' : 'Filter mismatch'
344+
]);
345+
}
346+
}
347+
348+
if ($filtered->count() > 0) {
349+
Log::debug(" Filtered out {$filtered->count()} player(s) outside point range:");
350+
foreach ($filtered as $name => $info) {
351+
Log::debug(" - {$name} ({$info['points']} pts): Δ{$info['diff']} > {$info['range']} range");
352+
}
285353
}
286354

287355
return $matchable;
@@ -308,8 +376,8 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
308376
if ($i >= $j) continue; // Skip self and duplicate checks
309377

310378
$diff = abs($p1->points - $p2->points);
311-
$waitTimeBonusP1 = (strtotime($p1->updated_at) - strtotime($p1->created_at)) * $pointsPerSecond;
312-
$waitTimeBonusP2 = (strtotime($p2->updated_at) - strtotime($p2->created_at)) * $pointsPerSecond;
379+
$waitTimeBonusP1 = $p1->secondsinQueue() * $pointsPerSecond;
380+
$waitTimeBonusP2 = $p2->secondsinQueue() * $pointsPerSecond;
313381

314382
$passesNormalRange = ($waitTimeBonusP1 + $maxPointsDifference >= $diff)
315383
|| ($waitTimeBonusP2 + $maxPointsDifference >= $diff);
@@ -328,6 +396,8 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
328396
'points1' => $p1->points,
329397
'points2' => $p2->points,
330398
'diff' => $diff,
399+
'wait1' => $p1->secondsinQueue(),
400+
'wait2' => $p2->secondsinQueue(),
331401
'pass' => $pass
332402
];
333403

@@ -350,20 +420,37 @@ private function allPlayersInRange(Collection $players, QmLadderRules $rules): b
350420
*/
351421
private function logComparisonTable(array $comparisonResults): void
352422
{
353-
Log::debug("=== 2v2 Player Comparison Table ===");
423+
Log::debug(" === 2v2 Player Pair Validation ===");
424+
$passCount = 0;
425+
$failCount = 0;
426+
354427
foreach ($comparisonResults as $result)
355428
{
356-
$status = $result['pass'] ? '✅ PASS' : '❌ FAIL';
429+
$status = $result['pass'] ? '' : '';
430+
if ($result['pass']) {
431+
$passCount++;
432+
} else {
433+
$failCount++;
434+
}
435+
436+
$waitInfo = isset($result['wait1']) && isset($result['wait2'])
437+
? " | Wait: {$result['wait1']}s/{$result['wait2']}s"
438+
: "";
439+
357440
Log::debug(sprintf(
358-
"%-15s (%4d pts) ↔ %-15s (%4d pts) | Diff: %4d | %s",
441+
" %s %-15s (%4d) ↔ %-15s (%4d) | Δ%4d%s",
442+
$status,
359443
$result['p1'],
360444
$result['points1'],
361445
$result['p2'],
362446
$result['points2'],
363447
$result['diff'],
364-
$status
448+
$waitInfo
365449
));
366450
}
367-
Log::debug("===================================");
451+
452+
$total = $passCount + $failCount;
453+
Log::debug(" Summary: {$passCount}/{$total} pairs passed, {$failCount}/{$total} failed");
454+
Log::debug(" =====================================");
368455
}
369456
}

cncnet-api/app/Http/Services/QuickMatchSpawnService.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public static function createSpawnStruct($qmMatch, QmMatchPlayer $qmPlayer, $lad
5757
"IsSpectator" => "False",
5858
"DisableChat" => ($isObserver || $notAllowedToChat) ? "True" : "False",
5959
"AllowChat" => (!$isObserver && !$notAllowedToChat) ? "True" : "False",
60+
"AutoSaveInterval" => 0,
6061
// Filter null values
6162
],
6263
function ($var)

cncnet-api/app/Models/QmQueueEntry.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@ public function ladderHistory()
2020
public function secondsinQueue()
2121
{
2222
$createdAt = $this->created_at;
23-
$updatedAt = $this->updated_at;
2423

25-
// Convert timestamps to Carbon instances
24+
// Convert timestamp to Carbon instance
2625
$createdAtCarbon = Carbon::parse($createdAt);
27-
$updatedAtCarbon = Carbon::parse($updatedAt);
2826

29-
// Calculate the difference in seconds
30-
$secondsDifference = $updatedAtCarbon->diffInSeconds($createdAtCarbon);
27+
// Calculate the difference in seconds from created_at to NOW
28+
$secondsDifference = now()->diffInSeconds($createdAtCarbon);
3129

3230
return $secondsDifference;
3331
}

0 commit comments

Comments
 (0)