Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Repositories/Eloquent/AllocationRepository.php
7460 views
1
<?php
2
3
namespace Pterodactyl\Repositories\Eloquent;
4
5
use Pterodactyl\Models\Allocation;
6
use Illuminate\Database\Eloquent\Builder;
7
use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;
8
9
class AllocationRepository extends EloquentRepository implements AllocationRepositoryInterface
10
{
11
/**
12
* Return the model backing this repository.
13
*/
14
public function model(): string
15
{
16
return Allocation::class;
17
}
18
19
/**
20
* Return all the allocations that exist for a node that are not currently
21
* allocated.
22
*/
23
public function getUnassignedAllocationIds(int $node): array
24
{
25
return Allocation::query()->select('id')
26
->whereNull('server_id')
27
->where('node_id', $node)
28
->get()
29
->pluck('id')
30
->toArray();
31
}
32
33
/**
34
* Return a concatenated result set of node ips that already have at least one
35
* server assigned to that IP. This allows for filtering out sets for
36
* dedicated allocation IPs.
37
*
38
* If an array of nodes is passed the results will be limited to allocations
39
* in those nodes.
40
*/
41
protected function getDiscardableDedicatedAllocations(array $nodes = []): array
42
{
43
$query = Allocation::query()->selectRaw('CONCAT_WS("-", node_id, ip) as result');
44
45
if (!empty($nodes)) {
46
$query->whereIn('node_id', $nodes);
47
}
48
49
return $query->whereNotNull('server_id')
50
->groupByRaw('CONCAT(node_id, ip)')
51
->get()
52
->pluck('result')
53
->toArray();
54
}
55
56
/**
57
* Return a single allocation from those meeting the requirements.
58
*/
59
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false): ?Allocation
60
{
61
$query = Allocation::query()->whereNull('server_id');
62
63
if (!empty($nodes)) {
64
$query->whereIn('node_id', $nodes);
65
}
66
67
if (!empty($ports)) {
68
$query->where(function (Builder $inner) use ($ports) {
69
$whereIn = [];
70
foreach ($ports as $port) {
71
if (is_array($port)) {
72
$inner->orWhereBetween('port', $port);
73
continue;
74
}
75
76
$whereIn[] = $port;
77
}
78
79
if (!empty($whereIn)) {
80
$inner->orWhereIn('port', $whereIn);
81
}
82
});
83
}
84
85
// If this allocation should not be shared with any other servers get
86
// the data and modify the query as necessary,
87
if ($dedicated) {
88
$discard = $this->getDiscardableDedicatedAllocations($nodes);
89
90
if (!empty($discard)) {
91
$query->whereNotIn(
92
$this->getBuilder()->raw('CONCAT_WS("-", node_id, ip)'),
93
$discard
94
);
95
}
96
}
97
98
return $query->inRandomOrder()->first();
99
}
100
}
101
102