Various updates and general cleanup
- Updated socket.io to v3 - Added namespaces for chat and TanksJS-Server - Replaced game-server-query with game-dig because it was not updated - Code cleanup
This commit is contained in:
parent
293a97d256
commit
b4e9c67be5
34
.eslintrc.js
Normal file
34
.eslintrc.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
module.exports = {
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"commonjs": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"globals": {
|
||||||
|
"Atomics": "readonly",
|
||||||
|
"SharedArrayBuffer": "readonly"
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"double"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
94
html/index.html
Normal file
94
html/index.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>API Documentation</title>
|
||||||
|
|
||||||
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="css/styles.css">
|
||||||
|
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/res/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/res/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/res/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/res/site.webmanifest">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h1>ARNweb API</h1>
|
||||||
|
</div>
|
||||||
|
<span class="apiReference get">
|
||||||
|
<span class="requestType get">GET</span>
|
||||||
|
<a href="/system"><code>/system</code></a><br>
|
||||||
|
<div>
|
||||||
|
<p>Returns json object containing general information about the server.</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="apiReference get">
|
||||||
|
<span class="requestType get">GET</span>
|
||||||
|
<a href="/chat"><code>/chat</code></a><br>
|
||||||
|
<div>
|
||||||
|
<p>Returns json object containing general information about the chat server.</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="apiReference get">
|
||||||
|
<span class="requestType get">GET</span>
|
||||||
|
<a href="/tanks"><code>/tanks</code></a><br>
|
||||||
|
<div>
|
||||||
|
<p>Returns json object containing status information about the TanksJS-Server instance.</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="apiReference other">
|
||||||
|
<span class="requestType other">Socket</span>
|
||||||
|
<a href="/socket.io/"><code>/socket.io/</code></a><br>
|
||||||
|
<div>
|
||||||
|
<p>Socket.io instance that serves both ARNweb chat and a TanksJS server.</p>
|
||||||
|
<p>Use the following namespaces to access them accordingly:</p><br>
|
||||||
|
|
||||||
|
<b><code>/socket.io/tanks</code></b>
|
||||||
|
<p>TanksJS-server instance, see <a href="//gitea.arnweb.nl/arne/TanksJS-Server">TanksJS-Server</a> for more
|
||||||
|
information.</p><br>
|
||||||
|
|
||||||
|
<b><code>/socket.io/chat</code></b>
|
||||||
|
<p>Simple chat backend server for <a href="//arnweb.nl/account">ARNweb Chat</a>.<br>Use the following
|
||||||
|
communication steps to make your own client:</p>
|
||||||
|
<p>
|
||||||
|
<code><b>Server -> Client</b><br>user_identify { }</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code><b>Server <- Client</b> <br>user_login { "username", "mailHash" }</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code><b>Server <- Client</b> <br>message_send { "username", "mailHash", "message" }</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code><b>Server -> Client</b><br>message_receive { "username", "mailHash", "message" }</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="apiReference get">
|
||||||
|
<span class="requestType get">GET</span>
|
||||||
|
<code>/:game/:host</code><br>
|
||||||
|
<div>
|
||||||
|
<p>Returns json object containing information about the requested game server.</p>
|
||||||
|
<p>Powered by node-GameDig, more info on <a href="//www.npmjs.com/package/gamedig">npm</a>.</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="apiReference other">
|
||||||
|
<span class="requestType other">cURL</span>
|
||||||
|
<code>/curl</code><br>
|
||||||
|
<div>
|
||||||
|
<p>Returns hello world to cURL requests.</p>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
65
index.html
65
index.html
@ -1,65 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>API Documentation</title>
|
|
||||||
|
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
|
||||||
<link rel="stylesheet" href="css/styles.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<h1>ARNweb API</h1>
|
|
||||||
</div>
|
|
||||||
<span class="apiReference get">
|
|
||||||
<span class="requestType get">GET</span>
|
|
||||||
<a href="/system"><code>/system</code></a><br>
|
|
||||||
<div>
|
|
||||||
<span>Returns json object containing general information about the server.</span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<span class="apiReference get">
|
|
||||||
<span class="requestType get">GET</span>
|
|
||||||
<a href="/chat"><code>/chat</code></a><br>
|
|
||||||
<div>
|
|
||||||
<span>Returns json object containing general information about the chat server.</span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<span class="apiReference other">
|
|
||||||
<span class="requestType other">Socket</span>
|
|
||||||
<a href="/chat/socket.io/"><code>/chat/socket.io/</code></a><br>
|
|
||||||
<div>
|
|
||||||
<span>Socket.io instance used by the chat on ARNweb.</span><br><br>
|
|
||||||
<span>
|
|
||||||
<bold>Server -> Client</bold><br><code>user_identify { }</code>
|
|
||||||
</span><br><br>
|
|
||||||
<span>
|
|
||||||
<bold>Server <- Client</bold> <br><code>user_login { "username", "mailHash" }</code>
|
|
||||||
</span><br><br>
|
|
||||||
<span>
|
|
||||||
<bold>Client -> Server</bold><br><code>message_send { "username", "mailHash", "message" }</code>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<span class="apiReference get">
|
|
||||||
<span class="requestType get">GET</span>
|
|
||||||
<code>/:game/:host</code><br>
|
|
||||||
<div>
|
|
||||||
<span>Returns json object containing information about the requested game server.</span><br>
|
|
||||||
<span><a href="//www.npmjs.com/package/game-server-query#games-list">Supported games</a></span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<span class="apiReference other">
|
|
||||||
<span class="requestType other">cURL</span>
|
|
||||||
<code>/curl</code><br>
|
|
||||||
<div>
|
|
||||||
<span>Returns hello world to cURL requests.</span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
147
index.js
147
index.js
@ -1,147 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const app = express();
|
|
||||||
const port = 2428;
|
|
||||||
|
|
||||||
const server = app.listen(port, () => console.log(`ARNweb API running on port ${port}`))
|
|
||||||
|
|
||||||
var io = require('socket.io').listen(server, { path: '/chat/socket.io' })
|
|
||||||
var striptags = require('striptags');
|
|
||||||
var MarkdownIt = require('markdown-it'),
|
|
||||||
md = new MarkdownIt();
|
|
||||||
var users = [];
|
|
||||||
|
|
||||||
const style = require('ansi-styles');
|
|
||||||
|
|
||||||
const os = require("os");
|
|
||||||
const si = require('systeminformation');
|
|
||||||
var sysInfo;
|
|
||||||
|
|
||||||
const gameQuery = require('game-server-query');
|
|
||||||
const fs = require('fs');
|
|
||||||
let rawdata = fs.readFileSync(__dirname + "/node_modules/game-server-query/games.json");
|
|
||||||
const games = JSON.parse(rawdata);
|
|
||||||
|
|
||||||
// Request documentation
|
|
||||||
app.get('/', (req, res) =>
|
|
||||||
res.sendFile(__dirname + "/index.html")
|
|
||||||
);
|
|
||||||
|
|
||||||
// Function for easy server broadcasts
|
|
||||||
function serverMsg(content) {
|
|
||||||
return {
|
|
||||||
'username': 'Server',
|
|
||||||
'mailHash': '470965550d3f019830c421f0535d9268',
|
|
||||||
'message': content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Socket.io server side
|
|
||||||
io.on('connection', function (socket) {
|
|
||||||
// Send identification request to client
|
|
||||||
socket.emit('user_identify');
|
|
||||||
|
|
||||||
// Bind username and mailhash to client
|
|
||||||
socket.on('user_login', function (user) {
|
|
||||||
socket.username = user.username;
|
|
||||||
socket.mailHash = user.mailHash;
|
|
||||||
if (users.length > 0) {
|
|
||||||
socket.emit('message_receive', serverMsg(`Hello ${socket.username}, welcome to ARNweb Chat. The following people are currently online: ${users.join(', ')}`));
|
|
||||||
} else {
|
|
||||||
socket.emit('message_receive', serverMsg(`Hello ${socket.username}, welcome to ARNweb Chat. You are the only one here at the moment`));
|
|
||||||
}
|
|
||||||
|
|
||||||
io.emit('message_receive', serverMsg(`${socket.username} has connected`));
|
|
||||||
users.push(socket.username);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send disconnect broadcast to all clients
|
|
||||||
socket.on('disconnect', function () {
|
|
||||||
io.emit('message_receive', serverMsg(`${socket.username} has disconnected`));
|
|
||||||
users.splice(users.indexOf(socket.username), 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle messages
|
|
||||||
socket.on('message_send', function (message) {
|
|
||||||
// Build message data for clients
|
|
||||||
var message = striptags(message, '<br />');
|
|
||||||
if (message !== '') {
|
|
||||||
message = md.render(message);
|
|
||||||
message = message.replace(/\r?\n/g, '<br />');
|
|
||||||
var msg = {
|
|
||||||
'username': socket.username,
|
|
||||||
'mailHash': socket.mailHash,
|
|
||||||
'message': message
|
|
||||||
}
|
|
||||||
// Send message to clients
|
|
||||||
io.emit('message_receive', msg);
|
|
||||||
} else {
|
|
||||||
socket.emit('message_receive', serverMsg(`Empty messages will not be sent.`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Chat socket and info
|
|
||||||
app.get('/chat/', function (req, res) {
|
|
||||||
// Server browser
|
|
||||||
res.json({
|
|
||||||
"status": "online",
|
|
||||||
"users": users
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// System info
|
|
||||||
app.get('/system/', function (req, res) {
|
|
||||||
var time = new Date();
|
|
||||||
sysInfo = {
|
|
||||||
"hostname": os.hostname(),
|
|
||||||
"type": os.type(),
|
|
||||||
"load": os.loadavg(),
|
|
||||||
"time": si.time()
|
|
||||||
};
|
|
||||||
si.cpuTemperature(function (data) {
|
|
||||||
sysInfo["temp"] = data;
|
|
||||||
});
|
|
||||||
si.mem(function (data) {
|
|
||||||
sysInfo["mem"] = data;
|
|
||||||
});
|
|
||||||
si.fsSize(function (data) {
|
|
||||||
sysInfo["fs"] = data;
|
|
||||||
res.json(sysInfo);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
// cURL
|
|
||||||
app.get('/curl/', function (req, res) {
|
|
||||||
const userAgent = req.headers['user-agent'];
|
|
||||||
if (userAgent.search(/curl|wget/i) !== -1) {
|
|
||||||
res.send(`
|
|
||||||
${style.green.open}Hello Green!${style.green.close}
|
|
||||||
${style.red.open}Hello Red!${style.red.close}
|
|
||||||
`);
|
|
||||||
} else {
|
|
||||||
res.send('Only cURL requests!');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/css/:stylesheet', function (req, res) {
|
|
||||||
res.sendFile(__dirname + '/css/' + req.params.stylesheet);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Game servers
|
|
||||||
app.get('/:type/:host', function (req, res) {
|
|
||||||
if (games[req.params.type] != undefined) {
|
|
||||||
gameQuery(
|
|
||||||
{
|
|
||||||
type: req.params.type,
|
|
||||||
host: req.params.host
|
|
||||||
},
|
|
||||||
function (state) {
|
|
||||||
res.json(state);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
res.json({ "error": "Error: Game type unknown." });
|
|
||||||
}
|
|
||||||
});
|
|
2602
package-lock.json
generated
2602
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "arnweb-api",
|
"name": "arnweb-api",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "API for api.arnweb.nl\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[D\u001b[Don\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[D\u001b[D\u001b[Dapi.arnweb.nl for getting information from various servers and other information about the server.",
|
"description": "API for getting information about services run on ARNweb.nl.",
|
||||||
"main": "index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.js"
|
"start": "node src/index.js",
|
||||||
|
"start:dev": "nodemon src/index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -15,16 +16,21 @@
|
|||||||
"game",
|
"game",
|
||||||
"arnweb"
|
"arnweb"
|
||||||
],
|
],
|
||||||
"author": "McArn",
|
"author": "Arne van Iterson",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^4.2.1",
|
"ansi-styles": "^4.2.1",
|
||||||
|
"colors": "^1.4.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"game-server-query": "^1.0.10",
|
"gamedig": "^2.0.23",
|
||||||
"markdown-it": "^10.0.0",
|
"markdown-it": "^10.0.0",
|
||||||
"os": "^0.1.1",
|
"os": "^0.1.1",
|
||||||
"socket.io": "^2.3.0",
|
"socket.io": "^3.0.1",
|
||||||
"striptags": "^3.1.1",
|
"striptags": "^3.1.1",
|
||||||
"systeminformation": "^4.16.0"
|
"systeminformation": "^4.16.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^7.13.0",
|
||||||
|
"nodemon": "^2.0.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
res/android-chrome-192x192.png
Normal file
BIN
res/android-chrome-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
BIN
res/android-chrome-512x512.png
Normal file
BIN
res/android-chrome-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
res/apple-touch-icon.png
Normal file
BIN
res/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
res/favicon-16x16.png
Normal file
BIN
res/favicon-16x16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 372 B |
BIN
res/favicon-32x32.png
Normal file
BIN
res/favicon-32x32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 650 B |
BIN
res/favicon.ico
Normal file
BIN
res/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
16
res/site.webmanifest
Normal file
16
res/site.webmanifest
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"short_name": "",
|
||||||
|
"icons": [{
|
||||||
|
"src": "/res/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
}, {
|
||||||
|
"src": "/res/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}],
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
116
src/index.js
Normal file
116
src/index.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const app = express();
|
||||||
|
const port = 2428;
|
||||||
|
const server = app.listen(port, () => console.log(`ARNweb API running on port ${port}`));
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
const style = require("ansi-styles");
|
||||||
|
const Gamedig = require("gamedig");
|
||||||
|
|
||||||
|
const io = require("socket.io")(server, {
|
||||||
|
path: "/socket.io"
|
||||||
|
});
|
||||||
|
|
||||||
|
var ns = {
|
||||||
|
chat: io.of("/chat"),
|
||||||
|
tanks: io.of("/tanks")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Request documentation
|
||||||
|
app.get("/", (req, res) =>
|
||||||
|
res.status(200).sendFile(path.resolve(__dirname + "/../html/index.html"))
|
||||||
|
);
|
||||||
|
|
||||||
|
app.get("/css/:stylesheet", function (req, res) {
|
||||||
|
res.status(200).sendFile(path.resolve(__dirname + "/../css/" + req.params.stylesheet));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/res/:icon", function (req, res) {
|
||||||
|
res.status(200).sendFile(path.resolve(__dirname + "/../res/" + req.params.icon));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Socket.io chat server side
|
||||||
|
const chat = require("./services/chat.js");
|
||||||
|
ns.chat.on("connection", function (socket) {
|
||||||
|
chat.handle(ns.chat, socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Chat socket and info
|
||||||
|
app.get("/chat/", function (req, res) {
|
||||||
|
// Server browser
|
||||||
|
res.status(200).json({
|
||||||
|
"status": "online",
|
||||||
|
"query": {
|
||||||
|
"path": req.path,
|
||||||
|
"time": Date.now()
|
||||||
|
},
|
||||||
|
"users": chat.users
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Socket.io tanks server side
|
||||||
|
const tanks = require("./services/tanks.js");
|
||||||
|
ns.tanks.on("connection", function (socket) {
|
||||||
|
tanks.handle(ns.tanks, socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/tanks", function (req, res) {
|
||||||
|
res.status(200).json({
|
||||||
|
"status": "online",
|
||||||
|
"query": {
|
||||||
|
"path": req.path,
|
||||||
|
"time": Date.now()
|
||||||
|
},
|
||||||
|
"players": tanks.players
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// System info
|
||||||
|
const system = require("./services/system.js");
|
||||||
|
app.get("/system/", function (req, res) {
|
||||||
|
system.handle(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// cURL
|
||||||
|
app.get("/curl/", function (req, res) {
|
||||||
|
const userAgent = req.headers["user-agent"];
|
||||||
|
if (userAgent.search(/curl|wget/i) !== -1) {
|
||||||
|
res.status(200).send(`
|
||||||
|
${style.green.open}Hello Green!${style.green.close}
|
||||||
|
${style.red.open}Hello Red!${style.red.close}
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
res.status(400).json({
|
||||||
|
"error": "Error: Only cURL requests."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Game servers
|
||||||
|
app.get("/:type/:host", function (req, res) {
|
||||||
|
var query = {
|
||||||
|
type: req.params.type
|
||||||
|
};
|
||||||
|
|
||||||
|
var host = String(req.params.host).split(":");
|
||||||
|
if (host.length > 1) {
|
||||||
|
query.host = host[0],
|
||||||
|
query.port = host[1];
|
||||||
|
} else {
|
||||||
|
query.host = req.params.host;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gamedig.query(
|
||||||
|
query
|
||||||
|
).then((state) => {
|
||||||
|
res.status(200).json(state);
|
||||||
|
}).catch((error) => {
|
||||||
|
query.path = req.path;
|
||||||
|
query.time = Date.now();
|
||||||
|
res.status(503).json({
|
||||||
|
"error": error.message,
|
||||||
|
"query": query
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
62
src/services/chat.js
Normal file
62
src/services/chat.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
var striptags = require("striptags");
|
||||||
|
var MarkdownIt = require("markdown-it"),
|
||||||
|
md = new MarkdownIt();
|
||||||
|
var users = [];
|
||||||
|
|
||||||
|
// Function for easy server broadcasts
|
||||||
|
function serverMsg(content) {
|
||||||
|
return {
|
||||||
|
"username": "Server",
|
||||||
|
"mailHash": "470965550d3f019830c421f0535d9268",
|
||||||
|
"message": content
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(io, socket) {
|
||||||
|
// Send identification request to client
|
||||||
|
socket.emit("user_identify");
|
||||||
|
|
||||||
|
// Bind username and mailhash to client
|
||||||
|
socket.on("user_login", function (user) {
|
||||||
|
socket.username = user.username;
|
||||||
|
socket.mailHash = user.mailHash;
|
||||||
|
if (users.length > 0) {
|
||||||
|
socket.emit("message_receive", serverMsg(`Hello ${socket.username}, welcome to ARNweb Chat. The following people are currently online: ${users.join(", ")}`));
|
||||||
|
} else {
|
||||||
|
socket.emit("message_receive", serverMsg(`Hello ${socket.username}, welcome to ARNweb Chat. You are the only one here at the moment`));
|
||||||
|
}
|
||||||
|
|
||||||
|
io.emit("message_receive", serverMsg(`${socket.username} has connected`));
|
||||||
|
users.push(socket.username);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send disconnect broadcast to all clients
|
||||||
|
socket.on("disconnect", function () {
|
||||||
|
io.emit("message_receive", serverMsg(`${socket.username} has disconnected`));
|
||||||
|
users.splice(users.indexOf(socket.username), 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle messages
|
||||||
|
socket.on("message_send", function (message) {
|
||||||
|
// Build message data for clients
|
||||||
|
message = striptags(message, "<br />");
|
||||||
|
if (message !== "") {
|
||||||
|
message = md.render(message);
|
||||||
|
message = message.replace(/\r?\n/g, "<br />");
|
||||||
|
var msg = {
|
||||||
|
"username": socket.username,
|
||||||
|
"mailHash": socket.mailHash,
|
||||||
|
"message": message
|
||||||
|
};
|
||||||
|
// Send message to clients
|
||||||
|
io.emit("message_receive", msg);
|
||||||
|
} else {
|
||||||
|
socket.emit("message_receive", serverMsg("Empty messages will not be sent."));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
handle,
|
||||||
|
users
|
||||||
|
};
|
26
src/services/system.js
Normal file
26
src/services/system.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const os = require("os");
|
||||||
|
const si = require("systeminformation");
|
||||||
|
var sysInfo;
|
||||||
|
|
||||||
|
function handle(req, res) {
|
||||||
|
sysInfo = {
|
||||||
|
"hostname": os.hostname(),
|
||||||
|
"type": os.type(),
|
||||||
|
"load": os.loadavg(),
|
||||||
|
"time": si.time()
|
||||||
|
};
|
||||||
|
si.cpuTemperature(function (data) {
|
||||||
|
sysInfo["temp"] = data;
|
||||||
|
});
|
||||||
|
si.mem(function (data) {
|
||||||
|
sysInfo["mem"] = data;
|
||||||
|
});
|
||||||
|
si.fsSize(function (data) {
|
||||||
|
sysInfo["fs"] = data;
|
||||||
|
res.status(200).json(sysInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
handle
|
||||||
|
};
|
130
src/services/tanks.js
Normal file
130
src/services/tanks.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
var colours = require("colors");
|
||||||
|
colours.enable();
|
||||||
|
colours.setTheme({
|
||||||
|
request: "green",
|
||||||
|
connect: "cyan",
|
||||||
|
disconnect: ["red", "dim"],
|
||||||
|
room: ["brightWhite"],
|
||||||
|
data: "grey"
|
||||||
|
});
|
||||||
|
|
||||||
|
const traffic = {
|
||||||
|
in: colours.data("-> "),
|
||||||
|
out: colours.data("<- "),
|
||||||
|
int: colours.data("-- ")
|
||||||
|
};
|
||||||
|
|
||||||
|
var players = {};
|
||||||
|
|
||||||
|
function handle(io, socket) {
|
||||||
|
// Handle disconnection
|
||||||
|
socket.on("disconnect", () => {
|
||||||
|
if (players[socket.id]) {
|
||||||
|
const room = players[socket.id].room;
|
||||||
|
|
||||||
|
var playerUpdate = {};
|
||||||
|
if (io.adapter.rooms[room]) {
|
||||||
|
for (const id in io.adapter.rooms[room].sockets) {
|
||||||
|
playerUpdate[id] = players[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io.in(room).emit("roomUpdate", playerUpdate);
|
||||||
|
|
||||||
|
console.log(traffic.out + colours.disconnect(`User ${String(socket.id)} disconnected from room ${room}`));
|
||||||
|
|
||||||
|
if (io.adapter.rooms.get(room) == undefined) {
|
||||||
|
console.log(traffic.int + colours.room(`Room ${room} has been deleted due to a lack of players`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete players[socket.id];
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(traffic.in + colours.request(`Socket ${String(socket.id)} is trying to connect`));
|
||||||
|
console.log(traffic.out + colours.data(`Requesting identification to client ${String(socket.id)}`));
|
||||||
|
|
||||||
|
// Request identification
|
||||||
|
socket.emit("identify");
|
||||||
|
|
||||||
|
// Wait for identification
|
||||||
|
socket.on("identification", (data) => {
|
||||||
|
console.log(traffic.in + colours.request(`User ${String(socket.id)} playing ${data.gameID} is trying to join a room with ${data.playersMax} players max`));
|
||||||
|
|
||||||
|
// Define room to be joined
|
||||||
|
var join = "";
|
||||||
|
|
||||||
|
// Check if there are any available rooms for the requested game and check if they aren't full
|
||||||
|
io.adapter.rooms.forEach((set, room) => {
|
||||||
|
if (/[0-9]_[0-9].*/i.test(room)) {
|
||||||
|
var roomId = room.split("_");
|
||||||
|
if (roomId[0] == data.gameID) {
|
||||||
|
if (roomId[1] == data.playersMax) {
|
||||||
|
if (io.adapter.rooms.get(room).size < data.playersMax) {
|
||||||
|
join += room;
|
||||||
|
} else {
|
||||||
|
console.log(traffic.int + colours.room(`Room ${room} is full, skipping.`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// If no available room is found, make one
|
||||||
|
if (join == "") {
|
||||||
|
var count = 0;
|
||||||
|
var regex = new RegExp(data.gameID + "_" + data.playersMax + "_[0-9].*");
|
||||||
|
io.adapter.rooms.forEach((set, room) => {
|
||||||
|
if (regex.test(room)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
join = data.gameID + "_" + data.playersMax + "_" + count;
|
||||||
|
console.log(traffic.int + colours.room(`There is no room available for the requested game, making room ${join}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.join(join);
|
||||||
|
|
||||||
|
// Start game if the max number of players is reached
|
||||||
|
if (io.adapter.rooms.get(join).size == data.playersMax) {
|
||||||
|
console.log(traffic.int + colours.room(`Room ${join} has reached the maximum amount of players, starting game`));
|
||||||
|
io.in(join).emit("gameStart");
|
||||||
|
}
|
||||||
|
|
||||||
|
players[socket.id] = {
|
||||||
|
username: data.name,
|
||||||
|
room: join
|
||||||
|
};
|
||||||
|
|
||||||
|
var playerUpdate = {};
|
||||||
|
io.adapter.rooms.get(join).forEach((id) => {
|
||||||
|
playerUpdate[id] = players[id];
|
||||||
|
});
|
||||||
|
|
||||||
|
io.in(join).emit("roomUpdate", playerUpdate);
|
||||||
|
|
||||||
|
console.log(traffic.in + colours.connect(`User ${String(socket.id)} connected to room ${join}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("update", (data) => {
|
||||||
|
if (players[socket.id]) {
|
||||||
|
socket.to(players[socket.id].room).emit("update", {
|
||||||
|
uuid: socket.id,
|
||||||
|
player: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("spectate", (data) => {
|
||||||
|
if (io.adapter.rooms.has(data)) {
|
||||||
|
console.log(traffic.in + colours.connect(`User ${String(socket.id)} is spectating room ${data}`));
|
||||||
|
socket.join(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
handle,
|
||||||
|
players
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user