Path: blob/1.0-develop/app/Services/Deployment/AllocationSelectionService.php
10263 views
<?php12namespace Pterodactyl\Services\Deployment;34use Pterodactyl\Models\Allocation;5use Pterodactyl\Exceptions\DisplayException;6use Pterodactyl\Services\Allocations\AssignmentService;7use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface;8use Pterodactyl\Exceptions\Service\Deployment\NoViableAllocationException;910class AllocationSelectionService11{12protected bool $dedicated = false;1314protected array $nodes = [];1516protected array $ports = [];1718/**19* AllocationSelectionService constructor.20*/21public function __construct(private AllocationRepositoryInterface $repository)22{23}2425/**26* Toggle if the selected allocation should be the only allocation belonging27* to the given IP address. If true an allocation will not be selected if an IP28* already has another server set to use on if its allocations.29*/30public function setDedicated(bool $dedicated): self31{32$this->dedicated = $dedicated;3334return $this;35}3637/**38* A list of node IDs that should be used when selecting an allocation. If empty, all39* nodes will be used to filter with.40*/41public function setNodes(array $nodes): self42{43$this->nodes = $nodes;4445return $this;46}4748/**49* An array of individual ports or port ranges to use when selecting an allocation. If50* empty, all ports will be considered when finding an allocation. If set, only ports appearing51* in the array or range will be used.52*53* @throws DisplayException54*/55public function setPorts(array $ports): self56{57$stored = [];58foreach ($ports as $port) {59if (is_digit($port)) {60$stored[] = $port;61}6263// Ranges are stored in the ports array as an array which can be64// better processed in the repository.65if (preg_match(AssignmentService::PORT_RANGE_REGEX, $port, $matches)) {66if (abs($matches[2] - $matches[1]) > AssignmentService::PORT_RANGE_LIMIT) {67throw new DisplayException(trans('exceptions.allocations.too_many_ports'));68}6970$stored[] = [$matches[1], $matches[2]];71}72}7374$this->ports = $stored;7576return $this;77}7879/**80* Return a single allocation that should be used as the default allocation for a server.81*82* @throws NoViableAllocationException83*/84public function handle(): Allocation85{86$allocation = $this->repository->getRandomAllocation($this->nodes, $this->ports, $this->dedicated);8788if (is_null($allocation)) {89throw new NoViableAllocationException(trans('exceptions.deployment.no_viable_allocations'));90}9192return $allocation;93}94}959697