Add back Egg Features (#1271)
Co-authored-by: Boy132 <Boy132@users.noreply.github.com> Co-authored-by: Lance Pioch <git@lance.sh> Co-authored-by: RMartinOscar <40749467+RMartinOscar@users.noreply.github.com>
This commit is contained in:
parent
fccd7e5e75
commit
8407547574
51
app/Extensions/Features/FeatureProvider.php
Normal file
51
app/Extensions/Features/FeatureProvider.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
abstract class FeatureProvider
|
||||
{
|
||||
/**
|
||||
* @var array<string, static>
|
||||
*/
|
||||
protected static array $providers = [];
|
||||
|
||||
/**
|
||||
* @param string[] $id
|
||||
* @return self|static[]
|
||||
*/
|
||||
public static function getProviders(string|array|null $id = null): array|self
|
||||
{
|
||||
if (is_array($id)) {
|
||||
return array_intersect_key(static::$providers, array_flip($id));
|
||||
}
|
||||
|
||||
return $id ? static::$providers[$id] : static::$providers;
|
||||
}
|
||||
|
||||
protected function __construct(protected Application $app)
|
||||
{
|
||||
if (array_key_exists($this->getId(), static::$providers)) {
|
||||
if (!$this->app->runningUnitTests()) {
|
||||
logger()->warning("Tried to create duplicate Feature provider with id '{$this->getId()}'");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static::$providers[$this->getId()] = $this;
|
||||
}
|
||||
|
||||
abstract public function getId(): string;
|
||||
|
||||
/**
|
||||
* A matching subset string (case-sensitive) from the console output
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
abstract public function getListeners(): array;
|
||||
|
||||
abstract public function getAction(): Action;
|
||||
}
|
122
app/Extensions/Features/GSLToken.php
Normal file
122
app/Extensions/Features/GSLToken.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use App\Facades\Activity;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Server;
|
||||
use App\Models\ServerVariable;
|
||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||
use Closure;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class GSLToken extends FeatureProvider
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
return [
|
||||
'gsl token expired',
|
||||
'account not found',
|
||||
];
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'gsltoken';
|
||||
}
|
||||
|
||||
public function getAction(): Action
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
|
||||
/** @var ServerVariable $serverVariable */
|
||||
$serverVariable = $server->serverVariables()->where('env_variable', 'STEAM_ACC')->first();
|
||||
|
||||
return Action::make($this->getId())
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Invalid GSL token')
|
||||
->modalDescription('It seems like your Gameserver Login Token (GSL token) is invalid or has expired.')
|
||||
->modalSubmitActionLabel('Update GSL Token')
|
||||
->disabledForm(fn () => !auth()->user()->can(Permission::ACTION_STARTUP_UPDATE, $server))
|
||||
->form([
|
||||
Placeholder::make('java')
|
||||
->label('You can either <x-filament::link href="https://steamcommunity.com/dev/managegameservers" target="_blank">generate a new one</x-filament::link> and enter it below or leave the field blank to remove it
|
||||
completely.'),
|
||||
TextInput::make('gsltoken')
|
||||
->label('GSL Token')
|
||||
->rules([
|
||||
fn (): Closure => function (string $attribute, $value, Closure $fail) use ($serverVariable) {
|
||||
$validator = Validator::make(['validatorkey' => $value], [
|
||||
'validatorkey' => $serverVariable->variable->rules,
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$message = str($validator->errors()->first())->replace('validatorkey', $serverVariable->variable->name);
|
||||
|
||||
$fail($message);
|
||||
}
|
||||
},
|
||||
])
|
||||
->hintIcon('tabler-code')
|
||||
->label(fn () => $serverVariable->variable->name)
|
||||
->hintIconTooltip(fn () => implode('|', $serverVariable->variable->rules))
|
||||
->prefix(fn () => '{{' . $serverVariable->variable->env_variable . '}}')
|
||||
->helperText(fn () => empty($serverVariable->variable->description) ? '—' : $serverVariable->variable->description),
|
||||
])
|
||||
->action(function (array $data, DaemonPowerRepository $powerRepository) use ($server, $serverVariable) {
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
try {
|
||||
$new = $data['gsltoken'] ?? '';
|
||||
$original = $serverVariable->variable_value;
|
||||
|
||||
$serverVariable->update([
|
||||
'variable_value' => $new,
|
||||
]);
|
||||
|
||||
if ($original !== $new) {
|
||||
|
||||
Activity::event('server:startup.edit')
|
||||
->property([
|
||||
'variable' => $serverVariable->variable->env_variable,
|
||||
'old' => $original,
|
||||
'new' => $new,
|
||||
])
|
||||
->log();
|
||||
}
|
||||
|
||||
$powerRepository->setServer($server)->send('restart');
|
||||
|
||||
Notification::make()
|
||||
->title('GSL Token updated')
|
||||
->body('Restart the server to use the new token.')
|
||||
->success()
|
||||
->send();
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->title('Error')
|
||||
->body($e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
97
app/Extensions/Features/JavaVersion.php
Normal file
97
app/Extensions/Features/JavaVersion.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use App\Facades\Activity;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Server;
|
||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
class JavaVersion extends FeatureProvider
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
return [
|
||||
'java.lang.UnsupportedClassVersionError',
|
||||
'minecraft 1.17 requires running the server with java 16 or above',
|
||||
'minecraft 1.18 requires running the server with java 17 or above',
|
||||
'unsupported major.minor version',
|
||||
'has been compiled by a more recent version of the java runtime',
|
||||
];
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'java_version';
|
||||
}
|
||||
|
||||
public function getAction(): Action
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
|
||||
return Action::make($this->getId())
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Unsupported Java Version')
|
||||
->modalDescription('This server is currently running an unsupported version of Java and cannot be started.')
|
||||
->modalSubmitActionLabel('Update Docker Image')
|
||||
->disabledForm(fn () => !auth()->user()->can(Permission::ACTION_STARTUP_DOCKER_IMAGE, $server))
|
||||
->form([
|
||||
Placeholder::make('java')
|
||||
->label('Please select a supported version from the list below to continue starting the server.'),
|
||||
Select::make('image')
|
||||
->label('Docker Image')
|
||||
->disabled(fn () => !in_array($server->image, $server->egg->docker_images))
|
||||
->options(fn () => collect($server->egg->docker_images)->mapWithKeys(fn ($key, $value) => [$key => $value]))
|
||||
->selectablePlaceholder(false)
|
||||
->default(fn () => $server->image)
|
||||
->notIn(fn () => $server->image)
|
||||
->required()
|
||||
->preload()
|
||||
->native(false),
|
||||
])
|
||||
->action(function (array $data, DaemonPowerRepository $powerRepository) use ($server) {
|
||||
try {
|
||||
$new = $data['image'];
|
||||
$original = $server->image;
|
||||
$server->forceFill(['image' => $new])->saveOrFail();
|
||||
|
||||
if ($original !== $server->image) {
|
||||
Activity::event('server:startup.image')
|
||||
->property(['old' => $original, 'new' => $new])
|
||||
->log();
|
||||
}
|
||||
$powerRepository->setServer($server)->send('restart');
|
||||
|
||||
Notification::make()
|
||||
->title('Docker image updated')
|
||||
->body('Restart the server to use the new image.')
|
||||
->success()
|
||||
->send();
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->title('Error')
|
||||
->body($e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
72
app/Extensions/Features/MinecraftEula.php
Normal file
72
app/Extensions/Features/MinecraftEula.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Repositories\Daemon\DaemonFileRepository;
|
||||
use App\Repositories\Daemon\DaemonPowerRepository;
|
||||
use Exception;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class MinecraftEula extends FeatureProvider
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
return [
|
||||
'You need to agree to the EULA in order to run the server',
|
||||
];
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'eula';
|
||||
}
|
||||
|
||||
public function getAction(): Action
|
||||
{
|
||||
return Action::make($this->getId())
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Minecraft EULA')
|
||||
->modalDescription(new HtmlString(Blade::render('By pressing "I Accept" below you are indicating your agreement to the <x-filament::link href="https://minecraft.net/eula" target="_blank">Minecraft EULA </x-filament::link>')))
|
||||
->modalSubmitActionLabel('I Accept')
|
||||
->action(function (DaemonFileRepository $fileRepository, DaemonPowerRepository $powerRepository) {
|
||||
try {
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
$content = $fileRepository->setServer($server)->getContent('eula.txt');
|
||||
$content = preg_replace('/(eula=)false/', '\1true', $content);
|
||||
$fileRepository->setServer($server)->putContent('eula.txt', $content);
|
||||
$powerRepository->setServer($server)->send('restart');
|
||||
|
||||
Notification::make()
|
||||
->title('Docker image updated')
|
||||
->body('Restart the server.')
|
||||
->success()
|
||||
->send();
|
||||
} catch (Exception $e) {
|
||||
Notification::make()
|
||||
->title('Error')
|
||||
->body($e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
76
app/Extensions/Features/PIDLimit.php
Normal file
76
app/Extensions/Features/PIDLimit.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class PIDLimit extends FeatureProvider
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
return [
|
||||
'pthread_create failed',
|
||||
'failed to create thread',
|
||||
'unable to create thread',
|
||||
'unable to create native thread',
|
||||
'unable to create new native thread',
|
||||
'exception in thread "craft async scheduler management thread"',
|
||||
];
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'pid_limit';
|
||||
}
|
||||
|
||||
public function getAction(): Action
|
||||
{
|
||||
return Action::make($this->getId())
|
||||
->requiresConfirmation()
|
||||
->icon('tabler-alert-triangle')
|
||||
->modalHeading(fn () => auth()->user()->isAdmin() ? 'Memory or process limit reached...' : 'Possible resource limit reached...')
|
||||
->modalDescription(new HtmlString(Blade::render(
|
||||
auth()->user()->isAdmin() ? <<<'HTML'
|
||||
<p>
|
||||
This server has reached the maximum process or memory limit.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
Increasing <code>container_pid_limit</code> in the wings
|
||||
configuration, <code>config.yml</code>, might help resolve
|
||||
this issue.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
<b>Note: Wings must be restarted for the configuration file changes to take effect</b>
|
||||
</p>
|
||||
HTML
|
||||
:
|
||||
<<<'HTML'
|
||||
<p>
|
||||
This server is attempting to use more resources than allocated. Please contact the administrator
|
||||
and give them the error below.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
<code>
|
||||
pthread_create failed, Possibly out of memory or process/resource limits reached
|
||||
</code>
|
||||
</p>
|
||||
HTML
|
||||
)))
|
||||
->modalCancelActionLabel('Close')
|
||||
->action(fn () => null);
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
64
app/Extensions/Features/SteamDiskSpace.php
Normal file
64
app/Extensions/Features/SteamDiskSpace.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extensions\Features;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class SteamDiskSpace extends FeatureProvider
|
||||
{
|
||||
public function __construct(protected Application $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/** @return array<string> */
|
||||
public function getListeners(): array
|
||||
{
|
||||
return [
|
||||
'steamcmd needs 250mb of free disk space to update',
|
||||
'0x202 after update job',
|
||||
];
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return 'steam_disk_space';
|
||||
}
|
||||
|
||||
public function getAction(): Action
|
||||
{
|
||||
return Action::make($this->getId())
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Out of available disk space...')
|
||||
->modalDescription(new HtmlString(Blade::render(
|
||||
auth()->user()->isAdmin() ? <<<'HTML'
|
||||
<p>
|
||||
This server has run out of available disk space and cannot complete the install or update
|
||||
process.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
Ensure the machine has enough disk space by typing{' '}
|
||||
<code class="rounded py-1 px-2">df -h</code> on the machine hosting
|
||||
this server. Delete files or increase the available disk space to resolve the issue.
|
||||
</p>
|
||||
HTML
|
||||
:
|
||||
<<<'HTML'
|
||||
<p>
|
||||
This server has run out of available disk space and cannot complete the install or update
|
||||
process. Please get in touch with the administrator(s) and inform them of disk space issues.
|
||||
</p>
|
||||
HTML
|
||||
)))
|
||||
->modalCancelActionLabel('Close')
|
||||
->action(fn () => null);
|
||||
}
|
||||
|
||||
public static function register(Application $app): self
|
||||
{
|
||||
return new self($app);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace App\Filament\Server\Pages;
|
||||
use App\Enums\ConsoleWidgetPosition;
|
||||
use App\Enums\ContainerStatus;
|
||||
use App\Exceptions\Http\Server\ServerStateConflictException;
|
||||
use App\Extensions\Features\FeatureProvider;
|
||||
use App\Filament\Server\Widgets\ServerConsole;
|
||||
use App\Filament\Server\Widgets\ServerCpuChart;
|
||||
use App\Filament\Server\Widgets\ServerMemoryChart;
|
||||
@ -13,8 +14,9 @@ use App\Filament\Server\Widgets\ServerOverview;
|
||||
use App\Livewire\AlertBanner;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Server;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\Concerns\InteractsWithActions;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Widgets\Widget;
|
||||
@ -23,6 +25,8 @@ use Livewire\Attributes\On;
|
||||
|
||||
class Console extends Page
|
||||
{
|
||||
use InteractsWithActions;
|
||||
|
||||
protected static ?string $navigationIcon = 'tabler-brand-tabler';
|
||||
|
||||
protected static ?int $navigationSort = 1;
|
||||
@ -47,6 +51,30 @@ class Console extends Page
|
||||
}
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
/** @var Server $server */
|
||||
$server = Filament::getTenant();
|
||||
/** @var FeatureProvider $feature */
|
||||
foreach ($server->egg->features() as $feature) {
|
||||
$this->cacheAction($feature->getAction());
|
||||
}
|
||||
}
|
||||
|
||||
#[On('mount-feature')]
|
||||
public function mountFeature(string $data): void
|
||||
{
|
||||
$data = json_decode($data);
|
||||
$feature = data_get($data, 'key');
|
||||
|
||||
$feature = FeatureProvider::getProviders($feature);
|
||||
if ($this->getMountedAction()) {
|
||||
return;
|
||||
}
|
||||
$this->mountAction($feature->getId());
|
||||
sleep(2); // TODO find a better way
|
||||
}
|
||||
|
||||
public function getWidgetData(): array
|
||||
{
|
||||
return [
|
||||
@ -126,33 +154,30 @@ class Console extends Page
|
||||
Action::make('start')
|
||||
->color('primary')
|
||||
->size(ActionSize::ExtraLarge)
|
||||
->action(fn () => $this->dispatch('setServerState', state: 'start', uuid: $server->uuid))
|
||||
->dispatch('setServerState', ['state' => 'start', 'uuid' => $server->uuid])
|
||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_START, $server))
|
||||
->disabled(fn () => $server->isInConflictState() || !$this->status->isStartable())
|
||||
->icon('tabler-player-play-filled'),
|
||||
Action::make('restart')
|
||||
->color('gray')
|
||||
->size(ActionSize::ExtraLarge)
|
||||
->action(fn () => $this->dispatch('setServerState', state: 'restart', uuid: $server->uuid))
|
||||
->dispatch('setServerState', ['state' => 'restart', 'uuid' => $server->uuid])
|
||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_RESTART, $server))
|
||||
->disabled(fn () => $server->isInConflictState() || !$this->status->isRestartable())
|
||||
->icon('tabler-reload'),
|
||||
Action::make('stop')
|
||||
->color('danger')
|
||||
->size(ActionSize::ExtraLarge)
|
||||
->action(fn () => $this->dispatch('setServerState', state: 'stop', uuid: $server->uuid))
|
||||
->dispatch('setServerState', ['state' => 'stop', 'uuid' => $server->uuid])
|
||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
||||
->hidden(fn () => $this->status->isStartingOrStopping() || $this->status->isKillable())
|
||||
->disabled(fn () => $server->isInConflictState() || !$this->status->isStoppable())
|
||||
->icon('tabler-player-stop-filled'),
|
||||
Action::make('kill')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Do you wish to kill this server?')
|
||||
->modalDescription('This can result in data corruption and/or data loss!')
|
||||
->modalSubmitActionLabel('Kill Server')
|
||||
->tooltip('This can result in data corruption and/or data loss!')
|
||||
->size(ActionSize::ExtraLarge)
|
||||
->action(fn () => $this->dispatch('setServerState', state: 'kill', uuid: $server->uuid))
|
||||
->dispatch('setServerState', ['state' => 'kill', 'uuid' => $server->uuid])
|
||||
->authorize(fn () => auth()->user()->can(Permission::ACTION_CONTROL_STOP, $server))
|
||||
->hidden(fn () => $server->isInConflictState() || !$this->status->isKillable())
|
||||
->icon('tabler-alert-square'),
|
||||
|
@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use App\Contracts\Validatable;
|
||||
use App\Exceptions\Service\Egg\HasChildrenException;
|
||||
use App\Exceptions\Service\HasActiveServersException;
|
||||
use App\Extensions\Features\FeatureProvider;
|
||||
use App\Traits\HasValidation;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
@ -70,19 +71,6 @@ class Egg extends Model implements Validatable
|
||||
*/
|
||||
public const EXPORT_VERSION = 'PLCN_v1';
|
||||
|
||||
/**
|
||||
* Different features that can be enabled on any given egg. These are used internally
|
||||
* to determine which types of frontend functionality should be shown to the user. Eggs
|
||||
* will automatically inherit features from a parent egg if they are already configured
|
||||
* to copy configuration values from said egg.
|
||||
*
|
||||
* To skip copying the features, an empty array value should be passed in ("[]") rather
|
||||
* than leaving it null.
|
||||
*/
|
||||
public const FEATURE_EULA_POPUP = 'eula';
|
||||
|
||||
public const FEATURE_FASTDL = 'fastdl';
|
||||
|
||||
/**
|
||||
* Fields that are not mass assignable.
|
||||
*/
|
||||
@ -172,6 +160,12 @@ class Egg extends Model implements Validatable
|
||||
});
|
||||
}
|
||||
|
||||
/** @return array<FeatureProvider> */
|
||||
public function features(): array
|
||||
{
|
||||
return FeatureProvider::getProviders($this->features);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the install script for the egg; if egg is copying from another
|
||||
* it will return the copied script.
|
||||
|
@ -15,6 +15,11 @@ use App\Extensions\Avatar\Providers\UiAvatarsProvider;
|
||||
use App\Extensions\OAuth\Providers\GitlabProvider;
|
||||
use App\Models;
|
||||
use App\Extensions\Captcha\Providers\TurnstileProvider;
|
||||
use App\Extensions\Features\GSLToken;
|
||||
use App\Extensions\Features\JavaVersion;
|
||||
use App\Extensions\Features\MinecraftEula;
|
||||
use App\Extensions\Features\PIDLimit;
|
||||
use App\Extensions\Features\SteamDiskSpace;
|
||||
use App\Extensions\OAuth\Providers\AuthentikProvider;
|
||||
use App\Extensions\OAuth\Providers\CommonProvider;
|
||||
use App\Extensions\OAuth\Providers\DiscordProvider;
|
||||
@ -121,6 +126,13 @@ class AppServiceProvider extends ServiceProvider
|
||||
GravatarProvider::register();
|
||||
UiAvatarsProvider::register();
|
||||
|
||||
// Default Feature providers
|
||||
GSLToken::register($app);
|
||||
JavaVersion::register($app);
|
||||
MinecraftEula::register($app);
|
||||
PIDLimit::register($app);
|
||||
SteamDiskSpace::register($app);
|
||||
|
||||
FilamentColor::register([
|
||||
'danger' => Color::Red,
|
||||
'gray' => Color::Zinc,
|
||||
|
@ -101,6 +101,9 @@ class ServerConfigurationStructureService
|
||||
'egg' => [
|
||||
'id' => $server->egg->uuid,
|
||||
'file_denylist' => $server->egg->inherit_file_denylist,
|
||||
'features' => collect($server->egg->features())->mapWithKeys(fn ($feature) => [
|
||||
$feature->getId() => $feature->getListeners(),
|
||||
])->all(),
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -46,6 +46,7 @@ class EggTransformer extends BaseTransformer
|
||||
'name' => $model->name,
|
||||
'author' => $model->author,
|
||||
'description' => $model->description,
|
||||
'features' => $model->features,
|
||||
// "docker_image" is deprecated, but left here to avoid breaking too many things at once
|
||||
// in external software. We'll remove it down the road once things have gotten the chance
|
||||
// to upgrade to using "docker_images".
|
||||
|
@ -129,6 +129,9 @@
|
||||
case 'install output':
|
||||
handleConsoleOutput(args[0]);
|
||||
break;
|
||||
case 'feature match':
|
||||
Livewire.dispatch('mount-feature', { data: args[0] });
|
||||
break;
|
||||
case 'status':
|
||||
handlePowerChangeEvent(args[0]);
|
||||
|
||||
|
@ -4,4 +4,7 @@
|
||||
:data="$this->getWidgetData()"
|
||||
:widgets="$this->getVisibleWidgets()"
|
||||
/>
|
||||
|
||||
<x-filament-actions::modals />
|
||||
|
||||
</x-filament-panels::page>
|
||||
|
Loading…
x
Reference in New Issue
Block a user