mirror of
https://github.com/pelican-dev/panel.git
synced 2025-09-08 21:58:36 +02:00
Allow eggs to be exported/imported as YAML (#1535)
This commit is contained in:
parent
5b2e9d94ca
commit
ec0727b406
@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Console\Commands\Egg;
|
||||
|
||||
use App\Enums\EggFormat;
|
||||
use App\Models\Egg;
|
||||
use App\Services\Eggs\Sharing\EggExporterService;
|
||||
use Exception;
|
||||
use Illuminate\Console\Command;
|
||||
use JsonException;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class CheckEggUpdatesCommand extends Command
|
||||
{
|
||||
@ -23,6 +26,9 @@ class CheckEggUpdatesCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws JsonException
|
||||
*/
|
||||
private function check(Egg $egg, EggExporterService $exporterService): void
|
||||
{
|
||||
if (is_null($egg->update_url)) {
|
||||
@ -31,22 +37,26 @@ class CheckEggUpdatesCommand extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$currentJson = json_decode($exporterService->handle($egg->id));
|
||||
unset($currentJson->exported_at);
|
||||
$ext = strtolower(pathinfo(parse_url($egg->update_url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
$isYaml = in_array($ext, ['yaml', 'yml']);
|
||||
|
||||
$updatedEgg = file_get_contents($egg->update_url);
|
||||
assert($updatedEgg !== false);
|
||||
$updatedJson = json_decode($updatedEgg);
|
||||
unset($updatedJson->exported_at);
|
||||
$local = $isYaml
|
||||
? Yaml::parse($exporterService->handle($egg->id, EggFormat::YAML))
|
||||
: json_decode($exporterService->handle($egg->id, EggFormat::JSON), true);
|
||||
|
||||
if (md5(json_encode($currentJson, JSON_THROW_ON_ERROR)) === md5(json_encode($updatedJson, JSON_THROW_ON_ERROR))) {
|
||||
$this->info("$egg->name: Up-to-date");
|
||||
cache()->put("eggs.$egg->uuid.update", false, now()->addHour());
|
||||
$remote = file_get_contents($egg->update_url);
|
||||
assert($remote !== false);
|
||||
|
||||
return;
|
||||
}
|
||||
$remote = $isYaml ? Yaml::parse($remote) : json_decode($remote, true);
|
||||
|
||||
$this->warn("$egg->name: Found update");
|
||||
cache()->put("eggs.$egg->uuid.update", true, now()->addHour());
|
||||
unset($local['exported_at'], $remote['exported_at']);
|
||||
|
||||
$localHash = md5(json_encode($local, JSON_THROW_ON_ERROR));
|
||||
$remoteHash = md5(json_encode($remote, JSON_THROW_ON_ERROR));
|
||||
|
||||
$status = $localHash === $remoteHash ? 'Up-to-date' : 'Found update';
|
||||
$this->{($localHash === $remoteHash) ? 'info' : 'warn'}("$egg->name: $status");
|
||||
|
||||
cache()->put("eggs.$egg->uuid.update", $localHash !== $remoteHash, now()->addHour());
|
||||
}
|
||||
}
|
||||
|
9
app/Enums/EggFormat.php
Normal file
9
app/Enums/EggFormat.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum EggFormat: string
|
||||
{
|
||||
case YAML = 'yaml';
|
||||
case JSON = 'json';
|
||||
}
|
@ -2,9 +2,12 @@
|
||||
|
||||
namespace App\Filament\Components\Actions;
|
||||
|
||||
use App\Enums\EggFormat;
|
||||
use App\Models\Egg;
|
||||
use App\Services\Eggs\Sharing\EggExporterService;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
class ExportEggAction extends Action
|
||||
{
|
||||
@ -21,8 +24,30 @@ class ExportEggAction extends Action
|
||||
|
||||
$this->authorize(fn () => auth()->user()->can('export egg'));
|
||||
|
||||
$this->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id);
|
||||
}, 'egg-' . $egg->getKebabName() . '.json'));
|
||||
$this->modalHeading(fn (Egg $egg) => trans('filament-actions::export.modal.actions.export.label') . ' ' . $egg->name);
|
||||
|
||||
$this->modalIcon($this->icon);
|
||||
|
||||
$this->form([
|
||||
Placeholder::make('')
|
||||
->label(fn (Egg $egg) => trans('admin/egg.export.modal', ['egg' => $egg->name])),
|
||||
]);
|
||||
|
||||
$this->modalFooterActionsAlignment(Alignment::Center);
|
||||
|
||||
$this->modalFooterActions([
|
||||
Action::make('json')
|
||||
->label(trans('admin/egg.export.as') . ' .json')
|
||||
->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id, EggFormat::JSON);
|
||||
}, 'egg-' . $egg->getKebabName() . '.json'))
|
||||
->close(),
|
||||
Action::make('yaml')
|
||||
->label(trans('admin/egg.export.as') . ' .yaml')
|
||||
->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id, EggFormat::YAML);
|
||||
}, 'egg-' . $egg->getKebabName() . '.yaml'))
|
||||
->close(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -47,13 +47,31 @@ class ImportEggAction extends Action
|
||||
|
||||
foreach ($eggs as $egg) {
|
||||
if ($egg instanceof TemporaryUploadedFile) {
|
||||
$name = str($egg->getClientOriginalName())->afterLast('egg-')->before('.json')->headline();
|
||||
$originalName = $egg->getClientOriginalName();
|
||||
$filename = str($originalName)->afterLast('egg-');
|
||||
$ext = str($originalName)->afterLast('.')->lower()->toString();
|
||||
|
||||
$name = match ($ext) {
|
||||
'json' => $filename->before('.json')->headline(),
|
||||
'yaml' => $filename->before('.yaml')->headline(),
|
||||
'yml' => $filename->before('.yml')->headline(),
|
||||
default => $filename->headline(),
|
||||
};
|
||||
$method = 'fromFile';
|
||||
} else {
|
||||
$egg = str($egg);
|
||||
$egg = $egg->contains('github.com') ? $egg->replaceFirst('blob', 'raw') : $egg;
|
||||
$name = $egg->afterLast('/egg-')->before('.json')->headline();
|
||||
$method = 'fromUrl';
|
||||
|
||||
$filename = $egg->afterLast('/egg-');
|
||||
$ext = $filename->afterLast('.')->lower()->toString();
|
||||
|
||||
$name = match ($ext) {
|
||||
'json' => $filename->before('.json')->headline(),
|
||||
'yaml' => $filename->before('.yaml')->headline(),
|
||||
'yml' => $filename->before('.yml')->headline(),
|
||||
default => $filename->headline(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
$eggImportService->$method($egg);
|
||||
@ -94,7 +112,7 @@ class ImportEggAction extends Action
|
||||
FileUpload::make('files')
|
||||
->label(trans('admin/egg.model_label'))
|
||||
->hint(trans('admin/egg.import.egg_help'))
|
||||
->acceptedFileTypes(['application/json'])
|
||||
->acceptedFileTypes(['application/json', 'application/yaml', 'application/x-yaml', 'text/yaml'])
|
||||
->preserveFilenames()
|
||||
->previewable(false)
|
||||
->storeFiles(false)
|
||||
@ -125,7 +143,7 @@ class ImportEggAction extends Action
|
||||
}),
|
||||
Repeater::make('urls')
|
||||
->label('')
|
||||
->itemLabel(fn (array $state) => str($state['url'])->afterLast('/egg-')->before('.json')->headline())
|
||||
->itemLabel(fn (array $state) => str($state['url'])->afterLast('/egg-')->beforeLast('.')->headline())
|
||||
->hint(trans('admin/egg.import.url_help'))
|
||||
->addActionLabel(trans('admin/egg.import.add_url'))
|
||||
->grid($isMultiple ? 2 : null)
|
||||
@ -139,7 +157,7 @@ class ImportEggAction extends Action
|
||||
->label(trans('admin/egg.import.url'))
|
||||
->placeholder('https://github.com/pelican-eggs/generic/blob/main/nodejs/egg-node-js-generic.json')
|
||||
->url()
|
||||
->endsWith('.json')
|
||||
->endsWith(['.json', '.yaml', '.yml'])
|
||||
->validationAttribute(trans('admin/egg.import.url')),
|
||||
]),
|
||||
]),
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
namespace App\Filament\Components\Tables\Actions;
|
||||
|
||||
use App\Enums\EggFormat;
|
||||
use App\Models\Egg;
|
||||
use App\Services\Eggs\Sharing\EggExporterService;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Tables\Actions\Action;
|
||||
|
||||
class ExportEggAction extends Action
|
||||
@ -23,8 +26,30 @@ class ExportEggAction extends Action
|
||||
|
||||
$this->authorize(fn () => auth()->user()->can('export egg'));
|
||||
|
||||
$this->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id);
|
||||
}, 'egg-' . $egg->getKebabName() . '.json'));
|
||||
$this->modalHeading(fn (Egg $egg) => trans('filament-actions::export.modal.actions.export.label') . ' ' . $egg->name);
|
||||
|
||||
$this->modalIcon($this->icon);
|
||||
|
||||
$this->form([
|
||||
Placeholder::make('')
|
||||
->label(fn (Egg $egg) => trans('admin/egg.export.modal', ['egg' => $egg->name])),
|
||||
]);
|
||||
|
||||
$this->modalFooterActionsAlignment(Alignment::Center);
|
||||
|
||||
$this->modalFooterActions([
|
||||
Action::make('json')
|
||||
->label(trans('admin/egg.export.as') . ' .json')
|
||||
->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id, EggFormat::JSON);
|
||||
}, 'egg-' . $egg->getKebabName() . '.json'))
|
||||
->close(),
|
||||
Action::make('yaml')
|
||||
->label(trans('admin/egg.export.as') . ' .yaml')
|
||||
->action(fn (EggExporterService $service, Egg $egg) => response()->streamDownload(function () use ($service, $egg) {
|
||||
echo $service->handle($egg->id, EggFormat::YAML);
|
||||
}, 'egg-' . $egg->getKebabName() . '.yaml'))
|
||||
->close(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ class ImportEggAction extends Action
|
||||
}
|
||||
}),
|
||||
Repeater::make('urls')
|
||||
->itemLabel(fn (array $state) => str($state['url'])->afterLast('/egg-')->before('.json')->headline())
|
||||
->itemLabel(fn (array $state) => str($state['url'])->afterLast('/egg-')->beforeLast('.')->headline())
|
||||
->hint(trans('admin/egg.import.url_help'))
|
||||
->addActionLabel(trans('admin/egg.import.add_url'))
|
||||
->grid($isMultiple ? 2 : null)
|
||||
@ -131,7 +131,7 @@ class ImportEggAction extends Action
|
||||
->label(trans('admin/egg.import.url'))
|
||||
->placeholder('https://github.com/pelican-eggs/generic/blob/main/nodejs/egg-node-js-generic.json')
|
||||
->url()
|
||||
->endsWith('.json')
|
||||
->endsWith(['.json', '.yaml', '.yml'])
|
||||
->validationAttribute(trans('admin/egg.import.url')),
|
||||
]),
|
||||
]),
|
||||
|
@ -69,7 +69,7 @@ class Egg extends Model implements Validatable
|
||||
/**
|
||||
* Defines the current egg export version.
|
||||
*/
|
||||
public const EXPORT_VERSION = 'PLCN_v1';
|
||||
public const EXPORT_VERSION = 'PLCN_v2';
|
||||
|
||||
/**
|
||||
* Fields that are not mass assignable.
|
||||
|
@ -2,17 +2,19 @@
|
||||
|
||||
namespace App\Services\Eggs\Sharing;
|
||||
|
||||
use App\Enums\EggFormat;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Egg;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Models\EggVariable;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
class EggExporterService
|
||||
{
|
||||
/**
|
||||
* Return a JSON representation of an egg and its variables.
|
||||
* Return a JSON or YAML representation of an egg and its variables.
|
||||
*/
|
||||
public function handle(int $egg): string
|
||||
public function handle(int $egg, EggFormat $format): string
|
||||
{
|
||||
$egg = Egg::with(['scriptFrom', 'configFrom', 'variables'])->findOrFail($egg);
|
||||
|
||||
@ -30,9 +32,7 @@ class EggExporterService
|
||||
'tags' => $egg->tags,
|
||||
'features' => $egg->features,
|
||||
'docker_images' => $egg->docker_images,
|
||||
'file_denylist' => Collection::make($egg->inherit_file_denylist)->filter(function ($value) {
|
||||
return !empty($value);
|
||||
}),
|
||||
'file_denylist' => Collection::make($egg->inherit_file_denylist)->filter(fn ($v) => !empty($v))->values(),
|
||||
'startup' => $egg->startup,
|
||||
'config' => [
|
||||
'files' => $egg->inherit_config_files,
|
||||
@ -50,9 +50,50 @@ class EggExporterService
|
||||
'variables' => $egg->variables->map(function (EggVariable $eggVariable) {
|
||||
return Collection::make($eggVariable->toArray())
|
||||
->except(['id', 'egg_id', 'created_at', 'updated_at']);
|
||||
}),
|
||||
})->values()->toArray(),
|
||||
];
|
||||
|
||||
return json_encode($struct, JSON_PRETTY_PRINT);
|
||||
return match ($format) {
|
||||
EggFormat::JSON => json_encode($struct, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
|
||||
EggFormat::YAML => Yaml::dump($this->yamlExport($struct), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK | Yaml::DUMP_OBJECT_AS_MAP),
|
||||
};
|
||||
}
|
||||
|
||||
protected function yamlExport(mixed $data): mixed
|
||||
{
|
||||
if ($data instanceof Collection) {
|
||||
$data = $data->all();
|
||||
}
|
||||
|
||||
if (is_string($data)) {
|
||||
$decoded = json_decode($data, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
return $this->yamlExport($decoded);
|
||||
}
|
||||
|
||||
return str_replace(["\r\n", '\\r\\n', '\\n'], "\n", $data);
|
||||
}
|
||||
|
||||
if (is_array($data)) {
|
||||
$result = [];
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (
|
||||
is_string($value) &&
|
||||
strtolower($key) === 'description' &&
|
||||
(str_contains($value, "\n") || strlen($value) > 80)
|
||||
) {
|
||||
$value = wordwrap($value, 100, "\n");
|
||||
} else {
|
||||
$value = $this->yamlExport($value);
|
||||
}
|
||||
|
||||
$result[$key] = $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Services\Eggs\Sharing;
|
||||
|
||||
use App\Exceptions\Service\InvalidFileUploadException;
|
||||
use JsonException;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Models\Egg;
|
||||
@ -11,6 +12,9 @@ use App\Models\EggVariable;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\TemporaryDirectory\TemporaryDirectory;
|
||||
use stdClass;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Throwable;
|
||||
|
||||
class EggImporterService
|
||||
{
|
||||
@ -28,9 +32,9 @@ class EggImporterService
|
||||
public function __construct(protected ConnectionInterface $connection) {}
|
||||
|
||||
/**
|
||||
* Take an uploaded JSON file and parse it into a new egg.
|
||||
* Take an uploaded JSON or YAML file and parse it into a new egg.
|
||||
*
|
||||
* @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable
|
||||
* @throws InvalidFileUploadException|Throwable
|
||||
*/
|
||||
public function fromFile(UploadedFile $file, ?Egg $egg = null): Egg
|
||||
{
|
||||
@ -46,7 +50,6 @@ class EggImporterService
|
||||
'copy_script_from' => null,
|
||||
]);
|
||||
|
||||
// Don't check for this anymore
|
||||
for ($i = 0; $i < count($parsed['variables']); $i++) {
|
||||
unset($parsed['variables'][$i]['field_type']);
|
||||
}
|
||||
@ -54,7 +57,6 @@ class EggImporterService
|
||||
$egg = $this->fillFromParsed($egg, $parsed);
|
||||
$egg->save();
|
||||
|
||||
// Update existing variables or create new ones.
|
||||
foreach ($parsed['variables'] ?? [] as $variable) {
|
||||
EggVariable::unguarded(function () use ($egg, $variable) {
|
||||
$variable['rules'] = is_array($variable['rules']) ? $variable['rules'] : explode('|', $variable['rules']);
|
||||
@ -66,7 +68,6 @@ class EggImporterService
|
||||
}
|
||||
|
||||
$imported = array_map(fn ($value) => $value['env_variable'], $parsed['variables'] ?? []);
|
||||
|
||||
$egg->variables()->whereNotIn('env_variable', $imported)->delete();
|
||||
|
||||
return $egg->refresh();
|
||||
@ -74,31 +75,39 @@ class EggImporterService
|
||||
}
|
||||
|
||||
/**
|
||||
* Take an url and parse it into a new egg or update an existing one.
|
||||
* Take a URL (YAML or JSON) and parse it into a new egg or update an existing one.
|
||||
*
|
||||
* @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable
|
||||
* @throws InvalidFileUploadException|Throwable
|
||||
*/
|
||||
public function fromUrl(string $url, ?Egg $egg = null): Egg
|
||||
{
|
||||
$info = pathinfo($url);
|
||||
$extension = strtolower($info['extension']);
|
||||
|
||||
$tmpDir = TemporaryDirectory::make()->deleteWhenDestroyed();
|
||||
$tmpPath = $tmpDir->path($info['basename']);
|
||||
|
||||
if (!file_put_contents($tmpPath, file_get_contents($url))) {
|
||||
throw new InvalidFileUploadException('Could not write temporary file.');
|
||||
$fileContents = @file_get_contents($url);
|
||||
|
||||
if (!$fileContents || !file_put_contents($tmpPath, $fileContents)) {
|
||||
throw new InvalidFileUploadException('Could not download or write temporary file.');
|
||||
}
|
||||
|
||||
return $this->fromFile(new UploadedFile($tmpPath, $info['basename'], 'application/json'), $egg);
|
||||
$mime = match ($extension) {
|
||||
'yaml', 'yml' => 'application/yaml',
|
||||
'json' => 'application/json',
|
||||
default => throw new InvalidFileUploadException('Unsupported file format.'),
|
||||
};
|
||||
|
||||
return $this->fromFile(new UploadedFile($tmpPath, $info['basename'], $mime), $egg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an uploaded file and parses out the egg configuration from within.
|
||||
*
|
||||
* @todo replace with DTO
|
||||
*
|
||||
* @return array<array-key, mixed>
|
||||
*
|
||||
* @throws \App\Exceptions\Service\InvalidFileUploadException
|
||||
* @throws InvalidFileUploadException|JsonException
|
||||
*/
|
||||
protected function parseFile(UploadedFile $file): array
|
||||
{
|
||||
@ -106,30 +115,56 @@ class EggImporterService
|
||||
throw new InvalidFileUploadException('The selected file was not uploaded successfully');
|
||||
}
|
||||
|
||||
$extension = strtolower($file->getClientOriginalExtension());
|
||||
$mime = $file->getMimeType();
|
||||
|
||||
try {
|
||||
$parsed = json_decode($file->getContent(), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (\JsonException $exception) {
|
||||
throw new InvalidFileUploadException('Could not read JSON file: ' . $exception->getMessage());
|
||||
$content = $file->getContent();
|
||||
|
||||
$parsed = match (true) {
|
||||
in_array($extension, ['yaml', 'yml']),
|
||||
str_contains($mime, 'yaml') => Yaml::parse($content),
|
||||
default => json_decode($content, true, 512, JSON_THROW_ON_ERROR),
|
||||
};
|
||||
} catch (Throwable $e) {
|
||||
throw new InvalidFileUploadException('File parse failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$version = $parsed['meta']['version'] ?? '';
|
||||
|
||||
$parsed = match ($version) {
|
||||
'PTDL_v1' => $this->convertToV2($parsed),
|
||||
'PTDL_v2' => $parsed,
|
||||
'PLCN_v1' => $parsed,
|
||||
default => throw new InvalidFileUploadException('The JSON file provided is not in a format that can be recognized.')
|
||||
'PTDL_v2', 'PLCN_v1', 'PLCN_v2' => $parsed,
|
||||
default => throw new InvalidFileUploadException('The file format is not recognized.'),
|
||||
};
|
||||
|
||||
// Make sure we only use recent variable format from now on
|
||||
if (array_get($parsed['config'], 'files')) {
|
||||
$parsed['config']['files'] = str_replace(
|
||||
array_keys(self::UPGRADE_VARIABLES),
|
||||
array_values(self::UPGRADE_VARIABLES),
|
||||
$parsed['config']['files'],
|
||||
);
|
||||
if (isset($parsed['config']) && (is_array($parsed['config']) || $parsed['config'] instanceof stdClass)) {
|
||||
$parsed['config'] = (array) $parsed['config'];
|
||||
foreach ($parsed['config'] as $key => $value) {
|
||||
if (is_array($value) || $value instanceof stdClass) {
|
||||
$parsed['config'][$key] = json_encode((array) $value, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
if ($key === 'files' && is_string($parsed['config'][$key])) {
|
||||
$parsed['config'][$key] = str_replace(
|
||||
array_keys(self::UPGRADE_VARIABLES),
|
||||
array_values(self::UPGRADE_VARIABLES),
|
||||
$parsed['config'][$key]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($parsed['scripts']['installation']) && (is_array($parsed['scripts']['installation']) || $parsed['scripts']['installation'] instanceof stdClass)) {
|
||||
$parsed['scripts']['installation'] = (array) $parsed['scripts']['installation'];
|
||||
foreach ($parsed['scripts']['installation'] as $key => $value) {
|
||||
if (is_array($value) || $value instanceof stdClass) {
|
||||
$parsed['scripts']['installation'][$key] = json_encode((array) $value, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reserved env var name handling
|
||||
[$forbidden, $allowed] = collect($parsed['variables'])
|
||||
->map(fn ($variable) => array_merge(
|
||||
$variable,
|
||||
@ -155,22 +190,7 @@ class EggImporterService
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the provided model with the parsed JSON data.
|
||||
*
|
||||
* @param array{
|
||||
* name: string,
|
||||
* description: string,
|
||||
* tags: string[],
|
||||
* features: string[],
|
||||
* docker_images: string[],
|
||||
* file_denylist: string[],
|
||||
* meta: array{update_url: string},
|
||||
* config: array{files: string, startup: string, logs: string, stop: string},
|
||||
* startup: string,
|
||||
* scripts: array{
|
||||
* installation: array{script: string, entrypoint: string, container: string},
|
||||
* },
|
||||
* } $parsed
|
||||
* @param array<string, mixed> $parsed
|
||||
*/
|
||||
protected function fillFromParsed(Egg $model, array $parsed): Egg
|
||||
{
|
||||
@ -182,9 +202,9 @@ class EggImporterService
|
||||
'docker_images' => Arr::get($parsed, 'docker_images'),
|
||||
'file_denylist' => Collection::make(Arr::get($parsed, 'file_denylist'))->filter(fn ($value) => !empty($value)),
|
||||
'update_url' => Arr::get($parsed, 'meta.update_url'),
|
||||
'config_files' => Arr::get($parsed, 'config.files'),
|
||||
'config_startup' => Arr::get($parsed, 'config.startup'),
|
||||
'config_logs' => Arr::get($parsed, 'config.logs'),
|
||||
'config_files' => json_encode(json_decode(Arr::get($parsed, 'config.files')), JSON_PRETTY_PRINT),
|
||||
'config_startup' => json_encode(json_decode(Arr::get($parsed, 'config.startup')), JSON_PRETTY_PRINT),
|
||||
'config_logs' => json_encode(json_decode(Arr::get($parsed, 'config.logs')), JSON_PRETTY_PRINT),
|
||||
'config_stop' => Arr::get($parsed, 'config.stop'),
|
||||
'startup' => Arr::get($parsed, 'startup'),
|
||||
'script_install' => Arr::get($parsed, 'scripts.installation.script'),
|
||||
@ -194,17 +214,11 @@ class EggImporterService
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a PTDL_V1 egg into the expected PTDL_V2 egg format. This just handles
|
||||
* the "docker_images" field potentially not being present, and not being in the
|
||||
* expected "key => value" format.
|
||||
*
|
||||
* @param array{images?: string[], image?: string, field_type?: string, docker_images?: array<array-key, string>} $parsed
|
||||
* @return array<array-key, mixed>
|
||||
* @param array<string, mixed> $parsed
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function convertToV2(array $parsed): array
|
||||
{
|
||||
// Maintain backwards compatability for eggs that are still using the old single image
|
||||
// string format. New eggs can provide an array of Docker images that can be used.
|
||||
if (!isset($parsed['images'])) {
|
||||
$images = [Arr::get($parsed, 'image') ?? 'nil'];
|
||||
} else {
|
||||
|
@ -3,10 +3,12 @@
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Egg;
|
||||
use Exception;
|
||||
use DirectoryIterator;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use App\Services\Eggs\Sharing\EggImporterService;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Throwable;
|
||||
|
||||
class EggSeeder extends Seeder
|
||||
{
|
||||
@ -46,22 +48,39 @@ class EggSeeder extends Seeder
|
||||
*/
|
||||
protected function parseEggFiles($name): void
|
||||
{
|
||||
$files = new \DirectoryIterator(database_path('Seeders/eggs/' . kebab_case($name)));
|
||||
$path = database_path('Seeders/eggs/' . kebab_case($name));
|
||||
$files = new DirectoryIterator($path);
|
||||
|
||||
$this->command->alert('Updating Eggs for: ' . $name);
|
||||
/** @var \DirectoryIterator $file */
|
||||
|
||||
/** @var DirectoryIterator $file */
|
||||
foreach ($files as $file) {
|
||||
if (!$file->isFile() || !$file->isReadable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extension = strtolower($file->getExtension());
|
||||
$filePath = $file->getRealPath();
|
||||
|
||||
try {
|
||||
$decoded = json_decode(file_get_contents($file->getRealPath()), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (Exception) {
|
||||
$decoded = match ($extension) {
|
||||
'json' => json_decode(file_get_contents($filePath), true, 512, JSON_THROW_ON_ERROR),
|
||||
'yaml', 'yml' => Yaml::parseFile($filePath),
|
||||
default => null,
|
||||
};
|
||||
} catch (Throwable) {
|
||||
$this->command->warn("Failed to parse {$file->getFilename()}, skipping.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = new UploadedFile($file->getPathname(), $file->getFilename(), 'application/json');
|
||||
if (!is_array($decoded) || !isset($decoded['name'], $decoded['author'])) {
|
||||
$this->command->warn("Invalid structure in {$file->getFilename()}, skipping.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$uploaded = new UploadedFile($filePath, $file->getFilename());
|
||||
|
||||
$egg = Egg::query()
|
||||
->where('author', $decoded['author'])
|
||||
@ -69,10 +88,10 @@ class EggSeeder extends Seeder
|
||||
->first();
|
||||
|
||||
if ($egg instanceof Egg) {
|
||||
$this->importerService->fromFile($file, $egg);
|
||||
$this->importerService->fromFile($uploaded, $egg);
|
||||
$this->command->info('Updated ' . $decoded['name']);
|
||||
} else {
|
||||
$this->importerService->fromFile($file);
|
||||
$this->importerService->fromFile($uploaded);
|
||||
$this->command->comment('Created ' . $decoded['name']);
|
||||
}
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/minecraft\/egg-bungeecord.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:35:34+00:00",
|
||||
"name": "Bungeecord",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "9e6b409e-4028-4947-aea8-50a2c404c271",
|
||||
"description": "For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream. Whether you are a small server wishing to string multiple game-modes together, or the owner of the ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be able to unlock your community's full potential.",
|
||||
"tags": [
|
||||
"minecraft",
|
||||
"proxy"
|
||||
],
|
||||
"features": [
|
||||
"eula",
|
||||
"java_version",
|
||||
"pid_limit"
|
||||
],
|
||||
"docker_images": {
|
||||
"Java 21": "ghcr.io\/parkervcp\/yolks:java_21",
|
||||
"Java 17": "ghcr.io\/parkervcp\/yolks:java_17",
|
||||
"Java 16": "ghcr.io\/parkervcp\/yolks:java_16",
|
||||
"Java 11": "ghcr.io\/parkervcp\/yolks:java_11",
|
||||
"Java 8": "ghcr.io\/parkervcp\/yolks:java_8"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": "java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}",
|
||||
"config": {
|
||||
"files": "{\r\n \"config.yml\": {\r\n \"parser\": \"yaml\",\r\n \"find\": {\r\n \"listeners[0].query_port\": \"{{server.allocations.default.port}}\",\r\n \"listeners[0].host\": \"0.0.0.0:{{server.allocations.default.port}}\",\r\n \"servers.*.address\": {\r\n \"regex:^(127\\\\.0\\\\.0\\\\.1|localhost)(:\\\\d{1,5})?$\": \"{{config.docker.interface}}$2\"\r\n }\r\n }\r\n }\r\n}",
|
||||
"startup": "{\r\n \"done\": \"Listening on \"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "end"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n# Bungeecord Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\ncd \/mnt\/server\r\n\r\nif [ -z \"${BUNGEE_VERSION}\" ] || [ \"${BUNGEE_VERSION}\" == \"latest\" ]; then\r\n BUNGEE_VERSION=\"lastStableBuild\"\r\nfi\r\n\r\ncurl -o ${SERVER_JARFILE} https:\/\/ci.md-5.net\/job\/BungeeCord\/${BUNGEE_VERSION}\/artifact\/bootstrap\/target\/BungeeCord.jar",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Bungeecord Version",
|
||||
"description": "The version of Bungeecord to download and use.",
|
||||
"env_variable": "BUNGEE_VERSION",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"alpha_num",
|
||||
"between:1,6"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Bungeecord Jar File",
|
||||
"description": "The name of the Jarfile to use when running Bungeecord.",
|
||||
"env_variable": "SERVER_JARFILE",
|
||||
"default_value": "bungeecord.jar",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^([\\w\\d._-]+)(\\.jar)$\/"
|
||||
],
|
||||
"sort": 2
|
||||
}
|
||||
]
|
||||
}
|
83
database/Seeders/eggs/minecraft/egg-bungeecord.yaml
Normal file
83
database/Seeders/eggs/minecraft/egg-bungeecord.yaml
Normal file
@ -0,0 +1,83 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/minecraft/egg-bungeecord.yaml'
|
||||
exported_at: '2025-07-25T13:32:34+00:00'
|
||||
name: Bungeecord
|
||||
author: panel@example.com
|
||||
uuid: 9e6b409e-4028-4947-aea8-50a2c404c271
|
||||
description: |-
|
||||
For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and
|
||||
reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream.
|
||||
Whether you are a small server wishing to string multiple game-modes together, or the owner of the
|
||||
ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be
|
||||
able to unlock your community's full potential.
|
||||
tags:
|
||||
- minecraft
|
||||
- proxy
|
||||
features:
|
||||
- eula
|
||||
- java_version
|
||||
- pid_limit
|
||||
docker_images:
|
||||
'Java 21': 'ghcr.io/parkervcp/yolks:java_21'
|
||||
'Java 17': 'ghcr.io/parkervcp/yolks:java_17'
|
||||
'Java 16': 'ghcr.io/parkervcp/yolks:java_16'
|
||||
'Java 11': 'ghcr.io/parkervcp/yolks:java_11'
|
||||
'Java 8': 'ghcr.io/parkervcp/yolks:java_8'
|
||||
file_denylist: { }
|
||||
startup: 'java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}'
|
||||
config:
|
||||
files:
|
||||
config.yml:
|
||||
parser: yaml
|
||||
find:
|
||||
'listeners[0].query_port': '{{server.allocations.default.port}}'
|
||||
'listeners[0].host': '0.0.0.0:{{server.allocations.default.port}}'
|
||||
'servers.*.address':
|
||||
'regex:^(127\.0\.0\.1|localhost)(:\d{1,5})?$': '{{config.docker.interface}}$2'
|
||||
startup:
|
||||
done: 'Listening on '
|
||||
logs: { }
|
||||
stop: end
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
# Bungeecord Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
if [ -z "${BUNGEE_VERSION}" ] || [ "${BUNGEE_VERSION}" == "latest" ]; then
|
||||
BUNGEE_VERSION="lastStableBuild"
|
||||
fi
|
||||
|
||||
curl -o ${SERVER_JARFILE} https://ci.md-5.net/job/BungeeCord/${BUNGEE_VERSION}/artifact/bootstrap/target/BungeeCord.jar
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'Bungeecord Jar File'
|
||||
description: 'The name of the Jarfile to use when running Bungeecord.'
|
||||
env_variable: SERVER_JARFILE
|
||||
default_value: bungeecord.jar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^([\w\d._-]+)(\.jar)$/'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Bungeecord Version'
|
||||
description: 'The version of Bungeecord to download and use.'
|
||||
env_variable: BUNGEE_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- alpha_num
|
||||
- 'between:1,6'
|
||||
sort: 1
|
File diff suppressed because one or more lines are too long
217
database/Seeders/eggs/minecraft/egg-forge-minecraft.yaml
Normal file
217
database/Seeders/eggs/minecraft/egg-forge-minecraft.yaml
Normal file
@ -0,0 +1,217 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/minecraft/egg-forge-minecraft.yaml'
|
||||
exported_at: '2025-07-25T13:32:25+00:00'
|
||||
name: 'Forge Minecraft'
|
||||
author: panel@example.com
|
||||
uuid: ed072427-f209-4603-875c-f540c6dd5a65
|
||||
description: |-
|
||||
Minecraft Forge Server. Minecraft Forge is a modding API (Application Programming Interface), which
|
||||
makes it easier to create mods, and also make sure mods are compatible with each other.
|
||||
tags:
|
||||
- minecraft
|
||||
features:
|
||||
- eula
|
||||
- java_version
|
||||
- pid_limit
|
||||
docker_images:
|
||||
'Java 21': 'ghcr.io/parkervcp/yolks:java_21'
|
||||
'Java 17': 'ghcr.io/parkervcp/yolks:java_17'
|
||||
'Java 16': 'ghcr.io/parkervcp/yolks:java_16'
|
||||
'Java 11': 'ghcr.io/parkervcp/yolks:java_11'
|
||||
'Java 8': 'ghcr.io/parkervcp/yolks:java_8'
|
||||
file_denylist: { }
|
||||
startup: 'java -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true $( [[ ! -f unix_args.txt ]] && printf %s "-jar {{SERVER_JARFILE}}" || printf %s "@unix_args.txt" )'
|
||||
config:
|
||||
files:
|
||||
server.properties:
|
||||
parser: properties
|
||||
find:
|
||||
server-ip: 0.0.0.0
|
||||
server-port: '{{server.allocations.default.port}}'
|
||||
query.port: '{{server.allocations.default.port}}'
|
||||
startup:
|
||||
done: ')! For help, type '
|
||||
logs: { }
|
||||
stop: stop
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# Forge Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
apt update
|
||||
apt install -y curl jq
|
||||
|
||||
if [[ ! -d /mnt/server ]]; then
|
||||
mkdir /mnt/server
|
||||
fi
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
# Remove spaces from the version number to avoid issues with curl
|
||||
FORGE_VERSION="$(echo "$FORGE_VERSION" | tr -d ' ')"
|
||||
MC_VERSION="$(echo "$MC_VERSION" | tr -d ' ')"
|
||||
|
||||
if [[ ! -z ${FORGE_VERSION} ]]; then
|
||||
DOWNLOAD_LINK=https://maven.minecraftforge.net/net/minecraftforge/forge/${FORGE_VERSION}/forge-${FORGE_VERSION}
|
||||
FORGE_JAR=forge-${FORGE_VERSION}*.jar
|
||||
else
|
||||
JSON_DATA=$(curl -sSL https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json)
|
||||
|
||||
if [[ "${MC_VERSION}" == "latest" ]] || [[ "${MC_VERSION}" == "" ]]; then
|
||||
echo -e "getting latest version of forge."
|
||||
MC_VERSION=$(echo -e ${JSON_DATA} | jq -r '.promos | del(."latest-1.7.10") | del(."1.7.10-latest-1.7.10") | to_entries[] | .key | select(contains("latest")) | split("-")[0]' | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | tail -1)
|
||||
BUILD_TYPE=latest
|
||||
fi
|
||||
|
||||
if [[ "${BUILD_TYPE}" != "recommended" ]] && [[ "${BUILD_TYPE}" != "latest" ]]; then
|
||||
BUILD_TYPE=recommended
|
||||
fi
|
||||
|
||||
echo -e "minecraft version: ${MC_VERSION}"
|
||||
echo -e "build type: ${BUILD_TYPE}"
|
||||
|
||||
## some variables for getting versions and things
|
||||
FILE_SITE=https://maven.minecraftforge.net/net/minecraftforge/forge/
|
||||
VERSION_KEY=$(echo -e ${JSON_DATA} | jq -r --arg MC_VERSION "${MC_VERSION}" --arg BUILD_TYPE "${BUILD_TYPE}" '.promos | del(."latest-1.7.10") | del(."1.7.10-latest-1.7.10") | to_entries[] | .key | select(contains($MC_VERSION)) | select(contains($BUILD_TYPE))')
|
||||
|
||||
## locating the forge version
|
||||
if [[ "${VERSION_KEY}" == "" ]] && [[ "${BUILD_TYPE}" == "recommended" ]]; then
|
||||
echo -e "dropping back to latest from recommended due to there not being a recommended version of forge for the mc version requested."
|
||||
VERSION_KEY=$(echo -e ${JSON_DATA} | jq -r --arg MC_VERSION "${MC_VERSION}" '.promos | del(."latest-1.7.10") | del(."1.7.10-latest-1.7.10") | to_entries[] | .key | select(contains($MC_VERSION)) | select(contains("latest"))')
|
||||
fi
|
||||
|
||||
## Error if the mc version set wasn't valid.
|
||||
if [ "${VERSION_KEY}" == "" ] || [ "${VERSION_KEY}" == "null" ]; then
|
||||
echo -e "The install failed because there is no valid version of forge for the version of minecraft selected."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FORGE_VERSION=$(echo -e ${JSON_DATA} | jq -r --arg VERSION_KEY "$VERSION_KEY" '.promos | .[$VERSION_KEY]')
|
||||
|
||||
if [[ "${MC_VERSION}" == "1.7.10" ]] || [[ "${MC_VERSION}" == "1.8.9" ]]; then
|
||||
DOWNLOAD_LINK=${FILE_SITE}${MC_VERSION}-${FORGE_VERSION}-${MC_VERSION}/forge-${MC_VERSION}-${FORGE_VERSION}-${MC_VERSION}
|
||||
FORGE_JAR=forge-${MC_VERSION}-${FORGE_VERSION}-${MC_VERSION}.jar
|
||||
if [[ "${MC_VERSION}" == "1.7.10" ]]; then
|
||||
FORGE_JAR=forge-${MC_VERSION}-${FORGE_VERSION}-${MC_VERSION}-universal.jar
|
||||
fi
|
||||
else
|
||||
DOWNLOAD_LINK=${FILE_SITE}${MC_VERSION}-${FORGE_VERSION}/forge-${MC_VERSION}-${FORGE_VERSION}
|
||||
FORGE_JAR=forge-${MC_VERSION}-${FORGE_VERSION}.jar
|
||||
fi
|
||||
fi
|
||||
|
||||
#Adding .jar when not eding by SERVER_JARFILE
|
||||
if [[ ! $SERVER_JARFILE = *\.jar ]]; then
|
||||
SERVER_JARFILE="$SERVER_JARFILE.jar"
|
||||
fi
|
||||
|
||||
#Downloading jars
|
||||
echo -e "Downloading forge version ${FORGE_VERSION}"
|
||||
echo -e "Download link is ${DOWNLOAD_LINK}"
|
||||
|
||||
if [[ ! -z "${DOWNLOAD_LINK}" ]]; then
|
||||
if curl --output /dev/null --silent --head --fail ${DOWNLOAD_LINK}-installer.jar; then
|
||||
echo -e "installer jar download link is valid."
|
||||
else
|
||||
echo -e "link is invalid. Exiting now"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
echo -e "no download link provided. Exiting now"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
curl -s -o installer.jar -sS ${DOWNLOAD_LINK}-installer.jar
|
||||
|
||||
#Checking if downloaded jars exist
|
||||
if [[ ! -f ./installer.jar ]]; then
|
||||
echo "!!! Error downloading forge version ${FORGE_VERSION} !!!"
|
||||
exit
|
||||
fi
|
||||
|
||||
function unix_args {
|
||||
echo -e "Detected Forge 1.17 or newer version. Setting up forge unix args."
|
||||
ln -sf libraries/net/minecraftforge/forge/*/unix_args.txt unix_args.txt
|
||||
}
|
||||
|
||||
# Delete args to support downgrading/upgrading
|
||||
rm -rf libraries/net/minecraftforge/forge
|
||||
rm unix_args.txt
|
||||
|
||||
#Installing server
|
||||
echo -e "Installing forge server.
|
||||
"
|
||||
java -jar installer.jar --installServer || { echo -e "
|
||||
Install failed using Forge version ${FORGE_VERSION} and Minecraft version ${MINECRAFT_VERSION}.
|
||||
Should you be using unlimited memory value of 0, make sure to increase the default install resource limits in the Daemon config or specify exact allocated memory in the server Build Configuration instead of 0!
|
||||
Otherwise, the Forge installer will not have enough memory."; exit 4; }
|
||||
|
||||
# Check if we need a symlink for 1.17+ Forge JPMS args
|
||||
if [[ $MC_VERSION =~ ^1\.(17|18|19|20|21|22|23) || $FORGE_VERSION =~ ^1\.(17|18|19|20|21|22|23) ]]; then
|
||||
unix_args
|
||||
|
||||
# Check if someone has set MC to latest but overwrote it with older Forge version, otherwise we would have false positives
|
||||
elif [[ $MC_VERSION == "latest" && $FORGE_VERSION =~ ^1\.(17|18|19|20|21|22|23) ]]; then
|
||||
unix_args
|
||||
else
|
||||
# For versions below 1.17 that ship with jar
|
||||
mv $FORGE_JAR $SERVER_JARFILE
|
||||
fi
|
||||
|
||||
echo -e "Deleting installer.jar file.
|
||||
"
|
||||
rm -rf installer.jar
|
||||
echo -e "Installation process is completed"
|
||||
container: 'openjdk:8-jdk-slim'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: 'Build Type'
|
||||
description: "The type of server jar to download from forge.\r\n\r\nValid types are \"recommended\" and \"latest\"."
|
||||
env_variable: BUILD_TYPE
|
||||
default_value: recommended
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'in:recommended,latest'
|
||||
sort: 3
|
||||
-
|
||||
name: 'Forge Version'
|
||||
description: "The full exact version.\r\n\r\nEx. 1.15.2-31.2.4\r\n\r\nOverrides MC_VERSION and BUILD_TYPE. If it fails to download the server files it will fail to\ninstall."
|
||||
env_variable: FORGE_VERSION
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- 'regex:/^[0-9\.\-]+$/'
|
||||
sort: 4
|
||||
-
|
||||
name: 'Minecraft Version'
|
||||
description: "The version of minecraft you want to install for.\r\n\r\nLeaving latest will install the latest recommended version."
|
||||
env_variable: MC_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:9'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Server Jar File'
|
||||
description: 'The name of the Jarfile to use when running Forge version below 1.17.'
|
||||
env_variable: SERVER_JARFILE
|
||||
default_value: server.jar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^([\w\d._-]+)(\.jar)$/'
|
||||
sort: 1
|
@ -1,98 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/minecraft\/egg-paper.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:35:44+00:00",
|
||||
"name": "Paper",
|
||||
"author": "parker@example.com",
|
||||
"uuid": "5da37ef6-58da-4169-90a6-e683e1721247",
|
||||
"description": "High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies.",
|
||||
"tags": [
|
||||
"minecraft"
|
||||
],
|
||||
"features": [
|
||||
"eula",
|
||||
"java_version",
|
||||
"pid_limit"
|
||||
],
|
||||
"docker_images": {
|
||||
"Java 21": "ghcr.io\/parkervcp\/yolks:java_21",
|
||||
"Java 17": "ghcr.io\/parkervcp\/yolks:java_17",
|
||||
"Java 16": "ghcr.io\/parkervcp\/yolks:java_16",
|
||||
"Java 11": "ghcr.io\/parkervcp\/yolks:java_11",
|
||||
"Java 8": "ghcr.io\/parkervcp\/yolks:java_8"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": "java -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true -jar {{SERVER_JARFILE}}",
|
||||
"config": {
|
||||
"files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"server-port\": \"{{server.allocations.default.port}}\",\r\n \"query.port\": \"{{server.allocations.default.port}}\"\r\n }\r\n }\r\n}",
|
||||
"startup": "{\r\n \"done\": \")! For help, type \"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "stop"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n# Paper Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\nPROJECT=paper\r\n\r\nif [ -n \"${DL_PATH}\" ]; then\r\n\techo -e \"Using supplied download url: ${DL_PATH}\"\r\n\tDOWNLOAD_URL=`eval echo $(echo ${DL_PATH} | sed -e 's\/{{\/${\/g' -e 's\/}}\/}\/g')`\r\nelse\r\n\tVER_EXISTS=`curl -s https:\/\/api.papermc.io\/v2\/projects\/${PROJECT} | jq -r --arg VERSION $MINECRAFT_VERSION '.versions[] | contains($VERSION)' | grep -m1 true`\r\n\tLATEST_VERSION=`curl -s https:\/\/api.papermc.io\/v2\/projects\/${PROJECT} | jq -r '.versions' | jq -r '.[-1]'`\r\n\r\n\tif [ \"${VER_EXISTS}\" == \"true\" ]; then\r\n\t\techo -e \"Version is valid. Using version ${MINECRAFT_VERSION}\"\r\n\telse\r\n\t\techo -e \"Specified version not found. Defaulting to the latest ${PROJECT} version\"\r\n\t\tMINECRAFT_VERSION=${LATEST_VERSION}\r\n\tfi\r\n\r\n\tBUILD_EXISTS=`curl -s https:\/\/api.papermc.io\/v2\/projects\/${PROJECT}\/versions\/${MINECRAFT_VERSION} | jq -r --arg BUILD ${BUILD_NUMBER} '.builds[] | tostring | contains($BUILD)' | grep -m1 true`\r\n\tLATEST_BUILD=`curl -s https:\/\/api.papermc.io\/v2\/projects\/${PROJECT}\/versions\/${MINECRAFT_VERSION} | jq -r '.builds' | jq -r '.[-1]'`\r\n\r\n\tif [ \"${BUILD_EXISTS}\" == \"true\" ]; then\r\n\t\techo -e \"Build is valid for version ${MINECRAFT_VERSION}. Using build ${BUILD_NUMBER}\"\r\n\telse\r\n\t\techo -e \"Using the latest ${PROJECT} build for version ${MINECRAFT_VERSION}\"\r\n\t\tBUILD_NUMBER=${LATEST_BUILD}\r\n\tfi\r\n\r\n\tJAR_NAME=${PROJECT}-${MINECRAFT_VERSION}-${BUILD_NUMBER}.jar\r\n\r\n\techo \"Version being downloaded\"\r\n\techo -e \"MC Version: ${MINECRAFT_VERSION}\"\r\n\techo -e \"Build: ${BUILD_NUMBER}\"\r\n\techo -e \"JAR Name of Build: ${JAR_NAME}\"\r\n\tDOWNLOAD_URL=https:\/\/api.papermc.io\/v2\/projects\/${PROJECT}\/versions\/${MINECRAFT_VERSION}\/builds\/${BUILD_NUMBER}\/downloads\/${JAR_NAME}\r\nfi\r\n\r\ncd \/mnt\/server\r\n\r\necho -e \"Running curl -o ${SERVER_JARFILE} ${DOWNLOAD_URL}\"\r\n\r\nif [ -f ${SERVER_JARFILE} ]; then\r\n\tmv ${SERVER_JARFILE} ${SERVER_JARFILE}.old\r\nfi\r\n\r\ncurl -o ${SERVER_JARFILE} ${DOWNLOAD_URL}\r\n\r\nif [ ! -f server.properties ]; then\r\n echo -e \"Downloading MC server.properties\"\r\n curl -o server.properties https:\/\/raw.githubusercontent.com\/parkervcp\/eggs\/master\/minecraft\/java\/server.properties\r\nfi",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Minecraft Version",
|
||||
"description": "The version of minecraft to download. \r\n\r\nLeave at latest to always get the latest version. Invalid versions will default to latest.",
|
||||
"env_variable": "MINECRAFT_VERSION",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string",
|
||||
"max:20"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Server Jar File",
|
||||
"description": "The name of the server jarfile to run the server with.",
|
||||
"env_variable": "SERVER_JARFILE",
|
||||
"default_value": "server.jar",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^([\\w\\d._-]+)(\\.jar)$\/"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Download Path",
|
||||
"description": "A URL to use to download a server.jar rather than the ones in the install script. This is not user viewable.",
|
||||
"env_variable": "DL_PATH",
|
||||
"default_value": "",
|
||||
"user_viewable": false,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 3
|
||||
},
|
||||
{
|
||||
"name": "Build Number",
|
||||
"description": "The build number for the paper release.\r\n\r\nLeave at latest to always get the latest version. Invalid versions will default to latest.",
|
||||
"env_variable": "BUILD_NUMBER",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:20"
|
||||
],
|
||||
"sort": 4
|
||||
}
|
||||
]
|
||||
}
|
142
database/Seeders/eggs/minecraft/egg-paper.yaml
Normal file
142
database/Seeders/eggs/minecraft/egg-paper.yaml
Normal file
@ -0,0 +1,142 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/minecraft/egg-paper.yaml'
|
||||
exported_at: '2025-07-25T13:30:10+00:00'
|
||||
name: Paper
|
||||
author: parker@example.com
|
||||
uuid: 5da37ef6-58da-4169-90a6-e683e1721247
|
||||
description: 'High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies.'
|
||||
tags:
|
||||
- minecraft
|
||||
features:
|
||||
- eula
|
||||
- java_version
|
||||
- pid_limit
|
||||
docker_images:
|
||||
'Java 21': 'ghcr.io/parkervcp/yolks:java_21'
|
||||
'Java 17': 'ghcr.io/parkervcp/yolks:java_17'
|
||||
'Java 16': 'ghcr.io/parkervcp/yolks:java_16'
|
||||
'Java 11': 'ghcr.io/parkervcp/yolks:java_11'
|
||||
'Java 8': 'ghcr.io/parkervcp/yolks:java_8'
|
||||
file_denylist: { }
|
||||
startup: 'java -Xms128M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true -jar {{SERVER_JARFILE}}'
|
||||
config:
|
||||
files:
|
||||
server.properties:
|
||||
parser: properties
|
||||
find:
|
||||
server-ip: 0.0.0.0
|
||||
server-port: '{{server.allocations.default.port}}'
|
||||
query.port: '{{server.allocations.default.port}}'
|
||||
startup:
|
||||
done: ')! For help, type '
|
||||
logs: { }
|
||||
stop: stop
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
# Paper Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
PROJECT=paper
|
||||
|
||||
if [ -n "${DL_PATH}" ]; then
|
||||
echo -e "Using supplied download url: ${DL_PATH}"
|
||||
DOWNLOAD_URL=`eval echo $(echo ${DL_PATH} | sed -e 's/{{/${/g' -e 's/}}/}/g')`
|
||||
else
|
||||
VER_EXISTS=`curl -s https://api.papermc.io/v2/projects/${PROJECT} | jq -r --arg VERSION $MINECRAFT_VERSION '.versions[] | contains($VERSION)' | grep -m1 true`
|
||||
LATEST_VERSION=`curl -s https://api.papermc.io/v2/projects/${PROJECT} | jq -r '.versions' | jq -r '.[-1]'`
|
||||
|
||||
if [ "${VER_EXISTS}" == "true" ]; then
|
||||
echo -e "Version is valid. Using version ${MINECRAFT_VERSION}"
|
||||
else
|
||||
echo -e "Specified version not found. Defaulting to the latest ${PROJECT} version"
|
||||
MINECRAFT_VERSION=${LATEST_VERSION}
|
||||
fi
|
||||
|
||||
BUILD_EXISTS=`curl -s https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION} | jq -r --arg BUILD ${BUILD_NUMBER} '.builds[] | tostring | contains($BUILD)' | grep -m1 true`
|
||||
LATEST_BUILD=`curl -s https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION} | jq -r '.builds' | jq -r '.[-1]'`
|
||||
|
||||
if [ "${BUILD_EXISTS}" == "true" ]; then
|
||||
echo -e "Build is valid for version ${MINECRAFT_VERSION}. Using build ${BUILD_NUMBER}"
|
||||
else
|
||||
echo -e "Using the latest ${PROJECT} build for version ${MINECRAFT_VERSION}"
|
||||
BUILD_NUMBER=${LATEST_BUILD}
|
||||
fi
|
||||
|
||||
JAR_NAME=${PROJECT}-${MINECRAFT_VERSION}-${BUILD_NUMBER}.jar
|
||||
|
||||
echo "Version being downloaded"
|
||||
echo -e "MC Version: ${MINECRAFT_VERSION}"
|
||||
echo -e "Build: ${BUILD_NUMBER}"
|
||||
echo -e "JAR Name of Build: ${JAR_NAME}"
|
||||
DOWNLOAD_URL=https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds/${BUILD_NUMBER}/downloads/${JAR_NAME}
|
||||
fi
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
echo -e "Running curl -o ${SERVER_JARFILE} ${DOWNLOAD_URL}"
|
||||
|
||||
if [ -f ${SERVER_JARFILE} ]; then
|
||||
mv ${SERVER_JARFILE} ${SERVER_JARFILE}.old
|
||||
fi
|
||||
|
||||
curl -o ${SERVER_JARFILE} ${DOWNLOAD_URL}
|
||||
|
||||
if [ ! -f server.properties ]; then
|
||||
echo -e "Downloading MC server.properties"
|
||||
curl -o server.properties https://raw.githubusercontent.com/parkervcp/eggs/master/minecraft/java/server.properties
|
||||
fi
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'Build Number'
|
||||
description: "The build number for the paper release.\r\n\r\nLeave at latest to always get the latest version. Invalid versions will default to latest."
|
||||
env_variable: BUILD_NUMBER
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:20'
|
||||
sort: 4
|
||||
-
|
||||
name: 'Download Path'
|
||||
description: |-
|
||||
A URL to use to download a server.jar rather than the ones in the install script. This is not user
|
||||
viewable.
|
||||
env_variable: DL_PATH
|
||||
default_value: ''
|
||||
user_viewable: false
|
||||
user_editable: false
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 3
|
||||
-
|
||||
name: 'Minecraft Version'
|
||||
description: "The version of minecraft to download. \r\n\r\nLeave at latest to always get the latest version. Invalid versions will default to latest."
|
||||
env_variable: MINECRAFT_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
- 'max:20'
|
||||
sort: 1
|
||||
-
|
||||
name: 'Server Jar File'
|
||||
description: 'The name of the server jarfile to run the server with.'
|
||||
env_variable: SERVER_JARFILE
|
||||
default_value: server.jar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^([\w\d._-]+)(\.jar)$/'
|
||||
sort: 2
|
@ -1,96 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/minecraft\/egg-sponge--sponge-vanilla.json"
|
||||
},
|
||||
"exported_at": "2025-04-25T06:05:10+00:00",
|
||||
"name": "Sponge",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "f0d2f88f-1ff3-42a0-b03f-ac44c5571e6d",
|
||||
"description": "A community-driven open source Minecraft: Java Edition modding platform.",
|
||||
"tags": [
|
||||
"minecraft"
|
||||
],
|
||||
"features": [
|
||||
"eula",
|
||||
"java_version",
|
||||
"pid_limit"
|
||||
],
|
||||
"docker_images": {
|
||||
"Java 21": "ghcr.io\/parkervcp\/yolks:java_21",
|
||||
"Java 17": "ghcr.io\/parkervcp\/yolks:java_17",
|
||||
"Java 16": "ghcr.io\/parkervcp\/yolks:java_16",
|
||||
"Java 11": "ghcr.io\/parkervcp\/yolks:java_11",
|
||||
"Java 8": "ghcr.io\/parkervcp\/yolks:java_8"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": "java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}",
|
||||
"config": {
|
||||
"files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"server-port\": \"{{server.allocations.default.port}}\",\r\n \"query.port\": \"{{server.allocations.default.port}}\"\r\n }\r\n }\r\n}",
|
||||
"startup": "{\r\n \"done\": \")! For help, type \"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "stop"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n# Sponge Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\ncd \/mnt\/server\r\n\r\nif [ $MINECRAFT_VERSION = 'latest' ] || [ -z $MINECRAFT_VERSION ]; then\r\n TARGET_VERSION_JSON=$(curl -sSL https:\/\/dl-api.spongepowered.org\/v2\/groups\/org.spongepowered\/artifacts\/${SPONGE_TYPE}\/latest?recommended=true)\r\n if [ -z \"${TARGET_VERSION_JSON}\" ]; then\r\n echo -e \"Failed to find latest recommended version!\"\r\n exit 1\r\n fi\r\n echo -e \"Found latest version for ${SPONGE_TYPE}\"\r\nelse\r\n if [ $SPONGE_TYPE = 'spongevanilla' ]; then \r\n VERSIONS_JSON=$(curl -sSL https:\/\/dl-api.spongepowered.org\/v2\/groups\/org.spongepowered\/artifacts\/${SPONGE_TYPE}\/versions?tags=,minecraft:${MINECRAFT_VERSION}&offset=0&limit=1)\r\n else\r\n FORGETAG='forge'\r\n if [ $SPONGE_TYPE = 'spongeneo' ]; then\r\n FORGETAG='neoforge'\r\n fi\r\n VERSIONS_JSON=$(curl -sSL https:\/\/dl-api.spongepowered.org\/v2\/groups\/org.spongepowered\/artifacts\/${SPONGE_TYPE}\/versions?tags=,minecraft:${MINECRAFT_VERSION},${FORGETAG}:${FORGE_VERSION}&offset=0&limit=1)\r\n fi\r\n \r\n if [ -z \"${VERSIONS_JSON}\" ]; then\r\n echo -e \"Failed to find recommended ${MINECRAFT_VERSION} version for ${SPONGE_TYPE} ${FORGE_VERSION}!\"\r\n exit 1\r\n fi\r\n \r\n VERSION_KEY=$(echo $VERSIONS_JSON | jq -r '.artifacts | to_entries[0].key')\r\n TARGET_VERSION_JSON=$(curl -sSL https:\/\/dl-api.spongepowered.org\/v2\/groups\/org.spongepowered\/artifacts\/${SPONGE_TYPE}\/versions\/${VERSION_KEY})\r\n \r\n if [ -z \"${TARGET_VERSION_JSON}\" ]; then\r\n echo -e \"Failed to find ${VERSION_KEY} for ${SPONGE_TYPE} ${FORGE_VERSION}!\"\r\n exit 1\r\n fi\r\n\r\n echo -e \"Found ${MINECRAFT_VERSION} for ${SPONGE_TYPE}\"\r\nfi\r\n\r\nTARGET_VERSION=`echo $TARGET_VERSION_JSON | jq '.assets[] | select(.classifier == \"universal\")'`\r\nif [ -z \"${TARGET_VERSION}\" ]; then\r\n TARGET_VERSION=`echo $TARGET_VERSION_JSON | jq '.assets[] | select(.classifier == \"\" and .extension == \"jar\")'`\r\nfi\r\n\r\nif [ -z \"${TARGET_VERSION}\" ]; then\r\n echo -e \"Failed to get download url data from the selected version\"\r\n exit 1\r\nfi\r\n\r\nSPONGE_URL=$(echo $TARGET_VERSION | jq -r '.downloadUrl')\r\nCHECKSUM=$(echo $TARGET_VERSION | jq -r '.md5')\r\necho -e \"Found file at ${SPONGE_URL} with checksum ${CHECKSUM}\"\r\n\r\necho -e \"running: curl -o ${SERVER_JARFILE} ${SPONGE_URL}\"\r\ncurl -o ${SERVER_JARFILE} ${SPONGE_URL}\r\n\r\nif [ $(basename $(md5sum ${SERVER_JARFILE})) = ${CHECKSUM} ] ; then\r\n echo \"Checksum passed\"\r\nelse\r\n echo \"Checksum failed\"\r\nfi\r\n\r\necho -e \"Install Complete\"",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"sort": 3,
|
||||
"name": "Forge\/Neoforge Version",
|
||||
"description": "The modding api target version if set to `spongeforge` or `spongeneo`. Leave blank if using `spongevanilla`",
|
||||
"env_variable": "FORGE_VERSION",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sort": 1,
|
||||
"name": "Minecraft Version",
|
||||
"description": "The version of Minecraft to target. Use \"latest\" to install the latest version. Go to Settings > Reinstall Server to apply.",
|
||||
"env_variable": "MINECRAFT_VERSION",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"between:3,15"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sort": 4,
|
||||
"name": "Server Jar File",
|
||||
"description": "The name of the Jarfile to use when running Sponge.",
|
||||
"env_variable": "SERVER_JARFILE",
|
||||
"default_value": "server.jar",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^([\\w\\d._-]+)(\\.jar)$\/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sort": 2,
|
||||
"name": "Sponge Type",
|
||||
"description": "SpongeVanilla if you are only using Sponge plugins.\nSpongeForge when using Forge mods and Sponge plugins.\nSpongeNeo when using NeoForge mods and Sponge plugins.",
|
||||
"env_variable": "SPONGE_TYPE",
|
||||
"default_value": "spongevanilla",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"in:spongevanilla,spongeforge,spongeneo"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
157
database/Seeders/eggs/minecraft/egg-sponge.yaml
Normal file
157
database/Seeders/eggs/minecraft/egg-sponge.yaml
Normal file
@ -0,0 +1,157 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.yaml'
|
||||
exported_at: '2025-07-25T13:30:14+00:00'
|
||||
name: Sponge
|
||||
author: panel@example.com
|
||||
uuid: f0d2f88f-1ff3-42a0-b03f-ac44c5571e6d
|
||||
description: 'A community-driven open source Minecraft: Java Edition modding platform.'
|
||||
tags:
|
||||
- minecraft
|
||||
features:
|
||||
- eula
|
||||
- java_version
|
||||
- pid_limit
|
||||
docker_images:
|
||||
'Java 21': 'ghcr.io/parkervcp/yolks:java_21'
|
||||
'Java 17': 'ghcr.io/parkervcp/yolks:java_17'
|
||||
'Java 16': 'ghcr.io/parkervcp/yolks:java_16'
|
||||
'Java 11': 'ghcr.io/parkervcp/yolks:java_11'
|
||||
'Java 8': 'ghcr.io/parkervcp/yolks:java_8'
|
||||
file_denylist: { }
|
||||
startup: 'java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}'
|
||||
config:
|
||||
files:
|
||||
server.properties:
|
||||
parser: properties
|
||||
find:
|
||||
server-ip: 0.0.0.0
|
||||
server-port: '{{server.allocations.default.port}}'
|
||||
query.port: '{{server.allocations.default.port}}'
|
||||
startup:
|
||||
done: ')! For help, type '
|
||||
logs: { }
|
||||
stop: stop
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
# Sponge Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
if [ $MINECRAFT_VERSION = 'latest' ] || [ -z $MINECRAFT_VERSION ]; then
|
||||
TARGET_VERSION_JSON=$(curl -sSL https://dl-api.spongepowered.org/v2/groups/org.spongepowered/artifacts/${SPONGE_TYPE}/latest?recommended=true)
|
||||
if [ -z "${TARGET_VERSION_JSON}" ]; then
|
||||
echo -e "Failed to find latest recommended version!"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "Found latest version for ${SPONGE_TYPE}"
|
||||
else
|
||||
if [ $SPONGE_TYPE = 'spongevanilla' ]; then
|
||||
VERSIONS_JSON=$(curl -sSL https://dl-api.spongepowered.org/v2/groups/org.spongepowered/artifacts/${SPONGE_TYPE}/versions?tags=,minecraft:${MINECRAFT_VERSION}&offset=0&limit=1)
|
||||
else
|
||||
FORGETAG='forge'
|
||||
if [ $SPONGE_TYPE = 'spongeneo' ]; then
|
||||
FORGETAG='neoforge'
|
||||
fi
|
||||
VERSIONS_JSON=$(curl -sSL https://dl-api.spongepowered.org/v2/groups/org.spongepowered/artifacts/${SPONGE_TYPE}/versions?tags=,minecraft:${MINECRAFT_VERSION},${FORGETAG}:${FORGE_VERSION}&offset=0&limit=1)
|
||||
fi
|
||||
|
||||
if [ -z "${VERSIONS_JSON}" ]; then
|
||||
echo -e "Failed to find recommended ${MINECRAFT_VERSION} version for ${SPONGE_TYPE} ${FORGE_VERSION}!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION_KEY=$(echo $VERSIONS_JSON | jq -r '.artifacts | to_entries[0].key')
|
||||
TARGET_VERSION_JSON=$(curl -sSL https://dl-api.spongepowered.org/v2/groups/org.spongepowered/artifacts/${SPONGE_TYPE}/versions/${VERSION_KEY})
|
||||
|
||||
if [ -z "${TARGET_VERSION_JSON}" ]; then
|
||||
echo -e "Failed to find ${VERSION_KEY} for ${SPONGE_TYPE} ${FORGE_VERSION}!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "Found ${MINECRAFT_VERSION} for ${SPONGE_TYPE}"
|
||||
fi
|
||||
|
||||
TARGET_VERSION=`echo $TARGET_VERSION_JSON | jq '.assets[] | select(.classifier == "universal")'`
|
||||
if [ -z "${TARGET_VERSION}" ]; then
|
||||
TARGET_VERSION=`echo $TARGET_VERSION_JSON | jq '.assets[] | select(.classifier == "" and .extension == "jar")'`
|
||||
fi
|
||||
|
||||
if [ -z "${TARGET_VERSION}" ]; then
|
||||
echo -e "Failed to get download url data from the selected version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SPONGE_URL=$(echo $TARGET_VERSION | jq -r '.downloadUrl')
|
||||
CHECKSUM=$(echo $TARGET_VERSION | jq -r '.md5')
|
||||
echo -e "Found file at ${SPONGE_URL} with checksum ${CHECKSUM}"
|
||||
|
||||
echo -e "running: curl -o ${SERVER_JARFILE} ${SPONGE_URL}"
|
||||
curl -o ${SERVER_JARFILE} ${SPONGE_URL}
|
||||
|
||||
if [ $(basename $(md5sum ${SERVER_JARFILE})) = ${CHECKSUM} ] ; then
|
||||
echo "Checksum passed"
|
||||
else
|
||||
echo "Checksum failed"
|
||||
fi
|
||||
|
||||
echo -e "Install Complete"
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'Forge/Neoforge Version'
|
||||
description: |-
|
||||
The modding api target version if set to `spongeforge` or `spongeneo`. Leave blank if using
|
||||
`spongevanilla`
|
||||
env_variable: FORGE_VERSION
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- string
|
||||
sort: 3
|
||||
-
|
||||
name: 'Minecraft Version'
|
||||
description: |-
|
||||
The version of Minecraft to target. Use "latest" to install the latest version. Go to Settings >
|
||||
Reinstall Server to apply.
|
||||
env_variable: MINECRAFT_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'between:3,15'
|
||||
sort: 1
|
||||
-
|
||||
name: 'Server Jar File'
|
||||
description: 'The name of the Jarfile to use when running Sponge.'
|
||||
env_variable: SERVER_JARFILE
|
||||
default_value: server.jar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^([\w\d._-]+)(\.jar)$/'
|
||||
sort: 4
|
||||
-
|
||||
name: 'Sponge Type'
|
||||
description: |-
|
||||
SpongeVanilla if you are only using Sponge plugins.
|
||||
SpongeForge when using Forge mods and Sponge plugins.
|
||||
SpongeNeo when using NeoForge mods and Sponge plugins.
|
||||
env_variable: SPONGE_TYPE
|
||||
default_value: spongevanilla
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'in:spongevanilla,spongeforge,spongeneo'
|
||||
sort: 2
|
@ -1,71 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/minecraft\/egg-vanilla-minecraft.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:35:55+00:00",
|
||||
"name": "Vanilla Minecraft",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "9ac39f3d-0c34-4d93-8174-c52ab9e6c57b",
|
||||
"description": "Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds and build amazing things from the simplest of homes to the grandest of castles. Play in Creative Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off dangerous mobs. Do all this alone or with friends.",
|
||||
"tags": [
|
||||
"minecraft"
|
||||
],
|
||||
"features": [
|
||||
"eula",
|
||||
"java_version",
|
||||
"pid_limit"
|
||||
],
|
||||
"docker_images": {
|
||||
"Java 21": "ghcr.io\/parkervcp\/yolks:java_21",
|
||||
"Java 17": "ghcr.io\/parkervcp\/yolks:java_17",
|
||||
"Java 16": "ghcr.io\/parkervcp\/yolks:java_16",
|
||||
"Java 11": "ghcr.io\/parkervcp\/yolks:java_11",
|
||||
"Java 8": "ghcr.io\/parkervcp\/yolks:java_8"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": "java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}",
|
||||
"config": {
|
||||
"files": "{\r\n \"server.properties\": {\r\n \"parser\": \"properties\",\r\n \"find\": {\r\n \"server-ip\": \"0.0.0.0\",\r\n \"server-port\": \"{{server.allocations.default.port}}\",\r\n \"query.port\": \"{{server.allocations.default.port}}\"\r\n }\r\n }\r\n}",
|
||||
"startup": "{\r\n \"done\": \")! For help, type \"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "stop"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n# Vanilla MC Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\nmkdir -p \/mnt\/server\r\ncd \/mnt\/server\r\n\r\nLATEST_VERSION=`curl https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq -r '.latest.release'`\r\nLATEST_SNAPSHOT_VERSION=`curl https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq -r '.latest.snapshot'`\r\n\r\necho -e \"latest version is $LATEST_VERSION\"\r\necho -e \"latest snapshot is $LATEST_SNAPSHOT_VERSION\"\r\n\r\nif [ -z \"$VANILLA_VERSION\" ] || [ \"$VANILLA_VERSION\" == \"latest\" ]; then\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $LATEST_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nelif [ \"$VANILLA_VERSION\" == \"snapshot\" ]; then\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $LATEST_SNAPSHOT_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nelse\r\n MANIFEST_URL=$(curl -sSL https:\/\/launchermeta.mojang.com\/mc\/game\/version_manifest.json | jq --arg VERSION $VANILLA_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')\r\nfi\r\n\r\nDOWNLOAD_URL=$(curl ${MANIFEST_URL} | jq .downloads.server | jq -r '. | .url')\r\n\r\necho -e \"running: curl -o ${SERVER_JARFILE} $DOWNLOAD_URL\"\r\ncurl -o ${SERVER_JARFILE} $DOWNLOAD_URL\r\n\r\necho -e \"Install Complete\"",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Server Jar File",
|
||||
"description": "The name of the server jarfile to run the server with.",
|
||||
"env_variable": "SERVER_JARFILE",
|
||||
"default_value": "server.jar",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^([\\w\\d._-]+)(\\.jar)$\/"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Server Version",
|
||||
"description": "The version of Minecraft Vanilla to install. Use \"latest\" to install the latest version, or use \"snapshot\" to install the latest snapshot. Go to Settings > Reinstall Server to apply.",
|
||||
"env_variable": "VANILLA_VERSION",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"between:3,15"
|
||||
],
|
||||
"sort": 2
|
||||
}
|
||||
]
|
||||
}
|
97
database/Seeders/eggs/minecraft/egg-vanilla-minecraft.yaml
Normal file
97
database/Seeders/eggs/minecraft/egg-vanilla-minecraft.yaml
Normal file
@ -0,0 +1,97 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/minecraft/egg-vanilla-minecraft.yaml'
|
||||
exported_at: '2025-07-25T13:32:13+00:00'
|
||||
name: 'Vanilla Minecraft'
|
||||
author: panel@example.com
|
||||
uuid: 9ac39f3d-0c34-4d93-8174-c52ab9e6c57b
|
||||
description: |-
|
||||
Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds
|
||||
and build amazing things from the simplest of homes to the grandest of castles. Play in Creative
|
||||
Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off
|
||||
dangerous mobs. Do all this alone or with friends.
|
||||
tags:
|
||||
- minecraft
|
||||
features:
|
||||
- eula
|
||||
- java_version
|
||||
- pid_limit
|
||||
docker_images:
|
||||
'Java 21': 'ghcr.io/parkervcp/yolks:java_21'
|
||||
'Java 17': 'ghcr.io/parkervcp/yolks:java_17'
|
||||
'Java 16': 'ghcr.io/parkervcp/yolks:java_16'
|
||||
'Java 11': 'ghcr.io/parkervcp/yolks:java_11'
|
||||
'Java 8': 'ghcr.io/parkervcp/yolks:java_8'
|
||||
file_denylist: { }
|
||||
startup: 'java -Xms128M -XX:MaxRAMPercentage=95.0 -jar {{SERVER_JARFILE}}'
|
||||
config:
|
||||
files:
|
||||
server.properties:
|
||||
parser: properties
|
||||
find:
|
||||
server-ip: 0.0.0.0
|
||||
server-port: '{{server.allocations.default.port}}'
|
||||
query.port: '{{server.allocations.default.port}}'
|
||||
startup:
|
||||
done: ')! For help, type '
|
||||
logs: { }
|
||||
stop: stop
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
# Vanilla MC Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
mkdir -p /mnt/server
|
||||
cd /mnt/server
|
||||
|
||||
LATEST_VERSION=`curl https://launchermeta.mojang.com/mc/game/version_manifest.json | jq -r '.latest.release'`
|
||||
LATEST_SNAPSHOT_VERSION=`curl https://launchermeta.mojang.com/mc/game/version_manifest.json | jq -r '.latest.snapshot'`
|
||||
|
||||
echo -e "latest version is $LATEST_VERSION"
|
||||
echo -e "latest snapshot is $LATEST_SNAPSHOT_VERSION"
|
||||
|
||||
if [ -z "$VANILLA_VERSION" ] || [ "$VANILLA_VERSION" == "latest" ]; then
|
||||
MANIFEST_URL=$(curl -sSL https://launchermeta.mojang.com/mc/game/version_manifest.json | jq --arg VERSION $LATEST_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')
|
||||
elif [ "$VANILLA_VERSION" == "snapshot" ]; then
|
||||
MANIFEST_URL=$(curl -sSL https://launchermeta.mojang.com/mc/game/version_manifest.json | jq --arg VERSION $LATEST_SNAPSHOT_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')
|
||||
else
|
||||
MANIFEST_URL=$(curl -sSL https://launchermeta.mojang.com/mc/game/version_manifest.json | jq --arg VERSION $VANILLA_VERSION -r '.versions | .[] | select(.id== $VERSION )|.url')
|
||||
fi
|
||||
|
||||
DOWNLOAD_URL=$(curl ${MANIFEST_URL} | jq .downloads.server | jq -r '. | .url')
|
||||
|
||||
echo -e "running: curl -o ${SERVER_JARFILE} $DOWNLOAD_URL"
|
||||
curl -o ${SERVER_JARFILE} $DOWNLOAD_URL
|
||||
|
||||
echo -e "Install Complete"
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'Server Jar File'
|
||||
description: 'The name of the server jarfile to run the server with.'
|
||||
env_variable: SERVER_JARFILE
|
||||
default_value: server.jar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^([\w\d._-]+)(\.jar)$/'
|
||||
sort: 1
|
||||
-
|
||||
name: 'Server Version'
|
||||
description: |-
|
||||
The version of Minecraft Vanilla to install. Use "latest" to install the latest version, or use
|
||||
"snapshot" to install the latest snapshot. Go to Settings > Reinstall Server to apply.
|
||||
env_variable: VANILLA_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'between:3,15'
|
||||
sort: 2
|
@ -1,277 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/rust\/egg-rust.json"
|
||||
},
|
||||
"exported_at": "2025-06-06T11:57:17+00:00",
|
||||
"name": "Rust",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "bace2dfb-209c-452a-9459-7d6f340b07ae",
|
||||
"description": "The only aim in Rust is to survive. To do this you will need to overcome struggles such as hunger, thirst and cold. Build a fire. Build a shelter. Kill animals for meat. Protect yourself from other players, and kill them for meat. Create alliances with other players and form a town. Do whatever it takes to survive.",
|
||||
"tags": [
|
||||
"source",
|
||||
"steamcmd"
|
||||
],
|
||||
"features": [
|
||||
"steam_disk_space"
|
||||
],
|
||||
"docker_images": {
|
||||
"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 \\\"{{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}",
|
||||
"logs": "{}",
|
||||
"stop": "quit"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +force_install_dir \/mnt\/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so",
|
||||
"container": "ghcr.io\/parkervcp\/installers:debian",
|
||||
"entrypoint": "bash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Server Name",
|
||||
"description": "The name of your server in the public server list.",
|
||||
"env_variable": "SERVER_HOSTNAME",
|
||||
"default_value": "A Rust Server",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:60"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Modding Framework",
|
||||
"description": "The modding framework to be used: carbon, oxide, vanilla.\r\nDefaults to \"vanilla\" for a non-modded server installation.",
|
||||
"env_variable": "FRAMEWORK",
|
||||
"default_value": "vanilla",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"in:vanilla,oxide,carbon"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Level",
|
||||
"description": "The world file for Rust to use.",
|
||||
"env_variable": "LEVEL",
|
||||
"default_value": "Procedural Map",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:20"
|
||||
],
|
||||
"sort": 3
|
||||
},
|
||||
{
|
||||
"name": "Description",
|
||||
"description": "The description under your server title. Commonly used for rules & info. Use \\n for newlines.",
|
||||
"env_variable": "DESCRIPTION",
|
||||
"default_value": "Powered by Panel",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string"
|
||||
],
|
||||
"sort": 4
|
||||
},
|
||||
{
|
||||
"name": "URL",
|
||||
"description": "The URL for your server. This is what comes up when clicking the \"Visit Website\" button.",
|
||||
"env_variable": "SERVER_URL",
|
||||
"default_value": "http:\/\/example.com",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"url"
|
||||
],
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "World Size",
|
||||
"description": "The world size for a procedural map.",
|
||||
"env_variable": "WORLD_SIZE",
|
||||
"default_value": "3000",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 6
|
||||
},
|
||||
{
|
||||
"name": "World Seed",
|
||||
"description": "The seed for a procedural map.",
|
||||
"env_variable": "WORLD_SEED",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 7
|
||||
},
|
||||
{
|
||||
"name": "Max Players",
|
||||
"description": "The maximum amount of players allowed in the server at once.",
|
||||
"env_variable": "MAX_PLAYERS",
|
||||
"default_value": "40",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 8
|
||||
},
|
||||
{
|
||||
"name": "Server Image",
|
||||
"description": "The header image for the top of your server listing.",
|
||||
"env_variable": "SERVER_IMG",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"url"
|
||||
],
|
||||
"sort": 9
|
||||
},
|
||||
{
|
||||
"name": "Query Port",
|
||||
"description": "Server Query Port. Can't be the same as Game's primary port.",
|
||||
"env_variable": "QUERY_PORT",
|
||||
"default_value": "27017",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 10
|
||||
},
|
||||
{
|
||||
"name": "RCON Port",
|
||||
"description": "Port for RCON connections.",
|
||||
"env_variable": "RCON_PORT",
|
||||
"default_value": "28016",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 11
|
||||
},
|
||||
{
|
||||
"name": "RCON Password",
|
||||
"description": "RCON access password.",
|
||||
"env_variable": "RCON_PASS",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^[\\w.-]*$\/",
|
||||
"max:64"
|
||||
],
|
||||
"sort": 12
|
||||
},
|
||||
{
|
||||
"name": "Save Interval",
|
||||
"description": "Sets the server\u2019s auto-save interval in seconds.",
|
||||
"env_variable": "SAVEINTERVAL",
|
||||
"default_value": "60",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 13
|
||||
},
|
||||
{
|
||||
"name": "Additional Arguments",
|
||||
"description": "Add additional startup parameters to the server.",
|
||||
"env_variable": "ADDITIONAL_ARGS",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 14
|
||||
},
|
||||
{
|
||||
"name": "App Port",
|
||||
"description": "Port for the Rust+ App. -1 to disable.",
|
||||
"env_variable": "APP_PORT",
|
||||
"default_value": "28082",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer"
|
||||
],
|
||||
"sort": 15
|
||||
},
|
||||
{
|
||||
"name": "Server Logo",
|
||||
"description": "The circular server logo for the Rust+ app.",
|
||||
"env_variable": "SERVER_LOGO",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"url"
|
||||
],
|
||||
"sort": 16
|
||||
},
|
||||
{
|
||||
"name": "Custom Map URL",
|
||||
"description": "Overwrites the map with the one from the direct download URL. Invalid URLs will cause the server to crash.",
|
||||
"env_variable": "MAP_URL",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"url"
|
||||
],
|
||||
"sort": 17
|
||||
},
|
||||
{
|
||||
"name": "App ID",
|
||||
"description": "",
|
||||
"env_variable": "SRCDS_APPID",
|
||||
"default_value": "258550",
|
||||
"user_viewable": false,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"in:258550"
|
||||
],
|
||||
"sort": 18
|
||||
}
|
||||
]
|
||||
}
|
280
database/Seeders/eggs/rust/egg-rust.yaml
Normal file
280
database/Seeders/eggs/rust/egg-rust.yaml
Normal file
@ -0,0 +1,280 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/rust/egg-rust.yaml'
|
||||
exported_at: '2025-07-25T13:30:56+00:00'
|
||||
name: Rust
|
||||
author: panel@example.com
|
||||
uuid: bace2dfb-209c-452a-9459-7d6f340b07ae
|
||||
description: |-
|
||||
The only aim in Rust is to survive. To do this you will need to overcome struggles such as hunger,
|
||||
thirst and cold. Build a fire. Build a shelter. Kill animals for meat. Protect yourself from other
|
||||
players, and kill them for meat. Create alliances with other players and form a town. Do whatever it
|
||||
takes to survive.
|
||||
tags:
|
||||
- source
|
||||
- steamcmd
|
||||
features:
|
||||
- steam_disk_space
|
||||
docker_images:
|
||||
'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 \"{{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:
|
||||
done: 'Server startup complete'
|
||||
logs: { }
|
||||
stop: quit
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# steamcmd Base Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
|
||||
## just in case someone removed the defaults.
|
||||
if [ "${STEAM_USER}" == "" ]; then
|
||||
echo -e "steam user is not set.
|
||||
"
|
||||
echo -e "Using anonymous user.
|
||||
"
|
||||
STEAM_USER=anonymous
|
||||
STEAM_PASS=""
|
||||
STEAM_AUTH=""
|
||||
else
|
||||
echo -e "user set to ${STEAM_USER}"
|
||||
fi
|
||||
|
||||
## download and install steamcmd
|
||||
cd /tmp
|
||||
mkdir -p /mnt/server/steamcmd
|
||||
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
|
||||
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
|
||||
mkdir -p /mnt/server/steamapps # Fix steamcmd disk write error when this folder is missing
|
||||
cd /mnt/server/steamcmd
|
||||
|
||||
# SteamCMD fails otherwise for some reason, even running as root.
|
||||
# This is changed at the end of the install process anyways.
|
||||
chown -R root:root /mnt
|
||||
export HOME=/mnt/server
|
||||
|
||||
## install game using steamcmd
|
||||
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6
|
||||
|
||||
## set up 32 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk32
|
||||
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
|
||||
|
||||
## set up 64 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk64
|
||||
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
|
||||
container: 'ghcr.io/parkervcp/installers:debian'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: 'Additional Arguments'
|
||||
description: 'Add additional startup parameters to the server.'
|
||||
env_variable: ADDITIONAL_ARGS
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 14
|
||||
-
|
||||
name: 'App ID'
|
||||
description: ''
|
||||
env_variable: SRCDS_APPID
|
||||
default_value: 258550
|
||||
user_viewable: false
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'in:258550'
|
||||
sort: 18
|
||||
-
|
||||
name: 'App Port'
|
||||
description: 'Port for the Rust+ App. -1 to disable.'
|
||||
env_variable: APP_PORT
|
||||
default_value: 28082
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 15
|
||||
-
|
||||
name: 'Custom Map URL'
|
||||
description: |-
|
||||
Overwrites the map with the one from the direct download URL. Invalid URLs will cause the server to
|
||||
crash.
|
||||
env_variable: MAP_URL
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- url
|
||||
sort: 17
|
||||
-
|
||||
name: Description
|
||||
description: 'The description under your server title. Commonly used for rules & info. Use \n for newlines.'
|
||||
env_variable: DESCRIPTION
|
||||
default_value: 'Powered by Panel'
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
sort: 4
|
||||
-
|
||||
name: Level
|
||||
description: 'The world file for Rust to use.'
|
||||
env_variable: LEVEL
|
||||
default_value: 'Procedural Map'
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:20'
|
||||
sort: 3
|
||||
-
|
||||
name: 'Max Players'
|
||||
description: 'The maximum amount of players allowed in the server at once.'
|
||||
env_variable: MAX_PLAYERS
|
||||
default_value: 40
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 8
|
||||
-
|
||||
name: 'Modding Framework'
|
||||
description: "The modding framework to be used: carbon, oxide, vanilla.\r\nDefaults to \"vanilla\" for a non-modded server installation."
|
||||
env_variable: FRAMEWORK
|
||||
default_value: vanilla
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'in:vanilla,oxide,carbon'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Query Port'
|
||||
description: "Server Query Port. Can't be the same as Game's primary port."
|
||||
env_variable: QUERY_PORT
|
||||
default_value: 27017
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 10
|
||||
-
|
||||
name: 'RCON Password'
|
||||
description: 'RCON access password.'
|
||||
env_variable: RCON_PASS
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^[\w.-]*$/'
|
||||
- 'max:64'
|
||||
sort: 12
|
||||
-
|
||||
name: 'RCON Port'
|
||||
description: 'Port for RCON connections.'
|
||||
env_variable: RCON_PORT
|
||||
default_value: 28016
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 11
|
||||
-
|
||||
name: 'Save Interval'
|
||||
description: 'Sets the server’s auto-save interval in seconds.'
|
||||
env_variable: SAVEINTERVAL
|
||||
default_value: 60
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 13
|
||||
-
|
||||
name: 'Server Image'
|
||||
description: 'The header image for the top of your server listing.'
|
||||
env_variable: SERVER_IMG
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- url
|
||||
sort: 9
|
||||
-
|
||||
name: 'Server Logo'
|
||||
description: 'The circular server logo for the Rust+ app.'
|
||||
env_variable: SERVER_LOGO
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- url
|
||||
sort: 16
|
||||
-
|
||||
name: 'Server Name'
|
||||
description: 'The name of your server in the public server list.'
|
||||
env_variable: SERVER_HOSTNAME
|
||||
default_value: 'A Rust Server'
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:60'
|
||||
sort: 1
|
||||
-
|
||||
name: URL
|
||||
description: 'The URL for your server. This is what comes up when clicking the "Visit Website" button.'
|
||||
env_variable: SERVER_URL
|
||||
default_value: 'http://example.com'
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- url
|
||||
sort: 5
|
||||
-
|
||||
name: 'World Seed'
|
||||
description: 'The seed for a procedural map.'
|
||||
env_variable: WORLD_SEED
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 7
|
||||
-
|
||||
name: 'World Size'
|
||||
description: 'The world size for a procedural map.'
|
||||
env_variable: WORLD_SIZE
|
||||
default_value: 3000
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
sort: 6
|
@ -1,120 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/source-engine\/egg-custom-source-engine-game.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:07+00:00",
|
||||
"name": "Custom Source Engine Game",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "2a42d0c2-c0ba-4067-9a0a-9b95d77a3490",
|
||||
"description": "This option allows modifying the startup arguments and other details to run a custom SRCDS based game on the panel.",
|
||||
"tags": [
|
||||
"source",
|
||||
"steamcmd"
|
||||
],
|
||||
"features": [
|
||||
"steam_disk_space"
|
||||
],
|
||||
"docker_images": {
|
||||
"ghcr.io\/parkervcp\/games:source": "ghcr.io\/parkervcp\/games:source"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": ".\/srcds_run -game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart",
|
||||
"config": {
|
||||
"files": "{}",
|
||||
"startup": "{\r\n \"done\": \"gameserver Steam ID\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "quit"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\n##\r\n#\r\n# Variables\r\n# STEAM_USER, STEAM_PASS, STEAM_AUTH - Steam user setup. If a user has 2fa enabled it will most likely fail due to timeout. Leave blank for anon install.\r\n# WINDOWS_INSTALL - if it's a windows server you want to install set to 1\r\n# SRCDS_APPID - steam app id ffound here - https:\/\/developer.valvesoftware.com\/wiki\/Dedicated_Servers_List\r\n# EXTRA_FLAGS - when a server has extra glas for things like beta installs or updates.\r\n#\r\n##\r\n\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +force_install_dir \/mnt\/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ \"${WINDOWS_INSTALL}\" == \"1\" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so",
|
||||
"container": "ghcr.io\/parkervcp\/installers:debian",
|
||||
"entrypoint": "bash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Game ID",
|
||||
"description": "The ID corresponding to the game to download and run using SRCDS.",
|
||||
"env_variable": "SRCDS_APPID",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"numeric",
|
||||
"digits_between:1,6"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Game Name",
|
||||
"description": "The name corresponding to the game to download and run using SRCDS.",
|
||||
"env_variable": "SRCDS_GAME",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"alpha_dash",
|
||||
"between:1,100"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Map",
|
||||
"description": "The default map for the server.",
|
||||
"env_variable": "SRCDS_MAP",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"alpha_dash"
|
||||
],
|
||||
"sort": 3
|
||||
},
|
||||
{
|
||||
"name": "Steam Username",
|
||||
"description": "",
|
||||
"env_variable": "STEAM_USER",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 4
|
||||
},
|
||||
{
|
||||
"name": "Steam Password",
|
||||
"description": "",
|
||||
"env_variable": "STEAM_PASS",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "Steam Auth",
|
||||
"description": "",
|
||||
"env_variable": "STEAM_AUTH",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string"
|
||||
],
|
||||
"sort": 6
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/source-engine/egg-custom-source-engine-game.yaml'
|
||||
exported_at: '2025-07-25T13:30:23+00:00'
|
||||
name: 'Custom Source Engine Game'
|
||||
author: panel@example.com
|
||||
uuid: 2a42d0c2-c0ba-4067-9a0a-9b95d77a3490
|
||||
description: |-
|
||||
This option allows modifying the startup arguments and other details to run a custom SRCDS based
|
||||
game on the panel.
|
||||
tags:
|
||||
- source
|
||||
- steamcmd
|
||||
features:
|
||||
- steam_disk_space
|
||||
docker_images:
|
||||
'ghcr.io/parkervcp/games:source': 'ghcr.io/parkervcp/games:source'
|
||||
file_denylist: { }
|
||||
startup: './srcds_run -game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart'
|
||||
config:
|
||||
files: { }
|
||||
startup:
|
||||
done: 'gameserver Steam ID'
|
||||
logs: { }
|
||||
stop: quit
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# steamcmd Base Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
##
|
||||
#
|
||||
# Variables
|
||||
# STEAM_USER, STEAM_PASS, STEAM_AUTH - Steam user setup. If a user has 2fa enabled it will most likely fail due to timeout. Leave blank for anon install.
|
||||
# WINDOWS_INSTALL - if it's a windows server you want to install set to 1
|
||||
# SRCDS_APPID - steam app id ffound here - https://developer.valvesoftware.com/wiki/Dedicated_Servers_List
|
||||
# EXTRA_FLAGS - when a server has extra glas for things like beta installs or updates.
|
||||
#
|
||||
##
|
||||
|
||||
|
||||
## just in case someone removed the defaults.
|
||||
if [ "${STEAM_USER}" == "" ]; then
|
||||
echo -e "steam user is not set.
|
||||
"
|
||||
echo -e "Using anonymous user.
|
||||
"
|
||||
STEAM_USER=anonymous
|
||||
STEAM_PASS=""
|
||||
STEAM_AUTH=""
|
||||
else
|
||||
echo -e "user set to ${STEAM_USER}"
|
||||
fi
|
||||
|
||||
## download and install steamcmd
|
||||
cd /tmp
|
||||
mkdir -p /mnt/server/steamcmd
|
||||
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
|
||||
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
|
||||
mkdir -p /mnt/server/steamapps # Fix steamcmd disk write error when this folder is missing
|
||||
cd /mnt/server/steamcmd
|
||||
|
||||
# SteamCMD fails otherwise for some reason, even running as root.
|
||||
# This is changed at the end of the install process anyways.
|
||||
chown -R root:root /mnt
|
||||
export HOME=/mnt/server
|
||||
|
||||
## install game using steamcmd
|
||||
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ "${WINDOWS_INSTALL}" == "1" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6
|
||||
|
||||
## set up 32 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk32
|
||||
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
|
||||
|
||||
## set up 64 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk64
|
||||
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
|
||||
container: 'ghcr.io/parkervcp/installers:debian'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: 'Game ID'
|
||||
description: 'The ID corresponding to the game to download and run using SRCDS.'
|
||||
env_variable: SRCDS_APPID
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- numeric
|
||||
- 'digits_between:1,6'
|
||||
sort: 1
|
||||
-
|
||||
name: 'Game Name'
|
||||
description: 'The name corresponding to the game to download and run using SRCDS.'
|
||||
env_variable: SRCDS_GAME
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- alpha_dash
|
||||
- 'between:1,100'
|
||||
sort: 2
|
||||
-
|
||||
name: Map
|
||||
description: 'The default map for the server.'
|
||||
env_variable: SRCDS_MAP
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- alpha_dash
|
||||
sort: 3
|
||||
-
|
||||
name: 'Steam Auth'
|
||||
description: ''
|
||||
env_variable: STEAM_AUTH
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 6
|
||||
-
|
||||
name: 'Steam Password'
|
||||
description: ''
|
||||
env_variable: STEAM_PASS
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 5
|
||||
-
|
||||
name: 'Steam Username'
|
||||
description: ''
|
||||
env_variable: STEAM_USER
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
sort: 4
|
@ -1,150 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/source-engine\/egg-garrys-mod.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:13+00:00",
|
||||
"name": "Garrys Mod",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "60ef81d4-30a2-4d98-ab64-f59c69e2f915",
|
||||
"description": "Garrys Mod, is a sandbox physics game created by Garry Newman, and developed by his company, Facepunch Studios.",
|
||||
"tags": [
|
||||
"source",
|
||||
"steamcmd"
|
||||
],
|
||||
"features": [
|
||||
"gsl_token",
|
||||
"steam_disk_space"
|
||||
],
|
||||
"docker_images": {
|
||||
"ghcr.io\/parkervcp\/games:source": "ghcr.io\/parkervcp\/games:source"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": ".\/srcds_run -game garrysmod -console -port {{SERVER_PORT}} +ip 0.0.0.0 +host_workshop_collection {{WORKSHOP_ID}} +map {{SRCDS_MAP}} +gamemode {{GAMEMODE}} -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}} +maxplayers {{MAX_PLAYERS}} -tickrate {{TICKRATE}} $( [ \"$LUA_REFRESH\" == \"1\" ] || printf %s '-disableluarefresh' )",
|
||||
"config": {
|
||||
"files": "{}",
|
||||
"startup": "{\r\n \"done\": \"gameserver Steam ID\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "quit"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +force_install_dir \/mnt\/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ \"${WINDOWS_INSTALL}\" == \"1\" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so\r\n\r\n# Creating needed default files for the game\r\ncd \/mnt\/server\/garrysmod\/lua\/autorun\/server\r\necho '\r\n-- Docs: https:\/\/wiki.garrysmod.com\/page\/resource\/AddWorkshop\r\n-- Place the ID of the workshop addon you want to be downloaded to people who join your server, not the collection ID\r\n-- Use https:\/\/beta.configcreator.com\/create\/gmod\/resources.lua to easily create a list based on your collection ID\r\n\r\nresource.AddWorkshop( \"\" )\r\n' > workshop.lua\r\n\r\ncd \/mnt\/server\/garrysmod\/cfg\r\necho '\r\n\/\/ Please do not set RCon in here, use the startup parameters.\r\n\r\nhostname\t\t\"New Gmod Server\"\r\nsv_password\t\t\"\"\r\nsv_loadingurl \"\"\r\nsv_downloadurl \"\"\r\n\r\n\/\/ Steam Server List Settings\r\n\/\/ sv_location \"eu\"\r\nsv_region \"255\"\r\nsv_lan \"0\"\r\nsv_max_queries_sec_global \"30000\"\r\nsv_max_queries_window \"45\"\r\nsv_max_queries_sec \"5\"\r\n\r\n\/\/ Server Limits\r\nsbox_maxprops\t\t100\r\nsbox_maxragdolls\t5\r\nsbox_maxnpcs\t\t10\r\nsbox_maxballoons\t10\r\nsbox_maxeffects\t\t10\r\nsbox_maxdynamite\t10\r\nsbox_maxlamps\t\t10\r\nsbox_maxthrusters\t10\r\nsbox_maxwheels\t\t10\r\nsbox_maxhoverballs\t10\r\nsbox_maxvehicles\t20\r\nsbox_maxbuttons\t\t10\r\nsbox_maxsents\t\t20\r\nsbox_maxemitters\t5\r\nsbox_godmode\t\t0\r\nsbox_noclip\t\t 0\r\n\r\n\/\/ Network Settings - Please keep these set to default.\r\n\r\nsv_minrate\t\t75000\r\nsv_maxrate\t\t0\r\ngmod_physiterations\t2\r\nnet_splitpacket_maxrate\t45000\r\ndecalfrequency\t\t12 \r\n\r\n\/\/ Execute Ban Files - Please do not edit\r\nexec banned_ip.cfg \r\nexec banned_user.cfg \r\n\r\n\/\/ Add custom lines under here\r\n' > server.cfg",
|
||||
"container": "ghcr.io\/parkervcp\/installers:debian",
|
||||
"entrypoint": "bash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Map",
|
||||
"description": "The default map for the server.",
|
||||
"env_variable": "SRCDS_MAP",
|
||||
"default_value": "gm_flatgrass",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"alpha_dash"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Steam Account Token",
|
||||
"description": "The Steam Account Token required for the server to be displayed publicly.",
|
||||
"env_variable": "STEAM_ACC",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"string",
|
||||
"alpha_num",
|
||||
"size:32"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Source AppID",
|
||||
"description": "Required for game to update on server restart. Do not modify this.",
|
||||
"env_variable": "SRCDS_APPID",
|
||||
"default_value": "4020",
|
||||
"user_viewable": false,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:20"
|
||||
],
|
||||
"sort": 3
|
||||
},
|
||||
{
|
||||
"name": "Workshop ID",
|
||||
"description": "The ID of your workshop collection (the numbers at the end of the URL)",
|
||||
"env_variable": "WORKSHOP_ID",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"nullable",
|
||||
"integer"
|
||||
],
|
||||
"sort": 4
|
||||
},
|
||||
{
|
||||
"name": "Gamemode",
|
||||
"description": "The gamemode of your server.",
|
||||
"env_variable": "GAMEMODE",
|
||||
"default_value": "sandbox",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string"
|
||||
],
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "Max Players",
|
||||
"description": "The maximum amount of players allowed on your game server.",
|
||||
"env_variable": "MAX_PLAYERS",
|
||||
"default_value": "32",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"max:128"
|
||||
],
|
||||
"sort": 6
|
||||
},
|
||||
{
|
||||
"name": "Tickrate",
|
||||
"description": "The tickrate defines how fast the server will update each entity's location.",
|
||||
"env_variable": "TICKRATE",
|
||||
"default_value": "22",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"max:100"
|
||||
],
|
||||
"sort": 7
|
||||
},
|
||||
{
|
||||
"name": "Lua Refresh",
|
||||
"description": "0 = disable Lua refresh,\r\n1 = enable Lua refresh",
|
||||
"env_variable": "LUA_REFRESH",
|
||||
"default_value": "0",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"boolean"
|
||||
],
|
||||
"sort": 8
|
||||
}
|
||||
]
|
||||
}
|
228
database/Seeders/eggs/source-engine/egg-garrys-mod.yaml
Normal file
228
database/Seeders/eggs/source-engine/egg-garrys-mod.yaml
Normal file
@ -0,0 +1,228 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/source-engine/egg-garrys-mod.yaml'
|
||||
exported_at: '2025-07-25T13:30:30+00:00'
|
||||
name: 'Garrys Mod'
|
||||
author: panel@example.com
|
||||
uuid: 60ef81d4-30a2-4d98-ab64-f59c69e2f915
|
||||
description: |-
|
||||
Garrys Mod, is a sandbox physics game created by Garry Newman, and developed by his company,
|
||||
Facepunch Studios.
|
||||
tags:
|
||||
- source
|
||||
- steamcmd
|
||||
features:
|
||||
- gsl_token
|
||||
- steam_disk_space
|
||||
docker_images:
|
||||
'ghcr.io/parkervcp/games:source': 'ghcr.io/parkervcp/games:source'
|
||||
file_denylist: { }
|
||||
startup: './srcds_run -game garrysmod -console -port {{SERVER_PORT}} +ip 0.0.0.0 +host_workshop_collection {{WORKSHOP_ID}} +map {{SRCDS_MAP}} +gamemode {{GAMEMODE}} -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}} +maxplayers {{MAX_PLAYERS}} -tickrate {{TICKRATE}} $( [ "$LUA_REFRESH" == "1" ] || printf %s ''-disableluarefresh'' )'
|
||||
config:
|
||||
files: { }
|
||||
startup:
|
||||
done: 'gameserver Steam ID'
|
||||
logs: { }
|
||||
stop: quit
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# steamcmd Base Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
## just in case someone removed the defaults.
|
||||
if [ "${STEAM_USER}" == "" ]; then
|
||||
echo -e "steam user is not set.
|
||||
"
|
||||
echo -e "Using anonymous user.
|
||||
"
|
||||
STEAM_USER=anonymous
|
||||
STEAM_PASS=""
|
||||
STEAM_AUTH=""
|
||||
else
|
||||
echo -e "user set to ${STEAM_USER}"
|
||||
fi
|
||||
|
||||
## download and install steamcmd
|
||||
cd /tmp
|
||||
mkdir -p /mnt/server/steamcmd
|
||||
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
|
||||
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
|
||||
mkdir -p /mnt/server/steamapps # Fix steamcmd disk write error when this folder is missing
|
||||
cd /mnt/server/steamcmd
|
||||
|
||||
# SteamCMD fails otherwise for some reason, even running as root.
|
||||
# This is changed at the end of the install process anyways.
|
||||
chown -R root:root /mnt
|
||||
export HOME=/mnt/server
|
||||
|
||||
## install game using steamcmd
|
||||
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ "${WINDOWS_INSTALL}" == "1" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6
|
||||
|
||||
## set up 32 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk32
|
||||
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
|
||||
|
||||
## set up 64 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk64
|
||||
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
|
||||
|
||||
# Creating needed default files for the game
|
||||
cd /mnt/server/garrysmod/lua/autorun/server
|
||||
echo '
|
||||
-- Docs: https://wiki.garrysmod.com/page/resource/AddWorkshop
|
||||
-- Place the ID of the workshop addon you want to be downloaded to people who join your server, not the collection ID
|
||||
-- Use https://beta.configcreator.com/create/gmod/resources.lua to easily create a list based on your collection ID
|
||||
|
||||
resource.AddWorkshop( "" )
|
||||
' > workshop.lua
|
||||
|
||||
cd /mnt/server/garrysmod/cfg
|
||||
echo '
|
||||
// Please do not set RCon in here, use the startup parameters.
|
||||
|
||||
hostname "New Gmod Server"
|
||||
sv_password ""
|
||||
sv_loadingurl ""
|
||||
sv_downloadurl ""
|
||||
|
||||
// Steam Server List Settings
|
||||
// sv_location "eu"
|
||||
sv_region "255"
|
||||
sv_lan "0"
|
||||
sv_max_queries_sec_global "30000"
|
||||
sv_max_queries_window "45"
|
||||
sv_max_queries_sec "5"
|
||||
|
||||
// Server Limits
|
||||
sbox_maxprops 100
|
||||
sbox_maxragdolls 5
|
||||
sbox_maxnpcs 10
|
||||
sbox_maxballoons 10
|
||||
sbox_maxeffects 10
|
||||
sbox_maxdynamite 10
|
||||
sbox_maxlamps 10
|
||||
sbox_maxthrusters 10
|
||||
sbox_maxwheels 10
|
||||
sbox_maxhoverballs 10
|
||||
sbox_maxvehicles 20
|
||||
sbox_maxbuttons 10
|
||||
sbox_maxsents 20
|
||||
sbox_maxemitters 5
|
||||
sbox_godmode 0
|
||||
sbox_noclip 0
|
||||
|
||||
// Network Settings - Please keep these set to default.
|
||||
|
||||
sv_minrate 75000
|
||||
sv_maxrate 0
|
||||
gmod_physiterations 2
|
||||
net_splitpacket_maxrate 45000
|
||||
decalfrequency 12
|
||||
|
||||
// Execute Ban Files - Please do not edit
|
||||
exec banned_ip.cfg
|
||||
exec banned_user.cfg
|
||||
|
||||
// Add custom lines under here
|
||||
' > server.cfg
|
||||
container: 'ghcr.io/parkervcp/installers:debian'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: Gamemode
|
||||
description: 'The gamemode of your server.'
|
||||
env_variable: GAMEMODE
|
||||
default_value: sandbox
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
sort: 5
|
||||
-
|
||||
name: 'Lua Refresh'
|
||||
description: "0 = disable Lua refresh,\r\n1 = enable Lua refresh"
|
||||
env_variable: LUA_REFRESH
|
||||
default_value: 0
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- boolean
|
||||
sort: 8
|
||||
-
|
||||
name: Map
|
||||
description: 'The default map for the server.'
|
||||
env_variable: SRCDS_MAP
|
||||
default_value: gm_flatgrass
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- alpha_dash
|
||||
sort: 1
|
||||
-
|
||||
name: 'Max Players'
|
||||
description: 'The maximum amount of players allowed on your game server.'
|
||||
env_variable: MAX_PLAYERS
|
||||
default_value: 32
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'max:128'
|
||||
sort: 6
|
||||
-
|
||||
name: 'Source AppID'
|
||||
description: 'Required for game to update on server restart. Do not modify this.'
|
||||
env_variable: SRCDS_APPID
|
||||
default_value: 4020
|
||||
user_viewable: false
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:20'
|
||||
sort: 3
|
||||
-
|
||||
name: 'Steam Account Token'
|
||||
description: 'The Steam Account Token required for the server to be displayed publicly.'
|
||||
env_variable: STEAM_ACC
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- string
|
||||
- alpha_num
|
||||
- 'size:32'
|
||||
sort: 2
|
||||
-
|
||||
name: Tickrate
|
||||
description: "The tickrate defines how fast the server will update each entity's location."
|
||||
env_variable: TICKRATE
|
||||
default_value: 22
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'max:100'
|
||||
sort: 7
|
||||
-
|
||||
name: 'Workshop ID'
|
||||
description: 'The ID of your workshop collection (the numbers at the end of the URL)'
|
||||
env_variable: WORKSHOP_ID
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- nullable
|
||||
- integer
|
||||
sort: 4
|
@ -1,65 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/source-engine\/egg-insurgency.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:22+00:00",
|
||||
"name": "Insurgency",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "a5702286-655b-4069-bf1e-925c7300b61a",
|
||||
"description": "Take to the streets for intense close quarters combat, where a team's survival depends upon securing crucial strongholds and destroying enemy supply in this multiplayer and cooperative Source Engine based experience.",
|
||||
"tags": [
|
||||
"source",
|
||||
"steamcmd"
|
||||
],
|
||||
"features": [
|
||||
"steam_disk_space"
|
||||
],
|
||||
"docker_images": {
|
||||
"ghcr.io\/parkervcp\/games:source": "ghcr.io\/parkervcp\/games:source"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": ".\/srcds_run -game insurgency -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart",
|
||||
"config": {
|
||||
"files": "{}",
|
||||
"startup": "{\r\n \"done\": \"gameserver Steam ID\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "quit"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +force_install_dir \/mnt\/server +login anonymous +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +quit\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so",
|
||||
"container": "ghcr.io\/parkervcp\/installers:debian",
|
||||
"entrypoint": "bash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Game ID",
|
||||
"description": "The ID corresponding to the game to download and run using SRCDS.",
|
||||
"env_variable": "SRCDS_APPID",
|
||||
"default_value": "237410",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^(237410)$\/"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Default Map",
|
||||
"description": "The default map to use when starting the server.",
|
||||
"env_variable": "SRCDS_MAP",
|
||||
"default_value": "sinjar",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^(\\w{1,20})$\/"
|
||||
],
|
||||
"sort": 2
|
||||
}
|
||||
]
|
||||
}
|
82
database/Seeders/eggs/source-engine/egg-insurgency.yaml
Normal file
82
database/Seeders/eggs/source-engine/egg-insurgency.yaml
Normal file
@ -0,0 +1,82 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/source-engine/egg-insurgency.yaml'
|
||||
exported_at: '2025-07-25T13:30:35+00:00'
|
||||
name: Insurgency
|
||||
author: panel@example.com
|
||||
uuid: a5702286-655b-4069-bf1e-925c7300b61a
|
||||
description: |-
|
||||
Take to the streets for intense close quarters combat, where a team's survival depends upon securing
|
||||
crucial strongholds and destroying enemy supply in this multiplayer and cooperative Source Engine
|
||||
based experience.
|
||||
tags:
|
||||
- source
|
||||
- steamcmd
|
||||
features:
|
||||
- steam_disk_space
|
||||
docker_images:
|
||||
'ghcr.io/parkervcp/games:source': 'ghcr.io/parkervcp/games:source'
|
||||
file_denylist: { }
|
||||
startup: './srcds_run -game insurgency -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart'
|
||||
config:
|
||||
files: { }
|
||||
startup:
|
||||
done: 'gameserver Steam ID'
|
||||
logs: { }
|
||||
stop: quit
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# steamcmd Base Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
## download and install steamcmd
|
||||
cd /tmp
|
||||
mkdir -p /mnt/server/steamcmd
|
||||
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
|
||||
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
|
||||
cd /mnt/server/steamcmd
|
||||
|
||||
# SteamCMD fails otherwise for some reason, even running as root.
|
||||
# This is changed at the end of the install process anyways.
|
||||
chown -R root:root /mnt
|
||||
export HOME=/mnt/server
|
||||
|
||||
## install game using steamcmd
|
||||
./steamcmd.sh +force_install_dir /mnt/server +login anonymous +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +quit
|
||||
|
||||
## set up 32 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk32
|
||||
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
|
||||
|
||||
## set up 64 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk64
|
||||
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
|
||||
container: 'ghcr.io/parkervcp/installers:debian'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: 'Default Map'
|
||||
description: 'The default map to use when starting the server.'
|
||||
env_variable: SRCDS_MAP
|
||||
default_value: sinjar
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^(\w{1,20})$/'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Game ID'
|
||||
description: 'The ID corresponding to the game to download and run using SRCDS.'
|
||||
env_variable: SRCDS_APPID
|
||||
default_value: 237410
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^(237410)$/'
|
||||
sort: 1
|
@ -1,81 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/source-engine\/egg-team-fortress2.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:28+00:00",
|
||||
"name": "Team Fortress 2",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "7f8eb681-b2c8-4bf8-b9f4-d79ff70b6e5d",
|
||||
"description": "Team Fortress 2 is a team-based first-person shooter multiplayer video game developed and published by Valve Corporation. It is the sequel to the 1996 mod Team Fortress for Quake and its 1999 remake.",
|
||||
"tags": [
|
||||
"source",
|
||||
"steamcmd"
|
||||
],
|
||||
"features": [
|
||||
"gsl_token",
|
||||
"steam_disk_space"
|
||||
],
|
||||
"docker_images": {
|
||||
"ghcr.io\/parkervcp\/games:source": "ghcr.io\/parkervcp\/games:source"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": ".\/srcds_run -game tf -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}}",
|
||||
"config": {
|
||||
"files": "{}",
|
||||
"startup": "{\r\n \"done\": \"gameserver Steam ID\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "quit"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'debian:buster-slim'\r\n\r\n##\r\n#\r\n# Variables\r\n# STEAM_USER, STEAM_PASS, STEAM_AUTH - Steam user setup. If a user has 2fa enabled it will most likely fail due to timeout. Leave blank for anon install.\r\n# WINDOWS_INSTALL - if it's a windows server you want to install set to 1\r\n# SRCDS_APPID - steam app id ffound here - https:\/\/developer.valvesoftware.com\/wiki\/Dedicated_Servers_List\r\n# EXTRA_FLAGS - when a server has extra glas for things like beta installs or updates.\r\n#\r\n##\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n echo -e \"steam user is not set.\\n\"\r\n echo -e \"Using anonymous user.\\n\"\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\r\nelse\r\n echo -e \"user set to ${STEAM_USER}\"\r\nfi\r\n\r\n## download and install steamcmd\r\ncd \/tmp\r\nmkdir -p \/mnt\/server\/steamcmd\r\ncurl -sSL -o steamcmd.tar.gz https:\/\/steamcdn-a.akamaihd.net\/client\/installer\/steamcmd_linux.tar.gz\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/steamapps # Fix steamcmd disk write error when this folder is missing\r\ncd \/mnt\/server\/steamcmd\r\n\r\n# SteamCMD fails otherwise for some reason, even running as root.\r\n# This is changed at the end of the install process anyways.\r\nchown -R root:root \/mnt\r\nexport HOME=\/mnt\/server\r\n\r\n## install game using steamcmd\r\n.\/steamcmd.sh +force_install_dir \/mnt\/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ \"${WINDOWS_INSTALL}\" == \"1\" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6\r\n\r\n## set up 32 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\n## set up 64 bit libraries\r\nmkdir -p \/mnt\/server\/.steam\/sdk64\r\ncp -v linux64\/steamclient.so ..\/.steam\/sdk64\/steamclient.so",
|
||||
"container": "ghcr.io\/parkervcp\/installers:debian",
|
||||
"entrypoint": "bash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Game ID",
|
||||
"description": "The ID corresponding to the game to download and run using SRCDS.",
|
||||
"env_variable": "SRCDS_APPID",
|
||||
"default_value": "232250",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"in:232250"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "Default Map",
|
||||
"description": "The default map to use when starting the server.",
|
||||
"env_variable": "SRCDS_MAP",
|
||||
"default_value": "cp_dustbowl",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"regex:\/^(\\w{1,20})$\/"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Steam",
|
||||
"description": "The Steam Game Server Login Token to display servers publicly. Generate one at https:\/\/steamcommunity.com\/dev\/managegameservers",
|
||||
"env_variable": "STEAM_ACC",
|
||||
"default_value": "",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"alpha_num",
|
||||
"size:32"
|
||||
],
|
||||
"sort": 3
|
||||
}
|
||||
]
|
||||
}
|
122
database/Seeders/eggs/source-engine/egg-team-fortress2.yaml
Normal file
122
database/Seeders/eggs/source-engine/egg-team-fortress2.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/source-engine/egg-team-fortress2.yaml'
|
||||
exported_at: '2025-07-25T13:30:44+00:00'
|
||||
name: 'Team Fortress 2'
|
||||
author: panel@example.com
|
||||
uuid: 7f8eb681-b2c8-4bf8-b9f4-d79ff70b6e5d
|
||||
description: |-
|
||||
Team Fortress 2 is a team-based first-person shooter multiplayer video game developed and published
|
||||
by Valve Corporation. It is the sequel to the 1996 mod Team Fortress for Quake and its 1999 remake.
|
||||
tags:
|
||||
- source
|
||||
- steamcmd
|
||||
features:
|
||||
- gsl_token
|
||||
- steam_disk_space
|
||||
docker_images:
|
||||
'ghcr.io/parkervcp/games:source': 'ghcr.io/parkervcp/games:source'
|
||||
file_denylist: { }
|
||||
startup: './srcds_run -game tf -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart +sv_setsteamaccount {{STEAM_ACC}}'
|
||||
config:
|
||||
files: { }
|
||||
startup:
|
||||
done: 'gameserver Steam ID'
|
||||
logs: { }
|
||||
stop: quit
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/bash
|
||||
# steamcmd Base Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
# Image to install with is 'debian:buster-slim'
|
||||
|
||||
##
|
||||
#
|
||||
# Variables
|
||||
# STEAM_USER, STEAM_PASS, STEAM_AUTH - Steam user setup. If a user has 2fa enabled it will most likely fail due to timeout. Leave blank for anon install.
|
||||
# WINDOWS_INSTALL - if it's a windows server you want to install set to 1
|
||||
# SRCDS_APPID - steam app id ffound here - https://developer.valvesoftware.com/wiki/Dedicated_Servers_List
|
||||
# EXTRA_FLAGS - when a server has extra glas for things like beta installs or updates.
|
||||
#
|
||||
##
|
||||
|
||||
## just in case someone removed the defaults.
|
||||
if [ "${STEAM_USER}" == "" ]; then
|
||||
echo -e "steam user is not set.
|
||||
"
|
||||
echo -e "Using anonymous user.
|
||||
"
|
||||
STEAM_USER=anonymous
|
||||
STEAM_PASS=""
|
||||
STEAM_AUTH=""
|
||||
else
|
||||
echo -e "user set to ${STEAM_USER}"
|
||||
fi
|
||||
|
||||
## download and install steamcmd
|
||||
cd /tmp
|
||||
mkdir -p /mnt/server/steamcmd
|
||||
curl -sSL -o steamcmd.tar.gz https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz
|
||||
tar -xzvf steamcmd.tar.gz -C /mnt/server/steamcmd
|
||||
mkdir -p /mnt/server/steamapps # Fix steamcmd disk write error when this folder is missing
|
||||
cd /mnt/server/steamcmd
|
||||
|
||||
# SteamCMD fails otherwise for some reason, even running as root.
|
||||
# This is changed at the end of the install process anyways.
|
||||
chown -R root:root /mnt
|
||||
export HOME=/mnt/server
|
||||
|
||||
## install game using steamcmd
|
||||
./steamcmd.sh +force_install_dir /mnt/server +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} $( [[ "${WINDOWS_INSTALL}" == "1" ]] && printf %s '+@sSteamCmdForcePlatformType windows' ) +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} validate +quit ## other flags may be needed depending on install. looking at you cs 1.6
|
||||
|
||||
## set up 32 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk32
|
||||
cp -v linux32/steamclient.so ../.steam/sdk32/steamclient.so
|
||||
|
||||
## set up 64 bit libraries
|
||||
mkdir -p /mnt/server/.steam/sdk64
|
||||
cp -v linux64/steamclient.so ../.steam/sdk64/steamclient.so
|
||||
container: 'ghcr.io/parkervcp/installers:debian'
|
||||
entrypoint: bash
|
||||
variables:
|
||||
-
|
||||
name: 'Default Map'
|
||||
description: 'The default map to use when starting the server.'
|
||||
env_variable: SRCDS_MAP
|
||||
default_value: cp_dustbowl
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- 'regex:/^(\w{1,20})$/'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Game ID'
|
||||
description: 'The ID corresponding to the game to download and run using SRCDS.'
|
||||
env_variable: SRCDS_APPID
|
||||
default_value: 232250
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- 'in:232250'
|
||||
sort: 1
|
||||
-
|
||||
name: Steam
|
||||
description: |-
|
||||
The Steam Game Server Login Token to display servers publicly. Generate one at
|
||||
https://steamcommunity.com/dev/managegameservers
|
||||
env_variable: STEAM_ACC
|
||||
default_value: ''
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- alpha_num
|
||||
- 'size:32'
|
||||
sort: 3
|
@ -1,50 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/voice-servers\/egg-mumble-server.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:35+00:00",
|
||||
"name": "Mumble Server",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "727ee758-7fb2-4979-972b-d3eba4e1e9f0",
|
||||
"description": "Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.",
|
||||
"tags": [
|
||||
"voice"
|
||||
],
|
||||
"features": [],
|
||||
"docker_images": {
|
||||
"Mumble": "ghcr.io\/parkervcp\/yolks:voice_mumble"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": "mumble-server -fg -ini murmur.ini",
|
||||
"config": {
|
||||
"files": "{\r\n \"murmur.ini\": {\r\n \"parser\": \"ini\",\r\n \"find\": {\r\n \"database\": \"\/home\/container\/murmur.sqlite\",\r\n \"logfile\": \"\/home\/container\/murmur.log\",\r\n \"port\": \"{{server.allocations.default.port}}\",\r\n \"host\": \"\",\r\n \"users\": \"{{server.environment.MAX_USERS}}\"\r\n }\r\n }\r\n}",
|
||||
"startup": "{\r\n \"done\": \"Server listening on\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "^C"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n\r\nif [ ! -d \/mnt\/server\/ ]; then\r\n mkdir \/mnt\/server\/\r\nfi\r\n\r\ncd \/mnt\/server\r\n\r\nFILE=\/mnt\/server\/murmur.ini\r\nif [ -f \"$FILE\" ]; then\r\n echo \"Config file already exists.\"\r\nelse \r\n echo \"Downloading the config file.\"\r\n apk add --no-cache murmur\r\n cp \/etc\/murmur.ini \/mnt\/server\/murmur.ini\r\n apk del murmur\r\nfi\r\necho \"done\"",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Maximum Users",
|
||||
"description": "Maximum concurrent users on the mumble server.",
|
||||
"env_variable": "MAX_USERS",
|
||||
"default_value": "100",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"numeric",
|
||||
"digits_between:1,5"
|
||||
],
|
||||
"sort": 1
|
||||
}
|
||||
]
|
||||
}
|
68
database/Seeders/eggs/voice-servers/egg-mumble-server.yaml
Normal file
68
database/Seeders/eggs/voice-servers/egg-mumble-server.yaml
Normal file
@ -0,0 +1,68 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/voice-servers/egg-mumble-server.yaml'
|
||||
exported_at: '2025-07-25T13:30:48+00:00'
|
||||
name: 'Mumble Server'
|
||||
author: panel@example.com
|
||||
uuid: 727ee758-7fb2-4979-972b-d3eba4e1e9f0
|
||||
description: |-
|
||||
Mumble is an open source, low-latency, high quality voice chat software primarily intended for use
|
||||
while gaming.
|
||||
tags:
|
||||
- voice
|
||||
features: { }
|
||||
docker_images:
|
||||
Mumble: 'ghcr.io/parkervcp/yolks:voice_mumble'
|
||||
file_denylist: { }
|
||||
startup: 'mumble-server -fg -ini murmur.ini'
|
||||
config:
|
||||
files:
|
||||
murmur.ini:
|
||||
parser: ini
|
||||
find:
|
||||
database: /home/container/murmur.sqlite
|
||||
logfile: /home/container/murmur.log
|
||||
port: '{{server.allocations.default.port}}'
|
||||
host: ''
|
||||
users: '{{server.environment.MAX_USERS}}'
|
||||
startup:
|
||||
done: 'Server listening on'
|
||||
logs: { }
|
||||
stop: ^C
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
|
||||
if [ ! -d /mnt/server/ ]; then
|
||||
mkdir /mnt/server/
|
||||
fi
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
FILE=/mnt/server/murmur.ini
|
||||
if [ -f "$FILE" ]; then
|
||||
echo "Config file already exists."
|
||||
else
|
||||
echo "Downloading the config file."
|
||||
apk add --no-cache murmur
|
||||
cp /etc/murmur.ini /mnt/server/murmur.ini
|
||||
apk del murmur
|
||||
fi
|
||||
echo "done"
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'Maximum Users'
|
||||
description: 'Maximum concurrent users on the mumble server.'
|
||||
env_variable: MAX_USERS
|
||||
default_value: 100
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- numeric
|
||||
- 'digits_between:1,5'
|
||||
sort: 1
|
@ -1,120 +0,0 @@
|
||||
{
|
||||
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL",
|
||||
"meta": {
|
||||
"version": "PLCN_v1",
|
||||
"update_url": "https:\/\/github.com\/pelican-dev\/panel\/raw\/main\/database\/Seeders\/eggs\/voice-servers\/egg-teamspeak3-server.json"
|
||||
},
|
||||
"exported_at": "2025-03-18T12:36:41+00:00",
|
||||
"name": "Teamspeak3 Server",
|
||||
"author": "panel@example.com",
|
||||
"uuid": "983b1fac-d322-4d5f-a636-436127326b37",
|
||||
"description": "VoIP software designed with security in mind, featuring crystal clear voice quality, endless customization options, and scalabilty up to thousands of simultaneous users.",
|
||||
"tags": [
|
||||
"voice"
|
||||
],
|
||||
"features": [],
|
||||
"docker_images": {
|
||||
"Debian": "ghcr.io\/parkervcp\/yolks:debian"
|
||||
},
|
||||
"file_denylist": [],
|
||||
"startup": ".\/ts3server default_voice_port={{SERVER_PORT}} query_port={{QUERY_PORT}} filetransfer_ip=0.0.0.0 filetransfer_port={{FILE_TRANSFER}} query_http_port={{QUERY_HTTP}} query_ssh_port={{QUERY_SSH}} query_protocols={{QUERY_PROTOCOLS_VAR}} license_accepted=1",
|
||||
"config": {
|
||||
"files": "{}",
|
||||
"startup": "{\r\n \"done\": \"listening on 0.0.0.0:\"\r\n}",
|
||||
"logs": "{}",
|
||||
"stop": "^C"
|
||||
},
|
||||
"scripts": {
|
||||
"installation": {
|
||||
"script": "#!\/bin\/ash\r\n# TS3 Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n\r\nif [ -z ${TS_VERSION} ] || [ ${TS_VERSION} == latest ]; then\r\n TS_VERSION=$(curl -sSL https:\/\/teamspeak.com\/versions\/server.json | jq -r '.linux.x86_64.version')\r\nfi\r\n\r\ncd \/mnt\/server\r\n\r\necho -e \"getting files from http:\/\/files.teamspeak-services.com\/releases\/server\/${TS_VERSION}\/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2\" \r\ncurl -L http:\/\/files.teamspeak-services.com\/releases\/server\/${TS_VERSION}\/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2 | tar -xvj --strip-components=1\r\ncp .\/redist\/libmariadb.so.2 .\/",
|
||||
"container": "ghcr.io\/parkervcp\/installers:alpine",
|
||||
"entrypoint": "ash"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "Server Version",
|
||||
"description": "The version of Teamspeak 3 to use when running the server.",
|
||||
"env_variable": "TS_VERSION",
|
||||
"default_value": "latest",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:6"
|
||||
],
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"name": "File Transfer Port",
|
||||
"description": "The Teamspeak file transfer port",
|
||||
"env_variable": "FILE_TRANSFER",
|
||||
"default_value": "30033",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"between:1025,65535"
|
||||
],
|
||||
"sort": 2
|
||||
},
|
||||
{
|
||||
"name": "Query Port",
|
||||
"description": "The Teamspeak Query Port",
|
||||
"env_variable": "QUERY_PORT",
|
||||
"default_value": "10011",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"between:1025,65535"
|
||||
],
|
||||
"sort": 3
|
||||
},
|
||||
{
|
||||
"name": "Query Protocols",
|
||||
"description": "Comma separated list of protocols that can be used to connect to the ServerQuery | \r\nPossible values are raw, ssh and http | \r\nE.g.: raw,ssh,http",
|
||||
"env_variable": "QUERY_PROTOCOLS_VAR",
|
||||
"default_value": "raw,http,ssh",
|
||||
"user_viewable": true,
|
||||
"user_editable": true,
|
||||
"rules": [
|
||||
"required",
|
||||
"string",
|
||||
"max:12"
|
||||
],
|
||||
"sort": 4
|
||||
},
|
||||
{
|
||||
"name": "Query SSH Port",
|
||||
"description": "TCP Port opened for ServerQuery connections using SSH",
|
||||
"env_variable": "QUERY_SSH",
|
||||
"default_value": "10022",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"between:1025,65535"
|
||||
],
|
||||
"sort": 5
|
||||
},
|
||||
{
|
||||
"name": "Query HTTP Port",
|
||||
"description": "TCP Port opened for ServerQuery connections using http",
|
||||
"env_variable": "QUERY_HTTP",
|
||||
"default_value": "10080",
|
||||
"user_viewable": true,
|
||||
"user_editable": false,
|
||||
"rules": [
|
||||
"required",
|
||||
"integer",
|
||||
"between:1025,65535"
|
||||
],
|
||||
"sort": 6
|
||||
}
|
||||
]
|
||||
}
|
116
database/Seeders/eggs/voice-servers/egg-teamspeak3-server.yaml
Normal file
116
database/Seeders/eggs/voice-servers/egg-teamspeak3-server.yaml
Normal file
@ -0,0 +1,116 @@
|
||||
_comment: 'DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PANEL'
|
||||
meta:
|
||||
version: PLCN_v2
|
||||
update_url: 'https://github.com/pelican-dev/panel/raw/main/database/Seeders/eggs/voice-servers/egg-teamspeak3-server.yaml'
|
||||
exported_at: '2025-07-25T13:30:53+00:00'
|
||||
name: 'Teamspeak3 Server'
|
||||
author: panel@example.com
|
||||
uuid: 983b1fac-d322-4d5f-a636-436127326b37
|
||||
description: |-
|
||||
VoIP software designed with security in mind, featuring crystal clear voice quality, endless
|
||||
customization options, and scalabilty up to thousands of simultaneous users.
|
||||
tags:
|
||||
- voice
|
||||
features: { }
|
||||
docker_images:
|
||||
Debian: 'ghcr.io/parkervcp/yolks:debian'
|
||||
file_denylist: { }
|
||||
startup: './ts3server default_voice_port={{SERVER_PORT}} query_port={{QUERY_PORT}} filetransfer_ip=0.0.0.0 filetransfer_port={{FILE_TRANSFER}} query_http_port={{QUERY_HTTP}} query_ssh_port={{QUERY_SSH}} query_protocols={{QUERY_PROTOCOLS_VAR}} license_accepted=1'
|
||||
config:
|
||||
files: { }
|
||||
startup:
|
||||
done: 'listening on 0.0.0.0:'
|
||||
logs: { }
|
||||
stop: ^C
|
||||
scripts:
|
||||
installation:
|
||||
script: |-
|
||||
#!/bin/ash
|
||||
# TS3 Installation Script
|
||||
#
|
||||
# Server Files: /mnt/server
|
||||
|
||||
if [ -z ${TS_VERSION} ] || [ ${TS_VERSION} == latest ]; then
|
||||
TS_VERSION=$(curl -sSL https://teamspeak.com/versions/server.json | jq -r '.linux.x86_64.version')
|
||||
fi
|
||||
|
||||
cd /mnt/server
|
||||
|
||||
echo -e "getting files from http://files.teamspeak-services.com/releases/server/${TS_VERSION}/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2"
|
||||
curl -L http://files.teamspeak-services.com/releases/server/${TS_VERSION}/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2 | tar -xvj --strip-components=1
|
||||
cp ./redist/libmariadb.so.2 ./
|
||||
container: 'ghcr.io/parkervcp/installers:alpine'
|
||||
entrypoint: ash
|
||||
variables:
|
||||
-
|
||||
name: 'File Transfer Port'
|
||||
description: 'The Teamspeak file transfer port'
|
||||
env_variable: FILE_TRANSFER
|
||||
default_value: 30033
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'between:1025,65535'
|
||||
sort: 2
|
||||
-
|
||||
name: 'Query HTTP Port'
|
||||
description: 'TCP Port opened for ServerQuery connections using http'
|
||||
env_variable: QUERY_HTTP
|
||||
default_value: 10080
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'between:1025,65535'
|
||||
sort: 6
|
||||
-
|
||||
name: 'Query Port'
|
||||
description: 'The Teamspeak Query Port'
|
||||
env_variable: QUERY_PORT
|
||||
default_value: 10011
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'between:1025,65535'
|
||||
sort: 3
|
||||
-
|
||||
name: 'Query Protocols'
|
||||
description: "Comma separated list of protocols that can be used to connect to the ServerQuery | \r\nPossible values are raw, ssh and http | \r\nE.g.: raw,ssh,http"
|
||||
env_variable: QUERY_PROTOCOLS_VAR
|
||||
default_value: 'raw,http,ssh'
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:12'
|
||||
sort: 4
|
||||
-
|
||||
name: 'Query SSH Port'
|
||||
description: 'TCP Port opened for ServerQuery connections using SSH'
|
||||
env_variable: QUERY_SSH
|
||||
default_value: 10022
|
||||
user_viewable: true
|
||||
user_editable: false
|
||||
rules:
|
||||
- required
|
||||
- integer
|
||||
- 'between:1025,65535'
|
||||
sort: 5
|
||||
-
|
||||
name: 'Server Version'
|
||||
description: 'The version of Teamspeak 3 to use when running the server.'
|
||||
env_variable: TS_VERSION
|
||||
default_value: latest
|
||||
user_viewable: true
|
||||
user_editable: true
|
||||
rules:
|
||||
- required
|
||||
- string
|
||||
- 'max:6'
|
||||
sort: 1
|
@ -13,14 +13,18 @@ return [
|
||||
'import' => [
|
||||
'file' => 'File',
|
||||
'url' => 'URL',
|
||||
'egg_help' => 'This should be the raw .json file ( egg-minecraft.json )',
|
||||
'url_help' => 'URLs must point directly to the raw .json file',
|
||||
'egg_help' => 'This should be the raw .json/.yaml file',
|
||||
'url_help' => 'URLs must point directly to the raw .json/.yaml file',
|
||||
'add_url' => 'New URL',
|
||||
'import_failed' => 'Import Failed',
|
||||
'import_success' => 'Import Success',
|
||||
'github' => 'Add from Github',
|
||||
'refresh' => 'Refresh',
|
||||
],
|
||||
'export' => [
|
||||
'modal' => 'How would you like to export :egg ?',
|
||||
'as' => 'As',
|
||||
],
|
||||
'in_use' => 'In Use',
|
||||
'servers' => 'Servers',
|
||||
'name' => 'Name',
|
||||
|
Loading…
x
Reference in New Issue
Block a user