Skip to content

Commit 0ca13fc

Browse files
authored
Merge branch 'develop' into hidedelifown
2 parents 76d671a + 8a97b73 commit 0ca13fc

File tree

21 files changed

+109
-290
lines changed

21 files changed

+109
-290
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ This file is a running track of new features and fixes to each version of the pa
33

44
This project follows [Semantic Versioning](http://semver.org) guidelines.
55

6+
## v1.1.3
7+
### Fixed
8+
* Server bulk power actions command will no longer attempt to run commands against installing or suspended servers.
9+
610
## v1.1.2
711
### Fixed
812
* Fixes an exception thrown while trying to validate IP access for the client API.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ I would like to extend my sincere thanks to the following sponsors for helping f
2525
| [**MineStrator**](https://minestrator.com/) | Looking for a French highend hosting company for you minecraft server? More than 14,000 members on our discord, trust us. |
2626
| [**DedicatedMC**](https://dedicatedmc.io/) | DedicatedMC provides Raw Power hosting at affordable pricing, making sure to never compromise on your performance and giving you the best performance money can buy. |
2727
| [**Skynode**](https://www.skynode.pro/) | Skynode provides blazing fast game servers along with a top-notch user experience. Whatever our clients are looking for, we're able to provide it! |
28-
| [**XCORE-SERVER.de**](https://xcore-server.de/) | XCORE-SERVER.de offers High-End Servers for hosting and gaming since 2012. Fast, excellent and well-known for eSports Gaming. |
28+
| [**XCORE**](https://xcore-server.de/) | XCORE offers High-End Servers for hosting and gaming since 2012. Fast, excellent and well-known for eSports Gaming. |
2929
| [**RoyaleHosting**](https://royalehosting.net/) | Build your dreams and deploy them with RoyaleHosting’s reliable servers and network. Easy to use, provisioned in a couple of minutes. |
3030
| [**Spill Hosting**](https://spillhosting.no/) | Spill Hosting is a Norwegian hosting service, which aims to cheap services on quality servers. Premium i9-9900K processors will run your game like a dream. |
3131
| [**DeinServerHost**](https://deinserverhost.de/) | DeinServerHost offers Dedicated, vps and Gameservers for many popular Games like Minecraft and Rust in Germany since 2013. |

app/Console/Commands/Server/BulkPowerActionCommand.php

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,15 @@
22

33
namespace Pterodactyl\Console\Commands\Server;
44

5+
use Pterodactyl\Models\Server;
56
use Illuminate\Console\Command;
6-
use GuzzleHttp\Exception\RequestException;
77
use Illuminate\Validation\ValidationException;
88
use Illuminate\Validation\Factory as ValidatorFactory;
99
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
10-
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
10+
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
1111

1212
class BulkPowerActionCommand extends Command
1313
{
14-
/**
15-
* @var \Pterodactyl\Repositories\Wings\DaemonPowerRepository
16-
*/
17-
private $powerRepository;
18-
19-
/**
20-
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
21-
*/
22-
private $repository;
23-
24-
/**
25-
* @var \Illuminate\Validation\Factory
26-
*/
27-
private $validator;
28-
2914
/**
3015
* @var string
3116
*/
@@ -40,36 +25,19 @@ class BulkPowerActionCommand extends Command
4025
protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.';
4126

4227
/**
43-
* BulkPowerActionCommand constructor.
28+
* Handle the bulk power request.
4429
*
4530
* @param \Pterodactyl\Repositories\Wings\DaemonPowerRepository $powerRepository
46-
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
4731
* @param \Illuminate\Validation\Factory $validator
48-
*/
49-
public function __construct(
50-
DaemonPowerRepository $powerRepository,
51-
ServerRepositoryInterface $repository,
52-
ValidatorFactory $validator
53-
) {
54-
parent::__construct();
55-
56-
$this->repository = $repository;
57-
$this->validator = $validator;
58-
$this->powerRepository = $powerRepository;
59-
}
60-
61-
/**
62-
* Handle the bulk power request.
63-
*
6432
* @throws \Illuminate\Validation\ValidationException
6533
*/
66-
public function handle()
34+
public function handle(DaemonPowerRepository $powerRepository, ValidatorFactory $validator)
6735
{
6836
$action = $this->argument('action');
6937
$nodes = empty($this->option('nodes')) ? [] : explode(',', $this->option('nodes'));
7038
$servers = empty($this->option('servers')) ? [] : explode(',', $this->option('servers'));
7139

72-
$validator = $this->validator->make([
40+
$validator = $validator->make([
7341
'action' => $action,
7442
'nodes' => $nodes,
7543
'servers' => $servers,
@@ -89,23 +57,18 @@ public function handle()
8957
throw new ValidationException($validator);
9058
}
9159

92-
$count = $this->repository->getServersForPowerActionCount($servers, $nodes);
60+
$count = $this->getQueryBuilder($servers, $nodes)->count();
9361
if (! $this->confirm(trans('command/messages.server.power.confirm', ['action' => $action, 'count' => $count])) && $this->input->isInteractive()) {
9462
return;
9563
}
9664

9765
$bar = $this->output->createProgressBar($count);
98-
$servers = $this->repository->getServersForPowerAction($servers, $nodes);
99-
100-
$servers->each(function ($server) use ($action, &$bar) {
66+
$this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) {
10167
$bar->clear();
10268

10369
try {
104-
$this->powerRepository
105-
->setNode($server->node)
106-
->setServer($server)
107-
->send($action);
108-
} catch (RequestException $exception) {
70+
$powerRepository->setServer($server)->send($action);
71+
} catch (DaemonConnectionException $exception) {
10972
$this->output->error(trans('command/messages.server.power.action_failed', [
11073
'name' => $server->name,
11174
'id' => $server->id,
@@ -120,4 +83,28 @@ public function handle()
12083

12184
$this->line('');
12285
}
86+
87+
/**
88+
* Returns the query builder instance that will return the servers that should be affected.
89+
*
90+
* @param array $servers
91+
* @param array $nodes
92+
* @return \Illuminate\Database\Eloquent\Builder
93+
*/
94+
protected function getQueryBuilder(array $servers, array $nodes)
95+
{
96+
$instance = Server::query()
97+
->where('suspended', false)
98+
->where('installed', Server::STATUS_INSTALLED);
99+
100+
if (! empty($nodes) && ! empty($servers)) {
101+
$instance->whereIn('id', $servers)->orWhereIn('node_id', $nodes);
102+
} else if (empty($nodes) && ! empty($servers)) {
103+
$instance->whereIn('id', $servers);
104+
} else if (! empty($nodes) && empty($servers)) {
105+
$instance->whereIn('node_id', $nodes);
106+
}
107+
108+
return $instance->with('node');
109+
}
123110
}

app/Contracts/Repository/ServerRepositoryInterface.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,6 @@ public function getDaemonServiceData(Server $server, bool $refresh = false): arr
9595
*/
9696
public function getByUuid(string $uuid): Server;
9797

98-
/**
99-
* Return all of the servers that should have a power action performed against them.
100-
*
101-
* @param int[] $servers
102-
* @param int[] $nodes
103-
* @param bool $returnCount
104-
* @return int|\Illuminate\Support\LazyCollection
105-
*/
106-
public function getServersForPowerAction(array $servers = [], array $nodes = [], bool $returnCount = false);
107-
108-
/**
109-
* Return the total number of servers that will be affected by the query.
110-
*
111-
* @param int[] $servers
112-
* @param int[] $nodes
113-
* @return int
114-
*/
115-
public function getServersForPowerActionCount(array $servers = [], array $nodes = []): int;
116-
11798
/**
11899
* Check if a given UUID and UUID-Short string are unique to a server.
119100
*

app/Http/Requests/Api/Client/Account/UpdatePasswordRequest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Pterodactyl\Http\Requests\Api\Client\Account;
44

5-
use Pterodactyl\Models\User;
65
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
76
use Pterodactyl\Exceptions\Http\Base\InvalidPasswordProvidedException;
87

@@ -32,8 +31,8 @@ public function authorize(): bool
3231
*/
3332
public function rules(): array
3433
{
35-
$rules = User::getRulesForUpdate($this->user());
36-
37-
return ['password' => array_merge($rules['password'], ['confirmed'])];
34+
return [
35+
'password' => ['required', 'string', 'confirmed', 'min:8'],
36+
];
3837
}
3938
}

app/Jobs/Schedule/RunTaskJob.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public function handle(
6969
$commandRepository->setServer($server)->send($this->task->payload);
7070
break;
7171
case 'backup':
72-
$backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null);
72+
$backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true);
7373
break;
7474
default:
7575
throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.');

app/Repositories/Eloquent/ServerRepository.php

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -194,45 +194,6 @@ public function getByUuid(string $uuid): Server
194194
}
195195
}
196196

197-
/**
198-
* Return all of the servers that should have a power action performed against them.
199-
*
200-
* @param int[] $servers
201-
* @param int[] $nodes
202-
* @param bool $returnCount
203-
* @return int|\Illuminate\Support\LazyCollection
204-
*/
205-
public function getServersForPowerAction(array $servers = [], array $nodes = [], bool $returnCount = false)
206-
{
207-
$instance = $this->getBuilder();
208-
209-
if (! empty($nodes) && ! empty($servers)) {
210-
$instance->whereIn('id', $servers)->orWhereIn('node_id', $nodes);
211-
} else if (empty($nodes) && ! empty($servers)) {
212-
$instance->whereIn('id', $servers);
213-
} else if (! empty($nodes) && empty($servers)) {
214-
$instance->whereIn('node_id', $nodes);
215-
}
216-
217-
if ($returnCount) {
218-
return $instance->count();
219-
}
220-
221-
return $instance->with('node')->cursor();
222-
}
223-
224-
/**
225-
* Return the total number of servers that will be affected by the query.
226-
*
227-
* @param int[] $servers
228-
* @param int[] $nodes
229-
* @return int
230-
*/
231-
public function getServersForPowerActionCount(array $servers = [], array $nodes = []): int
232-
{
233-
return $this->getServersForPowerAction($servers, $nodes, true);
234-
}
235-
236197
/**
237198
* Check if a given UUID and UUID-Short string are unique to a server.
238199
*

app/Services/Backups/InitiateBackupService.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Pterodactyl\Repositories\Wings\DaemonBackupRepository;
1414
use Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException;
1515
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
16+
use Pterodactyl\Services\Backups\DeleteBackupService;
1617

1718
class InitiateBackupService
1819
{
@@ -41,24 +42,32 @@ class InitiateBackupService
4142
*/
4243
private $backupManager;
4344

45+
/**
46+
* @var \Pterodactyl\Services\Backups\DeleteBackupService
47+
*/
48+
private $deleteBackupService;
49+
4450
/**
4551
* InitiateBackupService constructor.
4652
*
4753
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
4854
* @param \Illuminate\Database\ConnectionInterface $connection
4955
* @param \Pterodactyl\Repositories\Wings\DaemonBackupRepository $daemonBackupRepository
56+
* @param \Pterodactyl\Services\Backups\DeleteBackupService $deleteBackupService
5057
* @param \Pterodactyl\Extensions\Backups\BackupManager $backupManager
5158
*/
5259
public function __construct(
5360
BackupRepository $repository,
5461
ConnectionInterface $connection,
5562
DaemonBackupRepository $daemonBackupRepository,
63+
DeleteBackupService $deleteBackupService,
5664
BackupManager $backupManager
5765
) {
5866
$this->repository = $repository;
5967
$this->connection = $connection;
6068
$this->daemonBackupRepository = $daemonBackupRepository;
6169
$this->backupManager = $backupManager;
70+
$this->deleteBackupService = $deleteBackupService;
6271
}
6372

6473
/**
@@ -96,13 +105,8 @@ public function setIgnoredFiles(?array $ignored)
96105
* @throws \Pterodactyl\Exceptions\Service\Backup\TooManyBackupsException
97106
* @throws \Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
98107
*/
99-
public function handle(Server $server, string $name = null): Backup
108+
public function handle(Server $server, string $name = null, bool $override = false): Backup
100109
{
101-
// Do not allow the user to continue if this server is already at its limit.
102-
if (! $server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
103-
throw new TooManyBackupsException($server->backup_limit);
104-
}
105-
106110
$previous = $this->repository->getBackupsGeneratedDuringTimespan($server->id, 10);
107111
if ($previous->count() >= 2) {
108112
throw new TooManyRequestsHttpException(
@@ -111,6 +115,18 @@ public function handle(Server $server, string $name = null): Backup
111115
);
112116
}
113117

118+
// Check if the server has reached or exceeded it's backup limit
119+
if (!$server->backup_limit || $server->backups()->where('is_successful', true)->count() >= $server->backup_limit) {
120+
// Do not allow the user to continue if this server is already at its limit and can't override.
121+
if (!$override || $server->backup_limit <= 0) {
122+
throw new TooManyBackupsException($server->backup_limit);
123+
}
124+
125+
// Remove oldest backup
126+
$oldestBackup = $server->backups()->where('is_successful', true)->orderByDesc('created_at')->first();
127+
$this->deleteBackupService->handle($oldestBackup);
128+
}
129+
114130
return $this->connection->transaction(function () use ($server, $name) {
115131
/** @var \Pterodactyl\Models\Backup $backup */
116132
$backup = $this->repository->create([

config/database.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
'collation' => 'utf8mb4_unicode_ci',
4646
'prefix' => env('DB_PREFIX', ''),
4747
'strict' => env('DB_STRICT_MODE', false),
48-
'timezone' => env('DB_TIMEZONE', Time::getMySQLTimezoneOffset(env('APP_TIMEZONE')))
48+
'timezone' => env('DB_TIMEZONE', Time::getMySQLTimezoneOffset(env('APP_TIMEZONE', 'UTC')))
4949
],
5050

5151
/*
@@ -68,7 +68,7 @@
6868
'collation' => 'utf8mb4_unicode_ci',
6969
'prefix' => '',
7070
'strict' => false,
71-
'timezone' => env('DB_TIMEZONE', Time::getMySQLTimezoneOffset(env('APP_TIMEZONE')))
71+
'timezone' => env('DB_TIMEZONE', Time::getMySQLTimezoneOffset(env('APP_TIMEZONE', 'UTC')))
7272
],
7373
],
7474

database/migrations/2020_03_22_163911_merge_permissions_table_into_subusers.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ public function up()
8383
->map(function ($value) {
8484
return self::$permissionsMap[$value] ?? null;
8585
})->filter(function ($value) {
86-
return !is_null($value) && $value !== Permission::ACTION_WEBSOCKET_CONNECT;
86+
return ! is_null($value) && $value !== Permission::ACTION_WEBSOCKET_CONNECT;
8787
})
8888
// All subusers get this permission, so make sure it gets pushed into the array.
89-
->merge([ Permission::ACTION_WEBSOCKET_CONNECT ])
89+
->merge([Permission::ACTION_WEBSOCKET_CONNECT])
9090
->unique()
9191
->values()
9292
->toJson();
@@ -103,12 +103,12 @@ public function up()
103103
*/
104104
public function down()
105105
{
106-
$flipped = array_flip(self::$permissionsMap);
106+
$flipped = array_flip(array_filter(self::$permissionsMap));
107107

108108
foreach (DB::select('SELECT id, permissions FROM subusers') as $datum) {
109109
$values = [];
110110
foreach (json_decode($datum->permissions, true) as $permission) {
111-
if (!empty($v = $flipped[$permission])) {
111+
if (! empty($v = $flipped[$permission])) {
112112
$values[] = $datum->id;
113113
$values[] = $v;
114114
}

0 commit comments

Comments
 (0)