2016-01-24 02:30:03 +00:00
{{ -- Copyright ( c ) 2015 - 2016 Dane Everitt < dane @ daneeveritt . com > -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- 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 : -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- The above copyright notice and this permission notice shall be included in all -- }}
{{ -- copies or substantial portions of the Software . -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- 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 . -- }}
2015-12-06 18:58:49 +00:00
@ extends ( 'layouts.master' )
@ section ( 'title' )
Viewing Server : {{ $server -> name }}
@ endsection
@ section ( 'scripts' )
@ parent
2016-09-16 19:48:17 +00:00
{ !! Theme :: css ( 'css/jquery.terminal.css' ) !! }
{ !! Theme :: js ( 'js/jquery.mousewheel-min.js' ) !! }
{ !! Theme :: js ( 'js/jquery.terminal-0.11.6.min.js' ) !! }
{ !! Theme :: js ( 'js/unix_formatting.js' ) !! }
2016-10-30 04:06:55 +00:00
{ !! Theme :: js ( 'js/vendor/chartjs/chart.min.js' ) !! }
{ !! Theme :: js ( 'js/vendor/jquery/jquery-dateFormat.min.js' ) !! }
2015-12-06 18:58:49 +00:00
@ endsection
@ section ( 'content' )
2016-01-04 21:48:22 +00:00
< div class = " col-md-12 " >
2016-01-03 05:28:33 +00:00
< ul class = " nav nav-tabs tabs_with_panel " id = " config_tabs " >
2016-09-16 19:48:17 +00:00
< li class = " active " >< a href = " #console " data - toggle = " tab " > {{ trans ( 'server.index.control' ) }} </ a ></ li >
2016-10-30 04:06:55 +00:00
< li >< a href = " #resources " data - toggle = " tab " > Resource Use </ a ></ li >
2016-01-09 03:30:21 +00:00
@ can ( 'view-allocation' , $server ) < li >< a href = " #allocation " data - toggle = " tab " > {{ trans ( 'server.index.allocation' ) }} </ a ></ li >@ endcan
2016-01-03 05:28:33 +00:00
</ ul >
2015-12-06 18:58:49 +00:00
< div class = " tab-content " >
2016-01-03 05:28:33 +00:00
< div class = " tab-pane active " id = " console " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " row " >
< div class = " col-md-12 " >
2016-10-24 01:31:29 +00:00
< div class = " alert alert-info hidden " id = " consoleThrottled " >
The console is currently being throttled due to the speed at which data is being sent . Messages are being queued and will appear as the queue is worked through .
</ div >
< div id = " terminal " >
</ div >
2016-01-03 05:28:33 +00:00
</ div >
2016-09-16 19:48:17 +00:00
< div class = " col-md-12 " style = " text-align:center; " >
2016-01-03 05:28:33 +00:00
< hr />
2016-01-18 05:56:09 +00:00
@ can ( 'power-start' , $server ) < button class = " btn btn-success btn-sm disabled " data - attr = " power " data - action = " start " > Start </ button >@ endcan
@ can ( 'power-restart' , $server ) < button class = " btn btn-primary btn-sm disabled " data - attr = " power " data - action = " restart " > Restart </ button >@ endcan
@ can ( 'power-stop' , $server ) < button class = " btn btn-danger btn-sm disabled " data - attr = " power " data - action = " stop " > Stop </ button >@ endcan
@ can ( 'power-kill' , $server ) < button class = " btn btn-danger btn-sm disabled " data - attr = " power " data - action = " kill " >< i class = " fa fa-ban " data - toggle = " tooltip " data - placement = " top " title = " Kill Running Process " ></ i ></ button >@ endcan
< button class = " btn btn-primary btn-sm " data - toggle = " modal " data - target = " #pauseConsole " id = " pause_console " >< small >< i class = " fa fa-pause fa-fw " ></ i ></ small ></ button >
< div id = " pw_resp " style = " display:none;margin-top: 15px; " ></ div >
2016-01-03 05:28:33 +00:00
</ div >
</ div >
2015-12-06 18:58:49 +00:00
</ div >
</ div >
</ div >
2016-10-30 04:06:55 +00:00
< div class = " tab-pane " id = " resources " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " row " >
< div class = " col-md-12 " >
< canvas id = " chart_memory " style = " max-height:300px; " ></ canvas >
</ div >
</ div >
< div class = " row " style = " margin-top:15px; " >
< div class = " col-md-12 " >
< canvas id = " chart_cpu " style = " max-height:300px; " ></ canvas >
</ div >
</ div >
</ div >
</ div >
</ div >
2016-01-09 03:30:21 +00:00
@ can ( 'view-allocation' , $server )
2016-01-09 03:22:57 +00:00
< div class = " tab-pane " id = " allocation " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " alert alert-info " > Below is a listing of all avaliable IPs and Ports for your service . To change the default connection address for your server , simply click on the one you would like to make default below .</ div >
2016-09-30 22:21:02 +00:00
< table class = " table table-hover " >
< tr >
< th > IP Address </ th >
< th > Alias </ th >
< th > Port </ th >
< th ></ th >
</ tr >
2016-01-09 03:22:57 +00:00
@ foreach ( $allocations as $allocation )
2016-09-30 22:21:02 +00:00
< tr >
< td >
< code > {{ $allocation -> ip }} </ code >
</ td >
< td @ if ( is_null ( $allocation -> ip_alias )) class = " muted " @ endif >
@ if ( is_null ( $allocation -> ip_alias ))
< span class = " label label-default " > none </ span >
@ else
< code > {{ $allocation -> ip_alias }} </ code >
@ endif
</ td >
< td >< code > {{ $allocation -> port }} </ code ></ td >
< td class = " col-xs-2 " >
@ if ( $allocation -> id === $server -> allocation )
< span class = " label label-primary is-primary " data - allocation = " { { $allocation->id }} " > Primary </ span >
@ else
< span class = " label label-success muted muted-hover use-pointer " data - action = " set-connection " data - allocation = " { { $allocation->id }} " > Make Primary </ span >
@ endif
</ td >
</ tr >
2016-01-09 03:22:57 +00:00
@ endforeach
2016-09-30 22:21:02 +00:00
</ table >
2016-01-09 03:22:57 +00:00
</ div >
2015-12-06 18:58:49 +00:00
</ div >
</ div >
2016-01-09 03:22:57 +00:00
@ endcan
2015-12-06 18:58:49 +00:00
</ div >
</ div >
< div class = " modal fade " id = " pauseConsole " tabindex = " -1 " role = " dialog " aria - labelledby = " PauseConsole " aria - hidden = " true " >
< div class = " modal-dialog " >
< div class = " modal-content " >
< div class = " modal-header " >
< button type = " button " class = " close " data - dismiss = " modal " aria - hidden = " true " >& times ; </ button >
2016-09-16 19:48:17 +00:00
< h4 class = " modal-title " id = " PauseConsole " > ScrollStop & trade ; </ h4 >
2015-12-06 18:58:49 +00:00
</ div >
< div class = " modal-body " >
< div class = " row " >
< div class = " col-md-12 " >
2016-09-16 19:48:17 +00:00
< div id = " paused_console " style = " height: 300px; overflow-x: scroll; " ></ div >
2015-12-06 18:58:49 +00:00
</ div >
</ div >
</ div >
< div class = " modal-footer " >
< button type = " button " class = " btn btn-default " data - dismiss = " modal " > {{ trans ( 'strings.close' ) }} </ button >
</ div >
</ div >
</ div >
</ div >
2016-01-09 00:54:06 +00:00
@ if ( $server -> a_serviceFile === 'minecraft' )
2016-10-01 00:53:08 +00:00
< script src = " { { route('server.js', [ $server->uuidShort , 'minecraft', 'eula.js']) }} " ></ script >
2016-01-09 00:54:06 +00:00
@ endif
2015-12-06 18:58:49 +00:00
< script >
$ ( window ) . load ( function () {
$ ( '[data-toggle="tooltip"]' ) . tooltip ();
2016-09-16 19:48:17 +00:00
var initialStatusSent = false ;
var currentStatus = 0 ;
var terminal = $ ( '#terminal' ) . terminal ( function ( command , term ) {
@ can ( 'power-start' , $server )
if ( currentStatus === 0 && ( command === 'start' || command === 'boot' )) {
powerToggleServer ( 'start' );
}
@ endcan
@ can ( 'send-command' , $server )
if ( currentStatus === 0 && ! ( command === 'start' || command === 'boot' )) {
term . error ( 'Server is currently off, type `start` or `boot` to start server.' );
}
if ( currentStatus !== 0 && command !== '' ) {
$ . ajax ({
type : 'POST' ,
headers : {
'X-Access-Token' : '{{ $server->daemonSecret }}' ,
'X-Access-Server' : '{{ $server->uuid }}'
},
contentType : 'application/json; charset=utf-8' ,
url : '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/command' ,
timeout : 10000 ,
data : JSON . stringify ({ command : command })
}) . fail ( function ( jqXHR ) {
console . error ( jqXHR );
var error = 'An error occured while trying to process this request.' ;
if ( typeof jqXHR . responseJSON !== 'undefined' && typeof jqXHR . responseJSON . error !== 'undefined' ) {
error = jqXHR . responseJSON . error ;
}
term . error ( error );
});
}
@ else
term . error ( 'You do not have permission to send commands to this server.' );
@ endcan
}, {
greetings : '' ,
name : '{{ $server->uuid }}' ,
height : 400 ,
2016-09-17 23:13:19 +00:00
exit : false ,
2016-10-16 22:09:28 +00:00
prompt : '{{ $server->username }}:~$ ' ,
2016-09-16 19:48:17 +00:00
onBlur : function ( terminal ) {
return false ;
}
});
2015-12-06 18:58:49 +00:00
2016-10-30 04:06:55 +00:00
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 ,
}
}
2016-02-06 20:06:43 +00:00
});
2016-10-30 04:06:55 +00:00
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 ,
}
2016-02-06 20:06:43 +00:00
}
2016-10-30 04:06:55 +00:00
});
socket . on ( 'proc' , function ( proc ) {
if ( cpuData . length > 10 ) {
cpuData . shift ();
memoryData . shift ();
timeLabels . shift ();
2016-02-06 20:06:43 +00:00
}
2016-10-30 04:06:55 +00:00
var cpuUse = ({{ $server -> cpu }} > 0 ) ? parseFloat ((( proc . data . cpu . total / {{ $server -> cpu }}) * 100 ) . toFixed ( 3 ) . toString ()) : proc . data . cpu . total ;
cpuData . push ( cpuUse );
memoryData . push ( parseInt ( proc . data . memory . total / ( 1024 * 1024 )));
2016-02-06 20:06:43 +00:00
2016-10-30 04:06:55 +00:00
var m = new Date ();
2016-11-19 20:57:58 +00:00
timeLabels . push ( $ . format . date ( new Date (), 'HH:mm:ss' ));
2016-01-02 02:35:50 +00:00
2016-10-30 04:06:55 +00:00
CPUChart . update ();
MemoryChart . update ();
2015-12-06 18:58:49 +00:00
});
// Socket Recieves New Query
socket . on ( 'query' , function ( data ){
2016-10-30 01:46:53 +00:00
// Disabled.
2015-12-06 18:58:49 +00:00
});
// New Console Data Recieved
2016-10-24 01:31:29 +00:00
var outputQueue = [];
2015-12-06 18:58:49 +00:00
socket . on ( 'console' , function ( data ) {
2016-10-24 01:31:29 +00:00
outputQueue . push ( data . line );
2015-12-06 18:58:49 +00:00
});
2016-10-24 01:31:29 +00:00
window . setInterval ( pushOutputQueue , {{ env ( 'CONSOLE_PUSH_FREQ' , 250 ) }});
function pushOutputQueue ()
{
if ( outputQueue . length > {{ env ( 'CONSOLE_PUSH_COUNT' , 10 ) }}) {
$ ( '#consoleThrottled' ) . removeClass ( 'hidden' );
} else {
$ ( '#consoleThrottled' ) . addClass ( 'hidden' );
}
2016-11-01 22:22:07 +00:00
for ( var i = 0 ; i < {{ env ( 'CONSOLE_PUSH_COUNT' , 10 ) }} && outputQueue . length > 0 ; i ++ )
2016-10-24 01:31:29 +00:00
{
terminal . echo ( outputQueue [ 0 ]);
outputQueue . shift ();
}
}
2015-12-06 18:58:49 +00:00
// Update Listings on Initial Status
socket . on ( 'initial_status' , function ( data ) {
2016-09-16 19:48:17 +00:00
currentStatus = data . status ;
2015-12-06 18:58:49 +00:00
if ( data . status !== 0 ) {
$ . ajax ({
type : 'GET' ,
headers : {
'X-Access-Token' : '{{ $server->daemonSecret }}' ,
'X-Access-Server' : '{{ $server->uuid }}'
},
2016-01-01 23:08:15 +00:00
url : '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/log' ,
2015-12-06 18:58:49 +00:00
timeout : 10000
}) . done ( function ( data ) {
2016-09-16 19:48:17 +00:00
terminal . echo ( data );
}) . fail ( function () {
terminal . error ( 'Unable to load initial server log, try reloading the page.' );
2015-12-06 18:58:49 +00:00
});
}
updateServerPowerControls ( data . status );
updatePlayerListVisibility ( data . status );
});
// Update Listings on Status
socket . on ( 'status' , function ( data ) {
2016-09-16 19:48:17 +00:00
currentStatus = data . status ;
2015-12-06 18:58:49 +00:00
updateServerPowerControls ( data . status );
updatePlayerListVisibility ( data . status );
});
// Load Paused Console with Live Console Data
$ ( '#pause_console' ) . click ( function (){
2016-09-16 19:48:17 +00:00
$ ( '#paused_console' ) . html ( $ ( '#terminal' ) . html ());
2015-12-06 18:58:49 +00:00
});
function updatePlayerListVisibility ( data ) {
// Server is On or Starting
2015-12-31 22:55:42 +00:00
if ( data !== 0 ) {
2015-12-06 18:58:49 +00:00
$ ( '#stats_players' ) . show ();
} else {
$ ( '#stats_players' ) . hide ();
}
}
2016-01-03 05:28:33 +00:00
2016-01-09 03:36:57 +00:00
@ can ( 'set-allocation' , $server )
2016-01-03 20:15:14 +00:00
// Send Request
2016-09-30 22:21:02 +00:00
function handleChange () {
$ ( '[data-action="set-connection"]' ) . click ( function ( event ) {
event . preventDefault ();
var element = $ ( this );
2016-01-03 20:15:14 +00:00
2016-09-30 22:21:02 +00:00
$ . ajax ({
method : 'POST' ,
url : '/server/{{ $server->uuidShort }}/ajax/set-primary' ,
data : {
allocation : element . data ( 'allocation' )
},
headers : {
'X-CSRF-TOKEN' : '{{ csrf_token() }}'
}
}) . done ( function ( data ) {
swal ({
type : 'success' ,
title : '' ,
text : data
});
element . parents () . eq ( 2 ) . find ( '.is-primary' ) . addClass ( 'muted muted-hover label-success use-pointer' ) . attr ( 'data-action' , 'set-connection' ) . data ( 'action' , 'set-connection' ) . removeClass ( 'label-primary is-primary' ) . html ( 'Make Primary' );
element . removeClass ( 'muted muted-hover label-success use-pointer' ) . attr ( 'data-action' , 'do-nothing' ) . data ( 'action' , 'do-nothing' ) . addClass ( 'label-primary is-primary' ) . html ( 'Primary' );
handleChange ();
}) . fail ( function ( jqXHR ) {
console . error ( jqXHR );
var respError ;
if ( typeof jqXHR . responseJSON . error === 'undefined' || jqXHR . responseJSON . error === '' ) {
respError = 'An error occured while attempting to perform this action.' ;
} else {
respError = jqXHR . responseJSON . error ;
}
swal ({
type : 'error' ,
title : 'Whoops!' ,
text : respError
});
2016-01-09 03:36:57 +00:00
});
2016-01-03 20:15:14 +00:00
});
2016-09-30 22:21:02 +00:00
}
handleChange ();
2016-01-03 20:15:14 +00:00
@ endcan
2016-01-18 05:56:09 +00:00
var can_run = true ;
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 {
2016-09-28 23:16:10 +00:00
if ( data == 0 ) {
$ ( '[data-attr="power"][data-action="start"]' ) . removeClass ( 'disabled' );
}
2016-01-18 05:56:09 +00:00
$ ( '[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]' ) . addClass ( 'disabled' );
2015-12-06 18:58:49 +00:00
}
2016-01-18 05:56:09 +00:00
if ( data !== 0 ) {
$ ( '[data-attr="power"][data-action="kill"]' ) . removeClass ( 'disabled' );
} else {
$ ( '[data-attr="power"][data-action="kill"]' ) . addClass ( 'disabled' );
}
}
2015-12-06 18:58:49 +00:00
2016-01-18 05:56:09 +00:00
$ ( '[data-attr="power"]' ) . click ( function ( event ) {
event . preventDefault ();
var action = $ ( this ) . data ( 'action' );
var killConfirm = false ;
if ( action === 'kill' ) {
swal ({
type : 'warning' ,
title : '' ,
text : 'This operation will not save your server data gracefully. You should only use this if your server is failing to respond to normal stop commands.' ,
showCancelButton : true ,
allowOutsideClick : true ,
closeOnConfirm : true ,
confirmButtonText : 'Kill Server' ,
confirmButtonColor : '#d9534f'
}, function () {
setTimeout ( function () {
powerToggleServer ( 'kill' );
}, 100 );
2016-01-09 03:54:30 +00:00
});
2016-01-18 05:56:09 +00:00
} else {
powerToggleServer ( action );
2016-01-09 03:54:30 +00:00
}
2016-01-18 05:56:09 +00:00
});
function powerToggleServer ( action ) {
$ . ajax ({
type : 'PUT' ,
headers : {
'X-Access-Token' : '{{ $server->daemonSecret }}' ,
'X-Access-Server' : '{{ $server->uuid }}'
},
contentType : 'application/json; charset=utf-8' ,
data : JSON . stringify ({
action : action
}),
url : '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/server/power' ,
timeout : 10000
}) . fail ( function ( jqXHR ) {
var error = 'An error occured while trying to process this request.' ;
if ( typeof jqXHR . responseJSON !== 'undefined' && typeof jqXHR . responseJSON . error !== 'undefined' ) {
error = jqXHR . responseJSON . error ;
}
swal ({
type : 'error' ,
title : 'Whoops!' ,
text : error
});
});
}
2015-12-06 18:58:49 +00:00
});
$ ( document ) . ready ( function () {
$ ( '.server-index' ) . addClass ( 'active' );
});
</ script >
@ endsection