Skip to content

Commit 1f180f6

Browse files
alexp8Sneer-ra2
andauthored
Develop to master (#377)
* Duplicate handling. * Added page of list with active duplicates. * Full IP-check for confirmed duplicates. * Simplification. * Removed comment. * Small update. * Added database migration. * Added unit test. * track observers * move comment * update image.php --------- Co-authored-by: Sneer <[email protected]> Co-authored-by: Sneer-ra2 <[email protected]>
1 parent 1666a76 commit 1f180f6

File tree

22 files changed

+1749
-137
lines changed

22 files changed

+1749
-137
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function createMatch(Collection $maps, Collection $otherQMQueueEntries)
3838
!strpos($map->description, 'Map Info')
3939
&& !strpos($map->description, 'Map Guide')
4040
&& !strpos($map->description, 'Ladder Guide')
41+
&& !strpos($map->description, 'Ladder Info')
4142
&& !strpos($map->description, 'Ladder Rules');
4243
});
4344

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function matchup(): void
7676

7777
// Add observers to the match if there is any
7878
$observers = $opponents->filter(fn(QmQueueEntry $qmQueueEntry) => $qmQueueEntry->qmPlayer?->isObserver());
79-
if ($observers->count() < 0)
79+
if ($observers->count() > 0)
8080
{
8181
$this->matchHasObservers = true;
8282
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Models\Ladder;
6+
use App\Models\LadderHistory;
7+
use App\Models\PlayerCache;
8+
use App\Models\IpAddressHistory;
9+
use App\Models\QmUserId;
10+
use App\Models\User;
11+
use Illuminate\Http\Request;
12+
use Illuminate\Support\Collection;
13+
14+
class ActiveDuplicatesController extends Controller
15+
{
16+
public function index(Request $request)
17+
{
18+
$ladderAbbreviation = $request->abbreviation ?? \App\Helpers\GameHelper::$GAME_RA2;
19+
$ladder = Ladder::where('abbreviation', $ladderAbbreviation)->first();
20+
$period = $request->get('period', 'current');
21+
$targetMonth = $period === 'last' ? now()->subMonthNoOverflow() : now();
22+
$startDate = $targetMonth->startOfMonth();
23+
$endDate = $targetMonth->copy()->endOfMonth();
24+
$activeLadders = $period === 'last' ? Ladder::whereHas('last_month_matches')->get() : Ladder::whereHas('current_month_matches')->get();
25+
26+
$currentHistory = LadderHistory::where('ladder_id', $ladder->id)
27+
->where('starts', '=', $startDate->toDateTimeString())
28+
->where('ends', '=', $endDate->toDateTimeString())
29+
->first();
30+
31+
$playerCaches = PlayerCache::where('ladder_history_id', $currentHistory->id)
32+
->with('player.user')
33+
->get();
34+
35+
$potentialDuplicates = [];
36+
37+
foreach ($playerCaches as $cache)
38+
{
39+
$user = $cache->player->user;
40+
41+
if (!$user || !$user->isUnconfirmedPrimary())
42+
{
43+
continue;
44+
}
45+
46+
$relatedUsers = $this->findPotentialDuplicatesDetailed($user);
47+
48+
if ($relatedUsers->isNotEmpty())
49+
{
50+
$potentialDuplicates[] = [
51+
'user' => $user,
52+
'player' => $cache->player,
53+
'dupes' => $relatedUsers,
54+
];
55+
}
56+
}
57+
58+
return view('admin.active-duplicates', [
59+
'potentialDuplicates' => $potentialDuplicates,
60+
'ladder' => $ladder,
61+
'period' => $period,
62+
'activeLadders' => $activeLadders,
63+
'selectedAbbreviation' => $ladder->abbreviation,
64+
]);
65+
}
66+
67+
private function findPotentialDuplicatesDetailed(User $user): Collection
68+
{
69+
$dupesMap = [];
70+
71+
// IP-based duplicates.
72+
if ($user->ip_address_id)
73+
{
74+
$ipDupes = IpAddressHistory::with('user')
75+
->where('ip_address_id', $user->ip_address_id)
76+
->where('user_id', '!=', $user->id)
77+
->get()
78+
->pluck('user')
79+
->filter()
80+
->unique('id');
81+
82+
foreach ($ipDupes as $dupe)
83+
{
84+
$id = $dupe->id;
85+
if (!isset($dupesMap[$id]))
86+
{
87+
$dupesMap[$id] = [
88+
'user' => $dupe,
89+
'reasons' => [],
90+
];
91+
}
92+
$dupesMap[$id]['reasons'][] = 'IP';
93+
}
94+
}
95+
96+
// QM-ID-based duplicates.
97+
$qmIds = QmUserId::where('user_id', $user->id)->pluck('qm_user_id')->unique();
98+
99+
if ($qmIds->isNotEmpty())
100+
{
101+
$qmDupes = QmUserId::with('user')
102+
->whereIn('qm_user_id', $qmIds)
103+
->where('user_id', '!=', $user->id)
104+
->get()
105+
->pluck('user')
106+
->filter()
107+
->unique('id');
108+
109+
foreach ($qmDupes as $dupe)
110+
{
111+
$id = $dupe->id;
112+
if (!isset($dupesMap[$id]))
113+
{
114+
$dupesMap[$id] = [
115+
'user' => $dupe,
116+
'reasons' => [],
117+
];
118+
}
119+
$dupesMap[$id]['reasons'][] = 'QM-ID';
120+
}
121+
}
122+
123+
return collect($dupesMap)->values();
124+
}
125+
126+
}

0 commit comments

Comments
 (0)