diff --git a/.gitignore b/.gitignore index a30c114f5..efbbccdcf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.DS_Store* .env .vagrant/* +.vscode/* composer.lock @@ -12,3 +13,7 @@ Vagrantfile node_modules yarn.lock node_modules + +_ide_helper_models.php + +_ide_helper.php diff --git a/app/Http/Controllers/Admin/OptionController.php b/app/Http/Controllers/Admin/OptionController.php new file mode 100644 index 000000000..68ddfaf9e --- /dev/null +++ b/app/Http/Controllers/Admin/OptionController.php @@ -0,0 +1,210 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Http\Controllers\Admin; + +use Log; +use Alert; +use Javascript; +use Illuminate\Http\Request; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Http\Controllers\Controller; +use Pterodactyl\Repositories\OptionRepository; +use Pterodactyl\Repositories\VariableRepository; +use Pterodactyl\Exceptions\DisplayValidationException; + +class OptionController extends Controller +{ + /** + * Handles request to view page for adding new option. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function new(Request $request) + { + $services = Service::with('options')->get(); + Javascript::put(['services' => $services->keyBy('id')]); + + return view('admin.services.options.new', ['services' => $services]); + } + + /** + * Handles POST request to create a new option. + * + * @param Request $request + * @return \Illuminate\Response\RedirectResponse + */ + public function create(Request $request) + { + $repo = new OptionRepository; + + try { + $option = $repo->create($request->intersect([ + 'service_id', 'name', 'description', 'tag', + 'docker_image', 'startup', 'config_from', 'config_startup', + 'config_logs', 'config_files', 'config_stop', + ])); + Alert::success('Successfully created new service option.')->flash(); + + return redirect()->route('admin.services.option.view', $option->id); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.services.option.new')->withErrors(json_decode($ex->getMessage()))->withInput(); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occurred while attempting to create this service. This error has been logged.')->flash(); + } + + return redirect()->route('admin.services.option.new')->withInput(); + } + + /** + * Handles POST request to create a new option variable. + * + * @param Request $request + * @param int $id The ID of the service option to assign this variable to. + * @return \Illuminate\Response\RedirectResponse + */ + public function createVariable(Request $request, $id) + { + $repo = new VariableRepository; + + try { + $variable = $repo->create($id, $request->only([ + 'name', 'description', 'env_variable', + 'default_value', 'options', 'rules', + ])); + + Alert::success('New variable successfully assigned to this service option.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.services.option.variables', $id)->withErrors(json_decode($ex->getMessage())); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception was encountered while attempting to process that request. This error has been logged.')->flash(); + } + + return redirect()->route('admin.services.option.variables', $id); + } + + /** + * Display option overview page. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewConfiguration(Request $request, $id) + { + return view('admin.services.options.view', ['option' => ServiceOption::findOrFail($id)]); + } + + /** + * Display variable overview page for a service option. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewVariables(Request $request, $id) + { + return view('admin.services.options.variables', ['option' => ServiceOption::with('variables')->findOrFail($id)]); + } + + /** + * Handles POST when editing a configration for a service option. + * + * @param Request $request + * @return \Illuminate\Response\RedirectResponse + */ + public function editConfiguration(Request $request, $id) + { + $repo = new OptionRepository; + + try { + if ($request->input('action') !== 'delete') { + $repo->update($id, $request->intersect([ + 'name', 'description', 'tag', 'docker_image', 'startup', + 'config_from', 'config_stop', 'config_logs', 'config_files', 'config_startup', + ])); + Alert::success('Service option configuration has been successfully updated.')->flash(); + } else { + $option = ServiceOption::with('service')->where('id', $id)->first(); + $repo->delete($id); + Alert::success('Successfully deleted service option from the system.')->flash(); + + return redirect()->route('admin.services.view', $option->service_id); + } + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.services.option.view', $id)->withErrors(json_decode($ex->getMessage())); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception occurred while attempting to perform that action. This error has been logged.')->flash(); + } + + return redirect()->route('admin.services.option.view', $id); + } + + /** + * Handles POST when editing a configration for a service option. + * + * @param Request $request + * @param int $option + * @param int $variable + * @return \Illuminate\Response\RedirectResponse + */ + public function editVariable(Request $request, $option, $variable) + { + $repo = new VariableRepository; + + try { + if ($request->input('action') !== 'delete') { + $variable = $repo->update($variable, $request->only([ + 'name', 'description', 'env_variable', + 'default_value', 'options', 'rules', + ])); + Alert::success("The service variable '{$variable->name}' has been updated.")->flash(); + } else { + $repo->delete($variable); + Alert::success('That service variable has been deleted.')->flash(); + } + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.services.option.variables', $option)->withErrors(json_decode($ex->getMessage())); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An unhandled exception was encountered while attempting to process that request. This error has been logged.')->flash(); + } + + return redirect()->route('admin.services.option.variables', $option); + } +} diff --git a/app/Http/Controllers/Admin/PackController.php b/app/Http/Controllers/Admin/PackController.php index f4e577d0e..46674ae02 100644 --- a/app/Http/Controllers/Admin/PackController.php +++ b/app/Http/Controllers/Admin/PackController.php @@ -27,130 +27,166 @@ namespace Pterodactyl\Http\Controllers\Admin; use Log; use Alert; use Storage; -use Pterodactyl\Models; use Illuminate\Http\Request; +use Pterodactyl\Models\Pack; +use Pterodactyl\Models\Service; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; -use Pterodactyl\Repositories\ServiceRepository\Pack; +use Pterodactyl\Repositories\PackRepository; use Pterodactyl\Exceptions\DisplayValidationException; class PackController extends Controller { - public function __construct() + /** + * Display listing of all packs on the system. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function index(Request $request) { - // + $packs = Pack::with('option')->withCount('servers'); + + if (! is_null($request->input('query'))) { + $packs->search($request->input('query')); + } + + return view('admin.packs.index', ['packs' => $packs->paginate(50)]); } - public function listAll(Request $request) + /** + * Display new pack creation form. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function new(Request $request) { - return view('admin.services.packs.index', ['services' => Models\Service::all()]); - } - - public function listByOption(Request $request, $id) - { - return view('admin.services.packs.byoption', [ - 'option' => Models\ServiceOption::with('service', 'packs')->findOrFail($id), + return view('admin.packs.new', [ + 'services' => Service::with('options')->get(), ]); } - public function listByService(Request $request, $id) + /** + * Display new pack creation modal for use with template upload. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function newTemplate(Request $request) { - return view('admin.services.packs.byservice', [ - 'service' => Models\Service::with('options', 'options.packs')->findOrFail($id), - ]); - } - - public function new(Request $request, $opt = null) - { - return view('admin.services.packs.new', [ - 'services' => Models\Service::with('options')->get(), + return view('admin.packs.modal', [ + 'services' => Service::with('options')->get(), ]); } + /** + * Handle create pack request and route user to location. + * + * @param Request $request + * @return \Illuminate\View\View + */ public function create(Request $request) { - try { - $repo = new Pack; - $pack = $repo->create($request->only([ - 'name', 'version', 'description', - 'option', 'selectable', 'visible', - 'file_upload', - ])); - Alert::success('Successfully created new service!')->flash(); + $repo = new PackRepository; - return redirect()->route('admin.services.packs.edit', $pack->id)->withInput(); + try { + if ($request->input('action') === 'from_template') { + $pack = $repo->createWithTemplate($request->intersect(['option_id', 'file_upload'])); + } else { + $pack = $repo->create($request->intersect([ + 'name', 'description', 'version', 'option_id', + 'selectable', 'visible', 'locked', 'file_upload', + ])); + } + Alert::success('Pack successfully created on the system.')->flash(); + + return redirect()->route('admin.packs.view', $pack->id); } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.packs.new', $request->input('option'))->withErrors(json_decode($ex->getMessage()))->withInput(); + return redirect()->route('admin.packs.new')->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An error occured while attempting to add a new service pack.')->flash(); + Alert::danger('An error occured while attempting to add a new service pack. This error has been logged.')->flash(); } - return redirect()->route('admin.services.packs.new', $request->input('option'))->withInput(); + return redirect()->route('admin.packs.new')->withInput(); } - public function edit(Request $request, $id) + /** + * Display pack view template to user. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function view(Request $request, $id) { - $pack = Models\ServicePack::with('option.service')->findOrFail($id); - - return view('admin.services.packs.edit', [ - 'pack' => $pack, - 'services' => Models\Service::all()->load('options'), - 'files' => Storage::files('packs/' . $pack->uuid), + return view('admin.packs.view', [ + 'pack' => Pack::with('servers.node', 'servers.user')->findOrFail($id), + 'services' => Service::with('options')->get(), ]); } + /** + * Handle updating or deleting pack information. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ public function update(Request $request, $id) { - if (! is_null($request->input('action_delete'))) { - try { - $repo = new Pack; - $repo->delete($id); - Alert::success('The requested service pack has been deleted from the system.')->flash(); + $repo = new PackRepository; - return redirect()->route('admin.services.packs'); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to delete this pack.')->flash(); - } - - return redirect()->route('admin.services.packs.edit', $id); - } else { - try { - $repo = new Pack; - $repo->update($id, $request->only([ - 'name', 'version', 'description', - 'option', 'selectable', 'visible', + try { + if ($request->input('action') !== 'delete') { + $pack = $repo->update($id, $request->intersect([ + 'name', 'description', 'version', + 'option_id', 'selectable', 'visible', 'locked', ])); - Alert::success('Service pack has been successfully updated.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.packs.edit', $id)->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to add edit this pack.')->flash(); - } + Alert::success('Pack successfully updated.')->flash(); + } else { + $repo->delete($id); + Alert::success('Pack was successfully deleted from the system.')->flash(); - return redirect()->route('admin.services.packs.edit', $id); + return redirect()->route('admin.packs'); + } + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.packs.view', $id)->withErrors(json_decode($ex->getMessage())); + } catch (DisplayException $ex) { + Alert::danger($ex->getMessage())->flash(); + } catch (\Exception $ex) { + Log::error($ex); + Alert::danger('An error occured while attempting to edit this service pack. This error has been logged.')->flash(); } + + return redirect()->route('admin.packs.view', $id); } + /** + * Creates an archive of the pack and downloads it to the browser. + * + * @param Request $request + * @param int $id + * @param bool $files + * @return \Illuminate\Response\BinaryFileResponse + */ public function export(Request $request, $id, $files = false) { - $pack = Models\ServicePack::findOrFail($id); + $pack = Pack::findOrFail($id); $json = [ 'name' => $pack->name, 'version' => $pack->version, - 'description' => $pack->dscription, - 'selectable' => (bool) $pack->selectable, - 'visible' => (bool) $pack->visible, + 'description' => $pack->description, + 'selectable' => $pack->selectable, + 'visible' => $pack->visible, + 'locked' => $pack->locked, ]; $filename = tempnam(sys_get_temp_dir(), 'pterodactyl_'); - if ((bool) $files) { + if ($files === 'with-files') { $zip = new \ZipArchive; if (! $zip->open($filename, \ZipArchive::CREATE)) { abort(503, 'Unable to open file for writing.'); @@ -175,31 +211,4 @@ class PackController extends Controller ])->deleteFileAfterSend(true); } } - - public function uploadForm(Request $request, $for = null) - { - return view('admin.services.packs.upload', [ - 'services' => Models\Service::all()->load('options'), - ]); - } - - public function postUpload(Request $request) - { - try { - $repo = new Pack; - $pack = $repo->createWithTemplate($request->only(['option', 'file_upload'])); - Alert::success('Successfully created new service!')->flash(); - - return redirect()->route('admin.services.packs.edit', $pack->id)->withInput(); - } catch (DisplayValidationException $ex) { - return redirect()->back()->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to add a new service pack.')->flash(); - } - - return redirect()->back(); - } } diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 6b1808516..56dfdbad3 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -493,6 +493,8 @@ class ServersController extends Controller $repo->updateStartup($id, $request->except('_token'), true); Alert::success('Startup variables were successfully modified and assigned for this server.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('admin.servers.view.startup', $id)->withErrors(json_decode($ex->getMessage())); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (TransferException $ex) { diff --git a/app/Http/Controllers/Admin/ServiceController.php b/app/Http/Controllers/Admin/ServiceController.php index e831c8683..bcf4d9008 100644 --- a/app/Http/Controllers/Admin/ServiceController.php +++ b/app/Http/Controllers/Admin/ServiceController.php @@ -26,7 +26,6 @@ namespace Pterodactyl\Http\Controllers\Admin; use Log; use Alert; -use Storage; use Pterodactyl\Models; use Illuminate\Http\Request; use Pterodactyl\Exceptions\DisplayException; @@ -36,276 +35,118 @@ use Pterodactyl\Exceptions\DisplayValidationException; class ServiceController extends Controller { - public function __construct() - { - // - } - - public function getIndex(Request $request) + /** + * Display service overview page. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function index(Request $request) { return view('admin.services.index', [ - 'services' => Models\Service::withCount('servers')->get(), + 'services' => Models\Service::withCount('servers', 'options', 'packs')->get(), ]); } - public function getNew(Request $request) + /** + * Display create service page. + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function new(Request $request) { return view('admin.services.new'); } - public function postNew(Request $request) + /** + * Return base view for a service. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function view(Request $request, $id) { + return view('admin.services.view', [ + 'service' => Models\Service::with('options', 'options.servers')->findOrFail($id), + ]); + } + + /** + * Return function editing view for a service. + * + * @param Request $request + * @param int $id + * @return \Illuminate\View\View + */ + public function viewFunctions(Request $request, $id) + { + return view('admin.services.functions', ['service' => Models\Service::findOrFail($id)]); + } + + /** + * Handle post action for new service. + * + * @param Request $request + * @return \Illuminate\Response\RedirectResponse + */ + public function create(Request $request) + { + $repo = new ServiceRepository; + try { - $repo = new ServiceRepository\Service; - $service = $repo->create($request->only([ - 'name', 'description', 'file', - 'executable', 'startup', + $service = $repo->create($request->intersect([ + 'name', 'description', 'folder', 'startup', ])); Alert::success('Successfully created new service!')->flash(); - return redirect()->route('admin.services.service', $service->id); + return redirect()->route('admin.services.view', $service->id); } catch (DisplayValidationException $ex) { return redirect()->route('admin.services.new')->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An error occured while attempting to add a new service.')->flash(); + Alert::danger('An error occured while attempting to add a new service. This error has been logged.')->flash(); } return redirect()->route('admin.services.new')->withInput(); } - public function getService(Request $request, $service) + /** + * Edits configuration for a specific service. + * + * @param Request $request + * @param int $id + * @return \Illuminate\Response\RedirectResponse + */ + public function edit(Request $request, $id) { - return view('admin.services.view', [ - 'service' => Models\Service::with('options', 'options.servers')->findOrFail($service), - ]); - } + $repo = new ServiceRepository; + $redirectTo = ($request->input('redirect_to')) ? 'admin.services.view.functions' : 'admin.services.view'; - public function postService(Request $request, $service) - { try { - $repo = new ServiceRepository\Service; - $repo->update($service, $request->only([ - 'name', 'description', 'file', - 'executable', 'startup', - ])); - Alert::success('Successfully updated this service.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.service', $service)->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occurred while attempting to update this service.')->flash(); - } + if ($request->input('action') !== 'delete') { + $repo->update($id, $request->intersect([ + 'name', 'description', 'folder', 'startup', 'index_file', + ])); + Alert::success('Service has been updated successfully.')->flash(); + } else { + $repo->delete($id); + Alert::success('Successfully deleted service from the system.')->flash(); - return redirect()->route('admin.services.service', $service)->withInput(); - } - - public function deleteService(Request $request, $service) - { - try { - $repo = new ServiceRepository\Service; - $repo->delete($service); - Alert::success('Successfully deleted that service.')->flash(); - - return redirect()->route('admin.services'); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error was encountered while attempting to delete that service.')->flash(); - } - - return redirect()->route('admin.services.service', $service); - } - - public function getOption(Request $request, $service, $option) - { - $option = Models\ServiceOption::with('service', 'variables')->findOrFail($option); - $option->setRelation('servers', $option->servers()->with('user')->paginate(25)); - - return view('admin.services.options.view', ['option' => $option]); - } - - public function postOption(Request $request, $service, $option) - { - try { - $repo = new ServiceRepository\Option; - $repo->update($option, $request->only([ - 'name', 'description', 'tag', - 'executable', 'docker_image', 'startup', - ])); - Alert::success('Option settings successfully updated.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.option', [$service, $option])->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to modify this option.')->flash(); - } - - return redirect()->route('admin.services.option', [$service, $option])->withInput(); - } - - public function deleteOption(Request $request, $service, $option) - { - try { - $repo = new ServiceRepository\Option; - $repo->delete($option); - - Alert::success('Successfully deleted that option.')->flash(); - - return redirect()->route('admin.services.service', $service); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error was encountered while attempting to delete this option.')->flash(); - } - - return redirect()->route('admin.services.option', [$service, $option]); - } - - public function postOptionVariable(Request $request, $service, $option, $variable) - { - try { - $repo = new ServiceRepository\Variable; - - // Because of the way old() works on the display side we prefix all of the variables with thier ID - // We need to remove that prefix here since the repo doesn't want it. - $data = [ - 'user_viewable' => '0', - 'user_editable' => '0', - 'required' => '0', - ]; - foreach ($request->except(['_token']) as $id => $val) { - $data[str_replace($variable . '_', '', $id)] = $val; + return redirect()->route('admin.services'); } - $repo->update($variable, $data); - Alert::success('Successfully updated variable.')->flash(); } catch (DisplayValidationException $ex) { - $data = []; - foreach (json_decode($ex->getMessage(), true) as $id => $val) { - $data[$variable . '_' . $id] = $val; - } - - return redirect()->route('admin.services.option', [$service, $option])->withErrors((object) $data)->withInput(); + return redirect()->route($redirectTo, $id)->withErrors(json_decode($ex->getMessage()))->withInput(); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { Log::error($ex); - Alert::danger('An error occurred while attempting to update this service.')->flash(); + Alert::danger('An error occurred while attempting to update this service. This error has been logged.')->flash(); } - return redirect()->route('admin.services.option', [$service, $option])->withInput(); - } - - public function getNewVariable(Request $request, $service, $option) - { - return view('admin.services.options.variable', [ - 'option' => Models\ServiceOption::with('service')->findOrFail($option), - ]); - } - - public function postNewVariable(Request $request, $service, $option) - { - try { - $repo = new ServiceRepository\Variable; - $repo->create($option, $request->only([ - 'name', 'description', 'env_variable', - 'default_value', 'user_viewable', - 'user_editable', 'required', 'regex', - ])); - Alert::success('Successfully added new variable to this option.')->flash(); - - return redirect()->route('admin.services.option', [$service, $option]); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.option.variable.new', [$service, $option])->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occurred while attempting to add this variable.')->flash(); - } - - return redirect()->route('admin.services.option.variable.new', [$service, $option])->withInput(); - } - - public function newOption(Request $request, $service) - { - return view('admin.services.options.new', [ - 'service' => Models\Service::findOrFail($service), - ]); - } - - public function postNewOption(Request $request, $service) - { - try { - $repo = new ServiceRepository\Option; - $id = $repo->create($service, $request->except([ - '_token', - ])); - Alert::success('Successfully created new service option.')->flash(); - - return redirect()->route('admin.services.option', [$service, $id]); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.services.option.new', $service)->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to add this service option.')->flash(); - } - - return redirect()->route('admin.services.option.new', $service)->withInput(); - } - - public function deleteVariable(Request $request, $service, $option, $variable) - { - try { - $repo = new ServiceRepository\Variable; - $repo->delete($variable); - Alert::success('Deleted variable.')->flash(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An error occured while attempting to delete that variable.')->flash(); - } - - return redirect()->route('admin.services.option', [$service, $option]); - } - - public function getConfiguration(Request $request, $serviceId) - { - $service = Models\Service::findOrFail($serviceId); - - return view('admin.services.config', [ - 'service' => $service, - 'contents' => [ - 'json' => Storage::get('services/' . $service->file . '/main.json'), - 'index' => Storage::get('services/' . $service->file . '/index.js'), - ], - ]); - } - - public function postConfiguration(Request $request, $serviceId) - { - try { - $repo = new ServiceRepository\Service; - $repo->updateFile($serviceId, $request->only(['file', 'contents'])); - - return response('', 204); - } catch (DisplayException $ex) { - return response()->json([ - 'error' => $ex->getMessage(), - ], 503); - } catch (\Exception $ex) { - Log::error($ex); - - return response()->json([ - 'error' => 'An error occured while attempting to save the file.', - ], 503); - } + return redirect()->route($redirectTo, $id); } } diff --git a/app/Http/Controllers/Daemon/PackController.php b/app/Http/Controllers/Daemon/PackController.php index e96aa6ee5..4d35f6d77 100644 --- a/app/Http/Controllers/Daemon/PackController.php +++ b/app/Http/Controllers/Daemon/PackController.php @@ -47,7 +47,7 @@ class PackController extends Controller */ public function pull(Request $request, $uuid) { - $pack = Models\ServicePack::where('uuid', $uuid)->first(); + $pack = Models\Pack::where('uuid', $uuid)->first(); if (! $pack) { return response()->json(['error' => 'No such pack.'], 404); @@ -68,7 +68,7 @@ class PackController extends Controller */ public function hash(Request $request, $uuid) { - $pack = Models\ServicePack::where('uuid', $uuid)->first(); + $pack = Models\Pack::where('uuid', $uuid)->first(); if (! $pack) { return response()->json(['error' => 'No such pack.'], 404); diff --git a/app/Http/Controllers/Daemon/ServiceController.php b/app/Http/Controllers/Daemon/ServiceController.php index e362f0d06..99d69cf02 100644 --- a/app/Http/Controllers/Daemon/ServiceController.php +++ b/app/Http/Controllers/Daemon/ServiceController.php @@ -24,36 +24,28 @@ namespace Pterodactyl\Http\Controllers\Daemon; -use Storage; -use Pterodactyl\Models; use Illuminate\Http\Request; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; use Pterodactyl\Http\Controllers\Controller; class ServiceController extends Controller { - /** - * Controller Constructor. - */ - public function __construct() - { - // - } - /** * Returns a listing of all services currently on the system, * as well as the associated files and the file hashes for * caching purposes. * * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\JsonResponse */ public function list(Request $request) { $response = []; - foreach (Models\Service::all() as &$service) { - $response[$service->file] = [ - 'main.json' => sha1_file(storage_path('app/services/' . $service->file . '/main.json')), - 'index.js' => sha1_file(storage_path('app/services/' . $service->file . '/index.js')), + foreach (Service::all() as $service) { + $response[$service->folder] = [ + 'main.json' => sha1($this->getConfiguration($service->id)->toJson()), + 'index.js' => sha1($service->index_file), ]; } @@ -64,16 +56,45 @@ class ServiceController extends Controller * Returns the contents of the requested file for the given service. * * @param \Illuminate\Http\Request $request - * @param string $service + * @param string $folder * @param string $file - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\FileResponse */ - public function pull(Request $request, $service, $file) + public function pull(Request $request, $folder, $file) { - if (! Storage::exists('services/' . $service . '/' . $file)) { - return response()->json(['error' => 'No such file.'], 404); + $service = Service::where('folder', $folder)->firstOrFail(); + + if ($file === 'index.js') { + return response($service->index_file)->header('Content-Type', 'text/plain'); + } elseif ($file === 'main.json') { + return response()->json($this->getConfiguration($service->id)); } - return response()->file(storage_path('app/services/' . $service . '/' . $file)); + return abort(404); + } + + /** + * Returns a `main.json` file based on the configuration + * of each service option. + * + * @param int $id + * @return \Illuminate\Support\Collection + */ + protected function getConfiguration($id) + { + $options = ServiceOption::where('service_id', $id)->get(); + + return $options->mapWithKeys(function ($item) use ($options) { + return [ + $item->tag => array_filter([ + 'symlink' => $options->where('id', $item->config_from)->pluck('tag')->pop(), + 'startup' => json_decode($item->config_startup), + 'stop' => $item->config_stop, + 'configs' => json_decode($item->config_files), + 'log' => json_decode($item->config_logs), + 'query' => 'none', + ]), + ]; + }); } } diff --git a/app/Http/Controllers/Remote/RemoteController.php b/app/Http/Controllers/Remote/RemoteController.php index 2e8b782a1..93dd672e1 100644 --- a/app/Http/Controllers/Remote/RemoteController.php +++ b/app/Http/Controllers/Remote/RemoteController.php @@ -98,10 +98,6 @@ class RemoteController extends Controller ], 403); } - // Passes Validation, Setup Notifications - $notify = new NotificationService($server); - $notify->pass($request->input('notification')); - return response('', 201); } diff --git a/app/Http/Controllers/Server/ServerController.php b/app/Http/Controllers/Server/ServerController.php index 7be93ff61..c1514e334 100644 --- a/app/Http/Controllers/Server/ServerController.php +++ b/app/Http/Controllers/Server/ServerController.php @@ -24,7 +24,6 @@ namespace Pterodactyl\Http\Controllers\Server; -use DB; use Log; use Uuid; use Alert; @@ -209,37 +208,20 @@ class ServerController extends Controller public function getStartup(Request $request, $uuid) { $server = Models\Server::byUuid($uuid); - $server->load(['allocations' => function ($query) use ($server) { - $query->where('id', $server->allocation_id); - }]); + $server->load(['node', 'allocation', 'variables.variable']); + $this->authorize('view-startup', $server); - $variables = Models\ServiceVariable::select( - 'service_variables.*', - DB::raw('COALESCE(server_variables.variable_value, service_variables.default_value) as a_serverValue') - )->leftJoin('server_variables', 'server_variables.variable_id', '=', 'service_variables.id') - ->where('service_variables.option_id', $server->option_id) - ->where('server_variables.server_id', $server->id) - ->get(); - - $service = Models\Service::select( - DB::raw('IFNULL(service_options.executable, services.executable) as executable') - )->leftJoin('service_options', 'service_options.service_id', '=', 'services.id') - ->where('service_options.id', $server->option_id) - ->where('services.id', $server->service_id) - ->first(); - - $allocation = $server->allocations->pop(); - $ServerVariable = [ + $replacements = [ '{{SERVER_MEMORY}}' => $server->memory, - '{{SERVER_IP}}' => $allocation->ip, - '{{SERVER_PORT}}' => $allocation->port, + '{{SERVER_IP}}' => $server->allocation->ip, + '{{SERVER_PORT}}' => $server->allocation->port, ]; - $processed = str_replace(array_keys($ServerVariable), array_values($ServerVariable), $server->startup); - foreach ($variables as &$variable) { - $replace = ($variable->user_viewable === 1) ? $variable->a_serverValue : '[hidden]'; - $processed = str_replace('{{' . $variable->env_variable . '}}', $replace, $processed); + $processed = str_replace(array_keys($replacements), array_values($replacements), $server->startup); + foreach ($server->variables as $v) { + $replace = ($v->user_can_view) ? $v->variable_value : '[hidden]'; + $processed = str_replace('{{' . $v->variable->env_variable . '}}', $replace, $processed); } $server->js(); @@ -247,8 +229,8 @@ class ServerController extends Controller return view('server.settings.startup', [ 'server' => $server, 'node' => $server->node, - 'variables' => $variables->where('user_viewable', 1), - 'service' => $service, + 'variables' => $server->variables->where('user_can_view', true), + 'service' => $server->service, 'processedStartup' => $processed, ]); } @@ -311,6 +293,8 @@ class ServerController extends Controller $repo = new ServerRepository; $repo->updateStartup($server->id, $request->except('_token')); Alert::success('Server startup variables were successfully updated.')->flash(); + } catch (DisplayValidationException $ex) { + return redirect()->route('server.settings.startup', $uuid)->withErrors(json_decode($ex->getMessage())); } catch (DisplayException $ex) { Alert::danger($ex->getMessage())->flash(); } catch (\Exception $ex) { diff --git a/app/Http/Routes/AdminRoutes.php b/app/Http/Routes/AdminRoutes.php index c25cb91e3..f8cbc17fa 100644 --- a/app/Http/Routes/AdminRoutes.php +++ b/app/Http/Routes/AdminRoutes.php @@ -386,126 +386,99 @@ class AdminRoutes ], function () use ($router) { $router->get('/', [ 'as' => 'admin.services', - 'uses' => 'Admin\ServiceController@getIndex', + 'uses' => 'Admin\ServiceController@index', ]); $router->get('/new', [ 'as' => 'admin.services.new', - 'uses' => 'Admin\ServiceController@getNew', + 'uses' => 'Admin\ServiceController@new', ]); $router->post('/new', [ - 'uses' => 'Admin\ServiceController@postNew', + 'uses' => 'Admin\ServiceController@create', ]); - $router->get('/service/{id}', [ - 'as' => 'admin.services.service', - 'uses' => 'Admin\ServiceController@getService', + $router->get('/view/{id}', [ + 'as' => 'admin.services.view', + 'uses' => 'Admin\ServiceController@view', ]); - $router->post('/service/{id}', [ - 'uses' => 'Admin\ServiceController@postService', + $router->post('/view/{id}', 'Admin\ServiceController@edit'); + + $router->get('/view/{id}/functions', [ + 'as' => 'admin.services.view.functions', + 'uses' => 'Admin\ServiceController@viewFunctions', ]); - $router->delete('/service/{id}', [ - 'uses' => 'Admin\ServiceController@deleteService', + $router->delete('/view/{id}', [ + 'uses' => 'Admin\ServiceController@delete', ]); - $router->get('/service/{id}/configuration', [ - 'as' => 'admin.services.service.config', - 'uses' => 'Admin\ServiceController@getConfiguration', - ]); - - $router->post('/service/{id}/configuration', [ - 'uses' => 'Admin\ServiceController@postConfiguration', - ]); - - $router->get('/service/{service}/option/new', [ + // --------------------- + // Service Option Routes + // --------------------- + $router->get('/option/new', [ 'as' => 'admin.services.option.new', - 'uses' => 'Admin\ServiceController@newOption', + 'uses' => 'Admin\OptionController@new', ]); - $router->post('/service/{service}/option/new', [ - 'uses' => 'Admin\ServiceController@postNewOption', + $router->post('/option/new', 'Admin\OptionController@create'); + + $router->get('/option/{id}', [ + 'as' => 'admin.services.option.view', + 'uses' => 'Admin\OptionController@viewConfiguration', ]); - $router->get('/service/{service}/option/{option}', [ - 'as' => 'admin.services.option', - 'uses' => 'Admin\ServiceController@getOption', + $router->post('/option/{id}', 'Admin\OptionController@editConfiguration'); + + $router->get('/option/{id}/variables', [ + 'as' => 'admin.services.option.variables', + 'uses' => 'Admin\OptionController@viewVariables', ]); - $router->post('/service/{service}/option/{option}', [ - 'uses' => 'Admin\ServiceController@postOption', - ]); + $router->post('/option/{id}/variables', 'Admin\OptionController@createVariable'); - $router->delete('/service/{service}/option/{id}', [ - 'uses' => 'Admin\ServiceController@deleteOption', - ]); - - $router->get('/service/{service}/option/{option}/variable/new', [ - 'as' => 'admin.services.option.variable.new', - 'uses' => 'Admin\ServiceController@getNewVariable', - ]); - - $router->post('/service/{service}/option/{option}/variable/new', [ - 'uses' => 'Admin\ServiceController@postNewVariable', - ]); - - $router->post('/service/{service}/option/{option}/variable/{variable}', [ - 'as' => 'admin.services.option.variable', - 'uses' => 'Admin\ServiceController@postOptionVariable', - ]); - - $router->get('/service/{service}/option/{option}/variable/{variable}/delete', [ - 'as' => 'admin.services.option.variable.delete', - 'uses' => 'Admin\ServiceController@deleteVariable', + $router->post('/option/{id}/variables/{variable}', [ + 'as' => 'admin.services.option.variables.edit', + 'uses' => 'Admin\OptionController@editVariable', ]); }); // Service Packs $router->group([ - 'prefix' => 'admin/services/packs', + 'prefix' => 'admin/packs', 'middleware' => [ 'auth', 'admin', 'csrf', ], ], function () use ($router) { - $router->get('/new/{option?}', [ - 'as' => 'admin.services.packs.new', + $router->get('/', [ + 'as' => 'admin.packs', + 'uses' => 'Admin\PackController@index', + ]); + + $router->get('/new', [ + 'as' => 'admin.packs.new', 'uses' => 'Admin\PackController@new', ]); - $router->post('/new', [ - 'uses' => 'Admin\PackController@create', + + $router->post('/new', 'Admin\PackController@create'); + + $router->get('/new/template', [ + 'as' => 'admin.packs.new.template', + 'uses' => 'Admin\PackController@newTemplate', ]); - $router->get('/upload/{option?}', [ - 'as' => 'admin.services.packs.uploadForm', - 'uses' => 'Admin\PackController@uploadForm', + + $router->get('/view/{id}', [ + 'as' => 'admin.packs.view', + 'uses' => 'Admin\PackController@view', ]); - $router->post('/upload', [ - 'uses' => 'Admin\PackController@postUpload', - ]); - $router->get('/', [ - 'as' => 'admin.services.packs', - 'uses' => 'Admin\PackController@listAll', - ]); - $router->get('/for/option/{option}', [ - 'as' => 'admin.services.packs.option', - 'uses' => 'Admin\PackController@listByOption', - ]); - $router->get('/for/service/{service}', [ - 'as' => 'admin.services.packs.service', - 'uses' => 'Admin\PackController@listByService', - ]); - $router->get('/edit/{pack}', [ - 'as' => 'admin.services.packs.edit', - 'uses' => 'Admin\PackController@edit', - ]); - $router->post('/edit/{pack}', [ - 'uses' => 'Admin\PackController@update', - ]); - $router->get('/edit/{pack}/export/{archive?}', [ - 'as' => 'admin.services.packs.export', + + $router->post('/view/{id}', 'Admin\PackController@update'); + + $router->post('/view/{id}/export/{files?}', [ + 'as' => 'admin.packs.view.export', 'uses' => 'Admin\PackController@export', ]); }); diff --git a/app/Models/Pack.php b/app/Models/Pack.php new file mode 100644 index 000000000..0a6310660 --- /dev/null +++ b/app/Models/Pack.php @@ -0,0 +1,125 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Models; + +use File; +use Storage; +use Illuminate\Database\Eloquent\Model; +use Nicolaslopezj\Searchable\SearchableTrait; + +class Pack extends Model +{ + use SearchableTrait; + + /** + * The table associated with the model. + * + * @var string + */ + protected $table = 'packs'; + + /** + * Fields that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'option_id', 'name', 'version', 'description', 'selectable', 'visible', 'locked', + ]; + + /** + * Cast values to correct type. + * + * @var array + */ + protected $casts = [ + 'option_id' => 'integer', + 'selectable' => 'boolean', + 'visible' => 'boolean', + 'locked' => 'boolean', + ]; + + /** + * Parameters for search querying. + * + * @var array + */ + protected $searchable = [ + 'columns' => [ + 'packs.name' => 10, + 'packs.uuid' => 8, + 'service_options.name' => 6, + 'service_options.tag' => 5, + 'service_options.docker_image' => 5, + 'packs.version' => 2, + ], + 'joins' => [ + 'service_options' => ['packs.option_id', 'service_options.id'], + ], + ]; + + /** + * Returns all of the archived files for a given pack. + * + * @param bool $collection + * @return \Illuminate\Support\Collection|object + */ + public function files($collection = false) + { + $files = collect(Storage::files('packs/' . $this->uuid)); + + $files = $files->map(function ($item) { + $path = storage_path('app/' . $item); + + return (object) [ + 'name' => basename($item), + 'hash' => sha1_file($path), + 'size' => File::humanReadableSize($path), + ]; + }); + + return ($collection) ? $files : (object) $files->all(); + } + + /** + * Gets option associated with a service pack. + * + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function option() + { + return $this->belongsTo(ServiceOption::class); + } + + /** + * Gets servers associated with a pack. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function servers() + { + return $this->hasMany(Server::class); + } +} diff --git a/app/Models/Server.php b/app/Models/Server.php index 524708cde..c341aad70 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -65,43 +65,50 @@ class Server extends Model */ protected $guarded = ['id', 'installed', 'created_at', 'updated_at', 'deleted_at']; - /** - * Cast values to correct type. - * - * @var array - */ - protected $casts = [ - 'node_id' => 'integer', - 'suspended' => 'integer', - 'owner_id' => 'integer', - 'memory' => 'integer', - 'swap' => 'integer', - 'disk' => 'integer', - 'io' => 'integer', - 'cpu' => 'integer', - 'oom_disabled' => 'integer', - 'allocation_id' => 'integer', - 'service_id' => 'integer', - 'option_id' => 'integer', - 'pack_id' => 'integer', - 'installed' => 'integer', - ]; + /** + * Cast values to correct type. + * + * @var array + */ + protected $casts = [ + 'node_id' => 'integer', + 'suspended' => 'integer', + 'owner_id' => 'integer', + 'memory' => 'integer', + 'swap' => 'integer', + 'disk' => 'integer', + 'io' => 'integer', + 'cpu' => 'integer', + 'oom_disabled' => 'integer', + 'allocation_id' => 'integer', + 'service_id' => 'integer', + 'option_id' => 'integer', + 'pack_id' => 'integer', + 'installed' => 'integer', + ]; + /** + * Parameters for search querying. + * + * @var array + */ protected $searchable = [ - 'columns' => [ - 'servers.name' => 10, - 'servers.username' => 10, - 'servers.uuidShort' => 9, - 'servers.uuid' => 8, - 'users.email' => 6, - 'users.username' => 6, - 'nodes.name' => 2, - ], - 'joins' => [ + 'columns' => [ + 'servers.name' => 10, + 'servers.username' => 10, + 'servers.uuidShort' => 9, + 'servers.uuid' => 8, + 'packs.name' => 7, + 'users.email' => 6, + 'users.username' => 6, + 'nodes.name' => 2, + ], + 'joins' => [ + 'packs' => ['packs.id', 'servers.pack_id'], 'users' => ['users.id', 'servers.owner_id'], 'nodes' => ['nodes.id', 'servers.node_id'], - ], - ]; + ], + ]; /** * Returns a single server specified by UUID. @@ -111,7 +118,7 @@ class Server extends Model * @param string $uuid The Short-UUID of the server to return an object about. * @return \Illuminate\Database\Eloquent\Collection */ - public static function byUuid($uuid) + public static function byUuid($uuid, array $with = [], array $withCount = []) { if (! Auth::check()) { throw new \Exception('You must call Server:byUuid as an authenticated user.'); @@ -236,11 +243,11 @@ class Server extends Model /** * Gets information for the pack associated with this server. * - * @return \Illuminate\Database\Eloquent\Relations\HasOne + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function pack() { - return $this->hasOne(ServicePack::class, 'id', 'pack_id'); + return $this->belongsTo(Pack::class); } /** diff --git a/app/Models/ServerVariable.php b/app/Models/ServerVariable.php index e92c5caf2..165d5b3df 100644 --- a/app/Models/ServerVariable.php +++ b/app/Models/ServerVariable.php @@ -52,6 +52,36 @@ class ServerVariable extends Model 'variable_id' => 'integer', ]; + /** + * Determine if variable is viewable by users. + * + * @return bool + */ + public function getUserCanViewAttribute() + { + return (bool) $this->variable->user_viewable; + } + + /** + * Determine if variable is editable by users. + * + * @return bool + */ + public function getUserCanEditAttribute() + { + return (bool) $this->variable->user_editable; + } + + /** + * Determine if variable is required. + * + * @return bool + */ + public function getRequiredAttribute() + { + return $this->variable->required; + } + /** * Returns information about a given variables parent. * diff --git a/app/Models/Service.php b/app/Models/Service.php index 83cdb70b0..b05366882 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -41,9 +41,52 @@ class Service extends Model * @var array */ protected $fillable = [ - 'name', 'description', 'file', 'executable', 'startup', + 'name', 'description', 'folder', 'startup', 'index_file', ]; + /** + * Returns the default contents of the index.js file for a service. + * + * @return string + */ + public static function defaultIndexFile() + { + return <<<'EOF' +'use strict'; + +/** + * Pterodactyl - Daemon + * Copyright (c) 2015 - 2017 Dane Everitt + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +const rfr = require('rfr'); +const _ = require('lodash'); + +const Core = rfr('src/services/index.js'); + +class Service extends Core {} + +module.exports = Service; +EOF; + } + /** * Gets all service options associated with this service. * @@ -62,7 +105,7 @@ class Service extends Model public function packs() { return $this->hasManyThrough( - 'Pterodactyl\Models\ServicePack', 'Pterodactyl\Models\ServiceOption', + 'Pterodactyl\Models\Pack', 'Pterodactyl\Models\ServiceOption', 'service_id', 'option_id' ); } diff --git a/app/Models/ServiceOption.php b/app/Models/ServiceOption.php index adf646d88..a0f76df23 100644 --- a/app/Models/ServiceOption.php +++ b/app/Models/ServiceOption.php @@ -51,17 +51,6 @@ class ServiceOption extends Model 'service_id' => 'integer', ]; - /** - * Returns the display executable for the option and will use the parent - * service one if the option does not have one defined. - * - * @return string - */ - public function getDisplayExecutableAttribute($value) - { - return (is_null($this->executable)) ? $this->service->executable : $this->executable; - } - /** * Returns the display startup string for the option and will use the parent * service one if the option does not have one defined. @@ -110,6 +99,6 @@ class ServiceOption extends Model */ public function packs() { - return $this->hasMany(ServicePack::class, 'option_id'); + return $this->hasMany(Pack::class, 'option_id'); } } diff --git a/app/Models/ServiceVariable.php b/app/Models/ServiceVariable.php index aedfc6351..3d4647583 100644 --- a/app/Models/ServiceVariable.php +++ b/app/Models/ServiceVariable.php @@ -42,18 +42,33 @@ class ServiceVariable extends Model */ protected $guarded = ['id', 'created_at', 'updated_at']; - /** - * Cast values to correct type. - * - * @var array - */ - protected $casts = [ - 'option_id' => 'integer', - 'user_viewable' => 'integer', - 'user_editable' => 'integer', - 'required' => 'integer', - ]; + /** + * Cast values to correct type. + * + * @var array + */ + protected $casts = [ + 'option_id' => 'integer', + 'user_viewable' => 'integer', + 'user_editable' => 'integer', + ]; + /** + * Returns the display executable for the option and will use the parent + * service one if the option does not have one defined. + * + * @return string + */ + public function getRequiredAttribute($value) + { + return $this->rules === 'required' || str_contains($this->rules, ['required|', '|required']); + } + + /** + * Return server variables associated with this variable. + * + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ public function serverVariable() { return $this->hasMany(ServerVariable::class, 'variable_id'); diff --git a/app/Models/User.php b/app/Models/User.php index b660e304c..62ced4e72 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -66,7 +66,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac /** * A list of mass-assignable variables. * - * @var [type] + * @var array */ protected $fillable = ['username', 'email', 'name_first', 'name_last', 'password', 'language', 'use_totp', 'totp_secret', 'gravatar', 'root_admin']; @@ -88,6 +88,11 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac */ protected $hidden = ['password', 'remember_token', 'totp_secret']; + /** + * Parameters for search querying. + * + * @var array + */ protected $searchable = [ 'columns' => [ 'email' => 10, diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index a1181fb10..5a9a0d925 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -49,6 +49,8 @@ class AppServiceProvider extends ServiceProvider */ public function register() { - // + if ($this->app->environment() !== 'production') { + $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class); + } } } diff --git a/storage/app/services/minecraft/index.js b/app/Providers/MacroServiceProvider.php similarity index 62% rename from storage/app/services/minecraft/index.js rename to app/Providers/MacroServiceProvider.php index b53364bec..ad23aaf74 100644 --- a/storage/app/services/minecraft/index.js +++ b/app/Providers/MacroServiceProvider.php @@ -1,8 +1,7 @@ -'use strict'; - + + * Pterodactyl - Panel + * Copyright (c) 2015 - 2017 Dane Everitt . * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,17 +21,32 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -const rfr = require('rfr'); -const _ = require('lodash'); -const Core = rfr('src/services/index.js'); +namespace Pterodactyl\Providers; -class Service extends Core { - onConsole(data) { - // Hide the output spam from Bungeecord getting pinged. - if (_.endsWith(data, '<-> InitialHandler has connected')) return; - return super.onConsole(data); +use File; +use Illuminate\Support\ServiceProvider; + +class MacroServiceProvider extends ServiceProvider +{ + /** + * Bootstrap the application services. + * + * @return void + */ + public function boot() + { + File::macro('humanReadableSize', function ($path, $precision = 2) { + $size = File::size($path); + static $units = ['B', 'kB', 'MB', 'GB', 'TB']; + + $i = 0; + while (($size / 1024) > 0.9) { + $size = $size / 1024; + $i++; + } + + return round($size, ($i < 2) ? 0 : $precision) . ' ' . $units[$i]; + }); } } - -module.exports = Service; diff --git a/app/Repositories/DatabaseRepository.php b/app/Repositories/DatabaseRepository.php index b0d85b60f..5397fc5c7 100644 --- a/app/Repositories/DatabaseRepository.php +++ b/app/Repositories/DatabaseRepository.php @@ -199,7 +199,7 @@ class DatabaseRepository * Deletes a database server from the system if it is empty. * * @param int $server The ID of the Database Server. - * @return + * @return bool */ public function delete($server) { diff --git a/app/Repositories/OptionRepository.php b/app/Repositories/OptionRepository.php new file mode 100644 index 000000000..80a0a52a7 --- /dev/null +++ b/app/Repositories/OptionRepository.php @@ -0,0 +1,157 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Repositories; + +use DB; +use Validator; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Exceptions\DisplayValidationException; + +class OptionRepository +{ + /** + * Creates a new service option on the system. + * + * @param array $data + * @return \Pterodactyl\Models\ServiceOption + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ + public function create(array $data) + { + $validator = Validator::make($data, [ + 'service_id' => 'required|numeric|exists:services,id', + 'name' => 'required|string|max:255', + 'description' => 'required|string', + 'tag' => 'required|string|max:255|unique:service_options,tag', + 'docker_image' => 'required|string|max:255', + 'startup' => 'required|string', + 'config_from' => 'sometimes|required|numeric|exists:service_options,id', + 'config_startup' => 'required_without:config_from|json', + 'config_stop' => 'required_without:config_from|string|max:255', + 'config_logs' => 'required_without:config_from|json', + 'config_files' => 'required_without:config_from|json', + ]); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + if (isset($data['config_from'])) { + if (! ServiceOption::where('service_id', $data['service_id'])->where('id', $data['config_from'])->first()) { + throw new DisplayException('The `configuration from` directive must be a child of the assigned service.'); + } + } + + return ServiceOption::create($data); + } + + /** + * Deletes a service option from the system. + * + * @param int $id + * @return void + * + * @throws \Pterodactyl\Exceptions\DisplayException + */ + public function delete($id) + { + $option = ServiceOption::with('variables')->withCount('servers')->findOrFail($id); + + if ($option->servers_count > 0) { + throw new DisplayException('You cannot delete a service option that has servers associated with it.'); + } + + DB::transaction(function () use ($option) { + foreach ($option->variables as $variable) { + (new VariableRepository)->delete($variable->id); + } + + $option->delete(); + }); + } + + /** + * Updates a service option in the database which can then be used + * on nodes. + * + * @param int $id + * @param array $data + * @return \Pterodactyl\Models\ServiceOption + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ + public function update($id, array $data) + { + $option = ServiceOption::findOrFail($id); + + // Due to code limitations (at least when I am writing this currently) + // we have to make an assumption that if config_from is not passed + // that we should be telling it that no config is wanted anymore. + // + // This really is only an issue if we open API access to this function, + // in which case users will always need to pass `config_from` in order + // to keep it assigned. + if (! isset($data['config_from']) && ! is_null($option->config_from)) { + $option->config_from = null; + } + + $validator = Validator::make($data, [ + 'name' => 'sometimes|required|string|max:255', + 'description' => 'sometimes|required|string', + 'tag' => 'sometimes|required|string|max:255|unique:service_options,tag,' . $option->id, + 'docker_image' => 'sometimes|required|string|max:255', + 'startup' => 'sometimes|required|string', + 'config_from' => 'sometimes|required|numeric|exists:service_options,id', + ]); + + $validator->sometimes([ + 'config_startup', 'config_logs', 'config_files', + ], 'required_without:config_from|json', function ($input) use ($option) { + return ! (! $input->config_from && ! is_null($option->config_from)); + }); + + $validator->sometimes('config_stop', 'required_without:config_from|string|max:255', function ($input) use ($option) { + return ! (! $input->config_from && ! is_null($option->config_from)); + }); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + if (isset($data['config_from'])) { + if (! ServiceOption::where('service_id', $option->service_id)->where('id', $data['config_from'])->first()) { + throw new DisplayException('The `configuration from` directive must be a child of the assigned service.'); + } + } + + $option->fill($data)->save(); + + return $option; + } +} diff --git a/app/Repositories/ServiceRepository/Pack.php b/app/Repositories/PackRepository.php similarity index 61% rename from app/Repositories/ServiceRepository/Pack.php rename to app/Repositories/PackRepository.php index 2132c4954..fdc5fbd5d 100644 --- a/app/Repositories/ServiceRepository/Pack.php +++ b/app/Repositories/PackRepository.php @@ -22,37 +22,42 @@ * SOFTWARE. */ -namespace Pterodactyl\Repositories\ServiceRepository; +namespace Pterodactyl\Repositories; use DB; use Uuid; use Storage; use Validator; -use Pterodactyl\Models; +use Pterodactyl\Models\Pack; use Pterodactyl\Services\UuidService; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Exceptions\DisplayValidationException; -class Pack +class PackRepository { - public function __construct() - { - // - } - + /** + * Creates a new pack on the system. + * + * @param array $data + * @return \Pterodactyl\Models\Pack + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ public function create(array $data) { $validator = Validator::make($data, [ 'name' => 'required|string', 'version' => 'required|string', 'description' => 'sometimes|nullable|string', - 'option' => 'required|exists:service_options,id', - 'selectable' => 'sometimes|boolean', - 'visible' => 'sometimes|boolean', + 'selectable' => 'sometimes|required|boolean', + 'visible' => 'sometimes|required|boolean', + 'locked' => 'sometimes|required|boolean', + 'option_id' => 'required|exists:service_options,id', ]); if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); + throw new DisplayValidationException(json_encode($validator->errors())); } if (isset($data['file_upload'])) { @@ -65,33 +70,42 @@ class Pack } } - DB::beginTransaction(); - try { - $uuid = new UuidService; - $pack = Models\ServicePack::create([ - 'option_id' => $data['option'], - 'uuid' => $uuid->generate('service_packs', 'uuid'), + return DB::transaction(function () use ($data) { + $uuid = new UuidService(); + + $pack = new Pack; + $pack->uuid = $uuid->generate('packs', 'uuid'); + $pack->fill([ + 'option_id' => $data['option_id'], 'name' => $data['name'], 'version' => $data['version'], 'description' => (empty($data['description'])) ? null : $data['description'], 'selectable' => isset($data['selectable']), 'visible' => isset($data['visible']), - ]); + 'locked' => isset($data['locked']), + ])->save(); + + if (! $pack->exists) { + throw new DisplayException('Model does not exist after creation. Did an event prevent it from saving?'); + } Storage::makeDirectory('packs/' . $pack->uuid); if (isset($data['file_upload'])) { $data['file_upload']->storeAs('packs/' . $pack->uuid, 'archive.tar.gz'); } - DB::commit(); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } - - return $pack; + return $pack; + }); } + /** + * Creates a new pack on the system given a template file. + * + * @param array $data + * @return \Pterodactyl\Models\Pack + * + * @throws \Pterodactyl\Exceptions\DisplayException + */ public function createWithTemplate(array $data) { if (! isset($data['file_upload'])) { @@ -127,9 +141,10 @@ class Pack 'name' => $json->name, 'version' => $json->version, 'description' => $json->description, - 'option' => $data['option'], + 'option_id' => $data['option_id'], 'selectable' => $json->selectable, 'visible' => $json->visible, + 'locked' => $json->locked, ]); if (! $zip->extractTo(storage_path('app/packs/' . $pack->uuid), 'archive.tar.gz')) { @@ -147,42 +162,75 @@ class Pack 'name' => $json->name, 'version' => $json->version, 'description' => $json->description, - 'option' => $data['option'], + 'option_id' => $data['option_id'], 'selectable' => $json->selectable, 'visible' => $json->visible, + 'locked' => $json->locked, ]); } } + /** + * Updates a pack on the system. + * + * @param int $id + * @param array $data + * @return \Pterodactyl\Models\Pack + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ public function update($id, array $data) { $validator = Validator::make($data, [ - 'name' => 'required|string', - 'version' => 'required|string', - 'description' => 'string', - 'option' => 'required|exists:service_options,id', - 'selectable' => 'sometimes|boolean', - 'visible' => 'sometimes|boolean', + 'name' => 'sometimes|required|string', + 'option_id' => 'sometimes|required|exists:service_options,id', + 'version' => 'sometimes|required|string', + 'description' => 'sometimes|string', + 'selectable' => 'sometimes|required|boolean', + 'visible' => 'sometimes|required|boolean', + 'locked' => 'sometimes|required|boolean', ]); if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); + throw new DisplayValidationException(json_encode($validator->errors())); } - Models\ServicePack::findOrFail($id)->update([ - 'option_id' => $data['option'], - 'name' => $data['name'], - 'version' => $data['version'], + $pack = Pack::withCount('servers')->findOrFail($id); + + if ($pack->servers_count > 0 && (isset($data['option_id']) && (int) $data['option_id'] !== $pack->option_id)) { + throw new DisplayException('You cannot modify the associated option if servers are attached to a pack.'); + } + + $pack->fill([ + 'name' => isset($data['name']) ? $data['name'] : $pack->name, + 'option_id' => isset($data['option_id']) ? $data['option_id'] : $pack->option_id, + 'version' => isset($data['version']) ? $data['version'] : $pack->version, 'description' => (empty($data['description'])) ? null : $data['description'], 'selectable' => isset($data['selectable']), 'visible' => isset($data['visible']), - ]); + 'locked' => isset($data['locked']), + ])->save(); + + return $pack; } + /** + * Deletes a pack and files from the system. + * + * @param int $id + * @return void + * + * @throws \Pterodactyl\Exceptions\DisplayException + */ public function delete($id) { - $pack = Models\ServicePack::findOrFail($id); - // @TODO Check for linked servers; foreign key should block this. + $pack = Models\Pack::withCount('servers')->findOrFail($id); + + if ($pack->servers_count > 0) { + throw new DisplayException('Cannot delete a pack from the system if servers are assocaited with it.'); + } + DB::transaction(function () use ($pack) { $pack->delete(); Storage::deleteDirectory('packs/' . $pack->uuid); diff --git a/app/Repositories/ServerRepository.php b/app/Repositories/ServerRepository.php index 0e4e0f099..f95d45431 100644 --- a/app/Repositories/ServerRepository.php +++ b/app/Repositories/ServerRepository.php @@ -156,7 +156,7 @@ class ServerRepository if (! isset($data['pack_id']) || (int) $data['pack_id'] < 1) { $data['pack_id'] = null; } else { - $pack = Models\ServicePack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first(); + $pack = Models\Pack::where('id', $data['pack_id'])->where('option_id', $data['option_id'])->first(); if (! $pack) { throw new DisplayException('The requested service pack does not seem to exist for this combination.'); } @@ -627,23 +627,25 @@ class ServerRepository foreach ($server->option->variables as &$variable) { $set = isset($data['env_' . $variable->id]); - // Variable is required but was not passed into the function. - if ($variable->required && ! $set) { - throw new DisplayException('A required variable (' . $variable->env_variable . ') was not passed in the request.'); - } - // If user is not an admin and are trying to edit a non-editable field // or an invisible field just silently skip the variable. if (! $admin && (! $variable->user_editable || ! $variable->user_viewable)) { continue; } - // Confirm value is valid when compared aganist regex. - // @TODO: switch to Laravel validation rules. - if ($set && ! is_null($variable->regex)) { - if (! preg_match($variable->regex, $data['env_' . $variable->id])) { - throw new DisplayException('The value passed for a variable (' . $variable->env_variable . ') could not be matched aganist the regex for that field (' . $variable->regex . ').'); - } + // Perform Field Validation + $validator = Validator::make([ + 'variable_value' => ($set) ? $data['env_' . $variable->id] : null, + ], [ + 'variable_value' => $variable->rules, + ]); + + if ($validator->fails()) { + throw new DisplayValidationException(json_encode( + collect([ + 'notice' => ['There was a validation error with the `' . $variable->name . '` variable.'], + ])->merge($validator->errors()->toArray()) + )); } $svar = Models\ServerVariable::firstOrNew([ diff --git a/app/Repositories/ServiceRepository.php b/app/Repositories/ServiceRepository.php new file mode 100644 index 000000000..e8d606ffc --- /dev/null +++ b/app/Repositories/ServiceRepository.php @@ -0,0 +1,129 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Repositories; + +use DB; +use Validator; +use Pterodactyl\Models\Service; +use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Exceptions\DisplayValidationException; + +class ServiceRepository +{ + /** + * Creates a new service on the system. + * + * @param array $data + * @return \Pterodactyl\Models\Service + */ + public function create(array $data) + { + $validator = Validator::make($data, [ + 'name' => 'required|string|min:1|max:255', + 'description' => 'required|nullable|string', + 'folder' => 'required|unique:services,folder|regex:/^[\w.-]{1,50}$/', + 'startup' => 'required|nullable|string', + ]); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + return DB::transaction(function () use ($data) { + $service = new Service; + $service->author = config('pterodactyl.service.author'); + $service->fill([ + 'name' => $data['name'], + 'description' => (isset($data['description'])) ? $data['description'] : null, + 'folder' => $data['folder'], + 'startup' => (isset($data['startup'])) ? $data['startup'] : null, + 'index_file' => Service::defaultIndexFile(), + ])->save(); + + // It is possible for an event to return false or throw an exception + // which won't necessarily be detected by this transaction. + // + // This check ensures the model was actually saved. + if (! $service->exists) { + throw new \Exception('Service model was created however the response appears to be invalid. Did an event fire wrongly?'); + } + + return $service; + }); + } + + /** + * Updates a service. + * + * @param int $id + * @param array $data + * @return \Pterodactyl\Models\Service + */ + public function update($id, array $data) + { + $service = Service::findOrFail($id); + + $validator = Validator::make($data, [ + 'name' => 'sometimes|required|string|min:1|max:255', + 'description' => 'sometimes|required|nullable|string', + 'folder' => 'sometimes|required|regex:/^[\w.-]{1,50}$/', + 'startup' => 'sometimes|required|nullable|string', + 'index_file' => 'sometimes|required|string', + ]); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + return DB::transaction(function () use ($data, $service) { + $service->fill($data)->save(); + + return $service; + }); + } + + /** + * Deletes a service and associated files and options. + * + * @param int $id + * @return void + */ + public function delete($id) + { + $service = Service::withCount('servers')->with('options')->findOrFail($id); + + if ($service->servers_count > 0) { + throw new DisplayException('You cannot delete a service that has servers associated with it.'); + } + + DB::transaction(function () use ($service) { + foreach ($service->options as $option) { + (new OptionRepository)->delete($option->id); + } + + $service->delete(); + }); + } +} diff --git a/app/Repositories/ServiceRepository/Option.php b/app/Repositories/ServiceRepository/Option.php deleted file mode 100644 index e0b82d347..000000000 --- a/app/Repositories/ServiceRepository/Option.php +++ /dev/null @@ -1,124 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Repositories\ServiceRepository; - -use DB; -use Validator; -use Pterodactyl\Models; -use Pterodactyl\Exceptions\DisplayException; -use Pterodactyl\Exceptions\DisplayValidationException; - -class Option -{ - public function __construct() - { - // - } - - public function create($service, array $data) - { - $service = Models\Service::findOrFail($service); - - $validator = Validator::make($data, [ - 'name' => 'required|string|max:255', - 'description' => 'required|string|min:1', - 'tag' => 'required|string|max:255', - 'executable' => 'sometimes|string|max:255', - 'docker_image' => 'required|string|max:255', - 'startup' => 'sometimes|string', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - if (isset($data['executable']) && empty($data['executable'])) { - $data['executable'] = null; - } - - if (isset($data['startup']) && empty($data['startup'])) { - $data['startup'] = null; - } - - $option = new Models\ServiceOption; - $option->service_id = $service->id; - $option->fill($data); - $option->save(); - - return $option->id; - } - - public function delete($id) - { - $option = Models\ServiceOption::findOrFail($id); - $servers = Models\Server::where('option', $option->id)->get(); - - if (count($servers) !== 0) { - throw new DisplayException('You cannot delete an option that has servers attached to it currently.'); - } - - DB::beginTransaction(); - - try { - Models\ServiceVariable::where('option_id', $option->id)->delete(); - $option->delete(); - - DB::commit(); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } - } - - public function update($id, array $data) - { - $option = Models\ServiceOption::findOrFail($id); - - $validator = Validator::make($data, [ - 'name' => 'sometimes|required|string|max:255', - 'description' => 'sometimes|required|string|min:1', - 'tag' => 'sometimes|required|string|max:255', - 'executable' => 'sometimes|string|max:255', - 'docker_image' => 'sometimes|required|string|max:255', - 'startup' => 'sometimes|string', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - if (isset($data['executable']) && empty($data['executable'])) { - $data['executable'] = null; - } - - if (isset($data['startup']) && empty($data['startup'])) { - $data['startup'] = null; - } - - $option->fill($data); - - return $option->save(); - } -} diff --git a/app/Repositories/ServiceRepository/Service.php b/app/Repositories/ServiceRepository/Service.php deleted file mode 100644 index 206479a0a..000000000 --- a/app/Repositories/ServiceRepository/Service.php +++ /dev/null @@ -1,144 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Repositories\ServiceRepository; - -use DB; -use Uuid; -use Storage; -use Validator; -use Pterodactyl\Models; -use Pterodactyl\Exceptions\DisplayException; -use Pterodactyl\Exceptions\DisplayValidationException; - -class Service -{ - public function __construct() - { - // - } - - public function create(array $data) - { - $validator = Validator::make($data, [ - 'name' => 'required|string|min:1|max:255', - 'description' => 'required|string', - 'file' => 'required|unique:services,file|regex:/^[\w.-]{1,50}$/', - 'executable' => 'max:255|regex:/^(.*)$/', - 'startup' => 'string', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - DB::beginTransaction(); - try { - $service = new Models\Service; - $service->author = env('SERVICE_AUTHOR', (string) Uuid::generate(4)); - $service->fill($data); - $service->save(); - - Storage::put('services/' . $service->file . '/main.json', '{}'); - Storage::copy('services/.templates/index.js', 'services/' . $service->file . '/index.js'); - DB::commit(); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } - - return $service; - } - - public function update($id, array $data) - { - $service = Models\Service::findOrFail($id); - - $validator = Validator::make($data, [ - 'name' => 'sometimes|required|string|min:1|max:255', - 'description' => 'sometimes|required|string', - 'file' => 'sometimes|required|regex:/^[\w.-]{1,50}$/', - 'executable' => 'sometimes|max:255|regex:/^(.*)$/', - 'startup' => 'sometimes|string', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - $service->fill($data); - - return $service->save(); - } - - public function delete($id) - { - $service = Models\Service::findOrFail($id); - $servers = Models\Server::where('service', $service->id)->get(); - $options = Models\ServiceOption::select('id')->where('service_id', $service->id); - - if (count($servers) !== 0) { - throw new DisplayException('You cannot delete a service that has servers associated with it.'); - } - - DB::beginTransaction(); - try { - Models\ServiceVariable::whereIn('option_id', $options->get()->toArray())->delete(); - $options->delete(); - $service->delete(); - - Storage::deleteDirectory('services/' . $service->file); - DB::commit(); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } - } - - public function updateFile($id, array $data) - { - $service = Models\Service::findOrFail($id); - - $validator = Validator::make($data, [ - 'file' => 'required|in:index,main', - 'contents' => 'required|string', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - $filename = ($data['file'] === 'main') ? 'main.json' : 'index.js'; - $filepath = 'services/' . $service->file . '/' . $filename; - $backup = 'services/.bak/' . str_random(12) . '.bak'; - - try { - Storage::move($filepath, $backup); - Storage::put($filepath, $data['contents']); - } catch (\Exception $ex) { - Storage::move($backup, $filepath); - throw $ex; - } - } -} diff --git a/app/Repositories/ServiceRepository/Variable.php b/app/Repositories/ServiceRepository/Variable.php deleted file mode 100644 index f9836ff0f..000000000 --- a/app/Repositories/ServiceRepository/Variable.php +++ /dev/null @@ -1,144 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Repositories\ServiceRepository; - -use DB; -use Validator; -use Pterodactyl\Models; -use Pterodactyl\Exceptions\DisplayException; -use Pterodactyl\Exceptions\DisplayValidationException; - -class Variable -{ - public function __construct() - { - // - } - - public function create($id, array $data) - { - $option = Models\ServiceOption::select('id')->findOrFail($id); - - $validator = Validator::make($data, [ - 'name' => 'required|string|min:1|max:255', - 'description' => 'required|string', - 'env_variable' => 'required|regex:/^[\w]{1,255}$/', - 'default_value' => 'string|max:255', - 'user_viewable' => 'sometimes|required|nullable|boolean', - 'user_editable' => 'sometimes|required|nullable|boolean', - 'required' => 'sometimes|required|nullable|boolean', - 'regex' => 'required|string|min:1', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - if ($data['default_value'] !== '' && ! preg_match($data['regex'], $data['default_value'])) { - throw new DisplayException('The default value you entered cannot violate the regex requirements.'); - } - - if (Models\ServiceVariable::where('env_variable', $data['env_variable'])->where('option_id', $option->id)->first()) { - throw new DisplayException('An environment variable with that name already exists for this option.'); - } - - $data['user_viewable'] = (isset($data['user_viewable']) && in_array((int) $data['user_viewable'], [0, 1])) ? $data['user_viewable'] : 0; - $data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : 0; - $data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : 0; - $data['option_id'] = $option->id; - - $variable = Models\ServiceVariable::create($data); - - return $variable; - } - - public function delete($id) - { - $variable = Models\ServiceVariable::with('serverVariable')->findOrFail($id); - - DB::beginTransaction(); - try { - foreach ($variable->serverVariable as $svar) { - $svar->delete(); - } - $variable->delete(); - - DB::commit(); - } catch (\Exception $ex) { - DB::rollBack(); - throw $ex; - } - } - - public function update($id, array $data) - { - $variable = Models\ServiceVariable::findOrFail($id); - - $validator = Validator::make($data, [ - 'name' => 'sometimes|required|string|min:1|max:255', - 'description' => 'sometimes|required|string', - 'env_variable' => 'sometimes|required|regex:/^[\w]{1,255}$/', - 'default_value' => 'sometimes|string|max:255', - 'user_viewable' => 'sometimes|required|nullable|boolean', - 'user_editable' => 'sometimes|required|nullable|boolean', - 'required' => 'sometimes|required|nullable|boolean', - 'regex' => 'sometimes|required|string|min:1', - ]); - - if ($validator->fails()) { - throw new DisplayValidationException($validator->errors()); - } - - $data['default_value'] = (isset($data['default_value'])) ? $data['default_value'] : $variable->default_value; - $data['regex'] = (isset($data['regex'])) ? $data['regex'] : $variable->regex; - - if ($data['default_value'] !== '' && ! preg_match($data['regex'], $data['default_value'])) { - throw new DisplayException('The default value you entered cannot violate the regex requirements.'); - } - - if (Models\ServiceVariable::where('id', '!=', $variable->id)->where('env_variable', $data['env_variable'])->where('option_id', $variable->option_id)->first()) { - throw new DisplayException('An environment variable with that name already exists for this option.'); - } - - $data['user_viewable'] = (isset($data['user_viewable']) && in_array((int) $data['user_viewable'], [0, 1])) ? $data['user_viewable'] : $variable->user_viewable; - $data['user_editable'] = (isset($data['user_editable']) && in_array((int) $data['user_editable'], [0, 1])) ? $data['user_editable'] : $variable->user_editable; - $data['required'] = (isset($data['required']) && in_array((int) $data['required'], [0, 1])) ? $data['required'] : $variable->required; - - // Not using $data because the function that passes into this function - // can't do $requst->only() due to the page setup. - $variable->fill([ - 'name' => $data['name'], - 'description' => $data['description'], - 'env_variable' => $data['env_variable'], - 'default_value' => $data['default_value'], - 'user_viewable' => $data['user_viewable'], - 'user_editable' => $data['user_editable'], - 'required' => $data['required'], - 'regex' => $data['regex'], - ]); - - return $variable->save(); - } -} diff --git a/app/Repositories/VariableRepository.php b/app/Repositories/VariableRepository.php new file mode 100644 index 000000000..c707788d3 --- /dev/null +++ b/app/Repositories/VariableRepository.php @@ -0,0 +1,166 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Repositories; + +use DB; +use Validator; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; +use Pterodactyl\Exceptions\DisplayException; +use Pterodactyl\Exceptions\DisplayValidationException; + +class VariableRepository +{ + /** + * Create a new service variable. + * + * @param int $option + * @param array $data + * @return \Pterodactyl\Models\ServiceVariable + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ + public function create($option, array $data) + { + $option = ServiceOption::select('id')->findOrFail($option); + + $validator = Validator::make($data, [ + 'name' => 'required|string|min:1|max:255', + 'description' => 'sometimes|nullable|string', + 'env_variable' => 'required|regex:/^[\w]{1,255}$/', + 'default_value' => 'string', + 'options' => 'sometimes|required|array', + 'rules' => 'bail|required|string|min:1', + ]); + + // Ensure the default value is allowed by the rules provided. + $rules = (isset($data['rules'])) ? $data['rules'] : $variable->rules; + $validator->sometimes('default_value', $rules, function ($input) { + return $input->default_value; + }); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + if (isset($data['env_variable'])) { + $search = ServiceVariable::where('env_variable', $data['env_variable'])->where('option_id', $option->id); + if ($search->first()) { + throw new DisplayException('The envionment variable name assigned to this variable must be unique for this service option.'); + } + } + + if (! isset($data['options']) || ! is_array($data['options'])) { + $data['options'] = []; + } + + $data['option_id'] = $option->id; + $data['user_viewable'] = (in_array('user_viewable', $data['options'])); + $data['user_editable'] = (in_array('user_editable', $data['options'])); + + // Remove field that isn't used. + unset($data['options']); + + return ServiceVariable::create($data); + } + + /** + * Deletes a specified option variable as well as all server + * variables currently assigned. + * + * @param int $id + * @return void + */ + public function delete($id) + { + $variable = ServiceVariable::with('serverVariable')->findOrFail($id); + + DB::transaction(function () use ($variable) { + foreach ($variable->serverVariable as $v) { + $v->delete(); + } + + $variable->delete(); + }); + } + + /** + * Updates a given service variable. + * + * @param int $id + * @param array $data + * @return \Pterodactyl\Models\ServiceVariable + * + * @throws \Pterodactyl\Exceptions\DisplayException + * @throws \Pterodactyl\Exceptions\DisplayValidationException + */ + public function update($id, array $data) + { + $variable = ServiceVariable::findOrFail($id); + + $validator = Validator::make($data, [ + 'name' => 'sometimes|required|string|min:1|max:255', + 'description' => 'sometimes|nullable|string', + 'env_variable' => 'sometimes|required|regex:/^[\w]{1,255}$/', + 'default_value' => 'string', + 'options' => 'sometimes|required|array', + 'rules' => 'bail|sometimes|required|string|min:1', + ]); + + // Ensure the default value is allowed by the rules provided. + $rules = (isset($data['rules'])) ? $data['rules'] : $variable->rules; + $validator->sometimes('default_value', $rules, function ($input) { + return $input->default_value; + }); + + if ($validator->fails()) { + throw new DisplayValidationException($validator->errors()); + } + + if (isset($data['env_variable'])) { + $search = ServiceVariable::where('env_variable', $data['env_variable']) + ->where('option_id', $variable->option_id) + ->where('id', '!=', $variable->id); + if ($search->first()) { + throw new DisplayException('The envionment variable name assigned to this variable must be unique for this service option.'); + } + } + + if (! isset($data['options']) || ! is_array($data['options'])) { + $data['options'] = []; + } + + $data['user_viewable'] = (in_array('user_viewable', $data['options'])); + $data['user_editable'] = (in_array('user_editable', $data['options'])); + + // Remove field that isn't used. + unset($data['options']); + + $variable->fill($data)->save(); + + return $variable; + } +} diff --git a/app/Services/DeploymentService.php b/app/Services/DeploymentService.php index af1ede940..d4d28e9a9 100644 --- a/app/Services/DeploymentService.php +++ b/app/Services/DeploymentService.php @@ -79,7 +79,7 @@ class DeploymentService * @param int $memory * @param int $disk * @param int $location - * @return \Pterodactyl\Models\Node; + * @return \Pterodactyl\Models\Node * * @throws \Pterodactyl\Exceptions\DisplayException */ @@ -103,7 +103,7 @@ class DeploymentService /** * Returns a random allocation for a node. * @param int $node - * @return \Models\Pterodactyl\Allocation; + * @return \Models\Pterodactyl\Allocation */ public static function randomAllocation($node) { diff --git a/app/Services/FileService.php b/app/Services/FileService.php new file mode 100644 index 000000000..e69de29bb diff --git a/app/Services/NotificationService.php b/app/Services/NotificationService.php deleted file mode 100644 index 7912cf65d..000000000 --- a/app/Services/NotificationService.php +++ /dev/null @@ -1,62 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Services; - -use Pterodactyl\Models\Server; -use Pterodactyl\Notifications\Daemon; - -class NotificationService -{ - protected $server; - - protected $user; - - /** - * Daemon will pass an event name, this matches that event name with the notification to send. - * @var array - */ - protected $types = [ - // 'crashed' => 'CrashNotification', - // 'started' => 'StartNotification', - // 'stopped' => 'StopNotification', - // 'rebuild' => 'RebuildNotification' - ]; - - public function __construct(Server $server) - { - $this->server = $server; - } - - public function pass(array $notification) - { - if (! $notification->type) { - return; - } - - if (class_exists($this->types[$notification->type]::class)) { - $user->notify(new $this->types[$notification->type]($notification->payload)); - } - } -} diff --git a/composer.json b/composer.json index a95d82df1..a58fc7f82 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "phpunit/phpunit": "~5.0", "symfony/css-selector": "3.1.*", "symfony/dom-crawler": "3.1.*", - "laravel/homestead": "3.0.*" + "laravel/homestead": "3.0.*", + "barryvdh/laravel-ide-helper": "^2.3" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock index 535af7aa2..8975e85a0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "6a9656aff0fb3809d27a2a093a810197", - "content-hash": "8affaad10f155172b5079a72015b8bc5", + "hash": "7c01d337ebab3d47ae3479360c63e68f", + "content-hash": "c2addd888e0a4fd26518ea7c691f6f25", "packages": [ { "name": "aws/aws-sdk-php", @@ -3747,6 +3747,121 @@ } ], "packages-dev": [ + { + "name": "barryvdh/laravel-ide-helper", + "version": "v2.3.2", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-ide-helper.git", + "reference": "e82de98cef0d6597b1b686be0b5813a3a4bb53c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/e82de98cef0d6597b1b686be0b5813a3a4bb53c5", + "reference": "e82de98cef0d6597b1b686be0b5813a3a4bb53c5", + "shasum": "" + }, + "require": { + "barryvdh/reflection-docblock": "^2.0.4", + "illuminate/console": "^5.0,<5.5", + "illuminate/filesystem": "^5.0,<5.5", + "illuminate/support": "^5.0,<5.5", + "php": ">=5.4.0", + "symfony/class-loader": "^2.3|^3.0" + }, + "require-dev": { + "doctrine/dbal": "~2.3", + "phpunit/phpunit": "4.*", + "scrutinizer/ocular": "~1.1", + "squizlabs/php_codesniffer": "~2.3" + }, + "suggest": { + "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Barryvdh\\LaravelIdeHelper\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.", + "keywords": [ + "autocomplete", + "codeintel", + "helper", + "ide", + "laravel", + "netbeans", + "phpdoc", + "phpstorm", + "sublime" + ], + "time": "2017-02-22 12:27:33" + }, + { + "name": "barryvdh/reflection-docblock", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/ReflectionDocBlock.git", + "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/3dcbd98b5d9384a5357266efba8fd29884458e5c", + "reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0,<4.5" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Barryvdh": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2016-06-13 19:28:20" + }, { "name": "doctrine/instantiator", "version": "1.0.5", @@ -5008,6 +5123,62 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03 07:35:21" }, + { + "name": "symfony/class-loader", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/class-loader.git", + "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9", + "reference": "c29a5bc6ca14cfff1f5e3d7781ed74b6e898d2b9", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/finder": "~2.8|~3.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ClassLoader Component", + "homepage": "https://symfony.com", + "time": "2017-02-18 17:28:00" + }, { "name": "symfony/css-selector", "version": "v3.1.10", diff --git a/config/app.php b/config/app.php index 622098a9b..4721bb3d2 100644 --- a/config/app.php +++ b/config/app.php @@ -150,6 +150,7 @@ return [ Pterodactyl\Providers\AuthServiceProvider::class, Pterodactyl\Providers\EventServiceProvider::class, Pterodactyl\Providers\RouteServiceProvider::class, + Pterodactyl\Providers\MacroServiceProvider::class, Pterodactyl\Providers\PhraseAppTranslationProvider::class, /* diff --git a/config/pterodactyl.php b/config/pterodactyl.php new file mode 100644 index 000000000..30ea7ef97 --- /dev/null +++ b/config/pterodactyl.php @@ -0,0 +1,19 @@ + [ + 'core' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + 'author' => env('SERVICE_AUTHOR'), + ], + +]; diff --git a/database/migrations/2017_03_05_212803_DeleteServiceExecutableOption.php b/database/migrations/2017_03_05_212803_DeleteServiceExecutableOption.php new file mode 100644 index 000000000..5a1df2afb --- /dev/null +++ b/database/migrations/2017_03_05_212803_DeleteServiceExecutableOption.php @@ -0,0 +1,56 @@ +renameColumn('file', 'folder'); + $table->text('description')->nullable()->change(); + $table->text('startup')->nullable()->change(); + }); + + // Attempt to fix any startup commands for servers + // that we possibly can. + foreach (ServiceOption::with('servers')->get() as $option) { + $option->servers->each(function ($s) use ($option) { + $prepend = $option->display_executable; + $prepend = ($prepend === './ShooterGameServer') ? './ShooterGame/Binaries/Linux/ShooterGameServer' : $prepend; + $prepend = ($prepend === 'TerrariaServer.exe') ? 'mono TerrariaServer.exe' : $prepend; + + $s->startup = $prepend . ' ' . $s->startup; + $s->save(); + }); + } + + Schema::table('services', function (Blueprint $table) { + $table->dropColumn('executable'); + }); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('services', function (Blueprint $table) { + $table->string('executable')->after('folder'); + $table->renameColumn('folder', 'file'); + $table->text('description')->nullable(false)->change(); + $table->text('startup')->nullable(false)->change(); + }); + } +} diff --git a/database/migrations/2017_03_10_162934_AddNewServiceOptionsColumns.php b/database/migrations/2017_03_10_162934_AddNewServiceOptionsColumns.php new file mode 100644 index 000000000..f2c50cdd7 --- /dev/null +++ b/database/migrations/2017_03_10_162934_AddNewServiceOptionsColumns.php @@ -0,0 +1,48 @@ +dropColumn('executable'); + + $table->unsignedInteger('config_from')->nullable()->after('docker_image'); + $table->string('config_stop')->nullable()->after('docker_image'); + $table->text('config_logs')->nullable()->after('docker_image'); + $table->text('config_startup')->nullable()->after('docker_image'); + $table->text('config_files')->nullable()->after('docker_image'); + + $table->foreign('config_from')->references('id')->on('service_options'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_options', function (Blueprint $table) { + $table->dropForeign('config_from'); + + $table->dropColumn('config_from'); + $table->dropColumn('config_stop'); + $table->dropColumn('config_logs'); + $table->dropColumn('config_startup'); + $table->dropColumn('config_files'); + + $table->string('executable')->after('docker_image')->nullable(); + }); + } +} diff --git a/app/Models/ServicePack.php b/database/migrations/2017_03_10_173607_MigrateToNewServiceSystem.php similarity index 50% rename from app/Models/ServicePack.php rename to database/migrations/2017_03_10_173607_MigrateToNewServiceSystem.php index e82f72411..9f935fff8 100644 --- a/app/Models/ServicePack.php +++ b/database/migrations/2017_03_10_173607_MigrateToNewServiceSystem.php @@ -21,49 +21,45 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Illuminate\Database\Migrations\Migration; -namespace Pterodactyl\Models; - -use Illuminate\Database\Eloquent\Model; - -class ServicePack extends Model +class MigrateToNewServiceSystem extends Migration { /** - * The table associated with the model. + * Run the migrations. * - * @var string + * @return void */ - protected $table = 'service_packs'; + public function up() + { + DB::transaction(function () { + $service = Service::where('author', config('pterodactyl.service.core'))->where('folder', 'srcds')->first(); + if (! $service) { + return; + } + + $options = ServiceOption::where('service_id', $service->id)->get(); + $options->each(function ($item) use ($options) { + if ($item->tag === 'srcds' && $item->name === 'Insurgency') { + $item->tag = 'insurgency'; + } elseif ($item->tag === 'srcds' && $item->name === 'Team Fortress 2') { + $item->tag = 'tf2'; + } elseif ($item->tag === 'srcds' && $item->name === 'Custom Source Engine Game') { + $item->tag = 'source'; + } + }); + }); + } /** - * Fields that are not mass assignable. + * Reverse the migrations. * - * @var array + * @return void */ - protected $guarded = ['id', 'created_at', 'updated_at']; - - /** - * Cast values to correct type. - * - * @var array - */ - protected $casts = [ - 'option' => 'integer', - 'build_memory' => 'integer', - 'build_swap' => 'integer', - 'build_cpu' => 'integer', - 'build_io' => 'integer', - 'selectable' => 'boolean', - 'visible' => 'boolean', - ]; - - /** - * Gets option associated with a service pack. - * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - */ - public function option() - { - return $this->belongsTo(ServiceOption::class); - } + public function down() + { + // Not doing reversals right now... + } } diff --git a/database/migrations/2017_03_11_215455_ChangeServiceVariablesValidationRules.php b/database/migrations/2017_03_11_215455_ChangeServiceVariablesValidationRules.php new file mode 100644 index 000000000..225a1edc0 --- /dev/null +++ b/database/migrations/2017_03_11_215455_ChangeServiceVariablesValidationRules.php @@ -0,0 +1,52 @@ +renameColumn('regex', 'rules'); + }); + + DB::transaction(function () { + foreach (ServiceVariable::all() as $variable) { + $variable->rules = ($variable->required) ? 'required|regex:' . $variable->rules : 'regex:' . $variable->regex; + $variable->save(); + } + }); + + Schema::table('service_variables', function (Blueprint $table) { + $table->dropColumn('required'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_variables', function (Blueprint $table) { + $table->renameColumn('rules', 'regex'); + $table->boolean('required')->default(true)->before('regex'); + }); + + DB::transaction(function () { + foreach (ServiceVariable::all() as $variable) { + $variable->regex = str_replace(['required|regex:', 'regex:'], '', $variable->regex); + $variable->save(); + } + }); + } +} diff --git a/database/migrations/2017_03_12_150648_MoveFunctionsFromFileToDatabase.php b/database/migrations/2017_03_12_150648_MoveFunctionsFromFileToDatabase.php new file mode 100644 index 000000000..bbd5fda42 --- /dev/null +++ b/database/migrations/2017_03_12_150648_MoveFunctionsFromFileToDatabase.php @@ -0,0 +1,119 @@ + + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +const rfr = require('rfr'); +const _ = require('lodash'); + +const Core = rfr('src/services/index.js'); + +class Service extends Core {} + +module.exports = Service; +EOF; + + private $default_mc = <<<'EOF' +'use strict'; + +/** + * Pterodactyl - Daemon + * Copyright (c) 2015 - 2017 Dane Everitt + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +const rfr = require('rfr'); +const _ = require('lodash'); + +const Core = rfr('src/services/index.js'); + +class Service extends Core { + onConsole(data) { + // Hide the output spam from Bungeecord getting pinged. + if (_.endsWith(data, '<-> InitialHandler has connected')) return; + return super.onConsole(data); + } +} + +module.exports = Service; +EOF; + + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::table('services', function (Blueprint $table) { + $table->text('index_file')->after('startup'); + }); + + DB::transaction(function () { + Service::where('author', 'ptrdctyl-v040-11e6-8b77-86f30ca893d3')->where('folder', '!=', 'minecraft')->update([ + 'index_file' => $this->default, + ]); + + Service::where('author', 'ptrdctyl-v040-11e6-8b77-86f30ca893d3')->where('folder', 'minecraft')->update([ + 'index_file' => $this->default_mc, + ]); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('services', function (Blueprint $table) { + $table->dropColumn('index_file'); + }); + } +} diff --git a/database/migrations/2017_03_14_175631_RenameServicePacksToSingluarPacks.php b/database/migrations/2017_03_14_175631_RenameServicePacksToSingluarPacks.php new file mode 100644 index 000000000..910fb79df --- /dev/null +++ b/database/migrations/2017_03_14_175631_RenameServicePacksToSingluarPacks.php @@ -0,0 +1,44 @@ +dropForeign(['option_id']); + }); + + Schema::rename('service_packs', 'packs'); + + Schema::table('packs', function (Blueprint $table) { + $table->foreign('option_id')->references('id')->on('service_options'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('packs', function (Blueprint $table) { + $table->dropForeign(['option_id']); + }); + + Schema::rename('packs', 'service_packs'); + + Schema::table('service_packs', function (Blueprint $table) { + $table->foreign('option_id')->references('id')->on('service_options'); + }); + } +} diff --git a/database/migrations/2017_03_14_200326_AddLockedStatusToTable.php b/database/migrations/2017_03_14_200326_AddLockedStatusToTable.php new file mode 100644 index 000000000..4916cd028 --- /dev/null +++ b/database/migrations/2017_03_14_200326_AddLockedStatusToTable.php @@ -0,0 +1,32 @@ +boolean('locked')->default(false)->after('visible'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('packs', function (Blueprint $table) { + $table->dropColumn('locked'); + }); + } +} diff --git a/database/seeds/MinecraftServiceTableSeeder.php b/database/seeds/MinecraftServiceTableSeeder.php index 45f251ebd..d1e7b844a 100644 --- a/database/seeds/MinecraftServiceTableSeeder.php +++ b/database/seeds/MinecraftServiceTableSeeder.php @@ -21,15 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -use Pterodactyl\Models; use Illuminate\Database\Seeder; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; class MinecraftServiceTableSeeder extends Seeder { /** * The core service ID. * - * @var Models\Service + * @var \Pterodactyl\Models\Service */ protected $service; @@ -40,6 +42,47 @@ class MinecraftServiceTableSeeder extends Seeder */ protected $option = []; + private $default_mc = <<<'EOF' +'use strict'; + +/** + * Pterodactyl - Daemon + * Copyright (c) 2015 - 2017 Dane Everitt + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +const rfr = require('rfr'); +const _ = require('lodash'); + +const Core = rfr('src/services/index.js'); + +class Service extends Core { + onConsole(data) { + // Hide the output spam from Bungeecord getting pinged. + if (_.endsWith(data, '<-> InitialHandler has connected')) return; + return super.onConsole(data); + } +} + +module.exports = Service; +EOF; + /** * Run the database seeds. * @@ -54,55 +97,76 @@ class MinecraftServiceTableSeeder extends Seeder private function addCoreService() { - $this->service = Models\Service::create([ - 'author' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + $this->service = Service::updateOrCreate([ + 'author' => config('pterodactyl.service.core'), + 'folder' => 'minecraft', + ], [ 'name' => 'Minecraft', 'description' => 'Minecraft - the classic game from Mojang. With support for Vanilla MC, Spigot, and many others!', - 'file' => 'minecraft', - 'executable' => 'java', - 'startup' => '-Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}', + 'startup' => 'java -Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}', + 'index_file' => $this->default_mc, ]); } private function addCoreOptions() { - $this->option['vanilla'] = Models\ServiceOption::create([ + $this->option['vanilla'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'vanilla', + ], [ 'name' => 'Vanilla Minecraft', '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.', - 'tag' => 'vanilla', 'docker_image' => 'quay.io/pterodactyl/minecraft', - 'executable' => null, + 'config_startup' => '{"done": ")! For help, type ", "userInteraction": [ "Go to eula.txt for more info."]}', + 'config_logs' => '{"custom": false, "location": "logs/latest.log"}', + 'config_files' => '{"server.properties":{"parser": "properties", "find":{"server-ip": "0.0.0.0", "enable-query": "true", "server-port": "{{server.build.default.port}}", "query.port": "{{server.build.default.port}}"}}}', + 'config_stop' => 'stop', + 'config_from' => null, 'startup' => null, ]); - $this->option['spigot'] = Models\ServiceOption::create([ + $this->option['spigot'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'spigot', + ], [ 'name' => 'Spigot', 'description' => 'Spigot is the most widely-used modded Minecraft server software in the world. It powers many of the top Minecraft server networks around to ensure they can cope with their huge player base and ensure the satisfaction of their players. Spigot works by reducing and eliminating many causes of lag, as well as adding in handy features and settings that help make your job of server administration easier.', - 'tag' => 'spigot', 'docker_image' => 'quay.io/pterodactyl/minecraft:spigot', - 'executable' => null, - 'startup' => '-Xms128M -Xmx{{SERVER_MEMORY}}M -jar {{SERVER_JARFILE}}', - ]); - - $this->option['sponge'] = Models\ServiceOption::create([ - 'service_id' => $this->service->id, - 'name' => 'Sponge (SpongeVanilla)', - 'description' => 'SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.', - 'tag' => 'sponge', - 'docker_image' => 'quay.io/pterodactyl/minecraft:sponge', - 'executable' => null, + 'config_startup' => null, + 'config_files' => '{"spigot.yml":{"parser": "yaml", "find":{"settings.restart-on-crash": "false"}}}', + 'config_logs' => null, + 'config_stop' => null, + 'config_from' => $this->option['vanilla']->id, 'startup' => null, ]); - $this->option['bungeecord'] = Models\ServiceOption::create([ + $this->option['sponge'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'sponge', + ], [ + 'name' => 'Sponge (SpongeVanilla)', + 'description' => 'SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.', + 'docker_image' => 'quay.io/pterodactyl/minecraft:sponge', + 'config_startup' => '{"userInteraction": [ "You need to agree to the EULA"]}', + 'config_files' => null, + 'config_logs' => null, + 'config_stop' => null, + 'config_from' => $this->option['vanilla']->id, + 'startup' => null, + ]); + + $this->option['bungeecord'] = ServiceOption::updateOrCreate([ + 'service_id' => $this->service->id, + 'tag' => 'bungeecord', + ], [ 'name' => 'Bungeecord', '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.', - 'tag' => 'bungeecord', 'docker_image' => 'quay.io/pterodactyl/minecraft:bungeecord', - 'executable' => null, + 'config_startup' => '{"done": "Listening on ", "userInteraction": [ "Listening on /0.0.0.0:25577"]}', + 'config_files' => '{"config.yml":{"parser": "yaml", "find":{"listeners[0].query_enabled": true, "listeners[0].query_port": "{{server.build.default.port}}", "listeners[0].host": "0.0.0.0:{{server.build.default.port}}", "servers.*.address":{"127.0.0.1": "{{config.docker.interface}}", "localhost": "{{config.docker.interface}}"}}}}', + 'config_logs' => '{"custom": false, "location": "proxy.log.0"}', + 'config_stop' => 'end', + 'config_from' => null, 'startup' => null, ]); } @@ -117,121 +181,121 @@ class MinecraftServiceTableSeeder extends Seeder private function addVanillaVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['vanilla']->id, + 'env_variable' => 'SERVER_JARFILE', + ], [ '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' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([\w\d._-]+)(\.jar)$/', + 'rules' => 'required|regex:/^([\w\d._-]+)(\.jar)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['vanilla']->id, + 'env_variable' => 'VANILLA_VERSION', + ], [ 'name' => 'Server Version', 'description' => 'The version of Minecraft Vanilla to install. Use "latest" to install the latest version.', - 'env_variable' => 'VANILLA_VERSION', 'default_value' => 'latest', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(latest|[a-zA-Z0-9_\.-]{3,7})$/', + 'rules' => 'required|string|between:3,7', ]); } private function addSpigotVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['spigot']->id, + 'env_variable' => 'SERVER_JARFILE', + ], [ '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' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([\w\d._-]+)(\.jar)$/', + 'rules' => 'required|regex:/^([\w\d._-]+)(\.jar)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['spigot']->id, + 'env_variable' => 'DL_VERSION', + ], [ 'name' => 'Spigot Version', 'description' => 'The version of Spigot to download (using the --rev tag). Use "latest" for latest.', - 'env_variable' => 'DL_VERSION', 'default_value' => 'latest', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(latest|[a-zA-Z0-9_\.-]{3,7})$/', + 'rules' => 'required|string|between:3,7', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['spigot']->id, + 'env_variable' => 'DL_PATH', + ], [ 'name' => 'Download Path', 'description' => 'A URL to use to download Spigot rather than building it on the server. This is not user viewable. Use {{DL_VERSION}} in the URL to automatically insert the assigned version into the URL. If you do not enter a URL Spigot will build directly in the container (this will fail on low memory containers).', - 'env_variable' => 'DL_PATH', 'default_value' => '', 'user_viewable' => 0, 'user_editable' => 0, - 'required' => 0, - 'regex' => '/^(.*)$/', + 'rules' => 'string', ]); } private function addSpongeVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['sponge']->id, + 'env_variable' => 'SPONGE_VERSION', + ], [ 'name' => 'Sponge Version', 'description' => 'The version of SpongeVanilla to download and use.', - 'env_variable' => 'SPONGE_VERSION', - 'default_value' => '1.10.2-5.1.0-BETA-359', + 'default_value' => '1.10.2-5.2.0-BETA-381', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^([a-zA-Z0-9.\-_]+)$/', + 'rules' => 'required|regex:/^([a-zA-Z0-9.\-_]+)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['sponge']->id, + 'env_variable' => 'SERVER_JARFILE', + ], [ 'name' => 'Server Jar File', 'description' => 'The name of the Jarfile to use when running SpongeVanilla.', - 'env_variable' => 'SERVER_JARFILE', 'default_value' => 'server.jar', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([\w\d._-]+)(\.jar)$/', + 'rules' => 'required|regex:/^([\w\d._-]+)(\.jar)$/', ]); } private function addBungeecordVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['bungeecord']->id, + 'env_variable' => 'BUNGEE_VERSION', + ], [ 'name' => 'Bungeecord Version', 'description' => 'The version of Bungeecord to download and use.', - 'env_variable' => 'BUNGEE_VERSION', 'default_value' => 'latest', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(latest|[\d]{1,6})$/', + 'rules' => 'required|alpha_num|between:1,6', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['bungeecord']->id, + 'env_variable' => 'SERVER_JARFILE', + ], [ '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' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([\w\d._-]+)(\.jar)$/', + 'rules' => 'required|regex:/^([\w\d._-]+)(\.jar)$/', ]); } } diff --git a/database/seeds/SourceServiceTableSeeder.php b/database/seeds/SourceServiceTableSeeder.php index 87623335c..08e941ed5 100644 --- a/database/seeds/SourceServiceTableSeeder.php +++ b/database/seeds/SourceServiceTableSeeder.php @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -use Pterodactyl\Models; use Illuminate\Database\Seeder; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; class SourceServiceTableSeeder extends Seeder { @@ -54,57 +56,78 @@ class SourceServiceTableSeeder extends Seeder private function addCoreService() { - $this->service = Models\Service::create([ - 'author' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + $this->service = Service::updateOrCreate([ + 'author' => config('pterodactyl.service.core'), + 'folder' => 'srcds', + ], [ 'name' => 'Source Engine', 'description' => 'Includes support for most Source Dedicated Server games.', - 'file' => 'srcds', - 'executable' => './srcds_run', - 'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} -strictportbind -norestart', + 'startup' => './srcds_run -game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +ip 0.0.0.0 -strictportbind -norestart', + 'index_file' => Service::defaultIndexFile(), ]); } private function addCoreOptions() { - $this->option['insurgency'] = Models\ServiceOption::create([ - 'service_id' => $this->service->id, - 'name' => 'Insurgency', - '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.', - 'tag' => 'srcds', - 'docker_image' => 'quay.io/pterodactyl/srcds', - 'executable' => null, - 'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart', - ]); - - $this->option['tf2'] = Models\ServiceOption::create([ - 'service_id' => $this->service->id, - 'name' => 'Team Fortress 2', - '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.', - 'tag' => 'srcds', - 'docker_image' => 'quay.io/pterodactyl/srcds', - 'executable' => null, - 'startup' => '-game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} -strictportbind -norestart', - ]); - - $this->option['ark'] = Models\ServiceOption::create([ - 'service_id' => $this->service->id, - 'name' => 'Ark: Survival Evolved', - '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! — Gamepedia: ARK', - 'tag' => 'ark', - 'docker_image' => 'quay.io/pterodactyl/srcds:ark', - 'executable' => './ShooterGameServer', - 'startup' => 'TheIsland?listen?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}', - ]); - - $this->option['custom'] = Models\ServiceOption::create([ + $this->option['source'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'source', + ], [ 'name' => 'Custom Source Engine Game', 'description' => 'This option allows modifying the startup arguments and other details to run a custo SRCDS based game on the panel.', - 'tag' => 'srcds', 'docker_image' => 'quay.io/pterodactyl/srcds', - 'executable' => null, + 'config_startup' => '{"done": "Assigned anonymous gameserver", "userInteraction": []}', + 'config_files' => '{}', + 'config_logs' => '{"custom": true, "location": "logs/latest.log"}', + 'config_stop' => 'quit', + 'config_from' => null, 'startup' => null, ]); + + $this->option['insurgency'] = ServiceOption::updateOrCreate([ + 'service_id' => $this->service->id, + 'tag' => 'insurgency', + ], [ + 'name' => 'Insurgency', + '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.', + 'docker_image' => 'quay.io/pterodactyl/srcds', + 'config_startup' => null, + 'config_files' => null, + 'config_logs' => null, + 'config_stop' => null, + 'config_from' => $this->option['source']->id, + 'startup' => './srcds_run -game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart', + ]); + + $this->option['tf2'] = ServiceOption::updateOrCreate([ + 'service_id' => $this->service->id, + 'tag' => 'tf2', + ], [ + 'name' => 'Team Fortress 2', + '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.', + 'docker_image' => 'quay.io/pterodactyl/srcds', + 'config_startup' => null, + 'config_files' => null, + 'config_logs' => null, + 'config_stop' => null, + 'config_from' => $this->option['source']->id, + 'startup' => './srcds_run -game {{SRCDS_GAME}} -console -port {{SERVER_PORT}} +map {{SRCDS_MAP}} +ip 0.0.0.0 -strictportbind -norestart', + ]); + + $this->option['ark'] = ServiceOption::updateOrCreate([ + 'service_id' => $this->service->id, + 'tag' => 'ark', + ], [ + 'name' => 'Ark: Survival Evolved', + '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! — Gamepedia: ARK', + 'docker_image' => 'quay.io/pterodactyl/srcds:ark', + 'config_startup' => '{"done": "Setting breakpad minidump AppID"}', + 'config_files' => null, + 'config_logs' => null, + 'config_stop' => '^C', + 'config_from' => $this->option['source']->id, + 'startup' => './ShooterGame/Binaries/Linux/ShooterGameServer TheIsland?listen?ServerPassword={{ARK_PASSWORD}}?ServerAdminPassword={{ARK_ADMIN_PASSWORD}}?Port={{SERVER_PORT}}?MaxPlayers={{SERVER_MAX_PLAYERS}}', + ]); } private function addVariables() @@ -117,145 +140,145 @@ class SourceServiceTableSeeder extends Seeder private function addInsurgencyVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['insurgency']->id, + 'env_variable' => 'SRCDS_APPID', + ], [ 'name' => 'Game ID', 'description' => 'The ID corresponding to the game to download and run using SRCDS.', - 'env_variable' => 'SRCDS_APPID', 'default_value' => '17705', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(17705)$/', + 'rules' => 'required|regex:/^(17705)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['insurgency']->id, + 'env_variable' => 'SRCDS_GAME', + ], [ 'name' => 'Game Name', 'description' => 'The name corresponding to the game to download and run using SRCDS.', - 'env_variable' => 'SRCDS_GAME', 'default_value' => 'insurgency', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(insurgency)$/', + 'rules' => 'required|regex:/^(insurgency)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['insurgency']->id, + 'env_variable' => 'SRCDS_MAP', + ], [ 'name' => 'Default Map', 'description' => 'The default map to use when starting the server.', - 'env_variable' => 'SRCDS_MAP', 'default_value' => 'sinjar', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(\w{1,20})$/', + 'rules' => 'required|regex:/^(\w{1,20})$/', ]); } private function addTF2Variables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['tf2']->id, + 'env_variable' => 'SRCDS_APPID', + ], [ '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' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(232250)$/', + 'rules' => 'required|regex:/^(232250)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['tf2']->id, + 'env_variable' => 'SRCDS_GAME', + ], [ 'name' => 'Game Name', 'description' => 'The name corresponding to the game to download and run using SRCDS.', - 'env_variable' => 'SRCDS_GAME', 'default_value' => 'tf', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(tf)$/', + 'rules' => 'required|regex:/^(tf)$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['tf2']->id, + 'env_variable' => 'SRCDS_MAP', + ], [ 'name' => 'Default Map', 'description' => 'The default map to use when starting the server.', - 'env_variable' => 'SRCDS_MAP', 'default_value' => 'cp_dustbowl', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(\w{1,20})$/', + 'rules' => 'required|regex:/^(\w{1,20})$/', ]); } private function addArkVariables() { - DB::table('service_variables')->insert([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['ark']->id, + 'env_variable' => 'ARK_PASSWORD', + ], [ 'name' => 'Server Password', 'description' => 'If specified, players must provide this password to join the server.', - 'env_variable' => 'ARK_PASSWORD', 'default_value' => '', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 0, - 'regex' => '/^(\w\.*)$/', + 'rules' => 'alpha_dash|between:1,100', ]); - DB::table('service_variables')->insert([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['ark']->id, + 'env_variable' => 'ARK_ADMIN_PASSWORD', + ], [ 'name' => 'Admin Password', 'description' => 'If specified, players must provide this password (via the in-game console) to gain access to administrator commands on the server.', - 'env_variable' => 'ARK_ADMIN_PASSWORD', 'default_value' => '', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 0, - 'regex' => '/^(\w\.*)$/', + 'rules' => 'alpha_dash|between:1,100', ]); - DB::table('service_variables')->insert([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['ark']->id, + 'env_variable' => 'SERVER_MAX_PLAYERS', + ], [ 'name' => 'Maximum Players', 'description' => 'Specifies the maximum number of players that can play on the server simultaneously.', - 'env_variable' => 'SERVER_MAX_PLAYERS', 'default_value' => 20, 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^(\d{1,4})$/', + 'rules' => 'required|numeric|digits_between:1,4', ]); } private function addCustomVariables() { - Models\ServiceVariable::create([ - 'option_id' => $this->option['custom']->id, + ServiceVariable::updateOrCreate([ + 'option_id' => $this->option['source']->id, + 'env_variable' => 'SRCDS_APPID', + ], [ 'name' => 'Game ID', 'description' => 'The ID corresponding to the game to download and run using SRCDS.', - 'env_variable' => 'SRCDS_APPID', 'default_value' => '', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(\d){1,6}$/', + 'rules' => 'required|numeric|digits_between:1,6', ]); - Models\ServiceVariable::create([ - 'option_id' => $this->option['custom']->id, + ServiceVariable::updateOrCreate([ + 'option_id' => $this->option['source']->id, + 'env_variable' => 'SRCDS_GAME', + ], [ 'name' => 'Game Name', 'description' => 'The name corresponding to the game to download and run using SRCDS.', - 'env_variable' => 'SRCDS_GAME', 'default_value' => '', 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(.*)$/', + 'rules' => 'required|alpha_dash|between:1,100', ]); } } diff --git a/database/seeds/TerrariaServiceTableSeeder.php b/database/seeds/TerrariaServiceTableSeeder.php index 59fd1e519..036e42e0e 100644 --- a/database/seeds/TerrariaServiceTableSeeder.php +++ b/database/seeds/TerrariaServiceTableSeeder.php @@ -21,8 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -use Pterodactyl\Models; use Illuminate\Database\Seeder; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; class TerrariaServiceTableSeeder extends Seeder { @@ -54,53 +56,58 @@ class TerrariaServiceTableSeeder extends Seeder private function addCoreService() { - $this->service = Models\Service::create([ - 'author' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + $this->service = Service::updateOrCreate([ + 'author' => config('pterodactyl.service.core'), + 'folder' => 'terraria', + ], [ 'name' => 'Terraria', 'description' => 'Terraria is a land of adventure! A land of mystery! A land that\'s yours to shape, defend, and enjoy. Your options in Terraria are limitless. Are you an action gamer with an itchy trigger finger? A master builder? A collector? An explorer? There\'s something for everyone.', - 'file' => 'terraria', - 'executable' => 'TerrariaServer.exe', - 'startup' => '-port {{SERVER_PORT}} -autocreate 2 -worldname World', + 'startup' => 'mono TerrariaServer.exe -port {{SERVER_PORT}} -autocreate 2 -worldname World', ]); } private function addCoreOptions() { - $this->option['tshock'] = Models\ServiceOption::create([ + $this->option['tshock'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'tshock', + ], [ 'name' => 'Terraria Server (TShock)', 'description' => 'TShock is a server modification for Terraria, written in C#, and based upon the Terraria Server API. It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.', - 'tag' => 'tshock', 'docker_image' => 'quay.io/pterodactyl/terraria:tshock', - 'executable' => '', - 'startup' => '', + 'config_startup' => '{"userInteraction": [ "You need to agree to the EULA"]}', + 'config_startup' => '{"done": "Type \'help\' for a list of commands", "userInteraction": []}', + 'config_files' => '{"tshock/config.json":{"parser": "json", "find":{"ServerPort": "{{server.build.default.port}}", "MaxSlots": "{{server.build.env.MAX_SLOTS}}"}}}', + 'config_logs' => '{"custom": false, "location": "ServerLog.txt"}', + 'config_stop' => 'exit', + 'startup' => null, ]); } private function addVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['tshock']->id, + 'env_variable' => 'T_VERSION', + ], [ 'name' => 'TShock Version', 'description' => 'Which version of TShock to install and use.', - 'env_variable' => 'T_VERSION', - 'default_value' => '4.3.17', + 'default_value' => '4.3.22', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([0-9_\.-]{5,10})$/', + 'rules' => 'required|regex:/^([0-9_\.-]{5,10})$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['tshock']->id, + 'env_variable' => 'MAX_SLOTS', + ], [ 'name' => 'Maximum Slots', 'description' => 'Total number of slots to allow on the server.', - 'env_variable' => 'MAX_SLOTS', - 'default_value' => '20', + 'default_value' => 20, 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(\d){1,3}$/', + 'rules' => 'required|numeric|digits_between:1,3', ]); } } diff --git a/database/seeds/VoiceServiceTableSeeder.php b/database/seeds/VoiceServiceTableSeeder.php index 3856ac76a..2e1c26a8b 100644 --- a/database/seeds/VoiceServiceTableSeeder.php +++ b/database/seeds/VoiceServiceTableSeeder.php @@ -21,15 +21,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -use Pterodactyl\Models; use Illuminate\Database\Seeder; +use Pterodactyl\Models\Service; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; class VoiceServiceTableSeeder extends Seeder { /** * The core service ID. * - * @var Models\Service + * @var Service */ protected $service; @@ -54,75 +56,85 @@ class VoiceServiceTableSeeder extends Seeder private function addCoreService() { - $this->service = Models\Service::create([ - 'author' => 'ptrdctyl-v040-11e6-8b77-86f30ca893d3', + $this->service = Service::updateOrCreate([ + 'author' => config('pterodactyl.service.core'), + 'folder' => 'voice', + ], [ 'name' => 'Voice Servers', 'description' => 'Voice servers such as Mumble and Teamspeak 3.', - 'file' => 'voice', - 'executable' => '', 'startup' => '', ]); } private function addCoreOptions() { - $this->option['mumble'] = Models\ServiceOption::create([ + $this->option['mumble'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'mumble', + ], [ 'name' => 'Mumble Server', 'description' => 'Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.', - 'tag' => 'mumble', 'docker_image' => 'quay.io/pterodactyl/voice:mumble', - 'executable' => './murmur.x86', - 'startup' => '-fg', + 'config_startup' => '{"done": "Server listening on", "userInteraction": [ "Generating new server certificate"]}', + 'config_files' => '{"murmur.ini":{"parser": "ini", "find":{"logfile": "murmur.log", "port": "{{server.build.default.port}}", "host": "0.0.0.0", "users": "{{server.build.env.MAX_USERS}}"}}}', + 'config_logs' => '{"custom": true, "location": "logs/murmur.log"}', + 'config_stop' => '^C', + 'config_from' => null, + 'startup' => './murmur.x86 -fg', ]); - $this->option['ts3'] = Models\ServiceOption::create([ + $this->option['ts3'] = ServiceOption::updateOrCreate([ 'service_id' => $this->service->id, + 'tag' => 'ts3', + ], [ 'name' => 'Teamspeak3 Server', 'description' => 'VoIP software designed with security in mind, featuring crystal clear voice quality, endless customization options, and scalabilty up to thousands of simultaneous users.', - 'tag' => 'ts3', 'docker_image' => 'quay.io/pterodactyl/voice:ts3', - 'executable' => './ts3server_minimal_runscript.sh', - 'startup' => 'default_voice_port={{SERVER_PORT}} query_port={{SERVER_PORT}}', + 'config_startup' => '{"done": "listening on 0.0.0.0:", "userInteraction": []}', + 'config_files' => '{"ts3server.ini":{"parser": "ini", "find":{"default_voice_port": "{{server.build.default.port}}", "voice_ip": "0.0.0.0", "query_port": "{{server.build.default.port}}", "query_ip": "0.0.0.0"}}}', + 'config_logs' => '{"custom": true, "location": "logs/ts3.log"}', + 'config_stop' => '^C', + 'config_from' => null, + 'startup' => './ts3server_minimal_runscript.sh default_voice_port={{SERVER_PORT}} query_port={{SERVER_PORT}}', ]); } private function addVariables() { - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['mumble']->id, + 'env_variable' => 'MAX_USERS', + ], [ 'name' => 'Maximum Users', 'description' => 'Maximum concurrent users on the mumble server.', - 'env_variable' => 'MAX_USERS', - 'default_value' => '100', + 'default_value' => 100, 'user_viewable' => 1, 'user_editable' => 0, - 'required' => 1, - 'regex' => '/^(\d){1,6}$/', + 'rules' => 'required|numeric|digits_between:1,5', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['mumble']->id, + 'env_variable' => 'MUMBLE_VERSION', + ], [ 'name' => 'Server Version', 'description' => 'Version of Mumble Server to download and use.', - 'env_variable' => 'MUMBLE_VERSION', - 'default_value' => '1.2.16', + 'default_value' => '1.2.19', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([0-9_\.-]{5,8})$/', + 'rules' => 'required|regex:/^([0-9_\.-]{5,8})$/', ]); - Models\ServiceVariable::create([ + ServiceVariable::updateOrCreate([ 'option_id' => $this->option['ts3']->id, + 'env_variable' => 'T_VERSION', + ], [ 'name' => 'Server Version', 'description' => 'The version of Teamspeak 3 to use when running the server.', - 'env_variable' => 'T_VERSION', - 'default_value' => '3.0.13.4', + 'default_value' => '3.1.1.1', 'user_viewable' => 1, 'user_editable' => 1, - 'required' => 1, - 'regex' => '/^([0-9_\.-]{5,10})$/', + 'rules' => 'required|regex:/^([0-9_\.-]{5,10})$/', ]); } } diff --git a/public/js/laroute.js b/public/js/laroute.js index b4f553912..dde3acaf8 100644 --- a/public/js/laroute.js +++ b/public/js/laroute.js @@ -6,7 +6,7 @@ absolute: false, rootUrl: 'http://pterodactyl.app', - routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@saveStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@newDatabase"},{"host":null,"methods":["PATCH"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@resetDatabasePassword"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/database\/{database}\/delete","name":"admin.servers.view.database.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}","name":"admin.services.service","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getService"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postService"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{id}\/configuration","name":"admin.services.service.config","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{id}\/configuration","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@newOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":"admin.services.option","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getOption"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOption"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/service\/{service}\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":"admin.services.option.variable.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@getNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postNewVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}","name":"admin.services.option.variable","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@postOptionVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/service\/{service}\/option\/{option}\/variable\/{variable}\/delete","name":"admin.services.option.variable.delete","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@deleteVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/new\/{option?}","name":"admin.services.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/upload\/{option?}","name":"admin.services.packs.uploadForm","action":"Pterodactyl\Http\Controllers\Admin\PackController@uploadForm"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/upload","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@postUpload"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs","name":"admin.services.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@listAll"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/option\/{option}","name":"admin.services.packs.option","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByOption"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/for\/service\/{service}","name":"admin.services.packs.service","action":"Pterodactyl\Http\Controllers\Admin\PackController@listByService"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}","name":"admin.services.packs.edit","action":"Pterodactyl\Http\Controllers\Admin\PackController@edit"},{"host":null,"methods":["POST"],"uri":"admin\/services\/packs\/edit\/{pack}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/packs\/edit\/{pack}\/export\/{archive?}","name":"admin.services.packs.export","action":"Pterodactyl\Http\Controllers\Admin\PackController@export"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], + routes : [{"host":null,"methods":["GET","HEAD"],"uri":"admin","name":"admin.index","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/settings","name":"admin.settings","action":"Pterodactyl\Http\Controllers\Admin\BaseController@getSettings"},{"host":null,"methods":["POST"],"uri":"admin\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\BaseController@postSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users","name":"admin.users","action":"Pterodactyl\Http\Controllers\Admin\UserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/accounts.json","name":"admin.users.json","action":"Pterodactyl\Http\Controllers\Admin\UserController@getJson"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/view\/{id}","name":"admin.users.view","action":"Pterodactyl\Http\Controllers\Admin\UserController@getView"},{"host":null,"methods":["POST"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@updateUser"},{"host":null,"methods":["DELETE"],"uri":"admin\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@deleteUser"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/users\/new","name":"admin.users.new","action":"Pterodactyl\Http\Controllers\Admin\UserController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\UserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers","name":"admin.servers","action":"Pterodactyl\Http\Controllers\Admin\ServersController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/new","name":"admin.servers.new","action":"Pterodactyl\Http\Controllers\Admin\ServersController@new"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@create"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/new\/nodes","name":"admin.servers.new.nodes","action":"Pterodactyl\Http\Controllers\Admin\ServersController@newServerNodes"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}","name":"admin.servers.view","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/details","name":"admin.servers.view.details","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@setDetails"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/details\/container","name":"admin.servers.view.details.container","action":"Pterodactyl\Http\Controllers\Admin\ServersController@setContainer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/build","name":"admin.servers.view.build","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewBuild"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/build","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@updateBuild"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/startup","name":"admin.servers.view.startup","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewStartup"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@saveStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/database","name":"admin.servers.view.database","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDatabase"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@newDatabase"},{"host":null,"methods":["PATCH"],"uri":"admin\/servers\/view\/{id}\/database","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@resetDatabasePassword"},{"host":null,"methods":["DELETE"],"uri":"admin\/servers\/view\/{id}\/database\/{database}\/delete","name":"admin.servers.view.database.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@deleteDatabase"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/manage","name":"admin.servers.view.manage","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewManage"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/toggle","name":"admin.servers.view.manage.toggle","action":"Pterodactyl\Http\Controllers\Admin\ServersController@toggleInstall"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/rebuild","name":"admin.servers.view.manage.rebuild","action":"Pterodactyl\Http\Controllers\Admin\ServersController@rebuildContainer"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/manage\/suspension","name":"admin.servers.view.manage.suspension","action":"Pterodactyl\Http\Controllers\Admin\ServersController@manageSuspension"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/servers\/view\/{id}\/delete","name":"admin.servers.view.delete","action":"Pterodactyl\Http\Controllers\Admin\ServersController@viewDelete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServersController@delete"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/continue\/{force?}","name":"admin.servers.view.delete.continue","action":"Pterodactyl\Http\Controllers\Admin\ServersController@continueDeletion"},{"host":null,"methods":["POST"],"uri":"admin\/servers\/view\/{id}\/delete\/cancel","name":"admin.servers.view.delete.cancel","action":"Pterodactyl\Http\Controllers\Admin\ServersController@cancelDeletion"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes","name":"admin.nodes","action":"Pterodactyl\Http\Controllers\Admin\NodesController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/new","name":"admin.nodes.new","action":"Pterodactyl\Http\Controllers\Admin\NodesController@new"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}","name":"admin.nodes.view","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings","name":"admin.nodes.view.settings","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewSettings"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/settings","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@updateSettings"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/configuration","name":"admin.nodes.view.configuration","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":"admin.nodes.view.allocation","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewAllocation"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation","name":null,"action":"Pterodactyl\Http\Controllers\Admin\NodesController@createAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/servers","name":"admin.nodes.view.servers","action":"Pterodactyl\Http\Controllers\Admin\NodesController@viewServers"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/delete","name":"admin.nodes.view.delete","action":"Pterodactyl\Http\Controllers\Admin\NodesController@delete"},{"host":null,"methods":["DELETE"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove\/{allocation}","name":"admin.nodes.view.allocation.removeSingle","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveSingle"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/remove","name":"admin.nodes.view.allocation.removeBlock","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationRemoveBlock"},{"host":null,"methods":["POST"],"uri":"admin\/nodes\/view\/{id}\/allocation\/alias","name":"admin.nodes.view.allocation.setAlias","action":"Pterodactyl\Http\Controllers\Admin\NodesController@allocationSetAlias"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/nodes\/view\/{id}\/settings\/token","name":"admin.nodes.view.configuration.token","action":"Pterodactyl\Http\Controllers\Admin\NodesController@setToken"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/locations","name":"admin.locations","action":"Pterodactyl\Http\Controllers\Admin\LocationsController@getIndex"},{"host":null,"methods":["DELETE"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@deleteLocation"},{"host":null,"methods":["PATCH"],"uri":"admin\/locations\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@patchLocation"},{"host":null,"methods":["POST"],"uri":"admin\/locations","name":null,"action":"Pterodactyl\Http\Controllers\Admin\LocationsController@postLocation"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases","name":"admin.databases","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/databases\/new","name":"admin.databases.new","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@getNew"},{"host":null,"methods":["POST"],"uri":"admin\/databases\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@postNew"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete\/{id}","name":"admin.databases.delete","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteDatabase"},{"host":null,"methods":["DELETE"],"uri":"admin\/databases\/delete-server\/{id}","name":"admin.databases.delete-server","action":"Pterodactyl\Http\Controllers\Admin\DatabaseController@deleteServer"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services","name":"admin.services","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/new","name":"admin.services.new","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/view\/{id}","name":"admin.services.view","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@view"},{"host":null,"methods":["POST"],"uri":"admin\/services\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@edit"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/view\/{id}\/functions","name":"admin.services.view.functions","action":"Pterodactyl\Http\Controllers\Admin\ServiceController@viewFunctions"},{"host":null,"methods":["DELETE"],"uri":"admin\/services\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\ServiceController@delete"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/option\/new","name":"admin.services.option.new","action":"Pterodactyl\Http\Controllers\Admin\OptionController@new"},{"host":null,"methods":["POST"],"uri":"admin\/services\/option\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\OptionController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/option\/{id}","name":"admin.services.option.view","action":"Pterodactyl\Http\Controllers\Admin\OptionController@viewConfiguration"},{"host":null,"methods":["POST"],"uri":"admin\/services\/option\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Admin\OptionController@editConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/services\/option\/{id}\/variables","name":"admin.services.option.variables","action":"Pterodactyl\Http\Controllers\Admin\OptionController@viewVariables"},{"host":null,"methods":["POST"],"uri":"admin\/services\/option\/{id}\/variables","name":null,"action":"Pterodactyl\Http\Controllers\Admin\OptionController@createVariable"},{"host":null,"methods":["POST"],"uri":"admin\/services\/option\/{id}\/variables\/{variable}","name":"admin.services.option.variables.edit","action":"Pterodactyl\Http\Controllers\Admin\OptionController@editVariable"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/packs","name":"admin.packs","action":"Pterodactyl\Http\Controllers\Admin\PackController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/packs\/new","name":"admin.packs.new","action":"Pterodactyl\Http\Controllers\Admin\PackController@new"},{"host":null,"methods":["POST"],"uri":"admin\/packs\/new","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@create"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/packs\/new\/template","name":"admin.packs.new.template","action":"Pterodactyl\Http\Controllers\Admin\PackController@newTemplate"},{"host":null,"methods":["POST"],"uri":"admin\/packs\/new\/template","name":null,"action":"Pterodactyl\Http\Controllers\Admin\PackController@createTemplate"},{"host":null,"methods":["GET","HEAD"],"uri":"admin\/packs\/view\/{id}","name":"admin.packs.view","action":"Pterodactyl\Http\Controllers\Admin\PackController@view"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login","name":"auth.login","action":"Pterodactyl\Http\Controllers\Auth\LoginController@showLoginForm"},{"host":null,"methods":["POST"],"uri":"auth\/login","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@login"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/login\/totp","name":"auth.totp","action":"Pterodactyl\Http\Controllers\Auth\LoginController@totp"},{"host":null,"methods":["POST"],"uri":"auth\/login\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Auth\LoginController@totpCheckpoint"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password","name":"auth.password","action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm"},{"host":null,"methods":["POST"],"uri":"auth\/password","name":null,"action":"Pterodactyl\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/password\/reset\/{token}","name":"auth.reset","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@showResetForm"},{"host":null,"methods":["POST"],"uri":"auth\/password\/reset","name":"auth.reset.post","action":"Pterodactyl\Http\Controllers\Auth\ResetPasswordController@reset"},{"host":null,"methods":["GET","HEAD"],"uri":"auth\/logout","name":"auth.logout","action":"Pterodactyl\Http\Controllers\Auth\LoginController@logout"},{"host":null,"methods":["GET","HEAD"],"uri":"\/","name":"index","action":"Pterodactyl\Http\Controllers\Base\IndexController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"index","name":null,"action":"Closure"},{"host":null,"methods":["GET","HEAD"],"uri":"password-gen\/{length}","name":"password-gen","action":"Pterodactyl\Http\Controllers\Base\IndexController@getPassword"},{"host":null,"methods":["GET","HEAD"],"uri":"account","name":"account","action":"Pterodactyl\Http\Controllers\Base\AccountController@index"},{"host":null,"methods":["POST"],"uri":"account","name":null,"action":"Pterodactyl\Http\Controllers\Base\AccountController@update"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api","name":"account.api","action":"Pterodactyl\Http\Controllers\Base\APIController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/api\/new","name":"account.api.new","action":"Pterodactyl\Http\Controllers\Base\APIController@create"},{"host":null,"methods":["POST"],"uri":"account\/api\/new","name":null,"action":"Pterodactyl\Http\Controllers\Base\APIController@save"},{"host":null,"methods":["DELETE"],"uri":"account\/api\/revoke\/{key}","name":"account.api.revoke","action":"Pterodactyl\Http\Controllers\Base\APIController@revoke"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security","name":"account.security","action":"Pterodactyl\Http\Controllers\Base\SecurityController@index"},{"host":null,"methods":["GET","HEAD"],"uri":"account\/security\/revoke\/{id}","name":"account.security.revoke","action":"Pterodactyl\Http\Controllers\Base\SecurityController@revoke"},{"host":null,"methods":["PUT"],"uri":"account\/security\/totp","name":"account.security.totp","action":"Pterodactyl\Http\Controllers\Base\SecurityController@generateTotp"},{"host":null,"methods":["POST"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@setTotp"},{"host":null,"methods":["DELETE"],"uri":"account\/security\/totp","name":null,"action":"Pterodactyl\Http\Controllers\Base\SecurityController@disableTotp"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services","name":"daemon.services","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@list"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/services\/pull\/{service}\/{file}","name":"remote.install","action":"Pterodactyl\Http\Controllers\Daemon\ServiceController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}","name":"daemon.pack.pull","action":"Pterodactyl\Http\Controllers\Daemon\PackController@pull"},{"host":null,"methods":["GET","HEAD"],"uri":"daemon\/packs\/pull\/{uuid}\/hash","name":"daemon.pack.hash","action":"Pterodactyl\Http\Controllers\Daemon\PackController@hash"},{"host":null,"methods":["GET","HEAD"],"uri":"language\/{lang}","name":"langauge.set","action":"Pterodactyl\Http\Controllers\Base\LanguageController@setLanguage"},{"host":null,"methods":["POST"],"uri":"remote\/download","name":"remote.download","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postDownload"},{"host":null,"methods":["POST"],"uri":"remote\/install","name":"remote.install","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@postInstall"},{"host":null,"methods":["GET","HEAD"],"uri":"remote\/configuration\/{token}","name":"remote.configuration","action":"Pterodactyl\Http\Controllers\Remote\RemoteController@getConfiguration"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/ajax\/status","name":"server.ajax.status","action":"Pterodactyl\Http\Controllers\Server\AjaxController@getStatus"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}","name":"server.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/databases","name":"server.settings.databases","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDatabases"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/sftp","name":"server.settings.sftp","action":"Pterodactyl\Http\Controllers\Server\ServerController@getSFTP"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/sftp","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsSFTP"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/startup","name":"server.settings.startup","action":"Pterodactyl\Http\Controllers\Server\ServerController@getStartup"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/settings\/startup","name":null,"action":"Pterodactyl\Http\Controllers\Server\ServerController@postSettingsStartup"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/settings\/allocation","name":"server.settings.allocation","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAllocation"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files","name":"server.files.index","action":"Pterodactyl\Http\Controllers\Server\ServerController@getFiles"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/edit\/{file}","name":"server.files.edit","action":"Pterodactyl\Http\Controllers\Server\ServerController@getEditFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/download\/{file}","name":"server.files.download","action":"Pterodactyl\Http\Controllers\Server\ServerController@getDownloadFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/files\/add","name":"server.files.add","action":"Pterodactyl\Http\Controllers\Server\ServerController@getAddFile"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/directory-list","name":"server.files.directory-list","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postDirectoryList"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/files\/save","name":"server.files.save","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSaveFile"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users","name":"server.subusers","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/new","name":"server.subusers.new","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postNew"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/users\/view\/{id}","name":"server.subusers.view","action":"Pterodactyl\Http\Controllers\Server\SubuserController@getView"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/users\/view\/{id}","name":null,"action":"Pterodactyl\Http\Controllers\Server\SubuserController@postView"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/users\/delete\/{id}","name":"server.subusers.delete","action":"Pterodactyl\Http\Controllers\Server\SubuserController@deleteSubuser"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks","name":"server.tasks","action":"Pterodactyl\Http\Controllers\Server\TaskController@getIndex"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/view\/{id}","name":"server.tasks.view","action":"Pterodactyl\Http\Controllers\Server\TaskController@getView"},{"host":null,"methods":["GET","HEAD"],"uri":"server\/{server}\/tasks\/new","name":"server.tasks.new","action":"Pterodactyl\Http\Controllers\Server\TaskController@getNew"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/new","name":null,"action":"Pterodactyl\Http\Controllers\Server\TaskController@postNew"},{"host":null,"methods":["DELETE"],"uri":"server\/{server}\/tasks\/delete\/{id}","name":"server.tasks.delete","action":"Pterodactyl\Http\Controllers\Server\TaskController@deleteTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/tasks\/toggle\/{id}","name":"server.tasks.toggle","action":"Pterodactyl\Http\Controllers\Server\TaskController@toggleTask"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/set-primary","name":null,"action":"Pterodactyl\Http\Controllers\Server\AjaxController@postSetPrimary"},{"host":null,"methods":["POST"],"uri":"server\/{server}\/ajax\/settings\/reset-database-password","name":"server.ajax.reset-database-password","action":"Pterodactyl\Http\Controllers\Server\AjaxController@postResetDatabasePassword"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/open","name":"debugbar.openhandler","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@handle"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/clockwork\/{id}","name":"debugbar.clockwork","action":"Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/stylesheets","name":"debugbar.assets.css","action":"Barryvdh\Debugbar\Controllers\AssetController@css"},{"host":null,"methods":["GET","HEAD"],"uri":"_debugbar\/assets\/javascript","name":"debugbar.assets.js","action":"Barryvdh\Debugbar\Controllers\AssetController@js"}], prefix: '', route : function (name, parameters, route) { diff --git a/public/themes/pterodactyl/css/checkbox.css b/public/themes/pterodactyl/css/checkbox.css new file mode 100644 index 000000000..fd4a855ac --- /dev/null +++ b/public/themes/pterodactyl/css/checkbox.css @@ -0,0 +1,231 @@ +/** + * Bootsnip - "Bootstrap Checkboxes/Radios" + * Bootstrap 3.2.0 Snippet by i-heart-php + * + * Copyright (c) 2013 Bootsnipp.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + .checkbox { + padding-left: 20px; +} +.checkbox label { + display: inline-block; + position: relative; + padding-left: 5px; +} +.checkbox label::before { + content: ""; + display: inline-block; + position: absolute; + width: 17px; + height: 17px; + left: 0; + margin-left: -20px; + border: 1px solid #cccccc; + border-radius: 3px; + background-color: #fff; + -webkit-transition: border 0.15s ease-in-out, color 0.15s ease-in-out; + -o-transition: border 0.15s ease-in-out, color 0.15s ease-in-out; + transition: border 0.15s ease-in-out, color 0.15s ease-in-out; +} +.checkbox label::after { + display: inline-block; + position: absolute; + width: 16px; + height: 16px; + left: 0; + top: 0; + margin-left: -20px; + padding-left: 3px; + padding-top: 1px; + font-size: 11px; + color: #555555; +} +.checkbox input[type="checkbox"] { + opacity: 0; +} +.checkbox input[type="checkbox"]:focus + label::before { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.checkbox input[type="checkbox"]:checked + label::after { + font-family: 'FontAwesome'; + content: "\f00c"; +} +.checkbox input[type="checkbox"]:disabled + label { + opacity: 0.65; +} +.checkbox input[type="checkbox"]:disabled + label::before { + background-color: #eeeeee; + cursor: not-allowed; +} +.checkbox.checkbox-circle label::before { + border-radius: 50%; +} +.checkbox.checkbox-inline { + margin-top: 0; +} +.checkbox-primary input[type="checkbox"]:checked + label::before { + background-color: #428bca; + border-color: #428bca; +} +.checkbox-primary input[type="checkbox"]:checked + label::after { + color: #fff; +} +.checkbox-danger input[type="checkbox"]:checked + label::before { + background-color: #d9534f; + border-color: #d9534f; +} +.checkbox-danger input[type="checkbox"]:checked + label::after { + color: #fff; +} +.checkbox-info input[type="checkbox"]:checked + label::before { + background-color: #5bc0de; + border-color: #5bc0de; +} +.checkbox-info input[type="checkbox"]:checked + label::after { + color: #fff; +} +.checkbox-warning input[type="checkbox"]:checked + label::before { + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.checkbox-warning input[type="checkbox"]:checked + label::after { + color: #fff; +} +.checkbox-success input[type="checkbox"]:checked + label::before { + background-color: #5cb85c; + border-color: #5cb85c; +} +.checkbox-success input[type="checkbox"]:checked + label::after { + color: #fff; +} +.radio { + padding-left: 20px; +} +.radio label { + display: inline-block; + position: relative; + padding-left: 5px; +} +.radio label::before { + content: ""; + display: inline-block; + position: absolute; + width: 17px; + height: 17px; + left: 0; + margin-left: -20px; + border: 1px solid #cccccc; + border-radius: 50%; + background-color: #fff; + -webkit-transition: border 0.15s ease-in-out; + -o-transition: border 0.15s ease-in-out; + transition: border 0.15s ease-in-out; +} +.radio label::after { + display: inline-block; + position: absolute; + content: " "; + width: 11px; + height: 11px; + left: 3px; + top: 3px; + margin-left: -20px; + border-radius: 50%; + background-color: #555555; + -webkit-transform: scale(0, 0); + -ms-transform: scale(0, 0); + -o-transform: scale(0, 0); + transform: scale(0, 0); + -webkit-transition: -webkit-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); + -moz-transition: -moz-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); + -o-transition: -o-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); + transition: transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); +} +.radio input[type="radio"] { + opacity: 0; +} +.radio input[type="radio"]:focus + label::before { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.radio input[type="radio"]:checked + label::after { + -webkit-transform: scale(1, 1); + -ms-transform: scale(1, 1); + -o-transform: scale(1, 1); + transform: scale(1, 1); +} +.radio input[type="radio"]:disabled + label { + opacity: 0.65; +} +.radio input[type="radio"]:disabled + label::before { + cursor: not-allowed; +} +.radio.radio-inline { + margin-top: 0; +} +.radio-primary input[type="radio"] + label::after { + background-color: #428bca; +} +.radio-primary input[type="radio"]:checked + label::before { + border-color: #428bca; +} +.radio-primary input[type="radio"]:checked + label::after { + background-color: #428bca; +} +.radio-danger input[type="radio"] + label::after { + background-color: #d9534f; +} +.radio-danger input[type="radio"]:checked + label::before { + border-color: #d9534f; +} +.radio-danger input[type="radio"]:checked + label::after { + background-color: #d9534f; +} +.radio-info input[type="radio"] + label::after { + background-color: #5bc0de; +} +.radio-info input[type="radio"]:checked + label::before { + border-color: #5bc0de; +} +.radio-info input[type="radio"]:checked + label::after { + background-color: #5bc0de; +} +.radio-warning input[type="radio"] + label::after { + background-color: #f0ad4e; +} +.radio-warning input[type="radio"]:checked + label::before { + border-color: #f0ad4e; +} +.radio-warning input[type="radio"]:checked + label::after { + background-color: #f0ad4e; +} +.radio-success input[type="radio"] + label::after { + background-color: #5cb85c; +} +.radio-success input[type="radio"]:checked + label::before { + border-color: #5cb85c; +} +.radio-success input[type="radio"]:checked + label::after { + background-color: #5cb85c; +} diff --git a/public/themes/pterodactyl/css/pterodactyl.css b/public/themes/pterodactyl/css/pterodactyl.css index ca34e46a5..9d91c3192 100644 --- a/public/themes/pterodactyl/css/pterodactyl.css +++ b/public/themes/pterodactyl/css/pterodactyl.css @@ -20,6 +20,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ + @import 'checkbox.css'; + .login-box, .register-box { width: 40%; margin: 7% auto @@ -266,3 +268,7 @@ span[aria-labelledby="select2-pUserId-container"] { .terminal-notify:hover { opacity: .9; } + +.no-margin-bottom { + margin-bottom: 0 !important; +} diff --git a/resources/lang/en/server.php b/resources/lang/en/server.php index d8cae3ae2..43913b64e 100644 --- a/resources/lang/en/server.php +++ b/resources/lang/en/server.php @@ -234,7 +234,7 @@ return [ 'edit_params' => 'Edit Parameters', 'update' => 'Update Startup Parameters', 'startup_var' => 'Startup Command Variable', - 'startup_regex' => 'Verification Regex', + 'startup_regex' => 'Input Rules', ], 'sftp' => [ 'header' => 'SFTP Configuration', diff --git a/resources/themes/pterodactyl/admin/packs/index.blade.php b/resources/themes/pterodactyl/admin/packs/index.blade.php new file mode 100644 index 000000000..a4da22809 --- /dev/null +++ b/resources/themes/pterodactyl/admin/packs/index.blade.php @@ -0,0 +1,84 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + List Packs +@endsection + +@section('content-header') +

PacksAll service packs available on the system.

+ +@endsection + +@section('content') +
+
+
+
+

Pack List

+
+
+
+ +
+ + +
+
+
+
+
+
+ + + + + + + + + + @foreach ($packs as $pack) + + + + + + + + + @endforeach + +
IDPack NameVersionDescriptionOption + Servers
{{ $pack->id }}{{ $pack->name }}{{ $pack->version }}{{ str_limit($pack->description, 150) }}{{ $pack->option->name }}{{ $pack->servers_count }}
+
+ @if ($packs->hasPages()) + + @endif +
+
+
+@endsection diff --git a/resources/views/admin/services/packs/upload.blade.php b/resources/themes/pterodactyl/admin/packs/modal.blade.php similarity index 57% rename from resources/views/admin/services/packs/upload.blade.php rename to resources/themes/pterodactyl/admin/packs/modal.blade.php index cb5e548d8..fd4263575 100644 --- a/resources/views/admin/services/packs/upload.blade.php +++ b/resources/themes/pterodactyl/admin/packs/modal.blade.php @@ -1,7 +1,7 @@ diff --git a/resources/themes/pterodactyl/admin/services/functions.blade.php b/resources/themes/pterodactyl/admin/services/functions.blade.php new file mode 100644 index 000000000..634f38b72 --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/functions.blade.php @@ -0,0 +1,88 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services → {{ $service->name }} → Functions +@endsection + +@section('content-header') +

{{ $service->name }}Extend the default daemon functions using this service file.

+ +@endsection + +@section('content') +
+
+ +
+
+
+
+
+
+

Functions Control

+
+
+
+
{{ $service->index_file }}
+ +
+ +
+
+
+
+@endsection + +@section('footer-scripts') + @parent + {!! Theme::js('js/vendor/ace/ace.js') !!} + {!! Theme::js('js/vendor/ace/ext-modelist.js') !!} + +@endsection diff --git a/resources/themes/pterodactyl/admin/services/index.blade.php b/resources/themes/pterodactyl/admin/services/index.blade.php new file mode 100644 index 000000000..677af8b77 --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/index.blade.php @@ -0,0 +1,67 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services +@endsection + +@section('content-header') +

ServicesAll services currently available on this system.

+ +@endsection + +@section('content') +
+
+
+
+

Configured Services

+
+
+ + + + + + + + + @foreach($services as $service) + + + + + + + + @endforeach +
NameDescriptionOptionsPacksServers
{{ $service->name }}{{ $service->description }}{{ $service->options_count }}{{ $service->packs_count }}{{ $service->servers_count }}
+
+ +
+
+
+@endsection diff --git a/resources/themes/pterodactyl/admin/services/new.blade.php b/resources/themes/pterodactyl/admin/services/new.blade.php new file mode 100644 index 000000000..5d215e66f --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/new.blade.php @@ -0,0 +1,86 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + New Service +@endsection + +@section('content-header') +

New ServiceConfigure a new service to deploy to all nodes.

+ +@endsection + +@section('content') +
+
+
+
+
+

New Service

+
+
+
+ +
+ +

This should be a descriptive category name that emcompasses all of the options within the service.

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+ +

Services are downloaded by the daemon and stored in a folder using this name. The storage location is /srv/daemon/services/{NAME} by default.

+
+
+
+ +
+ +

The default start command to use when running options under this service. This command can be modified per-option and should include the executable to be called in the container.

+
+
+
+ +
+
+
+
+@endsection diff --git a/resources/themes/pterodactyl/admin/services/options/new.blade.php b/resources/themes/pterodactyl/admin/services/options/new.blade.php new file mode 100644 index 000000000..763e6096c --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/options/new.blade.php @@ -0,0 +1,170 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services → New Option +@endsection + +@section('content-header') +

New OptionCreate a new service option to assign to servers.

+ +@endsection + +@section('content') +
+
+
+
+
+

Configuration

+
+
+
+
+
+ + +
+
+ + +

A simple, human-readable name to use as an identifier for this service.

+
+
+ + +

A description of this service that will be displayed throughout the panel as needed.

+
+
+
+
+ + +

This should be a unique identifer for this service option that is not used for any other service options.

+
+
+ + +

The default docker image that should be used for new servers under this service option. This can be left blank to use the parent service's defined image, and can also be changed per-server.

+
+
+ + +

The default statup command that should be used for new servers under this service option. This can be left blank to use the parent service's startup, and can also be changed per-server.

+
+
+
+
+
+
+
+
+
+

Process Management

+
+
+
+
+
+

All fields are required unless you select a seperate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that option.

+
+
+
+
+ + +

If you would like to default to settings from another option select the option from the menu above.

+
+
+ + +

The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.

+
+
+ + +

This should be a JSON representation of where log files are stored, and wether or not the daemon should be creating custom logs.

+
+
+
+
+ + +

This should be a JSON representation of configuration files to modify and what parts should be changed.

+
+
+ + +

This should be a JSON representation of what values the daemon should be looking for when booting a server to determine completion.

+
+
+
+ +
+
+
+ +@endsection + +@section('footer-scripts') + @parent + {!! Theme::js('vendor/lodash/lodash.js') !!} + +@endsection diff --git a/resources/themes/pterodactyl/admin/services/options/variables.blade.php b/resources/themes/pterodactyl/admin/services/options/variables.blade.php new file mode 100644 index 000000000..830bec458 --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/options/variables.blade.php @@ -0,0 +1,166 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Service Options → {{ $option->name }} → Variables +@endsection + +@section('content-header') +

{{ $option->name }}Managing variables for this service option.

+ +@endsection + +@section('content') +
+ +
+
+ @foreach($option->variables as $variable) +
+
+
+

{{ $variable->name }}

+
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+

This variable can be accessed in the statup command by using {{ $variable->env_variable }}.

+
+
+
+ + +
+
+ + +

These rules are defined using standard Laravel Framework validation rules.

+
+
+ +
+
+
+ @endforeach +
+ +@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/services/options/view.blade.php b/resources/themes/pterodactyl/admin/services/options/view.blade.php new file mode 100644 index 000000000..6450fdef3 --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/options/view.blade.php @@ -0,0 +1,172 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services → Option: {{ $option->name }} +@endsection + +@section('content-header') +

{{ $option->name }}{{ str_limit($option->description, 50) }}

+ +@endsection + +@section('content') +
+
+ +
+
+
+
+
+
+
+

Configuration

+
+
+
+
+
+ + +

A simple, human-readable name to use as an identifier for this service.

+
+
+ + +

A description of this service that will be displayed throughout the panel as needed.

+
+
+
+
+ + +

This should be a unique identifer for this service option that is not used for any other service options.

+
+
+ + +

The default docker image that should be used for new servers under this service option. This can be left blank to use the parent service's defined image, and can also be changed per-server.

+
+
+ + +

The default statup command that should be used for new servers under this service option. This can be left blank to use the parent service's startup, and can also be changed per-server.

+
+
+
+
+
+
+
+
+
+

Process Management

+
+
+
+
+
+

The following configuration options should not be edited unless you understand how this system works. If wrongly modified it is possible for the daemon to break.

+

All fields are required unless you select a seperate option from the 'Copy Settings From' dropdown, in which case fields may be left blank to use the values from that option.

+
+
+
+
+ + +

If you would like to default to settings from another option select the option from the menu above.

+
+
+ + +

The command that should be sent to server processes to stop them gracefully. If you need to send a SIGINT you should enter ^C here.

+
+
+ + +

This should be a JSON representation of where log files are stored, and wether or not the daemon should be creating custom logs.

+
+
+
+
+ + +

This should be a JSON representation of configuration files to modify and what parts should be changed.

+
+
+ + +

This should be a JSON representation of what values the daemon should be looking for when booting a server to determine completion.

+
+
+
+
+ +
+
+
+
+@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/admin/services/view.blade.php b/resources/themes/pterodactyl/admin/services/view.blade.php new file mode 100644 index 000000000..ab31abe0d --- /dev/null +++ b/resources/themes/pterodactyl/admin/services/view.blade.php @@ -0,0 +1,135 @@ +{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} + +{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} +{{-- of this software and associated documentation files (the "Software"), to deal --}} +{{-- in the Software without restriction, including without limitation the rights --}} +{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} +{{-- copies of the Software, and to permit persons to whom the Software is --}} +{{-- furnished to do so, subject to the following conditions: --}} + +{{-- The above copyright notice and this permission notice shall be included in all --}} +{{-- copies or substantial portions of the Software. --}} + +{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} +{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} +{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} +{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} +{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} +{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} +{{-- SOFTWARE. --}} +@extends('layouts.admin') + +@section('title') + Services → {{ $service->name }} +@endsection + +@section('content-header') +

{{ $service->name }}{{ str_limit($service->description, 50) }}

+ +@endsection + +@section('content') +
+
+ +
+
+
+
+
+
+
+
+ +
+ +

This should be a descriptive category name that emcompasses all of the options within the service.

+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+ +

Services are downloaded by the daemon and stored in a folder using this name. The storage location is /srv/daemon/services/{NAME} by default.

+
+
+
+ +
+ +

The default start command to use when running options under this service. This command can be modified per-option and should include the executable to be called in the container.

+
+
+
+ +
+
+
+
+
+
+
+
+

Configured Options

+
+
+ + + + + + + + @foreach($service->options as $option) + + + + + + + @endforeach +
NameDescriptionTagServers
{{ $option->name }}{!! $option->description !!}{{ $option->tag }}{{ $option->servers->count() }}
+
+ +
+
+
+@endsection + +@section('footer-scripts') + @parent + +@endsection diff --git a/resources/themes/pterodactyl/layouts/admin.blade.php b/resources/themes/pterodactyl/layouts/admin.blade.php index 96b8c0e98..a6c735c60 100644 --- a/resources/themes/pterodactyl/layouts/admin.blade.php +++ b/resources/themes/pterodactyl/layouts/admin.blade.php @@ -106,6 +106,17 @@ Users +
  • SERVICE MANAGEMENT
  • +
  • + + Services + +
  • +
  • + + Packs + +
  • diff --git a/resources/themes/pterodactyl/server/settings/startup.blade.php b/resources/themes/pterodactyl/server/settings/startup.blade.php index 981d8e60c..b9377fa6e 100644 --- a/resources/themes/pterodactyl/server/settings/startup.blade.php +++ b/resources/themes/pterodactyl/server/settings/startup.blade.php @@ -42,9 +42,8 @@

    @lang('server.config.startup.command')

    -
    - {{ $service->executable }} - +
    +
    @can('edit-startup', $server) @@ -56,35 +55,35 @@
    @can('edit-startup', $server) - @foreach($variables as $variable) + @foreach($variables as $v)
    -

    {{ $variable->name }}

    +

    {{ $v->variable->name }}

    - user_editable) - name="env_{{ $variable->id }}" + user_can_edit) + name="env_{{ $v->variable->id }}" @else readonly @endif - class="form-control" type="text" value="{{ old('env_' . $variable->id, $variable->server_value) }}" /> -

    {{ $variable->description }}

    + class="form-control" type="text" value="{{ old('env_' . $v->id, $v->variable_value) }}" /> +

    {{ $v->variable->description }}

    - @if($variable->required && $variable->user_editable) + @if($v->required && $v->user_can_edit) @lang('strings.required') - @elseif(! $variable->required && $variable->user_editable) + @elseif(! $v->required && $v->user_can_edit) @lang('strings.optional') @endif - @if(! $variable->user_editable) + @if(! $v->user_can_edit) @lang('strings.read_only') @endif

    @@ -97,14 +96,4 @@ @section('footer-scripts') @parent {!! Theme::js('js/frontend/server.socket.js') !!} - @endsection diff --git a/resources/views/admin/servers/view.blade.php b/resources/views/admin/servers/view.blade.php deleted file mode 100644 index 3f65dbd11..000000000 --- a/resources/views/admin/servers/view.blade.php +++ /dev/null @@ -1,687 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Managing Server: {{ $server->name }} ({{ $server->uuidShort}}) -@endsection - -@section('content') -
    - - @if($server->suspended === 1 && !$server->trashed()) -
    - This server is suspended and has no user access. Processes cannot be started and files cannot be modified. All API access is disabled unless using a master token. -
    - @elseif($server->trashed()) -
    - This server is marked for deletion {{ Carbon::parse($server->deleted_at)->addMinutes(env('APP_DELETE_MINUTES', 10))->diffForHumans() }}. If you want to cancel this action simply click the button below. -

    -
    - - - - {!! csrf_field() !!} -
    -
    - @endif - @if($server->installed === 0) -
    - This server is still running through the install process and is not avaliable for use just yet. This message will disappear once this process is completed. -
    - @elseif($server->installed === 2) -
    - This server failed to install properly. You should delete it and try to create it again or check the daemon logs. -
    - @endif - -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    UUID{{ $server->uuid }}
    Docker Container ID
    Docker User ID
    Owner{{ $server->user->email }}
    Location{{ $server->node->location->short }}
    Node{{ $server->node->name }}
    Service{{ $server->option->service->name }} :: {{ $server->option->name }}
    Name{{ $server->name }}
    Memory{{ $server->memory }}MB / {{ $server->swap }}MB
    OOM Killer{!! ($server->oom_disabled === 0) ? 'Enabled' : 'Disabled' !!}
    Disk Space{{ $server->disk }}MB
    Block IO Weight{{ $server->io }}
    CPU Limit{{ $server->cpu }}%
    Default Connection{{ $server->allocation->ip }}:{{ $server->allocation->port }}
    Connection Alias - @if($server->allocation->alias !== $server->allocation->ip) - {{ $server->allocation->alias }}:{{ $server->allocation->port }} - @else - No Alias Assigned - @endif -
    Installed{!! ($server->installed === 1) ? 'Yes' : 'No' !!}
    Suspended{!! ($server->suspended === 1) ? 'Suspended' : 'No' !!}
    -
    -
    -
    - @if($server->installed === 1) -
    -
    -
    -
    -
    -
    - -
    - -

    Character limits: a-zA-Z0-9_- and [Space] (max 35 characters).

    -
    -
    -
    - -
    - -

    You can change the owner of this server by changing this field to an email matching another use on this system. If you do this a new daemon security token will be generated automatically.

    -
    -
    -
    - -
    - -

    This token should not be shared with anyone as it has full control over this server.

    -
    -
    -
    -
    - Yes, Reset Daemon Token -

    Resetting this token will cause any requests using the old token to fail.

    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -

    The docker image to use for this server. The default image for this service and option combination is {{ $server->docker_image }}.

    -
    -
    -
    -
    -
    - -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - After editing any of the options below you will need to restart the server for changes to take effect. If the server is currently off, you just need to start it and the container will be rebuilt with the new settings. -
    -
    -
    -
    -
    -
    - -
    - - MB -
    -
    -
    - -
    - - MB -
    -

    Setting this to 0 will disable swap space on this server.

    -
    -
    -
    -
    - -
    - - % -
    -

    Each physical core on the system is considered to be 100%. Setting this value to 0 will allow a server to use CPU time without restrictions.

    -
    -
    - -
    - -
    -

    Changing this value can have negative effects on all containers on the system. We strongly recommend leaving this value as 500.

    -
    -
    -
    -
    -
    -
    - Additional IPs and Ports can be assigned to this server for use by plugins or other software. The game port is what will show up for the user to use to connect to thier server, and what their configuration files will be forced to use for binding. -
    -
    -
    - - @foreach ($assigned as $assignment) -
    - - id === $server->allocation_id) checked="checked" @endif - name="default" value="{{ $assignment->ip }}:{{ $assignment->port }}"/> - - has_alias) - data-toggle="tooltip" data-placement="left" title="{{ $assignment->ip }}:{{ $assignment->port }}" - @endif - /> -
    - @endforeach -
    -
    -
    -
    - -
    - -
    -

    Please note that due to software limitations you cannot assign identical ports on different IPs to the same server. For example, you cannot assign both 192.168.0.5:25565 and 192.168.10.5:25565 to the same server.

    -
    -
    -
    -
    - -
    - -
    -

    Simply select which ports you would like to remove from the list above. If you want to assign a port on a different IP that is already in use you can select it above and delete it down here.

    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    Changing any of the values below will require a restart for them to take effect.
    - -
    - {{ $server->option->display_executable }} - -
    -

    The following data replacers are avaliable for the startup command: @{{SERVER_MEMORY}}, @{{SERVER_IP}}, and @{{SERVER_PORT}}. They will be replaced with the allocated memory, server ip, and server port respectively.

    -
    -
    -
    -
    -
    -
    - @foreach($server->option->variables as $variable) -
    - -
    - -
    -

    {!! $variable->description !!}
    Regex: {{ $variable->regex }}
    Access as: {{{{ $variable->env_variable }}}}

    -
    - @endforeach -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    Add New Database

    -
    -
    -
    - -
    -
    s{{ $server->id }}_
    - -
    -
    -
    - -
    - -
    -

    Which IP to allow connections from. Standard MySQL wildcard notation allowed (e.g. 192.168.%.%).

    -
    -
    -
    -
    - - -
    -
    - -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - @if(count($server->databases) > 0) -
    -
    - - - - - - - - - - - - @foreach($server->databases as $database) - - - - - - - - @endforeach - -
    DatabaseUser (Connections From)PasswordDB Server
    {{ $database->database }}{{ $database->username }} ({{ $database->remote }}){{ Crypt::decrypt($database->password) }} {{ $database->host->host }}:{{ $database->host->port }}
    -
    - @endif -
    -
    - @endif - @if($server->installed !== 2) -
    -
    -
    -
    -
    - -
    -

    This will take you to the server management page that users normally see and allow you to manage server files as well as check the console and data usage.

    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -

    This will toggle the install status for the server.

    -
    If you have just created this server it is ill advised to perform this action as the daemon will contact the panel when finished which could cause the install status to be wrongly set.
    -
    -
    -
    - @if($server->installed === 1) -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -

    This will trigger a rebuild of the server container when it next starts up. This is useful if you modified the server configuration file manually, or something just didn't work out correctly.

    -
    A rebuild will automatically occur whenever you edit build configuration settings for the server.
    -
    -
    -
    - @endif -
    -
    -
    - @if($server->suspended === 0) -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -

    This will suspend the server, stop any running processes, and immediately block the user from being able to access their files or otherwise manage the server through the panel or API.

    -
    - @else -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -

    This will unsuspend the server and restore normal user access.

    -
    - @endif -
    -
    -
    -
    - @endif -
    -
    -
    - @if($server->installed === 1) -
    -
    -
    -
    - {!! csrf_field() !!} - {!! method_field('DELETE') !!} - -
    -
    -
    -
    Deleting a server is an irreversible action. All data will be immediately removed relating to this server.
    -
    -
    -
    -
    - @endif -
    -
    -
    -
    - {!! csrf_field() !!} - {!! method_field('DELETE') !!} - -
    -
    -
    -
    This is the same as deleting a server, however, if an error is returned by the daemon it is ignored and the server is still removed from the panel.
    -
    -
    -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/services/config.blade.php b/resources/views/admin/services/config.blade.php deleted file mode 100644 index 2aa814428..000000000 --- a/resources/views/admin/services/config.blade.php +++ /dev/null @@ -1,180 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Manage Service Configuration -@endsection - -@section('content') -
    - -

    Service Configuration


    - -
    -
    -
    -
    -
    -
    -
    -
    {{ $contents['json'] }}
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    {{ $contents['index'] }}
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -{!! Theme::js('js/vendor/ace/ace.js') !!} -{!! Theme::js('js/vendor/ace/ext-modelist.js') !!} - -@endsection diff --git a/resources/views/admin/services/index.blade.php b/resources/views/admin/services/index.blade.php deleted file mode 100644 index c97df4cf1..000000000 --- a/resources/views/admin/services/index.blade.php +++ /dev/null @@ -1,65 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Manage Services -@endsection - -@section('content') -
    - -

    Server Services


    - - - - - - - - - - - @foreach ($services as $service) - - - - - - - @endforeach - - - - - - - -
    Service TypeDescriptionServers
    {{ $service->name }}{!! $service->description !!}{{ $service->servers_count }}
    -
    - -@endsection diff --git a/resources/views/admin/services/new.blade.php b/resources/views/admin/services/new.blade.php deleted file mode 100644 index 1bb829e00..000000000 --- a/resources/views/admin/services/new.blade.php +++ /dev/null @@ -1,95 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - New Service -@endsection - -@section('content') -
    - -

    Add New Service


    -
    -
    -
    - -
    - -

    This should be a descriptive category name that emcompasses all of the options within the service.

    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - /src/services/ - - /index.js -
    -

    This should be a unique alpha-numeric (a-z) name used to identify the service.

    -
    -
    - -
    - -
    -

    Changing this has no effect on operation of the daemon, it is simply used for display purposes on the panel. This can be changed per-option.

    -
    -
    -
    -
    - -
    - - -
    -

    This is the default startup that will be used for all servers created using this service. This can be changed per-option.

    -
    -
    -
    -
    -
    You will be able to add service options and variables once the service is created.
    - {!! csrf_field() !!} - -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/services/options/new.blade.php b/resources/views/admin/services/options/new.blade.php deleted file mode 100644 index 5585fad0f..000000000 --- a/resources/views/admin/services/options/new.blade.php +++ /dev/null @@ -1,98 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - New Service Option for {{ $service->name }} -@endsection - -@section('content') -
    - -

    Service Option Settings


    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -

    Leave blank to use parent executable.

    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -

    To use the default startup of the parent service simply leave this field blank.

    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/services/options/variable.blade.php b/resources/views/admin/services/options/variable.blade.php deleted file mode 100644 index 5ed9540c3..000000000 --- a/resources/views/admin/services/options/variable.blade.php +++ /dev/null @@ -1,122 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - New Variable for {{ $option->name }} -@endsection - -@section('content') -
    - -

    New Option Variable


    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -

    Regex code to use when verifying the contents of the field.

    -
    -
    -
    -
    -
    - -
    - -

    Accessed in startup by using {{}} parameter.

    -
    -
    -
    - -
    - -

    The default value to use for this field.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/services/options/view.blade.php b/resources/views/admin/services/options/view.blade.php deleted file mode 100644 index f40bc8154..000000000 --- a/resources/views/admin/services/options/view.blade.php +++ /dev/null @@ -1,211 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Manage Service Option {{ $option->name }} -@endsection - -@section('content') -
    - -
    Warning! This page contains advanced settings that the panel and daemon use to control servers. Modifying information on this page is not recommended unless you are absolutely sure of what you are doing.
    -

    Settings


    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -

    Leave blank to use parent executable.

    -
    -
    -
    - -
    - -

    Changing the docker image will only effect servers created or modified after this point.

    -
    -
    -
    -
    -
    - -
    - -

    To use the default startup of the parent service simply leave this field blank.

    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    -
    -
    -

    Variables


    - @foreach($option->variables as $variable) -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - -

    Accessed in startup by using {{{{ $variable->env_variable }}}} prameter.

    -
    -
    -
    - -
    - -

    The default value to use for this field.

    -
    -
    -
    - -
    - -

    Regex code to use when verifying the contents of the field.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - - -
    -
    -
    -
    - @endforeach -

    Servers


    - - - - - - - - - - @foreach ($option->servers as $server) - - - - - - @endforeach - -
    NameOwnerUpdated
    {{ $server->name }}{{ $server->user->email }}{{ $server->updated_at }}
    -
    - {!! $option->servers->render() !!} -
    -
    -
    -
    -
    - Deleting an option is an irreversible action. An option can only be deleted if no servers are associated with it. -
    - {!! csrf_field() !!} - {!! method_field('DELETE') !!} - -
    -
    -
    -
    - -@endsection diff --git a/resources/views/admin/services/packs/byoption.blade.php b/resources/views/admin/services/packs/byoption.blade.php deleted file mode 100644 index f781a3a3c..000000000 --- a/resources/views/admin/services/packs/byoption.blade.php +++ /dev/null @@ -1,90 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Service Packs for {{ $option->name }} -@endsection - -@section('content') -
    - -

    Service Packs


    - - - - - - - - - - - - @foreach ($option->packs as $pack) - - - - - - - - @endforeach - - - - -
    Pack NameVersionUUIDSelectableVisible
    {{ $pack->name }}{{ $pack->version }}{{ $pack->uuid }}@if($pack->selectable)@else@endif@if($pack->visible)@else@endif
    - - - - - - -
    -
    - -@endsection diff --git a/resources/views/admin/services/packs/byservice.blade.php b/resources/views/admin/services/packs/byservice.blade.php deleted file mode 100644 index f36ce4e4c..000000000 --- a/resources/views/admin/services/packs/byservice.blade.php +++ /dev/null @@ -1,67 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Service Packs for {{ $service->name }} -@endsection - -@section('content') -
    - -

    Service Packs


    - - - - - - - - - @foreach ($service->options as $option) - - - - - @endforeach - - - - -
    Service OptionTotal Packs
    {{ $option->name }}{{ $option->packs->count() }}
    - - - - - - -
    -
    - -@endsection diff --git a/resources/views/admin/services/packs/edit.blade.php b/resources/views/admin/services/packs/edit.blade.php deleted file mode 100644 index cc6470b3b..000000000 --- a/resources/views/admin/services/packs/edit.blade.php +++ /dev/null @@ -1,160 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Add New Service Pack -@endsection - -@section('content') -
    - -

    Manage Service Pack


    -
    -
    -
    - -
    - -

    The name of the pack which will be seen in dropdown menus and to users.

    -
    -
    -
    - -
    - -

    The version of the program included in this pack.

    -
    -
    -
    - -
    - -

    Provide a description of the pack which will be shown to users.

    -
    -
    -
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    Package Archive
    -
    -
    -
    - @if(count($files) > 1) -
    Warning! Service packs should only contain a single pack archive in .tar.gz format. We've detected more than one file for this pack.
    - @endif - - - - - - - - - - - @foreach($files as &$file) - - - - - - - @endforeach - -
    FilenameFile SizeSHA1 HashLast Modified
    {{ basename($file) }}{{ Storage::size($file) }} Bytes{{ sha1_file(storage_path('app/' . $file)) }}{{ Carbon::createFromTimestamp(Storage::lastModified($file))->toDateTimeString() }}
    -

    If you wish to modify or upload a new file it should be uploaded to {{ storage_path('app/packs/' . $pack->uuid) }} as archive.tar.gz.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - - - - -
    -
    - -
    -{!! Theme::js('js/vendor/ace/ace.js') !!} -{!! Theme::js('js/vendor/ace/ext-modelist.js') !!} - -@endsection diff --git a/resources/views/admin/services/packs/index.blade.php b/resources/views/admin/services/packs/index.blade.php deleted file mode 100644 index 6456ca317..000000000 --- a/resources/views/admin/services/packs/index.blade.php +++ /dev/null @@ -1,47 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Service Packs -@endsection - -@section('content') -
    - -

    Service Packs


    -
    - @foreach ($services as $service) - - @endforeach -
    -
    - -@endsection diff --git a/resources/views/admin/services/packs/new.blade.php b/resources/views/admin/services/packs/new.blade.php deleted file mode 100644 index d5b0440da..000000000 --- a/resources/views/admin/services/packs/new.blade.php +++ /dev/null @@ -1,135 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Add New Service Pack -@endsection - -@section('content') -
    - -

    New Service Pack


    -
    -
    -
    - -
    - -

    The name of the pack which will be seen in dropdown menus and to users.

    -
    -
    -
    - -
    - -

    The version of the program included in this pack.

    -
    -
    -
    - -
    - -

    Provide a description of the pack which will be shown to users.

    -
    -
    -
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    File Upload
    -
    -
    -
    - - -

    This package file must be a .tar.gz archive of files to use for either building or running this pack.

    If your file is larger than 20MB we recommend uploading it using SFTP. Once you have added this pack to the system, a path will be provided where you should upload the file. - This server is currently configured with the following limits: upload_max_filesize={{ ini_get('upload_max_filesize') }} and post_max_size={{ ini_get('post_max_size') }}. If your file is larger than either of those values this request will fail.

    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {!! csrf_field() !!} - -
    -
    - -
    -{!! Theme::js('js/vendor/ace/ace.js') !!} -{!! Theme::js('js/vendor/ace/ext-modelist.js') !!} - -@endsection diff --git a/resources/views/admin/services/view.blade.php b/resources/views/admin/services/view.blade.php deleted file mode 100644 index 6b660a5ac..000000000 --- a/resources/views/admin/services/view.blade.php +++ /dev/null @@ -1,135 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.admin') - -@section('title') - Manage Service -@endsection - -@section('content') -
    - -

    Service Options


    - - - - - - - - - - - @foreach($service->options as $option) - - - - - - - @endforeach - - - - - - - -
    Option NameDescriptionTagServers
    {{ $option->name }}{!! $option->description !!}{{ $option->tag }}{{ $option->servers->count() }}
    -
    -
    -
    -
    - -
    - -

    This should be a descriptive category name that emcompasses all of the options within the service.

    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    - /src/services/ - - /index.js -
    -

    This should be the name of the folder on the daemon that contains all of the service logic. Changing this can have unintended effects on servers or causes errors to occur.

    -
    -
    - -
    - -
    -

    Changing this has no effect on operation of the daemon, it is simply used for display purposes on the panel. This can be changed per-option.

    -
    -
    -
    -
    - -
    - {{ $service->executable }} - -
    -

    This is the default startup that will be used for all servers created using this service. This can be changed per-option.

    -
    -
    -
    -
    - {!! csrf_field() !!} - - -
    -
    -
    -
    -
    -
    -
    -
    - Deleting a service is an irreversible action. A service can only be deleted if no servers are associated with it. -
    - {!! csrf_field() !!} - {!! method_field('DELETE') !!} - -
    -
    -
    -
    - -@endsection diff --git a/resources/views/errors/403.blade.php b/resources/views/errors/403.blade.php deleted file mode 100644 index bc83eb24a..000000000 --- a/resources/views/errors/403.blade.php +++ /dev/null @@ -1,37 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.master') - -@section('title', '403: Forbidden') - -@section('content') -
    -
    -
    -

    HTTP 403: Access Denied

    -
    -
    -

    You do not have permission to access that function. Please contact your server administrator to request permission.

    -
    -
    -

    -

    Take me back or go home.

    -
    -@endsection diff --git a/resources/views/errors/404.blade.php b/resources/views/errors/404.blade.php deleted file mode 100644 index bdaec2cd4..000000000 --- a/resources/views/errors/404.blade.php +++ /dev/null @@ -1,37 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} -@extends('layouts.master') - -@section('title', '404: Not Found') - - -@section('right-nav') -@endsection - -@section('sidebar') -@endsection - -@section('content') -
    -

    404 - File Not Found

    -

    -

    Take me back or go home.

    -
    -@endsection diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php deleted file mode 100644 index f800c1ac5..000000000 --- a/resources/views/layouts/admin.blade.php +++ /dev/null @@ -1,226 +0,0 @@ -{{-- Copyright (c) 2015 - 2017 Dane Everitt --}} - -{{-- Permission is hereby granted, free of charge, to any person obtaining a copy --}} -{{-- of this software and associated documentation files (the "Software"), to deal --}} -{{-- in the Software without restriction, including without limitation the rights --}} -{{-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --}} -{{-- copies of the Software, and to permit persons to whom the Software is --}} -{{-- furnished to do so, subject to the following conditions: --}} - -{{-- The above copyright notice and this permission notice shall be included in all --}} -{{-- copies or substantial portions of the Software. --}} - -{{-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --}} -{{-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --}} -{{-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --}} -{{-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --}} -{{-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --}} -{{-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --}} -{{-- SOFTWARE. --}} - - - - @section('scripts') - - - - {!! Theme::css('css/vendor/bootstrap/bootstrap.css') !!} - {!! Theme::css('css/pterodactyl.css') !!} - {!! Theme::css('css/animate.css') !!} - {!! Theme::css('css/vendor/fontawesome/font-awesome.min.css') !!} - {!! Theme::css('css/vendor/sweetalert/sweetalert.min.css') !!} - {!! Theme::css('css/vendor/fuelux/fuelux.min.css') !!} - {!! Theme::js('js/vendor/jquery/jquery.min.js') !!} - {!! Theme::js('js/vendor/bootstrap/bootstrap.min.js') !!} - {!! Theme::js('js/vendor/sweetalert/sweetalert.min.js') !!} - {!! Theme::js('js/vendor/fuelux/fuelux.min.js') !!} - {!! Theme::js('js/admin.min.js') !!} - {!! Theme::js('js/bootstrap-notify.min.js') !!} - - @show - {{ Settings::get('company') }} - @yield('title') - - -
    - - -
    - -
    -
    -
    - @section('resp-errors') - @if (count($errors) > 0) -
    - - {{ trans('strings.whoops') }}! {{ trans('auth.errorencountered') }}

    -
      - @foreach ($errors->all() as $error) -
    • {{ $error }}
    • - @endforeach -
    -
    - @endif - @show - @section('resp-alerts') - @foreach (Alert::getMessages() as $type => $messages) - @foreach ($messages as $message) - - @endforeach - @endforeach - @show -
    -
    -
    - @yield('content') -
    -
    -
    - -
    - - - diff --git a/storage/app/services/.templates/index.js b/storage/app/services/.templates/index.js deleted file mode 100644 index f6b6695d0..000000000 --- a/storage/app/services/.templates/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -/** - * Pterodactyl - Daemon - * Copyright (c) 2015 - 2017 Dane Everitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -const rfr = require('rfr'); - -const Core = rfr('src/services/index.js'); - -class Service extends Core {} - -module.exports = Service; diff --git a/storage/app/services/minecraft/main.json b/storage/app/services/minecraft/main.json deleted file mode 100644 index 48a490cb3..000000000 --- a/storage/app/services/minecraft/main.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "vanilla": { - "startup": { - "done": ")! For help, type ", - "userInteraction": [ - "Go to eula.txt for more info." - ] - }, - "stop": "stop", - "configs": { - "server.properties": { - "parser": "properties", - "find": { - "server-ip": "0.0.0.0", - "enable-query": "true", - "server-port": "{{ server.build.default.port }}", - "query.port": "{{ server.build.default.port }}" - } - } - }, - "log": { - "custom": false, - "location": "logs/latest.log" - }, - "query": "minecraftping" - }, - "spigot": { - "symlink": "vanilla", - "configs": { - "spigot.yml": { - "parser": "yaml", - "find": { - "settings.restart-on-crash": "false" - } - } - } - }, - "bungeecord": { - "startup": { - "done": "Listening on ", - "userInteraction": [ - "Listening on /0.0.0.0:25577" - ] - }, - "stop": "end", - "configs": { - "config.yml": { - "parser": "yaml", - "find": { - "listeners[0].query_enabled": true, - "listeners[0].query_port": "{{ server.build.default.port }}", - "listeners[0].host": "0.0.0.0:{{ server.build.default.port }}", - "servers.*.address": { - "127.0.0.1": "{{ config.docker.interface }}", - "localhost": "{{ config.docker.interface }}" - } - } - } - }, - "log": { - "custom": false, - "location": "proxy.log.0" - }, - "query": "minecraftping" - }, - "sponge": { - "symlink": "vanilla", - "startup": { - "userInteraction": [ - "You need to agree to the EULA" - ] - } - } -} diff --git a/storage/app/services/srcds/index.js b/storage/app/services/srcds/index.js deleted file mode 100644 index f6b6695d0..000000000 --- a/storage/app/services/srcds/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -/** - * Pterodactyl - Daemon - * Copyright (c) 2015 - 2017 Dane Everitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -const rfr = require('rfr'); - -const Core = rfr('src/services/index.js'); - -class Service extends Core {} - -module.exports = Service; diff --git a/storage/app/services/srcds/main.json b/storage/app/services/srcds/main.json deleted file mode 100644 index 989a67537..000000000 --- a/storage/app/services/srcds/main.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "srcds": { - "startup": { - "done": "Assigned anonymous gameserver Steam ID", - "userInteraction": [] - }, - "stop": "quit", - "configs": {}, - "log": { - "custom": true, - "location": "logs/latest.log" - }, - "query": "protocol-valve" - }, - "ark": { - "symlink": "srcds", - "startup": { - "done": "Setting breakpad minidump AppID" - }, - "stop": "^C", - "query": "none" - } -} diff --git a/storage/app/services/terraria/index.js b/storage/app/services/terraria/index.js deleted file mode 100644 index f6b6695d0..000000000 --- a/storage/app/services/terraria/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -/** - * Pterodactyl - Daemon - * Copyright (c) 2015 - 2017 Dane Everitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -const rfr = require('rfr'); - -const Core = rfr('src/services/index.js'); - -class Service extends Core {} - -module.exports = Service; diff --git a/storage/app/services/terraria/main.json b/storage/app/services/terraria/main.json deleted file mode 100644 index 78f1b5bc0..000000000 --- a/storage/app/services/terraria/main.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "tshock": { - "startup": { - "done": "Type 'help' for a list of commands", - "userInteraction": [] - }, - "stop": "exit", - "configs": { - "tshock/config.json": { - "parser": "json", - "find": { - "ServerPort": "{{ server.build.default.port }}", - "MaxSlots": "{{ server.build.env.MAX_SLOTS }}" - } - } - }, - "log": { - "custom": false, - "location": "ServerLog.txt" - }, - "query": "none" - } -} diff --git a/storage/app/services/voice/index.js b/storage/app/services/voice/index.js deleted file mode 100644 index f6b6695d0..000000000 --- a/storage/app/services/voice/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -/** - * Pterodactyl - Daemon - * Copyright (c) 2015 - 2017 Dane Everitt - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -const rfr = require('rfr'); - -const Core = rfr('src/services/index.js'); - -class Service extends Core {} - -module.exports = Service; diff --git a/storage/app/services/voice/main.json b/storage/app/services/voice/main.json deleted file mode 100644 index bc7232f46..000000000 --- a/storage/app/services/voice/main.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "mumble": { - "startup": { - "done": "Server listening on", - "userInteraction": [ - "Generating new server certificate" - ] - }, - "stop": "^C", - "configs": { - "murmur.ini": { - "parser": "ini", - "find": { - "logfile": "murmur.log", - "port": "{{ server.build.default.port }}", - "host": "0.0.0.0", - "users": "{{ server.build.env.MAX_USERS }}" - } - } - }, - "log": { - "custom": true, - "location": "logs/murmur.log" - }, - "query": "mumbleping" - }, - "ts3": { - "startup": { - "done": "listening on 0.0.0.0:", - "userInteraction": [] - }, - "stop": "^C", - "configs": { - "ts3server.ini": { - "parser": "ini", - "find": { - "default_voice_port": "{{ server.build.default.port }}", - "voice_ip": "0.0.0.0", - "query_port": "{{ server.build.default.port }}", - "query_ip": "0.0.0.0" - } - } - }, - "log": { - "custom": true, - "location": "logs/ts3.log" - }, - "query": "none" - } -}