diff --git a/app/Console/Commands/Environment/QueueWorkerServiceCommand.php b/app/Console/Commands/Environment/QueueWorkerServiceCommand.php index 92ea88e75..23fdff40a 100644 --- a/app/Console/Commands/Environment/QueueWorkerServiceCommand.php +++ b/app/Console/Commands/Environment/QueueWorkerServiceCommand.php @@ -18,6 +18,17 @@ class QueueWorkerServiceCommand extends Command public function handle(): void { + if (@file_exists('/.dockerenv')) { + $result = Process::run('supervisorctl restart queue-worker'); + if ($result->failed()) { + $this->error('Error restarting service: ' . $result->errorOutput()); + + return; + } + $this->line('Queue worker service file updated successfully.'); + + return; + } $serviceName = $this->option('service-name') ?? $this->ask('Queue worker service name', 'pelican-queue'); $path = '/etc/systemd/system/' . $serviceName . '.service'; diff --git a/app/Enums/ContainerStatus.php b/app/Enums/ContainerStatus.php index 79cabf490..b83a61021 100644 --- a/app/Enums/ContainerStatus.php +++ b/app/Enums/ContainerStatus.php @@ -88,7 +88,7 @@ enum ContainerStatus: string implements HasColor, HasIcon, HasLabel public function isStartable(): bool { - return !in_array($this, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting]); + return !in_array($this, [ContainerStatus::Running, ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Missing]); } public function isRestartable(): bool @@ -97,18 +97,16 @@ enum ContainerStatus: string implements HasColor, HasIcon, HasLabel return true; } - return !in_array($this, [ContainerStatus::Offline]); + return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Missing]); } public function isStoppable(): bool { - return !in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline]); + return !in_array($this, [ContainerStatus::Starting, ContainerStatus::Stopping, ContainerStatus::Restarting, ContainerStatus::Exited, ContainerStatus::Offline, ContainerStatus::Missing]); } public function isKillable(): bool { - // [ContainerStatus::Restarting, ContainerStatus::Removing, ContainerStatus::Dead, ContainerStatus::Created] - - return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Running, ContainerStatus::Exited]); + return !in_array($this, [ContainerStatus::Offline, ContainerStatus::Running, ContainerStatus::Exited, ContainerStatus::Missing]); } } diff --git a/app/Enums/ServerState.php b/app/Enums/ServerState.php index 0746bb724..9ada541ad 100644 --- a/app/Enums/ServerState.php +++ b/app/Enums/ServerState.php @@ -27,8 +27,16 @@ enum ServerState: string implements HasColor, HasIcon, HasLabel }; } - public function getColor(): string + public function getColor(bool $hex = false): string { + if ($hex) { + return match ($this) { + self::Normal, self::Installing, self::RestoringBackup => '#2563EB', + self::Suspended => '#D97706', + self::InstallFailed, self::ReinstallFailed => '#EF4444', + }; + } + return match ($this) { self::Normal => 'primary', self::Installing => 'primary', diff --git a/app/Filament/Admin/Resources/RoleResource.php b/app/Filament/Admin/Resources/RoleResource.php index db3050574..ee4de9953 100644 --- a/app/Filament/Admin/Resources/RoleResource.php +++ b/app/Filament/Admin/Resources/RoleResource.php @@ -147,6 +147,8 @@ class RoleResource extends Resource */ private static function makeSection(string $model, array $options): Section { + $model = ucwords($model); + $icon = null; if (class_exists('\App\Filament\Admin\Resources\\' . $model . 'Resource')) { diff --git a/app/Filament/App/Resources/ServerResource/Pages/ListServers.php b/app/Filament/App/Resources/ServerResource/Pages/ListServers.php index 66651ab56..87f083943 100644 --- a/app/Filament/App/Resources/ServerResource/Pages/ListServers.php +++ b/app/Filament/App/Resources/ServerResource/Pages/ListServers.php @@ -9,12 +9,13 @@ use App\Filament\Server\Pages\Console; use App\Models\Permission; use App\Models\Server; use App\Repositories\Daemon\DaemonPowerRepository; -use AymanAlhattami\FilamentContextMenu\Columns\ContextMenuTextColumn; use Filament\Notifications\Notification; use Filament\Resources\Components\Tab; use Filament\Resources\Pages\ListRecords; +use Filament\Support\Enums\Alignment; use Filament\Tables\Actions\Action; -use Filament\Tables\Columns\ColumnGroup; +use Filament\Tables\Actions\ActionGroup; +use Filament\Tables\Columns\Column; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\SelectFilter; @@ -38,121 +39,73 @@ class ListServers extends ListRecords $this->daemonPowerRepository = new DaemonPowerRepository(); } - public function table(Table $table): Table + /** @return Stack[] */ + protected function gridColumns(): array { - $baseQuery = auth()->user()->accessibleServers(); + return [ + Stack::make([ + ServerEntryColumn::make('server_entry') + ->searchable(['name']), + ]), + ]; + } - $menuOptions = function (Server $server) { - $status = $server->retrieveStatus(); - - return [ - Action::make('start') - ->color('primary') - ->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_START, $server)) - ->visible(fn () => $status->isStartable()) - ->dispatch('powerAction', ['server' => $server, 'action' => 'start']) - ->icon('tabler-player-play-filled'), - Action::make('restart') - ->color('gray') - ->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_RESTART, $server)) - ->visible(fn () => $status->isRestartable()) - ->dispatch('powerAction', ['server' => $server, 'action' => 'restart']) - ->icon('tabler-refresh'), - Action::make('stop') - ->color('danger') - ->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server)) - ->visible(fn () => $status->isStoppable()) - ->dispatch('powerAction', ['server' => $server, 'action' => 'stop']) - ->icon('tabler-player-stop-filled'), - Action::make('kill') - ->color('danger') - ->tooltip('This can result in data corruption and/or data loss!') - ->dispatch('powerAction', ['server' => $server, 'action' => 'kill']) - ->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server)) - ->visible(fn () => $status->isKillable()) - ->icon('tabler-alert-square'), - ]; - }; - - $viewOne = [ - ContextMenuTextColumn::make('condition') - ->label('') - ->default('unknown') - ->wrap() + /** @return Column[] */ + protected function tableColumns(): array + { + return [ + TextColumn::make('condition') + ->label('Status') ->badge() - ->alignCenter() ->tooltip(fn (Server $server) => $server->formatResource('uptime', type: ServerResourceType::Time)) ->icon(fn (Server $server) => $server->condition->getIcon()) - ->color(fn (Server $server) => $server->condition->getColor()) - ->contextMenuActions($menuOptions) - ->enableContextMenu(fn (Server $server) => !$server->isInConflictState()), - ]; - - $viewTwo = [ - ContextMenuTextColumn::make('name') - ->label('') - ->size('md') - ->searchable() - ->contextMenuActions($menuOptions) - ->enableContextMenu(fn (Server $server) => !$server->isInConflictState()), - ContextMenuTextColumn::make('allocation.address') + ->color(fn (Server $server) => $server->condition->getColor()), + TextColumn::make('name') + ->label('Server') + ->description(fn (Server $server) => $server->description) + ->grow() + ->searchable(), + TextColumn::make('allocation.address') ->label('') ->badge() - ->copyable(request()->isSecure()) - ->contextMenuActions($menuOptions) - ->enableContextMenu(fn (Server $server) => !$server->isInConflictState()), - ]; - - $viewThree = [ + ->visibleFrom('md') + ->copyable(request()->isSecure()), TextColumn::make('cpuUsage') - ->label('') + ->label('Resources') ->icon('tabler-cpu') ->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('cpu', limit: true, type: ServerResourceType::Percentage, precision: 0)) ->state(fn (Server $server) => $server->formatResource('cpu_absolute', type: ServerResourceType::Percentage)) ->color(fn (Server $server) => $this->getResourceColor($server, 'cpu')), TextColumn::make('memoryUsage') ->label('') - ->icon('tabler-memory') + ->icon('tabler-device-desktop-analytics') ->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('memory', limit: true)) ->state(fn (Server $server) => $server->formatResource('memory_bytes')) ->color(fn (Server $server) => $this->getResourceColor($server, 'memory')), TextColumn::make('diskUsage') ->label('') - ->icon('tabler-device-floppy') + ->icon('tabler-device-sd-card') ->tooltip(fn (Server $server) => 'Usage Limit: ' . $server->formatResource('disk', limit: true)) ->state(fn (Server $server) => $server->formatResource('disk_bytes')) ->color(fn (Server $server) => $this->getResourceColor($server, 'disk')), ]; + } + + public function table(Table $table): Table + { + $baseQuery = auth()->user()->accessibleServers(); + + $usingGrid = (auth()->user()->getCustomization()['dashboard_layout'] ?? 'grid') === 'grid'; return $table ->paginated(false) ->query(fn () => $baseQuery) ->poll('15s') - ->columns( - (auth()->user()->getCustomization()['dashboard_layout'] ?? 'grid') === 'grid' - ? [ - Stack::make([ - ServerEntryColumn::make('server_entry') - ->searchable(['name']), - ]), - ] - : [ - ColumnGroup::make('Status') - ->label('Status') - ->columns($viewOne), - ColumnGroup::make('Server') - ->label('Servers') - ->columns($viewTwo), - ColumnGroup::make('Resources') - ->label('Resources') - ->columns($viewThree), - ] - ) - ->recordUrl(fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server)) - ->contentGrid([ - 'default' => 1, - 'md' => 2, - ]) + ->columns($usingGrid ? $this->gridColumns() : $this->tableColumns()) + ->recordUrl(!$usingGrid ? (fn (Server $server) => Console::getUrl(panel: 'server', tenant: $server)) : null) + ->actions(!$usingGrid ? ActionGroup::make(static::getPowerActions()) : []) + ->actionsAlignment(Alignment::Center->value) + ->contentGrid($usingGrid ? ['default' => 1, 'md' => 2] : null) ->emptyStateIcon('tabler-brand-docker') ->emptyStateDescription('') ->emptyStateHeading(fn () => $this->activeTab === 'my' ? 'You don\'t own any servers!' : 'You don\'t have access to any servers!') @@ -195,36 +148,33 @@ class ListServers extends ListRecords ]; } - public function getResourceColor(Server $server, string $resource): ?string + protected function getResourceColor(Server $server, string $resource): ?string { $current = null; $limit = null; switch ($resource) { case 'cpu': - $current = $server->resources()['cpu_absolute'] ?? 0; + $current = $server->retrieveResources()['cpu_absolute'] ?? 0; $limit = $server->cpu; if ($server->cpu === 0) { return null; } break; - case 'memory': - $current = $server->resources()['memory_bytes'] ?? 0; + $current = $server->retrieveResources()['memory_bytes'] ?? 0; $limit = $server->memory * 2 ** 20; if ($server->memory === 0) { return null; } break; - case 'disk': - $current = $server->resources()['disk_bytes'] ?? 0; + $current = $server->retrieveResources()['disk_bytes'] ?? 0; $limit = $server->disk * 2 ** 20; if ($server->disk === 0) { return null; } break; - default: return null; } @@ -238,7 +188,6 @@ class ListServers extends ListRecords } return null; - } #[On('powerAction')] @@ -253,6 +202,8 @@ class ListServers extends ListRecords ->success() ->send(); + cache()->forget("servers.$server->uuid.status"); + $this->redirect(self::getUrl(['activeTab' => $this->activeTab])); } catch (ConnectionException) { Notification::make() @@ -261,4 +212,36 @@ class ListServers extends ListRecords ->send(); } } + + /** @return Action[] */ + public static function getPowerActions(): array + { + return [ + Action::make('start') + ->color('primary') + ->icon('tabler-player-play-filled') + ->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_START, $server)) + ->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isStartable()) + ->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'start']), + Action::make('restart') + ->color('gray') + ->icon('tabler-reload') + ->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_RESTART, $server)) + ->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isRestartable()) + ->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'restart']), + Action::make('stop') + ->color('danger') + ->icon('tabler-player-stop-filled') + ->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server)) + ->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isStoppable()) + ->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'stop']), + Action::make('kill') + ->color('danger') + ->icon('tabler-alert-square') + ->tooltip('This can result in data corruption and/or data loss!') + ->authorize(fn (Server $server) => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server)) + ->visible(fn (Server $server) => !$server->isInConflictState() & $server->retrieveStatus()->isKillable()) + ->dispatch('powerAction', fn (Server $server) => ['server' => $server, 'action' => 'kill']), + ]; + } } diff --git a/app/Filament/Pages/Auth/EditProfile.php b/app/Filament/Pages/Auth/EditProfile.php index 937391d6b..945fd0b9f 100644 --- a/app/Filament/Pages/Auth/EditProfile.php +++ b/app/Filament/Pages/Auth/EditProfile.php @@ -32,6 +32,7 @@ use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\ToggleButtons; use Filament\Forms\Get; +use Filament\Forms\Set; use Filament\Notifications\Notification; use Filament\Pages\Auth\EditProfile as BaseEditProfile; use Filament\Support\Colors\Color; @@ -405,30 +406,38 @@ class EditProfile extends BaseEditProfile }) ->reactive() ->default('monospace') - ->afterStateUpdated(fn ($state, callable $set) => $set('font_preview', $state)), + ->afterStateUpdated(fn ($state, Set $set) => $set('font_preview', $state)), Placeholder::make('font_preview') ->label(trans('profile.font_preview')) ->columnSpan(2) ->content(function (Get $get) { $fontName = $get('console_font') ?? 'monospace'; $fontSize = $get('console_font_size') . 'px'; - $fontUrl = asset("storage/fonts/{$fontName}.ttf"); + $style = << - @font-face { - font-family: "CustomPreviewFont"; - src: url("$fontUrl"); - } - .preview-text { - font-family: "CustomPreviewFont"; - font-size: $fontSize; - margin-top: 10px; - display: block; - } - - The quick blue pelican jumps over the lazy pterodactyl. :) - HTML); + + The quick blue pelican jumps over the lazy pterodactyl. :) + HTML); }), TextInput::make('console_graph_period') ->label(trans('profile.graph_period')) diff --git a/app/Filament/Server/Resources/BackupResource.php b/app/Filament/Server/Resources/BackupResource.php index d163b751b..dc0a11600 100644 --- a/app/Filament/Server/Resources/BackupResource.php +++ b/app/Filament/Server/Resources/BackupResource.php @@ -14,6 +14,7 @@ use App\Repositories\Daemon\DaemonBackupRepository; use App\Services\Backups\DownloadLinkService; use App\Filament\Components\Tables\Columns\BytesColumn; use App\Filament\Components\Tables\Columns\DateTimeColumn; +use App\Services\Backups\DeleteBackupService; use Filament\Facades\Filament; use Filament\Forms\Components\Checkbox; use Filament\Forms\Components\Placeholder; @@ -30,6 +31,7 @@ use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Model; +use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\Request; class BackupResource extends Resource @@ -142,7 +144,7 @@ class BackupResource extends Resource ->send(); } - if (!$backup->is_successful && is_null($backup->completed_at)) { //TODO Change to Notifications + if (!$backup->is_successful && is_null($backup->completed_at)) { return Notification::make() ->danger() ->title('Backup Restore Failed') @@ -175,9 +177,26 @@ class BackupResource extends Resource ->visible(fn (Backup $backup) => $backup->status === BackupStatus::Successful), DeleteAction::make('delete') ->disabled(fn (Backup $backup) => $backup->is_locked) - ->modalDescription(fn (Backup $backup) => 'Do you wish to delete, ' . $backup->name . '?') + ->modalDescription(fn (Backup $backup) => 'Do you wish to delete ' . $backup->name . '?') ->modalSubmitActionLabel('Delete Backup') - ->action(fn (BackupController $backupController, Backup $backup, Request $request) => $backupController->delete($request, $server, $backup)) + ->action(function (Backup $backup, DeleteBackupService $deleteBackupService) { + try { + $deleteBackupService->handle($backup); + } catch (ConnectionException) { + Notification::make() + ->title('Could not delete backup') + ->body('Connection to node failed') + ->danger() + ->send(); + + return; + } + + Activity::event('server:backup.delete') + ->subject($backup) + ->property(['name' => $backup->name, 'failed' => !$backup->is_successful]) + ->log(); + }) ->visible(fn (Backup $backup) => $backup->status !== BackupStatus::InProgress), ]), ]); diff --git a/app/Http/Controllers/Api/Client/Servers/SettingsController.php b/app/Http/Controllers/Api/Client/Servers/SettingsController.php index 169f825b5..6bc765a08 100644 --- a/app/Http/Controllers/Api/Client/Servers/SettingsController.php +++ b/app/Http/Controllers/Api/Client/Servers/SettingsController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api\Client\Servers; use App\Facades\Activity; use App\Http\Controllers\Api\Client\ClientApiController; +use App\Http\Requests\Api\Client\Servers\Settings\DescriptionServerRequest; use App\Http\Requests\Api\Client\Servers\Settings\ReinstallServerRequest; use App\Http\Requests\Api\Client\Servers\Settings\RenameServerRequest; use App\Http\Requests\Api\Client\Servers\Settings\SetDockerImageRequest; @@ -34,24 +35,36 @@ class SettingsController extends ClientApiController public function rename(RenameServerRequest $request, Server $server): JsonResponse { $name = $request->input('name'); - $description = $request->has('description') ? (string) $request->input('description') : $server->description; - if ($server->name !== $name) { + $server->update(['name' => $name]); + + if ($server->wasChanged('name')) { Activity::event('server:settings.rename') - ->property(['old' => $server->name, 'new' => $name]) + ->property(['old' => $server->getOriginal('name'), 'new' => $name]) ->log(); - $server->name = $name; } - if ($server->description !== $description && config('panel.editable_server_descriptions')) { + return new JsonResponse([], Response::HTTP_NO_CONTENT); + } + + /** + * Update server description + */ + public function description(DescriptionServerRequest $request, Server $server): JsonResponse + { + if (!config('panel.editable_server_descriptions')) { + return new JsonResponse([], Response::HTTP_FORBIDDEN); + } + + $description = $request->input('description'); + $server->update(['description' => $description ?? '']); + + if ($server->wasChanged('description')) { Activity::event('server:settings.description') - ->property(['old' => $server->description, 'new' => $description]) + ->property(['old' => $server->getOriginal('description'), 'new' => $description]) ->log(); - $server->description = $description; } - $server->save(); - return new JsonResponse([], Response::HTTP_NO_CONTENT); } @@ -80,7 +93,7 @@ class SettingsController extends ClientApiController */ public function dockerImage(SetDockerImageRequest $request, Server $server): JsonResponse { - if (!in_array($server->image, array_values($server->egg->docker_images))) { + if (!in_array($server->image, $server->egg->docker_images)) { throw new BadRequestHttpException('This server\'s Docker image has been manually set by an administrator and cannot be updated.'); } diff --git a/app/Http/Requests/Api/Client/Servers/Settings/DescriptionServerRequest.php b/app/Http/Requests/Api/Client/Servers/Settings/DescriptionServerRequest.php new file mode 100644 index 000000000..ba2fa2125 --- /dev/null +++ b/app/Http/Requests/Api/Client/Servers/Settings/DescriptionServerRequest.php @@ -0,0 +1,30 @@ + 'string|nullable', + ]; + } +} diff --git a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php index c68e0d444..fb7d8e677 100644 --- a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php @@ -26,7 +26,6 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR { return [ 'name' => Server::getRules()['name'], - 'description' => 'string|nullable', ]; } } diff --git a/app/Models/Node.php b/app/Models/Node.php index c6ffb655d..e3ff28d88 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -333,26 +333,6 @@ class Node extends Model implements Validatable }); } - /** - * @return array - */ - public function serverStatuses(): array - { - $statuses = []; - try { - $statuses = Http::daemon($this)->connectTimeout(1)->timeout(1)->get('/api/servers')->json() ?? []; - } catch (Exception $exception) { - report($exception); - } - - foreach ($statuses as $status) { - $uuid = fluent($status)->get('configuration.uuid'); - cache()->remember("servers.$uuid.container.status", now()->addMinute(), fn () => fluent($status)->get('state')); - } - - return $statuses; - } - /** @return array{ * memory_total: int, memory_used: int, * swap_total: int, swap_used: int, diff --git a/app/Models/Permission.php b/app/Models/Permission.php index d9f489102..82718f06f 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -97,6 +97,8 @@ class Permission extends Model implements Validatable public const ACTION_SETTINGS_RENAME = 'settings.rename'; + public const ACTION_SETTINGS_DESCRIPTION = 'settings.description'; + public const ACTION_SETTINGS_REINSTALL = 'settings.reinstall'; public const ACTION_ACTIVITY_READ = 'activity.read'; @@ -176,7 +178,7 @@ class Permission extends Model implements Validatable [ 'name' => 'settings', 'icon' => 'tabler-settings', - 'permissions' => ['rename', 'reinstall'], + 'permissions' => ['rename', 'description', 'reinstall'], ], [ 'name' => 'activity', diff --git a/app/Models/Server.php b/app/Models/Server.php index 0115b1bbf..5ba473418 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -435,25 +435,24 @@ class Server extends Model implements Validatable public function retrieveStatus(): ContainerStatus { - $status = cache()->get("servers.$this->uuid.container.status"); + return cache()->remember("servers.$this->uuid.status", now()->addSeconds(15), function () { + // @phpstan-ignore myCustomRules.forbiddenGlobalFunctions + $details = app(DaemonServerRepository::class)->setServer($this)->getDetails(); - if ($status === null) { - $this->node->serverStatuses(); - - $status = cache()->get("servers.$this->uuid.container.status"); - } - - return ContainerStatus::tryFrom($status) ?? ContainerStatus::Missing; + return ContainerStatus::tryFrom(Arr::get($details, 'state')) ?? ContainerStatus::Missing; + }); } /** * @return array */ - public function resources(): array + public function retrieveResources(): array { - return cache()->remember("resources:$this->uuid", now()->addSeconds(15), function () { + return cache()->remember("servers.$this->uuid.resources", now()->addSeconds(15), function () { // @phpstan-ignore myCustomRules.forbiddenGlobalFunctions - return Arr::get(app(DaemonServerRepository::class)->setServer($this)->getDetails(), 'utilization', []); + $details = app(DaemonServerRepository::class)->setServer($this)->getDetails(); + + return Arr::get($details, 'utilization', []); }); } @@ -461,7 +460,7 @@ class Server extends Model implements Validatable { $resourceAmount = $this->{$resourceKey} ?? 0; if (!$limit) { - $resourceAmount = $this->resources()[$resourceKey] ?? 0; + $resourceAmount = $this->retrieveResources()[$resourceKey] ?? 0; } if ($type === ServerResourceType::Time) { @@ -494,7 +493,7 @@ class Server extends Model implements Validatable public function condition(): Attribute { return Attribute::make( - get: fn () => $this->isSuspended() ? ServerState::Suspended : $this->status ?? $this->retrieveStatus(), + get: fn () => $this->status ?? $this->retrieveStatus(), ); } } diff --git a/app/Providers/Filament/ServerPanelProvider.php b/app/Providers/Filament/ServerPanelProvider.php index d047c80b8..035faaa15 100644 --- a/app/Providers/Filament/ServerPanelProvider.php +++ b/app/Providers/Filament/ServerPanelProvider.php @@ -64,7 +64,7 @@ class ServerPanelProvider extends PanelProvider ->navigationItems([ NavigationItem::make('Open in Admin') ->url(fn () => EditServer::getUrl(['record' => Filament::getTenant()], panel: 'admin')) - ->visible(fn () => auth()->user()->can('view server', Filament::getTenant())) + ->visible(fn () => auth()->user()->canAccessPanel(Filament::getPanel('admin')) && auth()->user()->can('view server', Filament::getTenant())) ->icon('tabler-arrow-back') ->sort(99), ]) diff --git a/app/Services/Backups/DeleteBackupService.php b/app/Services/Backups/DeleteBackupService.php index a2402fdee..04cf9e548 100644 --- a/app/Services/Backups/DeleteBackupService.php +++ b/app/Services/Backups/DeleteBackupService.php @@ -6,12 +6,11 @@ use App\Extensions\Filesystem\S3Filesystem; use Aws\S3\S3Client; use Illuminate\Http\Response; use App\Models\Backup; -use GuzzleHttp\Exception\ClientException; use Illuminate\Database\ConnectionInterface; use App\Extensions\Backups\BackupManager; use App\Repositories\Daemon\DaemonBackupRepository; use App\Exceptions\Service\Backup\BackupLockedException; -use Illuminate\Http\Client\ConnectionException; +use Exception; class DeleteBackupService { @@ -48,12 +47,10 @@ class DeleteBackupService $this->connection->transaction(function () use ($backup) { try { $this->daemonBackupRepository->setServer($backup->server)->delete($backup); - } catch (ConnectionException $exception) { - $previous = $exception->getPrevious(); - + } catch (Exception $exception) { // Don't fail the request if the Daemon responds with a 404, just assume the backup // doesn't actually exist and remove its reference from the Panel as well. - if (!$previous instanceof ClientException || $previous->getResponse()->getStatusCode() !== Response::HTTP_NOT_FOUND) { + if ($exception->getCode() !== Response::HTTP_NOT_FOUND) { throw $exception; } } diff --git a/composer.json b/composer.json index f1919ec74..fe3ef777e 100644 --- a/composer.json +++ b/composer.json @@ -10,15 +10,14 @@ "ext-pdo": "*", "ext-zip": "*", "abdelhamiderrahmouni/filament-monaco-editor": "^0.2.5", - "aws/aws-sdk-php": "^3.343", - "aymanalhattami/filament-context-menu": "^1.0", + "aws/aws-sdk-php": "^3.344", "calebporzio/sushi": "^2.5", "chillerlan/php-qrcode": "^5.0.2", "dedoc/scramble": "^0.12.10", "doctrine/dbal": "~3.6.0", "filament/filament": "^3.3", "guzzlehttp/guzzle": "^7.9", - "laravel/framework": "^12.17", + "laravel/framework": "^12.18", "laravel/helpers": "^1.7", "laravel/sanctum": "^4.1", "laravel/socialite": "^5.21", @@ -105,4 +104,4 @@ }, "minimum-stability": "stable", "prefer-stable": true -} +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index 031416caf..ff0ce5af1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9a250ae6162d7d877649172284b56c13", + "content-hash": "a006241b5687d547b51a60e6ac50ccae", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -1020,16 +1020,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.343.23", + "version": "3.344.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "010869992129557cfbf2740d94d82ef3b5228462" + "reference": "0cf789243c7de82be7d3f7641cab37b5bb5d937d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/010869992129557cfbf2740d94d82ef3b5228462", - "reference": "010869992129557cfbf2740d94d82ef3b5228462", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0cf789243c7de82be7d3f7641cab37b5bb5d937d", + "reference": "0cf789243c7de82be7d3f7641cab37b5bb5d937d", "shasum": "" }, "require": { @@ -1111,86 +1111,10 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.343.23" + "source": "https://github.com/aws/aws-sdk-php/tree/3.344.3" }, "time": "2025-06-02T18:04:47+00:00" }, - { - "name": "aymanalhattami/filament-context-menu", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/aymanalhattami/filament-context-menu.git", - "reference": "5118d36303e86891d3037e6e26882d548b880b9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aymanalhattami/filament-context-menu/zipball/5118d36303e86891d3037e6e26882d548b880b9c", - "reference": "5118d36303e86891d3037e6e26882d548b880b9c", - "shasum": "" - }, - "require": { - "filament/filament": "^3.0", - "php": "^8.2", - "spatie/laravel-package-tools": "^1.15.0" - }, - "require-dev": { - "larastan/larastan": "^2.0", - "laravel/pint": "^1.0", - "nunomaduro/collision": "^8.0", - "orchestra/testbench": "^9.0", - "pestphp/pest": "^3.0", - "pestphp/pest-plugin-arch": "^3.0", - "pestphp/pest-plugin-laravel": "^3.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0" - }, - "type": "library", - "extra": { - "laravel": { - "aliases": { - "Skeleton": "AymanAlhattami\\FilamentContextMenu\\Facades\\FilamentContextMenu" - }, - "providers": [ - "AymanAlhattami\\FilamentContextMenu\\FilamentContextMenuServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "AymanAlhattami\\FilamentContextMenu\\": "src/", - "AymanAlhattami\\FilamentContextMenu\\Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ayman Alhattami", - "email": "ayman.m.alhattami@gmail.com", - "role": "Developer" - } - ], - "description": "context menu (right click menu) for filament", - "homepage": "https://github.com/aymanalhattami/filament-context-menu", - "keywords": [ - "ayman alhattami", - "context menu", - "filament", - "filament admin panel", - "filament context menu", - "filament_context_menu", - "laravel" - ], - "support": { - "issues": "https://github.com/aymanalhattami/filament-context-menu/issues", - "source": "https://github.com/aymanalhattami/filament-context-menu" - }, - "time": "2024-09-22T10:47:31+00:00" - }, { "name": "blade-ui-kit/blade-heroicons", "version": "2.6.0", @@ -2634,7 +2558,7 @@ }, { "name": "filament/actions", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", @@ -2687,16 +2611,16 @@ }, { "name": "filament/filament", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "94ee92244d2a64666fb8c1ea50cb7315ebceb63b" + "reference": "8d915ef313835f46f49175396de82feb0166d8a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/94ee92244d2a64666fb8c1ea50cb7315ebceb63b", - "reference": "94ee92244d2a64666fb8c1ea50cb7315ebceb63b", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/8d915ef313835f46f49175396de82feb0166d8a8", + "reference": "8d915ef313835f46f49175396de82feb0166d8a8", "shasum": "" }, "require": { @@ -2748,20 +2672,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-27T18:46:23+00:00" + "time": "2025-06-10T16:10:42+00:00" }, { "name": "filament/forms", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "d73cdda057a4f5bd409eab9573101e73edb404cc" + "reference": "014dd23a7691dc25bb037f26df852cfec5602d01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/d73cdda057a4f5bd409eab9573101e73edb404cc", - "reference": "d73cdda057a4f5bd409eab9573101e73edb404cc", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/014dd23a7691dc25bb037f26df852cfec5602d01", + "reference": "014dd23a7691dc25bb037f26df852cfec5602d01", "shasum": "" }, "require": { @@ -2804,11 +2728,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-06-03T13:40:37+00:00" + "time": "2025-06-10T16:10:45+00:00" }, { "name": "filament/infolists", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", @@ -2859,7 +2783,7 @@ }, { "name": "filament/notifications", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", @@ -2911,16 +2835,16 @@ }, { "name": "filament/support", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "4f9793ad3339301ca53ea6f2c984734f7ac38ce7" + "reference": "5c140580d7feeabb4d2b0007c854676ae87be1b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/4f9793ad3339301ca53ea6f2c984734f7ac38ce7", - "reference": "4f9793ad3339301ca53ea6f2c984734f7ac38ce7", + "url": "https://api.github.com/repos/filamentphp/support/zipball/5c140580d7feeabb4d2b0007c854676ae87be1b3", + "reference": "5c140580d7feeabb4d2b0007c854676ae87be1b3", "shasum": "" }, "require": { @@ -2966,20 +2890,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-06-03T06:16:13+00:00" + "time": "2025-06-10T16:10:55+00:00" }, { "name": "filament/tables", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "1a107a8411549297b97d1142b1f7a5fa7a65e32b" + "reference": "3d52c23443f6846774a6a2ce60f6e6173ce20943" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/1a107a8411549297b97d1142b1f7a5fa7a65e32b", - "reference": "1a107a8411549297b97d1142b1f7a5fa7a65e32b", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/3d52c23443f6846774a6a2ce60f6e6173ce20943", + "reference": "3d52c23443f6846774a6a2ce60f6e6173ce20943", "shasum": "" }, "require": { @@ -3018,11 +2942,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-06-02T09:43:47+00:00" + "time": "2025-06-10T16:10:40+00:00" }, { "name": "filament/widgets", - "version": "v3.3.20", + "version": "v3.3.21", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -3794,16 +3718,16 @@ }, { "name": "laravel/framework", - "version": "v12.17.0", + "version": "v12.18.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "8729d084510480fdeec9b6ad198180147d4a7f06" + "reference": "7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/8729d084510480fdeec9b6ad198180147d4a7f06", - "reference": "8729d084510480fdeec9b6ad198180147d4a7f06", + "url": "https://api.github.com/repos/laravel/framework/zipball/7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d", + "reference": "7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d", "shasum": "" }, "require": { @@ -4005,7 +3929,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-06-03T14:04:18+00:00" + "time": "2025-06-10T14:48:34+00:00" }, { "name": "laravel/helpers", @@ -6461,16 +6385,16 @@ }, { "name": "phpdocumentor/reflection", - "version": "6.2.1", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "ab969af5e53c3bb400eea958b90b87ecc34f4dff" + "reference": "d91b3270832785602adcc24ae2d0974ba99a8ff8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/ab969af5e53c3bb400eea958b90b87ecc34f4dff", - "reference": "ab969af5e53c3bb400eea958b90b87ecc34f4dff", + "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/d91b3270832785602adcc24ae2d0974ba99a8ff8", + "reference": "d91b3270832785602adcc24ae2d0974ba99a8ff8", "shasum": "" }, "require": { @@ -6527,9 +6451,9 @@ ], "support": { "issues": "https://github.com/phpDocumentor/Reflection/issues", - "source": "https://github.com/phpDocumentor/Reflection/tree/6.2.1" + "source": "https://github.com/phpDocumentor/Reflection/tree/6.3.0" }, - "time": "2025-05-30T18:42:55+00:00" + "time": "2025-06-06T13:39:18+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -7998,16 +7922,16 @@ }, { "name": "secondnetwork/blade-tabler-icons", - "version": "v3.33.0", + "version": "v3.34.0", "source": { "type": "git", "url": "https://github.com/secondnetwork/blade-tabler-icons.git", - "reference": "523b3ede493ce9f8cbe3a5bdce21769976a80b28" + "reference": "e48c0a5a53798d42c7beff760de8cbc7dbbccff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/secondnetwork/blade-tabler-icons/zipball/523b3ede493ce9f8cbe3a5bdce21769976a80b28", - "reference": "523b3ede493ce9f8cbe3a5bdce21769976a80b28", + "url": "https://api.github.com/repos/secondnetwork/blade-tabler-icons/zipball/e48c0a5a53798d42c7beff760de8cbc7dbbccff4", + "reference": "e48c0a5a53798d42c7beff760de8cbc7dbbccff4", "shasum": "" }, "require": { @@ -8050,9 +7974,9 @@ ], "support": { "issues": "https://github.com/secondnetwork/blade-tabler-icons/issues", - "source": "https://github.com/secondnetwork/blade-tabler-icons/tree/v3.33.0" + "source": "https://github.com/secondnetwork/blade-tabler-icons/tree/v3.34.0" }, - "time": "2025-05-17T06:28:48+00:00" + "time": "2025-06-09T08:41:55+00:00" }, { "name": "socialiteproviders/authentik", @@ -8701,16 +8625,16 @@ }, { "name": "spatie/laravel-health", - "version": "1.34.2", + "version": "1.34.3", "source": { "type": "git", "url": "https://github.com/spatie/laravel-health.git", - "reference": "e7d9d6e0807a9de46f544c76d54badc19af36ddc" + "reference": "d421bc223c7a8c872ad944706d98a74b1056f761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-health/zipball/e7d9d6e0807a9de46f544c76d54badc19af36ddc", - "reference": "e7d9d6e0807a9de46f544c76d54badc19af36ddc", + "url": "https://api.github.com/repos/spatie/laravel-health/zipball/d421bc223c7a8c872ad944706d98a74b1056f761", + "reference": "d421bc223c7a8c872ad944706d98a74b1056f761", "shasum": "" }, "require": { @@ -8782,7 +8706,7 @@ "spatie" ], "support": { - "source": "https://github.com/spatie/laravel-health/tree/1.34.2" + "source": "https://github.com/spatie/laravel-health/tree/1.34.3" }, "funding": [ { @@ -8790,7 +8714,7 @@ "type": "github" } ], - "time": "2025-05-20T08:31:02+00:00" + "time": "2025-06-04T22:04:19+00:00" }, { "name": "spatie/laravel-package-tools", @@ -12744,16 +12668,16 @@ }, { "name": "filp/whoops", - "version": "2.18.0", + "version": "2.18.1", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e" + "reference": "8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", - "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", + "url": "https://api.github.com/repos/filp/whoops/zipball/8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26", + "reference": "8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26", "shasum": "" }, "require": { @@ -12803,7 +12727,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.0" + "source": "https://github.com/filp/whoops/tree/2.18.1" }, "funding": [ { @@ -12811,7 +12735,7 @@ "type": "github" } ], - "time": "2025-03-15T12:00:00+00:00" + "time": "2025-06-03T18:56:14+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -12967,16 +12891,16 @@ }, { "name": "larastan/larastan", - "version": "v3.4.0", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "1042fa0c2ee490bb6da7381f3323f7292ad68222" + "reference": "dc20d24871d5a2138b292b0430d94d18da3dbc53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/1042fa0c2ee490bb6da7381f3323f7292ad68222", - "reference": "1042fa0c2ee490bb6da7381f3323f7292ad68222", + "url": "https://api.github.com/repos/larastan/larastan/zipball/dc20d24871d5a2138b292b0430d94d18da3dbc53", + "reference": "dc20d24871d5a2138b292b0430d94d18da3dbc53", "shasum": "" }, "require": { @@ -13044,7 +12968,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v3.4.0" + "source": "https://github.com/larastan/larastan/tree/v3.4.1" }, "funding": [ { @@ -13052,20 +12976,20 @@ "type": "github" } ], - "time": "2025-04-22T09:44:59+00:00" + "time": "2025-06-09T21:23:36+00:00" }, { "name": "laravel/pail", - "version": "v1.2.2", + "version": "v1.2.3", "source": { "type": "git", "url": "https://github.com/laravel/pail.git", - "reference": "f31f4980f52be17c4667f3eafe034e6826787db2" + "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/f31f4980f52be17c4667f3eafe034e6826787db2", - "reference": "f31f4980f52be17c4667f3eafe034e6826787db2", + "url": "https://api.github.com/repos/laravel/pail/zipball/8cc3d575c1f0e57eeb923f366a37528c50d2385a", + "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a", "shasum": "" }, "require": { @@ -13085,7 +13009,7 @@ "orchestra/testbench-core": "^8.13|^9.0|^10.0", "pestphp/pest": "^2.20|^3.0", "pestphp/pest-plugin-type-coverage": "^2.3|^3.0", - "phpstan/phpstan": "^1.10", + "phpstan/phpstan": "^1.12.27", "symfony/var-dumper": "^6.3|^7.0" }, "type": "library", @@ -13121,6 +13045,7 @@ "description": "Easily delve into your Laravel application's log files directly from the command line.", "homepage": "https://github.com/laravel/pail", "keywords": [ + "dev", "laravel", "logs", "php", @@ -13130,7 +13055,7 @@ "issues": "https://github.com/laravel/pail/issues", "source": "https://github.com/laravel/pail" }, - "time": "2025-01-28T15:15:15+00:00" + "time": "2025-06-05T13:55:57+00:00" }, { "name": "laravel/pint", diff --git a/database/Seeders/eggs/rust/egg-rust.json b/database/Seeders/eggs/rust/egg-rust.json index b38868888..ebe84d132 100644 --- a/database/Seeders/eggs/rust/egg-rust.json +++ b/database/Seeders/eggs/rust/egg-rust.json @@ -4,7 +4,7 @@ "version": "PLCN_v1", "update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/rust\/egg-rust.json" }, - "exported_at": "2025-03-18T12:36:48+00:00", + "exported_at": "2025-06-06T11:57:17+00:00", "name": "Rust", "author": "panel@example.com", "uuid": "bace2dfb-209c-452a-9459-7d6f340b07ae", @@ -20,7 +20,7 @@ "ghcr.io\/parkervcp\/games:rust": "ghcr.io\/parkervcp\/games:rust" }, "file_denylist": [], - "startup": ".\/RustDedicated -batchmode +server.port {{SERVER_PORT}} +server.queryport {{QUERY_PORT}} +server.identity \"rust\" +rcon.port {{RCON_PORT}} +rcon.web true +server.hostname \\\"{{HOSTNAME}}\\\" +server.level \\\"{{LEVEL}}\\\" +server.description \\\"{{DESCRIPTION}}\\\" +server.url \\\"{{SERVER_URL}}\\\" +server.headerimage \\\"{{SERVER_IMG}}\\\" +server.logoimage \\\"{{SERVER_LOGO}}\\\" +server.maxplayers {{MAX_PLAYERS}} +rcon.password \\\"{{RCON_PASS}}\\\" +server.saveinterval {{SAVEINTERVAL}} +app.port {{APP_PORT}} $( [ -z ${MAP_URL} ] && printf %s \"+server.worldsize \\\"{{WORLD_SIZE}}\\\" +server.seed \\\"{{WORLD_SEED}}\\\"\" || printf %s \"+server.levelurl {{MAP_URL}}\" ) {{ADDITIONAL_ARGS}}", + "startup": ".\/RustDedicated -batchmode +server.port {{SERVER_PORT}} +server.queryport {{QUERY_PORT}} +server.identity \"rust\" +rcon.port {{RCON_PORT}} +rcon.web true +server.hostname \\\"{{SERVER_HOSTNAME}}\\\" +server.level \\\"{{LEVEL}}\\\" +server.description \\\"{{DESCRIPTION}}\\\" +server.url \\\"{{SERVER_URL}}\\\" +server.headerimage \\\"{{SERVER_IMG}}\\\" +server.logoimage \\\"{{SERVER_LOGO}}\\\" +server.maxplayers {{MAX_PLAYERS}} +rcon.password \\\"{{RCON_PASS}}\\\" +server.saveinterval {{SAVEINTERVAL}} +app.port {{APP_PORT}} $( [ -z ${MAP_URL} ] && printf %s \"+server.worldsize \\\"{{WORLD_SIZE}}\\\" +server.seed \\\"{{WORLD_SEED}}\\\"\" || printf %s \"+server.levelurl {{MAP_URL}}\" ) {{ADDITIONAL_ARGS}}", "config": { "files": "{}", "startup": "{\r\n \"done\": \"Server startup complete\"\r\n}", @@ -38,7 +38,7 @@ { "name": "Server Name", "description": "The name of your server in the public server list.", - "env_variable": "HOSTNAME", + "env_variable": "SERVER_HOSTNAME", "default_value": "A Rust Server", "user_viewable": true, "user_editable": true, diff --git a/lang/en/server/users.php b/lang/en/server/users.php index cb570da58..99486bd48 100644 --- a/lang/en/server/users.php +++ b/lang/en/server/users.php @@ -16,7 +16,8 @@ return [ 'startup_update' => 'Allows a user to modify the startup variables for the server.', 'startup_docker_image' => 'Allows a user to modify the Docker image used when running the server.', 'settings_reinstall' => 'Allows a user to trigger a reinstall of this server.', - 'settings_rename' => 'Allows a user to rename this server and change the description of it.', + 'settings_rename' => 'Allows a user to rename this server.', + 'settings_description' => 'Allows a user to change the description of this server.', 'activity_read' => 'Allows a user to view the activity logs for the server.', 'websocket_*' => 'Allows a user access to the websocket for this server.', 'control_console' => 'Allows a user to send data to the server console.', diff --git a/public/css/aymanalhattami/filament-context-menu/filament-context-menu-styles.css b/public/css/aymanalhattami/filament-context-menu/filament-context-menu-styles.css deleted file mode 100644 index 49943cf90..000000000 --- a/public/css/aymanalhattami/filament-context-menu/filament-context-menu-styles.css +++ /dev/null @@ -1 +0,0 @@ -/*! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.fixed{position:fixed}.relative{position:relative}.z-50{z-index:50}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mt-1{margin-top:.25rem}.block{display:block}.flex{display:flex}.h-px{height:1px}.w-full{width:100%}.min-w-48{min-width:12rem}.max-w-2xl{max-width:42rem}.cursor-default{cursor:default}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.justify-between{justify-content:space-between}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-2{padding:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.pl-8{padding-left:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-neutral-800{--tw-text-opacity:1;color:rgb(38 38 38/var(--tw-text-opacity))}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid #0000;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-gray-950\/5{--tw-ring-color:#0307120d}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.context-menu-filament-action a,.context-menu-filament-action button{width:100%;justify-content:flex-start}.hover\:bg-neutral-100:hover{--tw-bg-opacity:1;background-color:rgb(245 245 245/var(--tw-bg-opacity))}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}@media (prefers-color-scheme:dark){.dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.dark\:bg-white\/5{background-color:#ffffff0d}.dark\:text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}.dark\:ring-white\/10{--tw-ring-color:#ffffff1a}.dark\:hover\:bg-white\/5:hover{background-color:#ffffff0d}} \ No newline at end of file diff --git a/resources/views/filament/components/server-console.blade.php b/resources/views/filament/components/server-console.blade.php index 366f814c7..b7ddf0537 100644 --- a/resources/views/filament/components/server-console.blade.php +++ b/resources/views/filament/components/server-console.blade.php @@ -5,7 +5,7 @@ $userFontSize = auth()->user()->getCustomization()['console_font_size'] ?? 14; $userRows = auth()->user()->getCustomization()['console_rows'] ?? 30; @endphp - @if($userFont) + @if($userFont !== "monospace")