Skip to content

Commit 8db9d9b

Browse files
committed
Very rough go at connecting to socket and rendering console data for server
1 parent 784c73b commit 8db9d9b

File tree

9 files changed

+311
-114
lines changed

9 files changed

+311
-114
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Server;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\JsonResponse;
7+
use Pterodactyl\Http\Controllers\Controller;
8+
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
9+
10+
class CredentialsController extends Controller
11+
{
12+
/**
13+
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
14+
*/
15+
private $keyProviderService;
16+
17+
/**
18+
* CredentialsController constructor.
19+
*
20+
* @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService
21+
*/
22+
public function __construct(DaemonKeyProviderService $keyProviderService)
23+
{
24+
$this->keyProviderService = $keyProviderService;
25+
}
26+
27+
/**
28+
* Return a set of credentials that the currently authenticated user can use to access
29+
* a given server with.
30+
*
31+
* @param \Illuminate\Http\Request $request
32+
* @return \Illuminate\Http\JsonResponse
33+
*
34+
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
35+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
36+
*/
37+
public function index(Request $request): JsonResponse
38+
{
39+
/** @var \Pterodactyl\Models\Server $server */
40+
$server = $request->attributes->get('server');
41+
$server->loadMissing('node');
42+
43+
return JsonResponse::create([
44+
'node' => $server->getRelation('node')->getConnectionAddress(),
45+
'key' => $this->keyProviderService->handle($server, $request->user()),
46+
]);
47+
}
48+
}

app/Models/Node.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ class Node extends Model implements CleansAttributes, ValidableContract
131131
'maintenance_mode' => false,
132132
];
133133

134+
/**
135+
* Get the connection address to use when making calls to this node.
136+
*
137+
* @return string
138+
*/
139+
public function getConnectionAddress(): string
140+
{
141+
return sprintf('%s://%s:%s', $this->scheme, $this->fqdn, $this->daemonListen);
142+
}
143+
134144
/**
135145
* Returns the configuration in JSON format.
136146
*

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "pterodactyl-panel",
33
"dependencies": {
44
"date-fns": "^1.29.0",
5+
"socket.io-client": "^2.1.1",
56
"vee-validate": "^2.1.0-beta.2",
67
"vue": "^2.5.7",
78
"vue-axios": "^2.1.1",

resources/assets/scripts/components/server/Server.vue

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,16 @@
6969
import {mapState} from 'vuex';
7070
import { ConsolePage } from './subpages/ConsolePage';
7171
72+
import io from 'socket.io-client';
73+
7274
export default {
7375
components: {
7476
ProgressBar, Navigation, ConsolePage, TerminalIcon, FolderIcon, UsersIcon,
7577
CalendarIcon, DatabaseIcon, GlobeIcon, SettingsIcon
7678
},
7779
7880
computed: {
79-
...mapState('server', ['server']),
81+
...mapState('server', ['server', 'credentials']),
8082
},
8183
8284
mounted: function () {
@@ -85,20 +87,70 @@
8587
8688
data: function () {
8789
return {
90+
socket: null,
8891
loadingServerData: true,
8992
};
9093
},
9194
9295
methods: {
96+
/**
97+
* Load the core server information needed for these pages to be functional.
98+
*/
9399
loadServer: function () {
94-
this.$store.dispatch('server/getServer', {server: this.$route.params.id})
100+
Promise.all([
101+
this.$store.dispatch('server/getServer', {server: this.$route.params.id}),
102+
this.$store.dispatch('server/getCredentials', {server: this.$route.params.id})
103+
])
95104
.then(() => {
96105
this.loadingServerData = false;
106+
this.initalizeWebsocket();
97107
})
98-
.catch(err => {
99-
console.error(err);
100-
});
108+
.catch(console.error);
109+
},
110+
111+
initalizeWebsocket: function () {
112+
this.$store.commit('server/CONSOLE_DATA', 'Connecting to ' + this.credentials.node + '...');
113+
this.socket = io(this.credentials.node + '/v1/ws/' + this.server.uuid, {
114+
query: 'token=' + this.credentials.key,
115+
});
116+
117+
this.socket.on('error', this._socket_error);
118+
this.socket.on('connect', this._socket_connect);
119+
this.socket.on('status', this._socket_status);
120+
this.socket.on('initial status', this._socket_status);
121+
this.socket.on('server log', this._socket_serverLog);
122+
this.socket.on('console', this._socket_consoleLine);
123+
},
124+
125+
_socket_error: function (err) {
126+
this.$store.commit('server/CONSOLE_DATA', 'There was a socket error: ' + err);
127+
console.error('there was a socket error:', err);
128+
},
129+
130+
_socket_connect: function () {
131+
this.$store.commit('server/CONSOLE_DATA', 'Connected to socket.');
132+
this.socket.emit('send server log');
133+
console.log('connected');
134+
},
135+
136+
_socket_status: function (data) {
137+
this.$store.commit('server/CONSOLE_DATA', 'Server state has changed.');
138+
console.warn(data);
139+
},
140+
141+
_socket_serverLog: function (data) {
142+
data.split(/\n/g).forEach(item => {
143+
this.$store.commit('server/CONSOLE_DATA', item);
144+
});
101145
},
102-
}
146+
147+
_socket_consoleLine: function (data) {
148+
if(data.line) {
149+
data.line.split(/\n/g).forEach((item) => {
150+
this.$store.commit('server/CONSOLE_DATA', item);
151+
});
152+
}
153+
}
154+
},
103155
}
104156
</script>

resources/assets/scripts/components/server/subpages/ConsolePage.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
<template>
22
<div>
33
<div class="text-xs font-mono">
4-
<div class="rounded-t p-2 bg-black text-grey-lightest h-48">
5-
4+
<div class="rounded-t p-2 bg-black text-grey-lightest overflow-scroll" style="min-height: 16rem;max-height:32rem;">
5+
<span class="block" v-for="line in console">{{line}}</span>
66
</div>
77
<div class="rounded-b p-2 bg-grey-darkest text-white">$</div>
88
</div>
99
</div>
1010
</template>
1111

1212
<script>
13+
import {mapState} from 'vuex';
14+
1315
export default {
1416
name: 'console-page',
1517
18+
computed: {
19+
...mapState('server', ['console']),
20+
},
21+
1622
data: function () {
1723
return {
1824
lines: [],

0 commit comments

Comments
 (0)