Merge branch 'develop' into feature/service-changes
This commit is contained in:
		
						commit
						9eb14614c2
					
				
							
								
								
									
										21
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -3,6 +3,27 @@ This file is a running track of new features and fixes to each version of the pa | ||||
| 
 | ||||
| This project follows [Semantic Versioning](http://semver.org) guidelines. | ||||
| 
 | ||||
| ## v0.5.2 (Bodacious Boreopterus) | ||||
| ### Fixed | ||||
| * Time axis on server graphs is corrected to show the minutes rather than the current month. | ||||
| * Node deletion now works correctly and deletes allocations as well. | ||||
| * Fixes a bug that would leave orphaned databases on the system if there was an error during creation. | ||||
| * Fixes an issue that could occur if a UUID contained `#e#` formatting within it when it comes to creating databases. | ||||
| * Fixed node status display to account for updated daemon security changes. | ||||
| * Fixes default language being selected as German (defaults to English now). | ||||
| * Fixes bug preventing the deletion of database servers. | ||||
| 
 | ||||
| ### Changed | ||||
| * Using `node:<name>` when filtering servers now properly filters the servers by node name, rather than looking for the node ID. | ||||
| * Using `owner:<email>` when filtering servers now properly filters by the owner's email rather than ID. | ||||
| * Added some quick help buttons to the admin index page for getting support or checking the documentation. | ||||
| * Panel now displays `Pterodactyl Panel` as the company name if one is not set. | ||||
| 
 | ||||
| ### Added | ||||
| * Added basic information about the daemon when viewing a node, including the host OS and version, CPU count, and the daemon version. | ||||
| * Added version checking for the daemon and panel that alerts admins when daemons or the panel is out of date. | ||||
| * Added multiplicator support to certain memory and disk fields that allow users to enter `10g` and have it converted to MB automatically. | ||||
| 
 | ||||
| ## v0.5.1 (Bodacious Boreopterus) | ||||
| ### Fixed | ||||
| * Fixes a bug that allowed a user to bypass 2FA authentication if using the correct username and password for an account. | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
| namespace Pterodactyl\Console\Commands; | ||||
| 
 | ||||
| use Illuminate\Console\Command; | ||||
| use Version; | ||||
| 
 | ||||
| class ShowVersion extends Command | ||||
| { | ||||
| @ -58,6 +59,6 @@ class ShowVersion extends Command | ||||
|      */ | ||||
|     public function handle() | ||||
|     { | ||||
|         $this->info('You are running Pterodactyl Panel ' . config('app.version')); | ||||
|         $this->info('You are running Pterodactyl Panel v' . Version::getCurrentPanel() . ' (' . ((Version::isLatestPanel()) ? 'Up to Date' : 'Latest: ' . Version::getDaemon()) . ')'); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										35
									
								
								app/Facades/Version.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Facades/Version.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Pterodactyl - Panel | ||||
|  * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.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. | ||||
|  */ | ||||
| namespace Pterodactyl\Facades; | ||||
| 
 | ||||
| use Illuminate\Support\Facades\Facade; | ||||
| 
 | ||||
| class Version extends Facade | ||||
| { | ||||
| 
 | ||||
|     protected static function getFacadeAccessor() | ||||
|     { | ||||
|         return '\Pterodactyl\Services\VersionService'; | ||||
|     } | ||||
| } | ||||
| @ -253,20 +253,22 @@ class NodesController extends Controller | ||||
| 
 | ||||
|     public function deleteNode(Request $request, $id) | ||||
|     { | ||||
|         $node = Models\Node::findOrFail($id); | ||||
|         $servers = Models\Server::where('node', $id)->count(); | ||||
|         if ($servers > 0) { | ||||
|             Alert::danger('You cannot delete a node with servers currently attached to it.')->flash(); | ||||
|         try { | ||||
|             $repo = new NodeRepository; | ||||
|             $repo->delete($id); | ||||
|             Alert::success('Successfully deleted the requested node from the panel.')->flash(); | ||||
|             return redirect()->route('admin.nodes'); | ||||
|         } catch (DisplayException $e) { | ||||
|             Alert::danger($e->getMessage())->flash(); | ||||
|         } catch (\Exception $e) { | ||||
|             Log::error($e); | ||||
|             Alert::danger('An unhandled exception occured while attempting to delete this node. Please try again.')->flash(); | ||||
|         } | ||||
| 
 | ||||
|         return redirect()->route('admin.nodes.view', [ | ||||
|             'id' => $id, | ||||
|             'tab' => 'tab_delete' | ||||
|         ]); | ||||
|     } | ||||
| 
 | ||||
|         $node->delete(); | ||||
|         Alert::success('Node successfully deleted.')->flash(); | ||||
|         return redirect()->route('admin.nodes'); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -68,14 +68,23 @@ class ServersController extends Controller | ||||
|                 $match = str_replace('"', '', $match); | ||||
|                 if (strpos($match, ':')) { | ||||
|                     list($field, $term) = explode(':', $match); | ||||
|                     $field = (strpos($field, '.')) ? $field : 'servers.' . $field; | ||||
|                     if ($field === 'node') { | ||||
|                         $field = 'nodes.name'; | ||||
|                     } else if ($field === 'owner') { | ||||
|                         $field = 'users.email'; | ||||
|                     } else if (!strpos($field, '.')) { | ||||
|                         $field = 'servers.' . $field; | ||||
|                     } | ||||
| 
 | ||||
|                     $query->orWhere($field, 'LIKE', '%' . $term . '%'); | ||||
|                 } else { | ||||
|                     $query->where('servers.name', 'LIKE', '%' . $match . '%'); | ||||
|                     $query->orWhere('servers.username', 'LIKE', '%' . $match . '%'); | ||||
|                     $query->orWhere('users.email', 'LIKE', '%' . $match . '%'); | ||||
|                     $query->orWhere('allocations.port', 'LIKE', '%' . $match . '%'); | ||||
|                     $query->orWhere('allocations.ip', 'LIKE', '%' . $match . '%'); | ||||
|                     $query->orWhere([ | ||||
|                         ['servers.username', 'LIKE', '%' . $match . '%'], | ||||
|                         ['users.email', 'LIKE', '%' . $match . '%'], | ||||
|                         ['allocations.port', 'LIKE', '%' . $match . '%'], | ||||
|                         ['allocations.ip', 'LIKE', '%' . $match . '%'], | ||||
|                     ]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -56,13 +56,12 @@ class DatabaseRepository { | ||||
|         } | ||||
| 
 | ||||
|         DB::beginTransaction(); | ||||
| 
 | ||||
|         try { | ||||
|             $db = new Models\Database; | ||||
|             $db->fill([ | ||||
|                 'server_id' => $server->id, | ||||
|                 'db_server' => $options['db_server'], | ||||
|                 'database' => $server->uuidShort . '_' . $options['database'], | ||||
|                 'database' => "s{$server->id}_{$options['database']}", | ||||
|                 'username' => $server->uuidShort . '_' . str_random(7), | ||||
|                 'remote' => $options['remote'], | ||||
|                 'password' => Crypt::encrypt(str_random(20)) | ||||
| @ -90,18 +89,31 @@ class DatabaseRepository { | ||||
| 
 | ||||
|             $capsule->setAsGlobal(); | ||||
| 
 | ||||
|             Capsule::statement('CREATE DATABASE ' . $db->database); | ||||
|             Capsule::statement('CREATE USER \'' . $db->username . '\'@\'' . $db->remote . '\' IDENTIFIED BY \'' . Crypt::decrypt($db->password) . '\''); | ||||
|             Capsule::statement('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON ' . $db->database . '.* TO \'' . $db->username . '\'@\'' . $db->remote . '\''); | ||||
|             Capsule::statement('FLUSH PRIVILEGES'); | ||||
| 
 | ||||
|             DB::commit(); | ||||
|             return true; | ||||
|         } catch (\Exception $ex) { | ||||
|             DB::rollback(); | ||||
|             DB::rollBack(); | ||||
|             throw new DisplayException('There was an error while connecting to the Database Host Server. Please check the error logs.', $ex); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             Capsule::statement('CREATE DATABASE `' . $db->database . '`'); | ||||
|             Capsule::statement('CREATE USER `' . $db->username . '`@`' . $db->remote . '` IDENTIFIED BY \'' . Crypt::decrypt($db->password) . '\''); | ||||
|             Capsule::statement('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `' . $db->database . '`.* TO `' . $db->username . '`@`' . $db->remote . '`'); | ||||
|             Capsule::statement('FLUSH PRIVILEGES'); | ||||
|             DB::commit(); | ||||
|         } catch (\Exception $ex) { | ||||
|             try { | ||||
|                 Capsule::statement('DROP DATABASE `' . $db->database . '`'); | ||||
|                 Capsule::statement('DROP USER `' . $db->username . '`@`' . $db->remote . '`'); | ||||
|             } catch (\Exception $exi) { | ||||
|                 // ignore it, if it fails its probably
 | ||||
|                 // because we failed to ever make the DB
 | ||||
|                 // or the user on the system.
 | ||||
|             } finally { | ||||
|                 DB::rollBack(); | ||||
|                 throw $ex; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Updates the password for a given database. | ||||
| @ -138,7 +150,7 @@ class DatabaseRepository { | ||||
| 
 | ||||
|             $capsule->setAsGlobal(); | ||||
|             Capsule::statement(sprintf( | ||||
|                 'SET PASSWORD FOR \'%s\'@\'%s\' = PASSWORD(\'%s\')', | ||||
|                 'SET PASSWORD FOR `%s`@`%s` = PASSWORD(\'%s\')', | ||||
|                 $db->username, | ||||
|                 $db->remote, | ||||
|                 $password | ||||
| @ -182,8 +194,8 @@ class DatabaseRepository { | ||||
| 
 | ||||
|             $capsule->setAsGlobal(); | ||||
| 
 | ||||
|             Capsule::statement('DROP USER \'' . $db->username . '\'@\'' . $db->remote . '\''); | ||||
|             Capsule::statement('DROP DATABASE ' . $db->database); | ||||
|             Capsule::statement('DROP USER `' . $db->username . '`@`' . $db->remote . '`'); | ||||
|             Capsule::statement('DROP DATABASE `' . $db->database . '`'); | ||||
| 
 | ||||
|             $db->delete(); | ||||
| 
 | ||||
| @ -219,6 +231,11 @@ class DatabaseRepository { | ||||
|      */ | ||||
|     public function add(array $data) | ||||
|     { | ||||
| 
 | ||||
|         if (isset($data['host'])) { | ||||
|             $data['host'] = gethostbyname($data['host']); | ||||
|         } | ||||
| 
 | ||||
|         $validator = Validator::make($data, [ | ||||
|             'name' => 'required|string|max:255', | ||||
|             'host' => 'required|ip|unique:database_servers,host', | ||||
|  | ||||
| @ -229,8 +229,30 @@ class NodeRepository { | ||||
| 
 | ||||
|     public function delete($id) | ||||
|     { | ||||
|         // @TODO: add logic;
 | ||||
|         return true; | ||||
|         $node = Models\Node::findOrFail($id); | ||||
|         if (Models\Server::where('node', $id)->count() > 0) { | ||||
|             throw new DisplayException('You cannot delete a node with servers currently attached to it.'); | ||||
|         } | ||||
| 
 | ||||
|         DB::beginTransaction(); | ||||
| 
 | ||||
|         try { | ||||
|             // Unlink Database Servers
 | ||||
|             Models\DatabaseServer::where('linked_node', $node->id)->update([ | ||||
|                 'linked_node' => null, | ||||
|             ]); | ||||
| 
 | ||||
|             // Delete Allocations
 | ||||
|             Models\Allocation::where('node', $node->id)->delete(); | ||||
| 
 | ||||
|             // Delete Node
 | ||||
|             $node->delete(); | ||||
| 
 | ||||
|             DB::commit(); | ||||
|         } catch (\Exception $ex) { | ||||
|             DB::rollback(); | ||||
|             throw $ex; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										93
									
								
								app/Services/VersionService.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								app/Services/VersionService.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Pterodactyl - Panel | ||||
|  * Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.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. | ||||
|  */ | ||||
| namespace Pterodactyl\Services; | ||||
| 
 | ||||
| use Cache; | ||||
| use GuzzleHttp\Client; | ||||
| 
 | ||||
| class VersionService | ||||
| { | ||||
| 
 | ||||
|     protected static $versions; | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         self::$versions = Cache::remember('versions', env('VERSION_CACHE_TIME', 60), function () { | ||||
|             $client = new Client(); | ||||
| 
 | ||||
|             try { | ||||
|                 $response = $client->request('GET', env('VERSION_CHECK_URL', 'https://cdn.pterodactyl.io/releases/latest.json')); | ||||
| 
 | ||||
|                 if ($response->getStatusCode() === 200) { | ||||
|                     return json_decode($response->getBody()); | ||||
|                 } else { | ||||
|                     throw new \Exception('Invalid response code.'); | ||||
|                 } | ||||
|             } catch (\Exception $ex) { | ||||
|                 // Failed request, just return errored version.
 | ||||
|                 return (object) [ | ||||
|                     'panel' => 'error', | ||||
|                     'daemon' => 'error', | ||||
|                 ]; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     public static function getPanel() | ||||
|     { | ||||
|         return self::$versions->panel; | ||||
|     } | ||||
| 
 | ||||
|     public static function getDaemon() | ||||
|     { | ||||
|         return self::$versions->daemon; | ||||
|     } | ||||
| 
 | ||||
|     public function getCurrentPanel() | ||||
|     { | ||||
|         return config('app.version'); | ||||
|     } | ||||
| 
 | ||||
|     public static function isLatestPanel() | ||||
|     { | ||||
|         if (config('app.version') === 'canary') { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         return (version_compare(config('app.version'), self::$versions->panel) >= 0); | ||||
|     } | ||||
| 
 | ||||
|     public static function isLatestDaemon($daemon) | ||||
|     { | ||||
|         if ($daemon === '0.0.0-canary') { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         return (version_compare($daemon, self::$versions->daemon) >= 0); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -217,6 +217,7 @@ return [ | ||||
|         'URL'       => Illuminate\Support\Facades\URL::class, | ||||
|         'Uuid'      => Webpatser\Uuid\Uuid::class, | ||||
|         'Validator' => Illuminate\Support\Facades\Validator::class, | ||||
|         'Version'   => Pterodactyl\Facades\Version::class, | ||||
|         'View'      => Illuminate\Support\Facades\View::class, | ||||
| 
 | ||||
|     ], | ||||
|  | ||||
							
								
								
									
										20
									
								
								public/js/admin.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								public/js/admin.min.js
									
									
									
									
										vendored
									
									
								
							| @ -46,4 +46,24 @@ $(document).ready(function () { | ||||
|         centerModal($(this)); | ||||
|     }); | ||||
|     $(window).on('resize', centerModal); | ||||
| 
 | ||||
|     // Idea code for multiplicators submitted by @Taronyuu on Github
 | ||||
|     // https://github.com/Pterodactyl/Panel/issues/154#issuecomment-257116078
 | ||||
|     $('input[data-multiplicator="true"]').on('change', function () { | ||||
|         var value = $(this).val(); | ||||
|         if (!/^\d+$/.test(value)) { | ||||
|             var multiplicator = value.replace(/[0-9]/g, '').toLowerCase(); | ||||
|             value = value.replace(/\D/g, ''); | ||||
| 
 | ||||
|             if (multiplicator === 't') { | ||||
|                 value = value * (1024 * 1024); | ||||
|             } | ||||
| 
 | ||||
|             if (multiplicator === 'g') { | ||||
|                 value = value * 1024; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $(this).val(value); | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| @ -93,7 +93,7 @@ | ||||
|                                     <td>{{ $db->username }}</td> | ||||
|                                     <td class="text-center">{{ $db->c_databases }}</td> | ||||
|                                     <td>@if(is_null($db->a_linkedNode))<em>unlinked</em>@else{{ $db->a_linkedNode }}@endif</td> | ||||
|                                     <td class="text-center"><a href="#" class="text-danger" data-action="delete" data-type="delete-dbserver" data-attr="{{ $db->id }}"><i class="fa fa-trash-o"></i></a></td> | ||||
|                                     <td class="text-center"><a href="#" class="text-danger" data-action="delete" data-type="delete-server" data-attr="{{ $db->id }}"><i class="fa fa-trash-o"></i></a></td> | ||||
|                                 </tr> | ||||
|                             @endforeach | ||||
|                         </tbody> | ||||
|  | ||||
| @ -24,13 +24,31 @@ | ||||
| @endsection | ||||
| 
 | ||||
| @section('content') | ||||
| <div class="col-md-12"> | ||||
| <div class="row"> | ||||
|     <div class="col-md-12"> | ||||
|         <ul class="breadcrumb"> | ||||
|             <li class="active">Admin Control</li> | ||||
|         </ul> | ||||
|         <h3 class="nopad">Pterodactyl Admin Control Panel</h3><hr /> | ||||
|     <p>Welcome to the most advanced, lightweight, and user-friendly open source game server control panel.</p> | ||||
|     <p>You are running version <code>{{ config('app.version') }}</code>.</p> | ||||
|         @if (Version::isLatestPanel()) | ||||
|             <div class="alert alert-success">You are running Pterodactyl Panel version <code>{{ Version::getCurrentPanel() }}</code>. Your panel is up-to-date!</div> | ||||
|         @else | ||||
|             <div class="alert alert-danger"> | ||||
|                 Your panel is <strong>not up-to-date!</strong> The latest version is <a href="https://github.com/Pterodactyl/Panel/releases/v{{ Version::getPanel() }}" target="_blank"><code>{{ Version::getPanel() }}</code></a> and you are currently running version <code>{{ Version::getCurrentPanel() }}</code>. | ||||
|             </div> | ||||
|         @endif | ||||
|     </div> | ||||
| </div> | ||||
| <div class="row"> | ||||
|     <div class="col-xs-4 text-center"> | ||||
|         <a href="https://discord.gg/0gYt8oU8QOkDhKLS"><button class="btn btn-sm btn-warning" style="width:100%;"><i class="fa fa-fw fa-support"></i> Get Help <small>(via Discord)</small></button></a> | ||||
|     </div> | ||||
|     <div class="col-xs-4 text-center"> | ||||
|         <a href="https://docs.pterodactyl.io"><button class="btn btn-sm btn-default" style="width:100%;"><i class="fa fa-fw fa-link"></i> Documentation</button></a> | ||||
|     </div> | ||||
|     <div class="col-xs-4 text-center"> | ||||
|         <a href="https://github.com/Pterodactyl/Panel"><button class="btn btn-sm btn-default" style="width:100%;"><i class="fa fa-fw fa-support"></i> Github</button></a> | ||||
|     </div> | ||||
| </div> | ||||
| <script> | ||||
| $(document).ready(function () { | ||||
|  | ||||
| @ -70,21 +70,27 @@ | ||||
| <script> | ||||
| $(document).ready(function () { | ||||
|     $('#sidebar_links').find("a[href='/admin/nodes']").addClass('active'); | ||||
|     pingNodes(); | ||||
|     setInterval(pingNodes, 10000); | ||||
| }); | ||||
| function pingNodes() { | ||||
|     (function pingNodes() { | ||||
|         $('td[data-action="ping"]').each(function(i, element) { | ||||
|             $.ajax({ | ||||
|                 type: 'GET', | ||||
|                 url: $(element).data('location'), | ||||
|                 headers: { | ||||
|                     'X-Access-Token': '{{ $node->daemonSecret }}' | ||||
|                 }, | ||||
|                 timeout: 5000 | ||||
|             }).done(function (data) { | ||||
|                 $(element).find('i').tooltip({ | ||||
|                     title: 'v' + data.version, | ||||
|                 }); | ||||
|                 $(element).removeClass('text-muted').find('i').removeClass().addClass('fa fa-fw fa-heartbeat faa-pulse animated').css('color', '#50af51'); | ||||
|             }).fail(function () { | ||||
|                 $(element).removeClass('text-muted').find('i').removeClass().addClass('fa fa-fw fa-heart-o').css('color', '#d9534f'); | ||||
|             }).always(function () { | ||||
|                 setTimeout(pingNodes, 10000); | ||||
|             }); | ||||
|         }); | ||||
| } | ||||
|     })(); | ||||
| }); | ||||
| </script> | ||||
| @endsection | ||||
|  | ||||
| @ -92,14 +92,14 @@ | ||||
|                         <div class="form-group col-md-6 col-xs-6"> | ||||
|                             <label for="memory" class="control-label">Total Memory</label> | ||||
|                             <div class="input-group"> | ||||
|                                 <input type="text" name="memory" class="form-control" value="{{ old('memory') }}"/> | ||||
|                                 <input type="text" name="memory" data-multiplicator="true" class="form-control" value="{{ old('memory') }}"/> | ||||
|                                 <span class="input-group-addon">MB</span> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="form-group col-md-6 col-xs-6"> | ||||
|                             <label for="memory_overallocate" class="control-label">Overallocate</label> | ||||
|                             <div class="input-group"> | ||||
|                                 <input type="text" name="memory_overallocate" class="form-control" value="{{ old('memory_overallocate', 0) }}"/> | ||||
|                                 <input type="text" name="memory_overallocate" data-multiplicator="true" class="form-control" value="{{ old('memory_overallocate', 0) }}"/> | ||||
|                                 <span class="input-group-addon">%</span> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
| @ -69,6 +69,18 @@ | ||||
|                 <div class="panel-body"> | ||||
|                     <table class="table table-striped" style="margin-bottom:0;"> | ||||
|                         <tbody> | ||||
|                             <tr> | ||||
|                                 <td>Daemon Version</td> | ||||
|                                 <td><code data-attr="info-version"><i class="fa fa-refresh fa-fw fa-spin"></i></code> (Latest: <code>{{ Version::getPanel() }}</code>)</td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td>System Information</td> | ||||
|                                 <td data-attr="info-system"><i class="fa fa-refresh fa-fw fa-spin"></i></td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td>Total CPU Cores</td> | ||||
|                                 <td data-attr="info-cpus"><i class="fa fa-refresh fa-fw fa-spin"></i></td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td>Total Servers</td> | ||||
|                                 <td>{{ count($servers) }}</td> | ||||
| @ -171,7 +183,7 @@ | ||||
|                             <div class="form-group col-md-3 col-xs-6"> | ||||
|                                 <label for="memory" class="control-label">Total Memory</label> | ||||
|                                 <div class="input-group"> | ||||
|                                     <input type="text" name="memory" class="form-control" value="{{ old('memory', $node->memory) }}"/> | ||||
|                                     <input type="text" name="memory" class="form-control" data-multiplicator="true" value="{{ old('memory', $node->memory) }}"/> | ||||
|                                     <span class="input-group-addon">MB</span> | ||||
|                                 </div> | ||||
|                             </div> | ||||
| @ -185,7 +197,7 @@ | ||||
|                             <div class="form-group col-md-3 col-xs-6"> | ||||
|                                 <label for="disk" class="control-label">Disk Space</label> | ||||
|                                 <div class="input-group"> | ||||
|                                     <input type="text" name="disk" class="form-control" value="{{ old('disk', $node->disk) }}"/> | ||||
|                                     <input type="text" name="disk" class="form-control" data-multiplicator="true" value="{{ old('disk', $node->disk) }}"/> | ||||
|                                     <span class="input-group-addon">MB</span> | ||||
|                                 </div> | ||||
|                             </div> | ||||
| @ -777,6 +789,24 @@ $(document).ready(function () { | ||||
|         element.parent().removeClass('has-error has-success'); | ||||
|     } | ||||
| 
 | ||||
|     (function getInformation() { | ||||
|         $.ajax({ | ||||
|             method: 'GET', | ||||
|             url: '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}', | ||||
|             timeout: 5000, | ||||
|             headers: { | ||||
|                 'X-Access-Token': '{{ $node->daemonSecret }}' | ||||
|             }, | ||||
|         }).done(function (data) { | ||||
|             $('[data-attr="info-version"]').html(data.version); | ||||
|             $('[data-attr="info-system"]').html(data.system.type + '(' + data.system.arch + ') <code>' + data.system.release + '</code>'); | ||||
|             $('[data-attr="info-cpus"]').html(data.system.cpus); | ||||
|         }).fail(function (jqXHR) { | ||||
| 
 | ||||
|         }).always(function() { | ||||
|             setTimeout(getInformation, 10000); | ||||
|         }); | ||||
|     })(); | ||||
| }); | ||||
| </script> | ||||
| @endsection | ||||
|  | ||||
| @ -118,14 +118,14 @@ | ||||
|                 <div class="form-group col-md-4 col-xs-4"> | ||||
|                     <label for="memory" class="control-label">Memory</label> | ||||
|                     <div class="input-group"> | ||||
|                         <input type="text" name="memory" class="form-control" value="{{ old('memory') }}"/> | ||||
|                         <input type="text" name="memory" data-multiplicator="true" class="form-control" value="{{ old('memory') }}"/> | ||||
|                         <span class="input-group-addon">MB</span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="form-group col-md-4 col-xs-4"> | ||||
|                     <label for="memory" class="control-label">Swap</label> | ||||
|                     <div class="input-group"> | ||||
|                         <input type="text" name="swap" class="form-control" value="{{ old('swap', 0) }}"/> | ||||
|                         <input type="text" name="swap" data-multiplicator="true" class="form-control" value="{{ old('swap', 0) }}"/> | ||||
|                         <span class="input-group-addon">MB</span> | ||||
|                     </div> | ||||
|                 </div> | ||||
| @ -150,7 +150,7 @@ | ||||
|                 <div class="form-group col-md-4 col-xs-4"> | ||||
|                     <label for="disk" class="control-label">Disk Space</label> | ||||
|                     <div class="input-group"> | ||||
|                         <input type="text" name="disk" class="form-control" value="{{ old('disk') }}"/> | ||||
|                         <input type="text" name="disk" data-multiplicator="true" class="form-control" value="{{ old('disk') }}"/> | ||||
|                         <span class="input-group-addon">MB</span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
| @ -228,14 +228,14 @@ | ||||
|                                 <div class="col-md-6 form-group {{ $errors->has('memory') ? 'has-error' : '' }}"> | ||||
|                                     <label for="memory" class="control-label">Allocated Memory</label> | ||||
|                                     <div class="input-group"> | ||||
|                                         <input type="text" name="memory" class="form-control" value="{{ old('memory', $server->memory) }}"/> | ||||
|                                         <input type="text" name="memory" data-multiplicator="true" class="form-control" value="{{ old('memory', $server->memory) }}"/> | ||||
|                                         <span class="input-group-addon">MB</span> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|                                 <div class="col-md-6 form-group {{ $errors->has('swap') ? 'has-error' : '' }}"> | ||||
|                                     <label for="swap" class="control-label">Allocated Swap</label> | ||||
|                                     <div class="input-group"> | ||||
|                                         <input type="text" name="swap" class="form-control" value="{{ old('swap', $server->swap) }}"/> | ||||
|                                         <input type="text" name="swap" data-multiplicator="true" class="form-control" value="{{ old('swap', $server->swap) }}"/> | ||||
|                                         <span class="input-group-addon">MB</span> | ||||
|                                     </div> | ||||
|                                     <p class="text-muted"><small>Setting this to <code>0</code> will disable swap space on this server.</small></p> | ||||
| @ -373,7 +373,7 @@ | ||||
|                                 <div class="form-group col-md-6"> | ||||
|                                     <label class="control-label">Database Name:</label> | ||||
|                                     <div class="input-group"> | ||||
|                                         <div class="input-group-addon">{{ $server->uuidShort }}_</div> | ||||
|                                         <div class="input-group-addon">s{{ $server->id }}_</div> | ||||
|                                         <input type="text" name="database" value="{{ old('database') }}" class="form-control"> | ||||
|                                     </div> | ||||
|                                 </div> | ||||
|  | ||||
| @ -44,7 +44,7 @@ | ||||
|                 <div> | ||||
|                     <select name="default_language" class="form-control"> | ||||
|                         <option value="de" @if(Settings::get('default_language') === 'de')selected @endif>Deutsch</option> | ||||
|                         <option value="en" @if(Settings::get('default_language') === 'en')selected @endif>English</option> | ||||
|                         <option value="en" @if(Settings::get('default_language', 'en') === 'en')selected @endif>English</option> | ||||
|                         <option value="es" @if(Settings::get('default_language') === 'es')selected @endif>Español</option> | ||||
|                         <option value="fr" @if(Settings::get('default_language') === 'fr')selected @endif>Français</option> | ||||
|                         <option value="it" @if(Settings::get('default_language') === 'it')selected @endif>Italiano</option> | ||||
|  | ||||
| @ -64,7 +64,7 @@ | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                 </button> | ||||
|                 <a class="navbar-brand" href="/">{{ Settings::get('company') }}</a> | ||||
|                 <a class="navbar-brand" href="/">{{ Settings::get('company', 'Pterodactyl Panel') }}</a> | ||||
|             </div> | ||||
|             <div class="navbar-collapse collapse navbar-responsive-collapse"> | ||||
|                 @section('navbar-links') | ||||
|  | ||||
| @ -164,7 +164,7 @@ | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                 </button> | ||||
|                 <a class="navbar-brand" href="/">{{ Settings::get('company') }}</a> | ||||
|                 <a class="navbar-brand" href="/">{{ Settings::get('company', 'Pterodactyl Panel') }}</a> | ||||
|             </div> | ||||
|             <div class="navbar-collapse collapse navbar-responsive-collapse"> | ||||
|                 @section('server-name') | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dane Everitt
						Dane Everitt