Merge branch 'develop' of https://github.com/Pterodactyl/Panel into develop

This commit is contained in:
Dane Everitt 2020-04-12 12:22:53 -07:00
commit 4ed7b26f89
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
29 changed files with 414 additions and 137 deletions

View file

@ -65,14 +65,14 @@ class EmailSettingsCommand extends Command
public function handle() public function handle()
{ {
$this->variables['MAIL_DRIVER'] = $this->option('driver') ?? $this->choice( $this->variables['MAIL_DRIVER'] = $this->option('driver') ?? $this->choice(
trans('command/messages.environment.mail.ask_driver'), [ trans('command/messages.environment.mail.ask_driver'), [
'smtp' => 'SMTP Server', 'smtp' => 'SMTP Server',
'mail' => 'PHP\'s Internal Mail Function', 'mail' => 'PHP\'s Internal Mail Function',
'mailgun' => 'Mailgun Transactional Email', 'mailgun' => 'Mailgun Transactional Email',
'mandrill' => 'Mandrill Transactional Email', 'mandrill' => 'Mandrill Transactional Email',
'postmark' => 'Postmarkapp Transactional Email', 'postmark' => 'Postmarkapp Transactional Email',
], $this->config->get('mail.driver', 'smtp') ], $this->config->get('mail.driver', 'smtp')
); );
$method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables'; $method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables';
if (method_exists($this, $method)) { if (method_exists($this, $method)) {

View file

@ -22,4 +22,12 @@ interface UserRepositoryInterface extends RepositoryInterface, SearchableInterfa
* @return \Illuminate\Support\Collection * @return \Illuminate\Support\Collection
*/ */
public function filterUsersByQuery(?string $query): Collection; public function filterUsersByQuery(?string $query): Collection;
/**
* Returns a user with the given id in a format that can be used for dropdowns.
*
* @param int $id
* @return \Pterodactyl\Models\Model
*/
public function filterById(int $id): \Pterodactyl\Models\Model;
} }

View file

@ -6,6 +6,7 @@ use Exception;
use Carbon\Carbon; use Carbon\Carbon;
use Cron\CronExpression; use Cron\CronExpression;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\ViewErrorBag;
class Utilities class Utilities
{ {
@ -50,4 +51,15 @@ class Utilities
sprintf('%s %s %s * %s', $minute, $hour, $dayOfMonth, $dayOfWeek) sprintf('%s %s %s * %s', $minute, $hour, $dayOfMonth, $dayOfWeek)
)->getNextRunDate()); )->getNextRunDate());
} }
public static function checked($name, $default)
{
$errors = session('errors');
if (isset($errors) && $errors instanceof ViewErrorBag && $errors->any()) {
return old($name) ? 'checked' : '';
}
return ($default) ? 'checked' : '';
}
} }

View file

@ -165,6 +165,7 @@ class DatabaseController extends Controller
$this->alert->danger( $this->alert->danger(
sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage()) sprintf('There was an error while trying to connect to the host or while executing a query: "%s"', $exception->getMessage())
)->flash(); )->flash();
return $redirect->withInput($request->normalize()); return $redirect->withInput($request->normalize());
} else { } else {
throw $exception; throw $exception;

View file

@ -177,10 +177,15 @@ class UserController extends Controller
* Get a JSON response of users on the system. * Get a JSON response of users on the system.
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* @return \Illuminate\Support\Collection * @return \Illuminate\Support\Collection|\Pterodactyl\Models\Model
*/ */
public function json(Request $request) public function json(Request $request)
{ {
// Handle single user requests.
if ($request->query('user_id')) {
return $this->repository->filterById($request->input('user_id'));
}
return $this->repository->filterUsersByQuery($request->input('q')); return $this->repository->filterUsersByQuery($request->input('q'));
} }
} }

View file

@ -86,7 +86,7 @@ class ScheduleTaskController extends ClientApiController
} }
$this->repository->update($task->id, [ $this->repository->update($task->id, [
'action' => $request->input('action'), 'action' => $request->input('action'),
'payload' => $request->input('payload'), 'payload' => $request->input('payload'),
'time_offset' => $request->input('time_offset'), 'time_offset' => $request->input('time_offset'),
]); ]);

View file

@ -3,8 +3,6 @@
namespace Pterodactyl\Http\Controllers\Api\Remote\Servers; namespace Pterodactyl\Http\Controllers\Api\Remote\Servers;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Http\Request;
use Pterodactyl\Models\Server;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Controllers\Controller;
use Pterodactyl\Repositories\Eloquent\BackupRepository; use Pterodactyl\Repositories\Eloquent\BackupRepository;

View file

@ -54,4 +54,22 @@ class UserRepository extends EloquentRepository implements UserRepositoryInterfa
return $item; return $item;
}); });
} }
/**
* Returns a user with the given id in a format that can be used for dropdowns.
*
* @param int $id
* @return \Pterodactyl\Models\Model
*/
public function filterById(int $id): \Pterodactyl\Models\Model
{
$this->setColumns([
'id', 'email', 'username', 'name_first', 'name_last',
]);
$model = $this->getBuilder()->findOrFail($id, $this->getColumns())->getModel();
$model->md5 = md5(strtolower($model->email));
return $model;
}
} }

View file

@ -41,8 +41,8 @@ class NodeCreationService
*/ */
public function handle(array $data) public function handle(array $data)
{ {
$data['daemon_token'] = Str::random(Node::DAEMON_TOKEN_LENGTH); $data['daemon_token'] = $this->encrypter->encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH));
$data['daemon_token_id'] = $this->encrypter->encrypt(Str::random(Node::DAEMON_TOKEN_ID_LENGTH)); $data['daemon_token_id'] = Str::random(Node::DAEMON_TOKEN_ID_LENGTH);
return $this->repository->create($data, true, true); return $this->repository->create($data, true, true);
} }

View file

@ -168,8 +168,8 @@ return [
| Cast the given "real type" to the given "type". | Cast the given "real type" to the given "type".
| |
*/ */
'type_overrides' => [ 'type_overrides' => [
'integer' => 'int', 'integer' => 'int',
'boolean' => 'bool', 'boolean' => 'bool',
], ],
]; ];

View file

@ -3,8 +3,8 @@
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Faker\Generator as Faker;
use Pterodactyl\Models\Node; use Pterodactyl\Models\Node;
use Faker\Generator as Faker;
use Pterodactyl\Models\ApiKey; use Pterodactyl\Models\ApiKey;
/* /*

View file

@ -26,8 +26,8 @@ class ChangeServicesToUseAMoreUniqueIdentifier extends Migration
DB::table('services')->get(['id', 'author', 'uuid'])->each(function ($service) { DB::table('services')->get(['id', 'author', 'uuid'])->each(function ($service) {
DB::table('services')->where('id', $service->id)->update([ DB::table('services')->where('id', $service->id)->update([
'author' => ($service->author === 'ptrdctyl-v040-11e6-8b77-86f30ca893d3') ? 'support@pterodactyl.io' : 'unknown@unknown-author.com', 'author' => ($service->author === 'ptrdctyl-v040-11e6-8b77-86f30ca893d3') ? 'support@pterodactyl.io' : 'unknown@unknown-author.com',
'uuid' => Uuid::uuid4()->toString(), 'uuid' => Uuid::uuid4()->toString(),
]); ]);
}); });

View file

@ -44,12 +44,12 @@ class MergePermissionsTableIntoSubusers extends Migration
{ {
foreach (DB::select('SELECT id, permissions FROM subusers') as $datum) { foreach (DB::select('SELECT id, permissions FROM subusers') as $datum) {
$values = []; $values = [];
foreach(json_decode($datum->permissions, true) as $permission) { foreach (json_decode($datum->permissions, true) as $permission) {
$values[] = $datum->id; $values[] = $datum->id;
$values[] = $permission; $values[] = $permission;
} }
if (!empty($values)) { if (! empty($values)) {
$string = 'VALUES ' . implode(', ', array_fill(0, count($values) / 2, '(?, ?)')); $string = 'VALUES ' . implode(', ', array_fill(0, count($values) / 2, '(?, ?)'));
DB::insert('INSERT INTO permissions(`subuser_id`, `permission`) ' . $string, $values); DB::insert('INSERT INTO permissions(`subuser_id`, `permission`) ' . $string, $values);

View file

@ -14,7 +14,7 @@ class AddThreadsColumnToServersTable extends Migration
public function up() public function up()
{ {
Schema::table('servers', function (Blueprint $table) { Schema::table('servers', function (Blueprint $table) {
$table->string('threads')->nullable(); $table->string('threads')->nullable()->after('cpu');
}); });
} }

View file

@ -1,8 +1,8 @@
<?php <?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBackupsTable extends Migration class CreateBackupsTable extends Migration
{ {

View file

@ -3,9 +3,9 @@
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Container\Container; use Illuminate\Container\Container;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Contracts\Encryption\Encrypter; use Illuminate\Contracts\Encryption\Encrypter;
class StoreNodeTokensAsEncryptedValue extends Migration class StoreNodeTokensAsEncryptedValue extends Migration

View file

@ -3,26 +3,35 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2019-02-13T12:30:54-05:00", "exported_at": "2018-10-29T20:51:32+01:00",
"name": "Ark: Survival Evolved", "name": "Ark: Survival Evolved",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"description": "As a man or woman stranded, naked, freezing, and starving on the unforgiving shores of a mysterious island called ARK, use your skill and cunning to kill or tame and ride the plethora of leviathan dinosaurs and other primeval creatures roaming the land. Hunt, harvest resources, craft items, grow crops, research technologies, and build shelters to withstand the elements and store valuables, all while teaming up with (or preying upon) hundreds of other players to survive, dominate... and escape! \u2014 Gamepedia: ARK", "description": "As a man or woman stranded, naked, freezing, and starving on the unforgiving shores of a mysterious island called ARK, use your skill and cunning to kill or tame and ride the plethora of leviathan dinosaurs and other primeval creatures roaming the land. Hunt, harvest resources, craft items, grow crops, research technologies, and build shelters to withstand the elements and store valuables, all while teaming up with (or preying upon) hundreds of other players to survive, dominate... and escape! \u2014 Gamepedia: ARK",
"image": "quay.io\/pterodactyl\/core:source", "image": "quay.io\/pterodactyl\/core:source",
"startup": ".\/ShooterGame\/Binaries\/Linux\/ShooterGameServer {{SERVER_MAP}}?listen?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}", "startup": "\"cd ShooterGame\/Binaries\/Linux && .\/ShooterGameServer {{SERVER_MAP}}?listen?SessionName='{{SESSION_NAME}}'?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}?RCONPort={{RCON_PORT}}?QueryPort={{QUERY_PORT}}?RCONEnabled={{ENABLE_RCON}} -server -log\"",
"config": { "config": {
"files": "{}", "files": "{}",
"startup": "{\r\n \"done\": \"Setting breakpad minidump AppID = 346110\",\r\n \"userInteraction\": []\r\n}", "startup": "{\r\n \"done\": \"Setting breakpad minidump AppID = 346110\",\r\n \"userInteraction\": []\r\n}",
"logs": "{\r\n \"custom\": true,\r\n \"location\": \"logs\/latest.log\"\r\n}", "logs": "{\r\n \"custom\": true,\r\n \"location\": \"logs\/latest.log\"\r\n}",
"stop": "quit" "stop": "^C"
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\n# ARK: Installation Script\n#\n# Server Files: \/mnt\/server\napt -y update\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\n\ncd \/tmp\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\n\nmkdir -p \/mnt\/server\/steamcmd\nmkdir -p \/mnt\/server\/Engine\/Binaries\/ThirdParty\/SteamCMD\/Linux\n\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/Engine\/Binaries\/ThirdParty\/SteamCMD\/Linux\n\ncd \/mnt\/server\/steamcmd\n\n# SteamCMD fails otherwise for some reason, even running as root.\n# This is changed at the end of the install process anyways.\nchown -R root:root \/mnt\n\nexport HOME=\/mnt\/server\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update 376030 +quit\n\nmkdir -p \/mnt\/server\/.steam\/sdk32\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so", "script": "#!\/bin\/bash\r\n# ARK: Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\ncd \/tmp\r\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\r\n\r\nmkdir -p \/mnt\/server\/steamcmd\r\nmkdir -p \/mnt\/server\/Engine\/Binaries\/ThirdParty\/SteamCMD\/Linux\r\n\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\r\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/Engine\/Binaries\/ThirdParty\/SteamCMD\/Linux\r\n\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\n\r\nexport HOME=\/mnt\/server\r\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update 376030 +quit\r\n\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so\r\n\r\ncd \/mnt\/server\/Engine\/Binaries\/ThirdParty\/SteamCMD\/Linux\r\n\r\nln -sf ..\/..\/..\/..\/..\/Steam\/steamapps steamapps\r\n\r\ncd \/mnt\/server",
"container": "ubuntu:16.04", "container": "ubuntu:16.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },
"variables": [ "variables": [
{
"name": "Server Name",
"description": "ARK server name",
"env_variable": "SESSION_NAME",
"default_value": "ARK SERVER",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|string|max:128"
},
{ {
"name": "Server Password", "name": "Server Password",
"description": "If specified, players must provide this password to join the server.", "description": "If specified, players must provide this password to join the server.",
@ -39,7 +48,43 @@
"default_value": "", "default_value": "",
"user_viewable": 1, "user_viewable": 1,
"user_editable": 1, "user_editable": 1,
"rules": "nullable|alpha_dash|between:1,100" "rules": "nullable|alpha_dash|between:1,100"
},
{
"name": "Server Port",
"description": "ARK server port used by client.",
"env_variable": "PORT",
"default_value": "7777",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|numeric"
},
{
"name": "Use Rcon",
"description": "Enable or disable rcon system. (true or false)",
"env_variable": "ENABLE_RCON",
"default_value": "false",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|string|max:5"
},
{
"name": "Rcon Port",
"description": "ARK rcon port used by rcon tools.",
"env_variable": "RCON_PORT",
"default_value": "27020",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|numeric"
},
{
"name": "Query Port",
"description": "ARK query port used by steam server browser and ark client server browser.",
"env_variable": "QUERY_PORT",
"default_value": "27015",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|numeric"
}, },
{ {
"name": "Maximum Players", "name": "Maximum Players",
@ -50,9 +95,18 @@
"user_editable": 1, "user_editable": 1,
"rules": "required|numeric|digits_between:1,4" "rules": "required|numeric|digits_between:1,4"
}, },
{
"name": "App ID",
"description": "ARK steam app id for auto updates. Leave blank to avoid auto update.",
"env_variable": "SRCDS_APPID",
"default_value": "376030",
"user_viewable": 1,
"user_editable": 0,
"rules": "nullable|numeric"
},
{ {
"name": "Server Map", "name": "Server Map",
"description": "Available Maps: TheIsland, TheCenter, Ragnarok, ScorchedEarth_P, Aberration_P", "description": "Available Maps: TheIsland, TheCenter, Ragnarok, ScorchedEarth_P, Aberration_P, Extinction",
"env_variable": "SERVER_MAP", "env_variable": "SERVER_MAP",
"default_value": "TheIsland", "default_value": "TheIsland",
"user_viewable": 1, "user_viewable": 1,
@ -60,4 +114,4 @@
"rules": "required|string|max:20" "rules": "required|string|max:20"
} }
] ]
} }

View file

@ -3,7 +3,7 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2018-06-19T07:46:06-04:00", "exported_at": "2019-12-08T10:52:19-05:00",
"name": "Counter-Strike: Global Offensive", "name": "Counter-Strike: Global Offensive",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"description": "Counter-Strike: Global Offensive is a multiplayer first-person shooter video game developed by Hidden Path Entertainment and Valve Corporation.", "description": "Counter-Strike: Global Offensive is a multiplayer first-person shooter video game developed by Hidden Path Entertainment and Valve Corporation.",
@ -17,8 +17,8 @@
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\n# CSGO Installation Script\n#\n# Server Files: \/mnt\/server\napt -y update\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\n\ncd \/tmp\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\n\nmkdir -p \/mnt\/server\/steamcmd\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\ncd \/mnt\/server\/steamcmd\n\n# SteamCMD fails otherwise for some reason, even running as root.\n# This is changed at the end of the install process anyways.\nchown -R root:root \/mnt\n\nexport HOME=\/mnt\/server\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update 740 +quit\n\nmkdir -p \/mnt\/server\/.steam\/sdk32\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so", "script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'ubuntu:18.04'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\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\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 +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +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": "ubuntu:16.04", "container": "ubuntu:18.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },
@ -51,4 +51,4 @@
"rules": "required|string|max:20" "rules": "required|string|max:20"
} }
] ]
} }

View file

@ -3,7 +3,7 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2018-01-21T16:59:45-06:00", "exported_at": "2019-12-08T10:54:26-05:00",
"name": "Custom Source Engine Game", "name": "Custom Source Engine Game",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"description": "This option allows modifying the startup arguments and other details to run a custom SRCDS based game on the panel.", "description": "This option allows modifying the startup arguments and other details to run a custom SRCDS based game on the panel.",
@ -17,8 +17,8 @@
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\n# SRCDS Base Installation Script\n#\n# Server Files: \/mnt\/server\napt -y update\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\n\ncd \/tmp\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\n\nmkdir -p \/mnt\/server\/steamcmd\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\ncd \/mnt\/server\/steamcmd\n\n# SteamCMD fails otherwise for some reason, even running as root.\n# This is changed at the end of the install process anyways.\nchown -R root:root \/mnt\n\nexport HOME=\/mnt\/server\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} +quit\n\nmkdir -p \/mnt\/server\/.steam\/sdk32\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so", "script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'ubuntu:18.04'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\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\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 +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +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": "ubuntu:16.04", "container": "ubuntu:18.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },
@ -51,4 +51,4 @@
"rules": "required|string|alpha_dash" "rules": "required|string|alpha_dash"
} }
] ]
} }

View file

@ -3,7 +3,7 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2019-02-16T14:20:52-05:00", "exported_at": "2019-12-08T10:56:42-05:00",
"name": "Garrys Mod", "name": "Garrys Mod",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"description": "Garrys Mod, is a sandbox physics game created by Garry Newman, and developed by his company, Facepunch Studios.", "description": "Garrys Mod, is a sandbox physics game created by Garry Newman, and developed by his company, Facepunch Studios.",
@ -17,8 +17,8 @@
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\r\n# Garry's Mod Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\ncd \/tmp\r\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\r\n\r\nmkdir -p \/mnt\/server\/steamcmd\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\n\r\nexport HOME=\/mnt\/server\r\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update 4020 +quit\r\n\r\nmkdir -p \/mnt\/server\/.steam\/sdk32\r\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/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\n\r\n\/\/ Steam Server List Settings\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", "script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'ubuntu:18.04'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\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\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 +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +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\n\r\n\/\/ Steam Server List Settings\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": "ubuntu:16.04", "container": "ubuntu:18.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },
@ -87,4 +87,4 @@
"rules": "required|integer|max:100" "rules": "required|integer|max:100"
} }
] ]
} }

View file

@ -3,7 +3,7 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2018-01-21T16:59:48-06:00", "exported_at": "2019-12-08T10:57:32-05:00",
"name": "Insurgency", "name": "Insurgency",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"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.", "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.",
@ -17,8 +17,8 @@
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\n# SRCDS Base Installation Script\n#\n# Server Files: \/mnt\/server\napt -y update\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\n\ncd \/tmp\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\n\nmkdir -p \/mnt\/server\/steamcmd\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\ncd \/mnt\/server\/steamcmd\n\n# SteamCMD fails otherwise for some reason, even running as root.\n# This is changed at the end of the install process anyways.\nchown -R root:root \/mnt\n\nexport HOME=\/mnt\/server\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} +quit\n\nmkdir -p \/mnt\/server\/.steam\/sdk32\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so", "script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'ubuntu:18.04'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\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\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 +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +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": "ubuntu:16.04", "container": "ubuntu:18.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },
@ -51,4 +51,4 @@
"rules": "required|regex:\/^(\\w{1,20})$\/" "rules": "required|regex:\/^(\\w{1,20})$\/"
} }
] ]
} }

View file

@ -3,7 +3,7 @@
"meta": { "meta": {
"version": "PTDL_v1" "version": "PTDL_v1"
}, },
"exported_at": "2018-01-21T16:59:45-06:00", "exported_at": "2019-12-08T10:58:48-05:00",
"name": "Team Fortress 2", "name": "Team Fortress 2",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"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.", "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.",
@ -17,8 +17,8 @@
}, },
"scripts": { "scripts": {
"installation": { "installation": {
"script": "#!\/bin\/bash\n# SRCDS Base Installation Script\n#\n# Server Files: \/mnt\/server\napt -y update\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\n\ncd \/tmp\ncurl -sSL -o steamcmd.tar.gz http:\/\/media.steampowered.com\/installer\/steamcmd_linux.tar.gz\n\nmkdir -p \/mnt\/server\/steamcmd\ntar -xzvf steamcmd.tar.gz -C \/mnt\/server\/steamcmd\ncd \/mnt\/server\/steamcmd\n\n# SteamCMD fails otherwise for some reason, even running as root.\n# This is changed at the end of the install process anyways.\nchown -R root:root \/mnt\n\nexport HOME=\/mnt\/server\n.\/steamcmd.sh +login anonymous +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} +quit\n\nmkdir -p \/mnt\/server\/.steam\/sdk32\ncp -v linux32\/steamclient.so ..\/.steam\/sdk32\/steamclient.so", "script": "#!\/bin\/bash\r\n# steamcmd Base Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\n# Image to install with is 'ubuntu:18.04'\r\napt -y update\r\napt -y --no-install-recommends install curl lib32gcc1 ca-certificates\r\n\r\n## just in case someone removed the defaults.\r\nif [ \"${STEAM_USER}\" == \"\" ]; then\r\n STEAM_USER=anonymous\r\n STEAM_PASS=\"\"\r\n STEAM_AUTH=\"\"\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\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 +login ${STEAM_USER} ${STEAM_PASS} ${STEAM_AUTH} +force_install_dir \/mnt\/server +app_update ${SRCDS_APPID} ${EXTRA_FLAGS} +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": "ubuntu:16.04", "container": "ubuntu:18.04",
"entrypoint": "bash" "entrypoint": "bash"
} }
}, },

View file

@ -21,65 +21,29 @@ $(document).ready(function() {
$('#pNestId').select2({ $('#pNestId').select2({
placeholder: 'Select a Nest', placeholder: 'Select a Nest',
}).change(); }).change();
$('#pEggId').select2({ $('#pEggId').select2({
placeholder: 'Select a Nest Egg', placeholder: 'Select a Nest Egg',
}); });
$('#pPackId').select2({ $('#pPackId').select2({
placeholder: 'Select a Service Pack', placeholder: 'Select a Service Pack',
}); });
$('#pNodeId').select2({ $('#pNodeId').select2({
placeholder: 'Select a Node', placeholder: 'Select a Node',
}).change(); }).change();
$('#pAllocation').select2({ $('#pAllocation').select2({
placeholder: 'Select a Default Allocation', placeholder: 'Select a Default Allocation',
}); });
$('#pAllocationAdditional').select2({ $('#pAllocationAdditional').select2({
placeholder: 'Select Additional Allocations', placeholder: 'Select Additional Allocations',
}); });
$('#pUserId').select2({
ajax: {
url: '/admin/users/accounts.json',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page,
};
},
processResults: function (data, params) {
return { results: data };
},
cache: true,
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 2,
templateResult: function (data) {
if (data.loading) return data.text;
return '<div class="user-block"> \
<img class="img-circle img-bordered-xs" src="https://www.gravatar.com/avatar/' + data.md5 + '?s=120" alt="User Image"> \
<span class="username"> \
<a href="#">' + data.name_first + ' ' + data.name_last +'</a> \
</span> \
<span class="description"><strong>' + data.email + '</strong> - ' + data.username + '</span> \
</div>';
},
templateSelection: function (data) {
return '<div> \
<span> \
<img class="img-rounded img-bordered-xs" src="https://www.gravatar.com/avatar/' + data.md5 + '?s=120" style="height:28px;margin-top:-4px;" alt="User Image"> \
</span> \
<span style="padding-left:5px;"> \
' + data.name_first + ' ' + data.name_last + ' (<strong>' + data.email + '</strong>) \
</span> \
</div>';
}
});
}); });
var lastActiveBox = null; let lastActiveBox = null;
$(document).on('click', function (event) { $(document).on('click', function (event) {
if (lastActiveBox !== null) { if (lastActiveBox !== null) {
lastActiveBox.removeClass('box-primary'); lastActiveBox.removeClass('box-primary');
@ -97,10 +61,8 @@ $('#pNodeId').on('change', function () {
data: v.allocations, data: v.allocations,
placeholder: 'Select a Default Allocation', placeholder: 'Select a Default Allocation',
}); });
$('#pAllocationAdditional').html('').select2({
data: v.allocations, updateAdditionalAllocations();
placeholder: 'Select Additional Allocations',
})
} }
}); });
}); });
@ -117,8 +79,8 @@ $('#pNestId').on('change', function (event) {
}); });
$('#pEggId').on('change', function (event) { $('#pEggId').on('change', function (event) {
var parentChain = _.get(Pterodactyl.nests, $('#pNestId').val(), null); let parentChain = _.get(Pterodactyl.nests, $('#pNestId').val(), null);
var objectChain = _.get(parentChain, 'eggs.' + $(this).val(), null); let objectChain = _.get(parentChain, 'eggs.' + $(this).val(), null);
$('#pDefaultContainer').val(_.get(objectChain, 'docker_image', 'not defined!')); $('#pDefaultContainer').val(_.get(objectChain, 'docker_image', 'not defined!'));
@ -139,10 +101,13 @@ $('#pEggId').on('change', function (event) {
), ),
}); });
const variableIds = {};
$('#appendVariablesTo').html(''); $('#appendVariablesTo').html('');
$.each(_.get(objectChain, 'variables', []), function (i, item) { $.each(_.get(objectChain, 'variables', []), function (i, item) {
var isRequired = (item.required === 1) ? '<span class="label label-danger">Required</span> ' : ''; variableIds[item.env_variable] = 'var_ref_' + item.id;
var dataAppend = ' \
let isRequired = (item.required === 1) ? '<span class="label label-danger">Required</span> ' : '';
let dataAppend = ' \
<div class="form-group col-sm-6"> \ <div class="form-group col-sm-6"> \
<label for="var_ref_' + item.id + '" class="control-label">' + isRequired + item.name + '</label> \ <label for="var_ref_' + item.id + '" class="control-label">' + isRequired + item.name + '</label> \
<input type="text" id="var_ref_' + item.id + '" autocomplete="off" name="environment[' + item.env_variable + ']" class="form-control" value="' + item.default_value + '" /> \ <input type="text" id="var_ref_' + item.id + '" autocomplete="off" name="environment[' + item.env_variable + ']" class="form-control" value="' + item.default_value + '" /> \
@ -153,4 +118,86 @@ $('#pEggId').on('change', function (event) {
'; ';
$('#appendVariablesTo').append(dataAppend); $('#appendVariablesTo').append(dataAppend);
}); });
// If you receive a warning on this line, it should be fine to ignore. this function is
// defined in "resources/views/admin/servers/new.blade.php" near the bottom of the file.
serviceVariablesUpdated($('#pEggId').val(), variableIds);
}); });
$('#pAllocation').on('change', function () {
updateAdditionalAllocations();
});
function updateAdditionalAllocations() {
let currentAllocation = $('#pAllocation').val();
let currentNode = $('#pNodeId').val();
$.each(Pterodactyl.nodeData, function (i, v) {
if (v.id == currentNode) {
let allocations = [];
for (let i = 0; i < v.allocations.length; i++) {
const allocation = v.allocations[i];
if (allocation.id != currentAllocation) {
allocations.push(allocation);
}
}
$('#pAllocationAdditional').html('').select2({
data: allocations,
placeholder: 'Select Additional Allocations',
});
}
});
}
function initUserIdSelect(data) {
$('#pUserId').select2({
ajax: {
url: '/admin/users/accounts.json',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page,
};
},
processResults: function (data, params) {
return { results: data };
},
cache: true,
},
data: data,
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 2,
templateResult: function (data) {
if (data.loading) return data.text;
return '<div class="user-block"> \
<img class="img-circle img-bordered-xs" src="https://www.gravatar.com/avatar/' + data.md5 + '?s=120" alt="User Image"> \
<span class="username"> \
<a href="#">' + data.name_first + ' ' + data.name_last +'</a> \
</span> \
<span class="description"><strong>' + data.email + '</strong> - ' + data.username + '</span> \
</div>';
},
templateSelection: function (data) {
return '<div> \
<span> \
<img class="img-rounded img-bordered-xs" src="https://www.gravatar.com/avatar/' + data.md5 + '?s=120" style="height:28px;margin-top:-4px;" alt="User Image"> \
</span> \
<span style="padding-left:5px;"> \
' + data.name_first + ' ' + data.name_last + ' (<strong>' + data.email + '</strong>) \
</span> \
</div>';
}
});
}

View file

@ -6,6 +6,7 @@ import { faCircle } from '@fortawesome/free-solid-svg-icons/faCircle';
import classNames from 'classnames'; import classNames from 'classnames';
import { faMemory } from '@fortawesome/free-solid-svg-icons/faMemory'; import { faMemory } from '@fortawesome/free-solid-svg-icons/faMemory';
import { faMicrochip } from '@fortawesome/free-solid-svg-icons/faMicrochip'; import { faMicrochip } from '@fortawesome/free-solid-svg-icons/faMicrochip';
import { faHdd } from '@fortawesome/free-solid-svg-icons/faHdd';
import { bytesToHuman } from '@/helpers'; import { bytesToHuman } from '@/helpers';
import SuspenseSpinner from '@/components/elements/SuspenseSpinner'; import SuspenseSpinner from '@/components/elements/SuspenseSpinner';
import TitledGreyBox from '@/components/elements/TitledGreyBox'; import TitledGreyBox from '@/components/elements/TitledGreyBox';
@ -42,6 +43,7 @@ const StopOrKillButton = ({ onPress }: { onPress: (action: PowerAction) => void
export default () => { export default () => {
const [ memory, setMemory ] = useState(0); const [ memory, setMemory ] = useState(0);
const [ cpu, setCpu ] = useState(0); const [ cpu, setCpu ] = useState(0);
const [ disk, setDisk ] = useState(0);
const server = ServerContext.useStoreState(state => state.server.data!); const server = ServerContext.useStoreState(state => state.server.data!);
const status = ServerContext.useStoreState(state => state.status.value); const status = ServerContext.useStoreState(state => state.status.value);
@ -58,6 +60,7 @@ export default () => {
setMemory(stats.memory_bytes); setMemory(stats.memory_bytes);
setCpu(stats.cpu_absolute); setCpu(stats.cpu_absolute);
setDisk(stats.disk_bytes);
}; };
const sendPowerCommand = (command: PowerAction) => { const sendPowerCommand = (command: PowerAction) => {
@ -92,6 +95,14 @@ export default () => {
/> />
&nbsp;{status} &nbsp;{status}
</p> </p>
<p className={'text-xs mt-2'}>
<FontAwesomeIcon
icon={faMicrochip}
fixedWidth={true}
className={'mr-1'}
/>
&nbsp;{cpu.toFixed(2)} %
</p>
<p className={'text-xs mt-2'}> <p className={'text-xs mt-2'}>
<FontAwesomeIcon <FontAwesomeIcon
icon={faMemory} icon={faMemory}
@ -103,11 +114,12 @@ export default () => {
</p> </p>
<p className={'text-xs mt-2'}> <p className={'text-xs mt-2'}>
<FontAwesomeIcon <FontAwesomeIcon
icon={faMicrochip} icon={faHdd}
fixedWidth={true} fixedWidth={true}
className={'mr-1'} className={'mr-1'}
/> />
&nbsp;{cpu.toFixed(2)} % &nbsp;{bytesToHuman(disk)}
<span className={'text-neutral-500'}>/ {server.limits.disk} MB</span>
</p> </p>
</TitledGreyBox> </TitledGreyBox>
<Can action={[ 'control.start', 'control.stop', 'control.restart' ]} matchAny={true}> <Can action={[ 'control.start', 'control.stop', 'control.restart' ]} matchAny={true}>

View file

@ -26,6 +26,7 @@
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Core Details</h3> <h3 class="box-title">Core Details</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
@ -33,20 +34,23 @@
<input type="text" class="form-control" id="pName" name="name" value="{{ old('name') }}" placeholder="Server Name"> <input type="text" class="form-control" id="pName" name="name" value="{{ old('name') }}" placeholder="Server Name">
<p class="small text-muted no-margin">Character limits: <code>a-z A-Z 0-9 _ - .</code> and <code>[Space]</code> (max 200 characters).</p> <p class="small text-muted no-margin">Character limits: <code>a-z A-Z 0-9 _ - .</code> and <code>[Space]</code> (max 200 characters).</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="pUserId">Server Owner</label> <label for="pUserId">Server Owner</label>
<select class="form-control" style="padding-left:0;" name="owner_id" id="pUserId"></select> <select id="pUserId" name="owner_id" class="form-control" style="padding-left:0;"></select>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label for="description" class="control-label">Server Description</label> <label for="pDescription" class="control-label">Server Description</label>
<textarea name="description" rows="3" class="form-control">{{ old('description') }}</textarea> <textarea id="pDescription" name="description" rows="3" class="form-control">{{ old('description') }}</textarea>
<p class="text-muted small">A brief description of this server.</p> <p class="text-muted small">A brief description of this server.</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="checkbox checkbox-primary no-margin-bottom"> <div class="checkbox checkbox-primary no-margin-bottom">
<input id="pStartOnCreation" name="start_on_completion" type="checkbox" value="1" checked /> <input id="pStartOnCreation" name="start_on_completion" type="checkbox" {{ \Pterodactyl\Helpers\Utilities::checked('start_on_completion', 1) }} />
<label for="pStartOnCreation" class="strong">Start Server when Installed</label> <label for="pStartOnCreation" class="strong">Start Server when Installed</label>
</div> </div>
</div> </div>
@ -55,6 +59,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="box">
@ -62,6 +67,7 @@
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Allocation Management</h3> <h3 class="box-title">Allocation Management</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-sm-4"> <div class="form-group col-sm-4">
<label for="pNodeId">Node</label> <label for="pNodeId">Node</label>
@ -78,22 +84,26 @@
</optgroup> </optgroup>
@endforeach @endforeach
</select> </select>
<p class="small text-muted no-margin">The node which this server will be deployed to.</p> <p class="small text-muted no-margin">The node which this server will be deployed to.</p>
</div> </div>
<div class="form-group col-sm-4"> <div class="form-group col-sm-4">
<label for="pAllocation">Default Allocation</label> <label for="pAllocation">Default Allocation</label>
<select name="allocation_id" id="pAllocation" class="form-control"></select> <select id="pAllocation" name="allocation_id" class="form-control"></select>
<p class="small text-muted no-margin">The main allocation that will be assigned to this server.</p> <p class="small text-muted no-margin">The main allocation that will be assigned to this server.</p>
</div> </div>
<div class="form-group col-sm-4"> <div class="form-group col-sm-4">
<label for="pAllocationAdditional">Additional Allocation(s)</label> <label for="pAllocationAdditional">Additional Allocation(s)</label>
<select name="allocation_additional[]" id="pAllocationAdditional" class="form-control" multiple></select> <select id="pAllocationAdditional" name="allocation_additional[]" class="form-control" multiple></select>
<p class="small text-muted no-margin">Additional allocations to assign to this server on creation.</p> <p class="small text-muted no-margin">Additional allocations to assign to this server on creation.</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="box">
@ -101,18 +111,20 @@
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Application Feature Limits</h3> <h3 class="box-title">Application Feature Limits</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="cpu" class="control-label">Database Limit</label> <label for="pDatabaseLimit" class="control-label">Database Limit</label>
<div> <div>
<input type="text" name="database_limit" class="form-control" value="{{ old('database_limit', 0) }}"/> <input type="text" id="pDatabaseLimit" name="database_limit" class="form-control" value="{{ old('database_limit', 0) }}"/>
</div> </div>
<p class="text-muted small">The total number of databases a user is allowed to create for this server. Leave blank to allow unlimited.</p> <p class="text-muted small">The total number of databases a user is allowed to create for this server. Leave blank to allow unlimited.</p>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="cpu" class="control-label">Allocation Limit</label> <label for="pAllocationLimit" class="control-label">Allocation Limit</label>
<div> <div>
<input type="text" name="allocation_limit" class="form-control" value="{{ old('allocation_limit', 0) }}"/> <input type="text" id="pAllocationLimit" name="allocation_limit" class="form-control" value="{{ old('allocation_limit', 0) }}"/>
</div> </div>
<p class="text-muted small">The total number of allocations a user is allowed to create for this server. Leave blank to allow unlimited.</p> <p class="text-muted small">The total number of allocations a user is allowed to create for this server. Leave blank to allow unlimited.</p>
</div> </div>
@ -126,71 +138,90 @@
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Resource Management</h3> <h3 class="box-title">Resource Management</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pCPU">CPU Limit</label> <label for="pCPU">CPU Limit</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" value="{{ old('cpu', 0) }}" name="cpu" id="pCPU" /> <input type="text" id="pCPU" name="cpu" class="form-control" value="{{ old('cpu', 0) }}" />
<span class="input-group-addon">%</span> <span class="input-group-addon">%</span>
</div> </div>
<p class="text-muted small">If you do not want to limit CPU usage, set the value to <code>0</code>. To determine a value, take the number of <em>physical</em> cores and multiply it by 100. For example, on a quad core system <code>(4 * 100 = 400)</code> there is <code>400%</code> available. To limit a server to using half of a single core, you would set the value to <code>50</code>. To allow a server to use up to two physical cores, set the value to <code>200</code>. BlockIO should be a value between <code>10</code> and <code>1000</code>. Please see <a href="https://docs.docker.com/engine/reference/run/#/block-io-bandwidth-blkio-constraint" target="_blank">this documentation</a> for more information about it.<p>
<p class="text-muted small">If you do not want to limit CPU usage, set the value to <code>0</code>. To determine a value, take the number of <em>physical</em> cores and multiply it by 100. For example, on a quad core system <code>(4 * 100 = 400)</code> there is <code>400%</code> available. To limit a server to using half of a single core, you would set the value to <code>50</code>. To allow a server to use up to two physical cores, set the value to <code>200</code>. BlockIO should be a value between <code>10</code> and <code>1000</code>. Please see <a href="https://docs.docker.com/engine/reference/run/#/block-io-bandwidth-blkio-constraint" target="_blank">this documentation</a> for more information about it.<p>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pThreads">CPU Threads</label> <label for="pThreads">CPU Threads</label>
<div> <div>
<input type="text" class="form-control" value="{{ old('threads') }}" name="threads" id="pThreads" /> <input type="text" id="pThreads" name="threads" class="form-control" value="{{ old('threads') }}" />
</div> </div>
<p class="text-muted small"><strong>Advanced:</strong> Enter the specific CPU cores that this process can run on, or leave blank to allow all cores. This can be a single number, or a comma seperated list. Example: <code>0</code>, <code>0-1,3</code>, or <code>0,1,3,4</code>.</p> <p class="text-muted small"><strong>Advanced:</strong> Enter the specific CPU cores that this process can run on, or leave blank to allow all cores. This can be a single number, or a comma seperated list. Example: <code>0</code>, <code>0-1,3</code>, or <code>0,1,3,4</code>.</p>
</div> </div>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pMemory">Memory</label> <label for="pMemory">Memory</label>
<div class="input-group"> <div class="input-group">
<input type="text" value="{{ old('memory') }}" class="form-control" name="memory" id="pMemory" /> <input type="text" id="pMemory" name="memory" class="form-control" value="{{ old('memory') }}" />
<span class="input-group-addon">MB</span> <span class="input-group-addon">MB</span>
</div> </div>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pSwap">Swap</label> <label for="pSwap">Swap</label>
<div class="input-group"> <div class="input-group">
<input type="text" value="{{ old('swap', 0) }}" class="form-control" name="swap" id="pSwap" /> <input type="text" id="pSwap" name="swap" class="form-control" value="{{ old('swap', 0) }}" />
<span class="input-group-addon">MB</span> <span class="input-group-addon">MB</span>
</div> </div>
</div> </div>
</div> </div>
<div class="box-footer no-border no-pad-top no-pad-bottom"> <div class="box-footer no-border no-pad-top no-pad-bottom">
<p class="text-muted small">If you do not want to assign swap space to a server, simply put <code>0</code> for the value, or <code>-1</code> to allow unlimited swap space. If you want to disable memory limiting on a server, simply enter <code>0</code> into the memory field.<p> <p class="text-muted small">If you do not want to assign swap space to a server, simply put <code>0</code> for the value, or <code>-1</code> to allow unlimited swap space. If you want to disable memory limiting on a server, simply enter <code>0</code> into the memory field.<p>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pDisk">Disk Space</label> <label for="pDisk">Disk Space</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" value="{{ old('disk') }}" name="disk" id="pDisk" /> <input type="text" id="pDisk" name="disk" class="form-control" value="{{ old('disk') }}" />
<span class="input-group-addon">MB</span> <span class="input-group-addon">MB</span>
</div> </div>
</div> </div>
<div class="form-group col-xs-6"> <div class="form-group col-xs-6">
<label for="pIO">Block IO Weight</label> <label for="pIO">Block IO Weight</label>
<div> <div>
<input type="text" class="form-control" value="{{ old('io', 500) }}" name="io" id="pIO" /> <input type="text" id="pIO" name="io" class="form-control" value="{{ old('io', 500) }}" />
</div> </div>
<p class="text-muted small"><strong>Advanced</strong>: The IO performance of this server relative to other <em>running</em> containers on the system. Value should be between <code>10</code> and <code>1000</code>.</code></p>
<p class="text-muted small"><strong>Advanced</strong>: The IO performance of this server relative to other <em>running</em> containers on the system. Value should be between <code>10</code> and <code>1000</code>.</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Nest Configuration</h3> <h3 class="box-title">Nest Configuration</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<label for="pNestId">Nest</label> <label for="pNestId">Nest</label>
<select name="nest_id" id="pNestId" class="form-control">
<select id="pNestId" name="nest_id" class="form-control">
@foreach($nests as $nest) @foreach($nests as $nest)
<option value="{{ $nest->id }}" <option value="{{ $nest->id }}"
@if($nest->id === old('nest_id')) @if($nest->id === old('nest_id'))
@ -199,33 +230,40 @@
>{{ $nest->name }}</option> >{{ $nest->name }}</option>
@endforeach @endforeach
</select> </select>
<p class="small text-muted no-margin">Select the Nest that this server will be grouped under.</p> <p class="small text-muted no-margin">Select the Nest that this server will be grouped under.</p>
</div> </div>
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<label for="pEggId">Egg</label> <label for="pEggId">Egg</label>
<select name="egg_id" id="pEggId" class="form-control"></select> <select id="pEggId" name="egg_id" class="form-control"></select>
<p class="small text-muted no-margin">Select the Egg that will define how this server should operate.</p> <p class="small text-muted no-margin">Select the Egg that will define how this server should operate.</p>
</div> </div>
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<label for="pPackId">Data Pack</label> <label for="pPackId">Data Pack</label>
<select name="pack_id" id="pPackId" class="form-control"></select> <select id="pPackId" name="pack_id" class="form-control"></select>
<p class="small text-muted no-margin">Select a data pack to be automatically installed on this server when first created.</p> <p class="small text-muted no-margin">Select a data pack to be automatically installed on this server when first created.</p>
</div> </div>
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<div class="checkbox checkbox-primary no-margin-bottom"> <div class="checkbox checkbox-primary no-margin-bottom">
<input id="pSkipScripting" name="skip_scripts" type="checkbox" value="1" /> <input type="checkbox" id="pSkipScripting" name="skip_scripts" {{ \Pterodactyl\Helpers\Utilities::checked('skip_scripts', 0) }} />
<label for="pSkipScripting" class="strong">Skip Egg Install Script</label> <label for="pSkipScripting" class="strong">Skip Egg Install Script</label>
</div> </div>
<p class="small text-muted no-margin">If the selected Egg has an install script attached to it, the script will run during install after the pack is installed. If you would like to skip this step, check this box.</p> <p class="small text-muted no-margin">If the selected Egg has an install script attached to it, the script will run during install after the pack is installed. If you would like to skip this step, check this box.</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Docker Configuration</h3> <h3 class="box-title">Docker Configuration</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<label for="pDefaultContainer">Docker Image</label> <label for="pDefaultContainer">Docker Image</label>
@ -236,23 +274,28 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Startup Configuration</h3> <h3 class="box-title">Startup Configuration</h3>
</div> </div>
<div class="box-body row"> <div class="box-body row">
<div class="form-group col-xs-12"> <div class="form-group col-xs-12">
<label for="pStartup">Startup Command</label> <label for="pStartup">Startup Command</label>
<input type="text" id="pStartup" value="{{ old('startup') }}" class="form-control" name="startup" /> <input type="text" id="pStartup" name="startup" value="{{ old('startup') }}" class="form-control" />
<p class="small text-muted no-margin">The following data substitutes are available for the startup command: <code>@{{SERVER_MEMORY}}</code>, <code>@{{SERVER_IP}}</code>, and <code>@{{SERVER_PORT}}</code>. They will be replaced with the allocated memory, server IP, and server port respectively.</p> <p class="small text-muted no-margin">The following data substitutes are available for the startup command: <code>@{{SERVER_MEMORY}}</code>, <code>@{{SERVER_IP}}</code>, and <code>@{{SERVER_PORT}}</code>. They will be replaced with the allocated memory, server IP, and server port respectively.</p>
</div> </div>
</div> </div>
<div class="box-header with-border" style="margin-top:-10px;"> <div class="box-header with-border" style="margin-top:-10px;">
<h3 class="box-title">Service Variables</h3> <h3 class="box-title">Service Variables</h3>
</div> </div>
<div class="box-body row" id="appendVariablesTo"></div> <div class="box-body row" id="appendVariablesTo"></div>
<div class="box-footer"> <div class="box-footer">
{!! csrf_field() !!} {!! csrf_field() !!}
<input type="submit" class="btn btn-success pull-right" value="Create Server" /> <input type="submit" class="btn btn-success pull-right" value="Create Server" />
@ -266,5 +309,84 @@
@section('footer-scripts') @section('footer-scripts')
@parent @parent
{!! Theme::js('vendor/lodash/lodash.js') !!} {!! Theme::js('vendor/lodash/lodash.js') !!}
<script type="application/javascript">
// Persist 'Service Variables'
function serviceVariablesUpdated(eggId, ids) {
@if (old('egg_id'))
// Check if the egg id matches.
if (eggId != '{{ old('egg_id') }}') {
return;
}
@if (old('environment'))
@foreach (old('environment') as $key => $value)
$('#' + ids['{{ $key }}']).val('{{ $value }}');
@endforeach
@endif
@endif
}
// END Persist 'Service Variables'
</script>
{!! Theme::js('js/admin/new-server.js') !!} {!! Theme::js('js/admin/new-server.js') !!}
<script type="application/javascript">
$(document).ready(function() {
// Persist 'Server Owner' select2
@if (old('owner_id'))
$.ajax({
url: '/admin/users/accounts.json?user_id={{ old('owner_id') }}',
dataType: 'json',
}).then(function (data) {
initUserIdSelect([ data ]);
});
@else
initUserIdSelect();
@endif
// END Persist 'Server Owner' select2
// Persist 'Node' select2
@if (old('node_id'))
$('#pNodeId').val('{{ old('node_id') }}').change();
// Persist 'Default Allocation' select2
@if (old('allocation_id'))
$('#pAllocation').val('{{ old('allocation_id') }}').change();
@endif
// END Persist 'Default Allocation' select2
// Persist 'Additional Allocations' select2
@if (old('allocation_additional'))
const additional_allocations = [];
@for ($i = 0; $i < count(old('allocation_additional')); $i++)
additional_allocations.push('{{ old('allocation_additional.'.$i)}}');
@endfor
$('#pAllocationAdditional').val(additional_allocations).change();
@endif
// END Persist 'Additional Allocations' select2
@endif
// END Persist 'Node' select2
// Persist 'Nest' select2
@if (old('nest_id'))
$('#pNestId').val('{{ old('nest_id') }}').change();
// Persist 'Egg' select2
@if (old('egg_id'))
$('#pEggId').val('{{ old('egg_id') }}').change();
@endif
// END Persist 'Egg' select2
// Persist 'Data Pack' select2
@if (old('pack_id'))
$('#pPackId').val('{{ old('pack_id') }}').change();
@endif
// END Persist 'Data Pack' select2
@endif
// END Persist 'Nest' select2
});
</script>
@endsection @endsection

View file

@ -173,7 +173,7 @@
</footer> </footer>
</div> </div>
@section('footer-scripts') @section('footer-scripts')
{!! Theme::js('js/keyboard.polyfill.js') !!} <script src="/js/keyboard.polyfill.js" type="application/javascript"></script>
<script>keyboardeventKeyPolyfill.polyfill();</script> <script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!} {!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!}
@ -185,7 +185,7 @@
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js?t={cache-version}') !!} {!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/select2/select2.full.min.js?t={cache-version}') !!} {!! Theme::js('vendor/select2/select2.full.min.js?t={cache-version}') !!}
{!! Theme::js('js/admin/functions.js?t={cache-version}') !!} {!! Theme::js('js/admin/functions.js?t={cache-version}') !!}
{!! Theme::js('js/autocomplete.js?t={cache-version}') !!} <script src="/js/autocomplete.js" type="application/javascript"></script>
@if(Auth::user()->root_admin) @if(Auth::user()->root_admin)
<script> <script>

View file

@ -52,7 +52,7 @@
{!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!} {!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/bootstrap/bootstrap.min.js?t={cache-version}') !!} {!! Theme::js('vendor/bootstrap/bootstrap.min.js?t={cache-version}') !!}
{!! Theme::js('js/autocomplete.js?t={cache-version}') !!} <script src="/js/autocomplete.js" type="application/javascript"></script>
{!! Theme::js('vendor/particlesjs/particles.min.js?t={cache-version}') !!} {!! Theme::js('vendor/particlesjs/particles.min.js?t={cache-version}') !!}
<script type="text/javascript"> <script type="text/javascript">
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */ /* particlesJS.load(@dom-id, @path-json, @callback (optional)); */

View file

@ -274,7 +274,7 @@
<div class="control-sidebar-bg"></div> <div class="control-sidebar-bg"></div>
</div> </div>
@section('footer-scripts') @section('footer-scripts')
{!! Theme::js('js/keyboard.polyfill.js?t={cache-version}') !!} <script src="/js/keyboard.polyfill.js" type="application/javascript"></script>
<script>keyboardeventKeyPolyfill.polyfill();</script> <script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!} {!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!}
@ -284,7 +284,7 @@
{!! Theme::js('vendor/adminlte/app.min.js?t={cache-version}') !!} {!! Theme::js('vendor/adminlte/app.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/socketio/socket.io.v203.min.js?t={cache-version}') !!} {!! Theme::js('vendor/socketio/socket.io.v203.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js?t={cache-version}') !!} {!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js?t={cache-version}') !!}
{!! Theme::js('js/autocomplete.js?t={cache-version}') !!} <script src="/js/autocomplete.js" type="application/javascript"></script>
@if(Auth::user()->root_admin) @if(Auth::user()->root_admin)
<script> <script>

View file

@ -54,11 +54,11 @@ class PackUpdateServiceTest extends TestCase
{ {
$model = factory(Pack::class)->make(); $model = factory(Pack::class)->make();
$this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [ $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [
'locked' => false, 'locked' => false,
'visible' => false, 'visible' => false,
'selectable' => false, 'selectable' => false,
'test-data' => 'value', 'test-data' => 'value',
])->once()->andReturn(1); ])->once()->andReturn(1);
$this->assertEquals(1, $this->service->handle($model, ['test-data' => 'value'])); $this->assertEquals(1, $this->service->handle($model, ['test-data' => 'value']));
} }
@ -88,11 +88,11 @@ class PackUpdateServiceTest extends TestCase
$this->repository->shouldReceive('setColumns')->with(['id', 'egg_id'])->once()->andReturnSelf() $this->repository->shouldReceive('setColumns')->with(['id', 'egg_id'])->once()->andReturnSelf()
->shouldReceive('find')->with($model->id)->once()->andReturn($model); ->shouldReceive('find')->with($model->id)->once()->andReturn($model);
$this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [ $this->repository->shouldReceive('withoutFreshModel->update')->with($model->id, [
'locked' => false, 'locked' => false,
'visible' => false, 'visible' => false,
'selectable' => false, 'selectable' => false,
'test-data' => 'value', 'test-data' => 'value',
])->once()->andReturn(1); ])->once()->andReturn(1);
$this->assertEquals(1, $this->service->handle($model->id, ['test-data' => 'value'])); $this->assertEquals(1, $this->service->handle($model->id, ['test-data' => 'value']));
} }