New theme assigned to server console page.
This commit is contained in:
parent
4cc9f7447c
commit
c7f3bb5112
8 changed files with 390 additions and 6 deletions
|
@ -58,8 +58,19 @@ class ServerController extends Controller
|
|||
public function getIndex(Request $request)
|
||||
{
|
||||
$server = Models\Server::getByUUID($request->route()->server);
|
||||
$node = Models\Node::find($server->node);
|
||||
|
||||
Javascript::put([
|
||||
'server' => [
|
||||
'uuid' => $server->uuid,
|
||||
'daemonSecret' => $server->daemonSecret,
|
||||
'username' => $server->username,
|
||||
],
|
||||
'node' => [
|
||||
'scheme' => $node->scheme,
|
||||
'fqdn' => $node->fqdn,
|
||||
'daemonListen' => $node->daemonListen,
|
||||
],
|
||||
'meta' => [
|
||||
'saveFile' => route('server.files.save', $server->uuidShort),
|
||||
'csrfToken' => csrf_token(),
|
||||
|
@ -69,7 +80,7 @@ class ServerController extends Controller
|
|||
return view('server.index', [
|
||||
'server' => $server,
|
||||
'allocations' => Models\Allocation::where('assigned_to', $server->id)->orderBy('ip', 'asc')->orderBy('port', 'asc')->get(),
|
||||
'node' => Models\Node::find($server->node),
|
||||
'node' => $node,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
$(window).load(function () {
|
||||
socket.on('console', function (data) {
|
||||
Socket.on('console', function (data) {
|
||||
if (data.line.indexOf('You need to agree to the EULA in order to run the server') > -1) {
|
||||
swal({
|
||||
title: 'EULA Acceptance',
|
||||
|
|
203
public/themes/pterodactyl/js/frontend/console.js
Normal file
203
public/themes/pterodactyl/js/frontend/console.js
Normal file
|
@ -0,0 +1,203 @@
|
|||
// 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.
|
||||
var CONSOLE_PUSH_COUNT = 50;
|
||||
var CONSOLE_PUSH_FREQ = 200;
|
||||
|
||||
(function initConsole() {
|
||||
window.TerminalQueue = [];
|
||||
window.Terminal = $('#terminal').terminal(function (command, term) {
|
||||
Socket.emit('send command', command);
|
||||
}, {
|
||||
greetings: '',
|
||||
name: Pterodactyl.server.uuid,
|
||||
height: 450,
|
||||
exit: false,
|
||||
prompt: Pterodactyl.server.username + ':~$ ',
|
||||
scrollOnEcho: false,
|
||||
scrollBottomOffset: 5,
|
||||
onBlur: function (terminal) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
Socket.on('initial status', function (data) {
|
||||
Terminal.clear();
|
||||
if (data.status === 1 || data.status === 2) {
|
||||
Socket.emit('send server log');
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function pushOutputQueue() {
|
||||
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
||||
// console throttled warning show
|
||||
}
|
||||
|
||||
if (TerminalQueue.length > 0) {
|
||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
||||
Terminal.echo(TerminalQueue[0]);
|
||||
TerminalQueue.shift();
|
||||
}
|
||||
}
|
||||
|
||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
||||
})();
|
||||
|
||||
$(document).ready(function () {
|
||||
$('[data-attr="power"]').click(function (event) {
|
||||
Socket.emit('set status', $(this).data('action'));
|
||||
});
|
||||
var ctc = $('#chart_cpu');
|
||||
var timeLabels = [];
|
||||
var cpuData = [];
|
||||
var CPUChart = new Chart(ctc, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timeLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: "Percent Use",
|
||||
fill: false,
|
||||
lineTension: 0.03,
|
||||
backgroundColor: "#00A1CB",
|
||||
borderColor: "#00A1CB",
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
borderJoinStyle: 'miter',
|
||||
pointBorderColor: "rgba(75,192,192,1)",
|
||||
pointBackgroundColor: "#fff",
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "rgba(75,192,192,1)",
|
||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 10,
|
||||
data: cpuData,
|
||||
spanGaps: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'CPU Usage (as Percent Total)'
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
animation: {
|
||||
duration: 1,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ctm = $('#chart_memory');
|
||||
var memoryData = [];
|
||||
var MemoryChart = new Chart(ctm, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: timeLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: "Memory Use",
|
||||
fill: false,
|
||||
lineTension: 0.03,
|
||||
backgroundColor: "#01A4A4",
|
||||
borderColor: "#01A4A4",
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
borderJoinStyle: 'miter',
|
||||
pointBorderColor: "rgba(75,192,192,1)",
|
||||
pointBackgroundColor: "#fff",
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "rgba(75,192,192,1)",
|
||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 10,
|
||||
data: memoryData,
|
||||
spanGaps: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Memory Usage (in Megabytes)'
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
animation: {
|
||||
duration: 1,
|
||||
}
|
||||
}
|
||||
});
|
||||
Socket.on('proc', function (proc) {
|
||||
if (cpuData.length > 10) {
|
||||
cpuData.shift();
|
||||
memoryData.shift();
|
||||
timeLabels.shift();
|
||||
}
|
||||
|
||||
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
||||
cpuData.push(cpuUse);
|
||||
memoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
||||
|
||||
var m = new Date();
|
||||
timeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
||||
|
||||
CPUChart.update();
|
||||
MemoryChart.update();
|
||||
});
|
||||
|
||||
// Update Listings on Initial Status
|
||||
Socket.on('initial status', function (data) {
|
||||
updateServerPowerControls(data.status);
|
||||
});
|
||||
|
||||
// Update Listings on Status
|
||||
Socket.on('status', function (data) {
|
||||
updateServerPowerControls(data.status);
|
||||
});
|
||||
|
||||
function updateServerPowerControls (data) {
|
||||
// Server is On or Starting
|
||||
if(data == 1 || data == 2) {
|
||||
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
||||
} else {
|
||||
if (data == 0) {
|
||||
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
||||
}
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
||||
}
|
||||
|
||||
if(data !== 0) {
|
||||
$('[data-attr="power"][data-action="kill"]').removeClass('disabled');
|
||||
} else {
|
||||
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
||||
}
|
||||
}
|
||||
});
|
69
public/themes/pterodactyl/js/frontend/server.socket.js
Normal file
69
public/themes/pterodactyl/js/frontend/server.socket.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
// 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.
|
||||
(function initSocket() {
|
||||
if (typeof io !== 'function') {
|
||||
console.error('Socket.io is reqired to use this panel.');
|
||||
return;
|
||||
}
|
||||
|
||||
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
|
||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
||||
});
|
||||
|
||||
Socket.io.on('connect_error', function (err) {
|
||||
console.error('Could not connect to socket.io.', err);
|
||||
});
|
||||
|
||||
// Connected to Socket Successfully
|
||||
Socket.on('connect', function () {
|
||||
console.log('connected to socket');
|
||||
});
|
||||
|
||||
Socket.on('initial status', function (data) {
|
||||
setStatusIcon(data.status);
|
||||
});
|
||||
|
||||
Socket.on('status', function (data) {
|
||||
setStatusIcon(data.status);
|
||||
});
|
||||
|
||||
Socket.on('console', function (data) {
|
||||
TerminalQueue.push(data.line);
|
||||
});
|
||||
})();
|
||||
|
||||
function setStatusIcon(status) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-danger"></i> Offline');
|
||||
break;
|
||||
case 1:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-success"></i> Online');
|
||||
break;
|
||||
case 2:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Starting');
|
||||
break;
|
||||
case 3:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Stopping');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
9
resources/lang/en/server.php
Normal file
9
resources/lang/en/server.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'index' => [
|
||||
'title' => 'Viewing Server :name',
|
||||
'header' => 'Server Console',
|
||||
'header_sub' => 'Control your server in real time.',
|
||||
]
|
||||
];
|
|
@ -61,7 +61,7 @@
|
|||
@foreach($servers as $server)
|
||||
<tr class="dynamic-update" data-server="{{ $server->uuidShort }}">
|
||||
<td><code>{{ $server->uuidShort }}</code></td>
|
||||
<td><a href="/server/{{ $server->uuidShort }}">{{ $server->name }}</a></td>
|
||||
<td><a href="{{ route('server.index', $server->uuidShort) }}">{{ $server->name }}</a></td>
|
||||
<td>{{ $server->nodeName }}</td>
|
||||
<td><code>@if(!is_null($server->ip_alias)){{ $server->ip_alias }}@else{{ $server->ip }}@endif:{{ $server->port }}</code></td>
|
||||
<td class="text-center hidden-sm hidden-xs"><span data-action="memory">--</span> / {{ $server->memory === 0 ? '∞' : $server->memory }} MB</td>
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
<div class="user-panel">
|
||||
<div class="info">
|
||||
<p>{{ $server->name }}</p>
|
||||
<a href="#"><i class="fa fa-circle text-success"></i> Online</a>
|
||||
<a href="#" id="server_status_icon"><i class="fa fa-circle text-default"></i> Checking...</a>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
@ -129,12 +129,12 @@
|
|||
</li>
|
||||
@if (isset($server->name) && isset($node->name))
|
||||
<li class="header">SERVER MANAGEMENT</li>
|
||||
<li>
|
||||
<li class="{{ Route::currentRouteName() !== 'server.index' ?: 'active' }}">
|
||||
<a href="{{ route('server.index', $server->uuidShort) }}">
|
||||
<i class="fa fa-terminal"></i> <span>Console</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="treeview">
|
||||
<li class="treeview {{ Route::currentRouteName() !== 'server.files.index' ?: 'active' }}">
|
||||
<a href="#">
|
||||
<i class="fa fa-files-o"></i>
|
||||
<span>File Management</span>
|
||||
|
@ -248,6 +248,7 @@
|
|||
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
|
||||
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
|
||||
{!! Theme::js('vendor/adminlte/app.min.js') !!}
|
||||
{!! Theme::js('js/vendor/socketio/socket.io.min.js') !!}
|
||||
@show
|
||||
</body>
|
||||
</html>
|
||||
|
|
91
resources/themes/pterodactyl/server/index.blade.php
Normal file
91
resources/themes/pterodactyl/server/index.blade.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
{{-- 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. --}}
|
||||
@extends('layouts.master')
|
||||
|
||||
@section('title')
|
||||
{{ trans('server.index.title', [ 'name' => $server->name]) }}
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
@parent
|
||||
{!! Theme::css('css/jquery.terminal.css') !!}
|
||||
@endsection
|
||||
|
||||
@section('content-header')
|
||||
<h1>{{ trans('server.index.header') }}<small>{{ trans('server.index.header_sub')}}</small></h1>
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('index') }}">{{ trans('strings.servers') }}</a></li>
|
||||
<li class="active">{{ $server->name }}</li>
|
||||
</ol>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-body">
|
||||
<div id="terminal" style="width:100%;"></div>
|
||||
</div>
|
||||
<div class="box-footer text-center">
|
||||
<button class="btn btn-success" data-attr="power" data-action="start">Start</button>
|
||||
<button class="btn btn-primary" data-attr="power" data-action="restart">Restart</button>
|
||||
<button class="btn btn-danger" data-attr="power" data-action="stop">Stop</button>
|
||||
<button class="btn btn-danger" data-attr="power" data-action="kill">Kill</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Memory Usage</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="chart_memory" style="max-height:300px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">CPU Usage</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="chart_cpu" style="max-height:300px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('footer-scripts')
|
||||
@parent
|
||||
{!! Theme::js('js/frontend/server.socket.js') !!}
|
||||
{!! Theme::js('js/jquery.mousewheel-min.js') !!}
|
||||
{!! Theme::js('js/jquery.terminal-0.11.23.min.js') !!}
|
||||
{!! Theme::js('js/unix_formatting.js') !!}
|
||||
{!! Theme::js('js/frontend/console.js') !!}
|
||||
{!! Theme::js('js/vendor/chartjs/chart.min.js') !!}
|
||||
{!! Theme::js('js/vendor/jquery/jquery-dateFormat.min.js') !!}
|
||||
@if($server->a_serviceFile === 'minecraft')
|
||||
{!! Theme::js('js/plugins/minecraft/eula.js') !!}
|
||||
@endif
|
||||
@endsection
|
Loading…
Reference in a new issue