First commit

This commit is contained in:
Arne van Iterson 2019-12-31 15:52:52 +01:00
commit 5d1bb2ce58
8 changed files with 1517 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

103
css/styles.css Normal file
View File

@ -0,0 +1,103 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body div:first-of-type {
font-family: 'Courier New', Courier, monospace;
text-align: center;
}
body div:first-of-type h1 {
font-size: 64px;
font-weight: lighter;
margin: 10px;
}
body span.apiReference {
color: #3b4151;
max-width: 750px;
margin: 1em auto;
position: relative;
display: block;
padding: 5px;
border-radius: 3px;
}
body span.apiReference code {
font-size: 1.1em;
color: black;
}
body span.apiReference a {
color: unset;
text-decoration: underline;
}
body span.apiReference span.requestType {
color: white;
display: inline-block;
padding: 5px 15px 5px 15px;
margin: 6px;
border-radius: 3px;
font-weight: 600;
text-align: center;
}
body span.apiReference span.requestType.get {
background-color: #61affe;
}
body span.apiReference span.requestType.post {
background-color: #49cc90;
}
body span.apiReference span.requestType.delete {
background-color: #f93e3e;
}
body span.apiReference span.requestType.put {
background-color: #fca130;
}
body span.apiReference span.requestType.patch {
background-color: #50e3c2;
}
body span.apiReference span.requestType.socket {
background-color: #403d58;
}
body span.apiReference div {
margin-left: 5px;
}
body span.apiReference.get {
border: 1px solid #61affe;
background-color: rgba(97, 175, 254, 0.1);
}
body span.apiReference.post {
border: 1px solid #49cc90;
background-color: rgba(73, 204, 144, 0.1);
}
body span.apiReference.patch {
border: 1px solid #50e3c2;
background-color: rgba(80, 227, 194, 0.1);
}
body span.apiReference.delete {
border: 1px solid #f93e3e;
background-color: rgba(249, 62, 62, 0.1);
}
body span.apiReference.put {
border: 1px solid #fca130;
background-color: rgba(252, 161, 48, 0.1);
}
body span.apiReference.socket {
border: 1px solid #403d58;
background-color: rgba(64, 61, 88, 0.1);
}
/*# sourceMappingURL=styles.css.map */

9
css/styles.css.map Normal file
View File

@ -0,0 +1,9 @@
{
"version": 3,
"mappings": "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",
"sources": [
"styles.scss"
],
"names": [],
"file": "styles.css"
}

84
css/styles.scss Normal file
View File

@ -0,0 +1,84 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
div:first-of-type {
font-family: 'Courier New', Courier, monospace;
text-align: center;
h1 {
font-size: 64px;
font-weight: lighter;
margin: 10px;
}
}
span.apiReference {
color: #3b4151;
max-width: 750px;
margin: 1em auto;
position: relative;
display: block;
padding: 5px;
border-radius: 3px;
code {
font-size: 1.1em;
color: black;
}
a {
color: unset;
text-decoration: underline;
}
span.requestType {
color: white;
display: inline-block;
padding: 5px 15px 5px 15px;
margin: 6px;
border-radius: 3px;
font-weight: 600;
text-align: center;
}
span.requestType.get {
background-color: #61affe;
}
span.requestType.post {
background-color: #49cc90;
}
span.requestType.delete {
background-color: #f93e3e;
}
span.requestType.put {
background-color: #fca130;
}
span.requestType.patch {
background-color: #50e3c2;
}
span.requestType.socket {
background-color: #403d58;
}
div {
margin-left: 5px;
}
}
span.apiReference.get {
border: 1px solid #61affe;
background-color: rgba(97,175,254,.1);
}
span.apiReference.post {
border: 1px solid #49cc90;
background-color: rgba(73,204,144,.1);
}
span.apiReference.patch {
border: 1px solid #50e3c2;
background-color: rgba(80,227,194,.1);
}
span.apiReference.delete {
border: 1px solid #f93e3e;
background-color: rgba(249,62,62,.1);
}
span.apiReference.put {
border: 1px solid #fca130;
background-color: rgba(252,161,48,.1);
}
span.apiReference.socket {
border: 1px solid #403d58;
background-color: rgba(64, 61, 88, .1);
}
}

49
index.html Normal file
View File

@ -0,0 +1,49 @@
<!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 socket">
<span class="requestType socket">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>
</body>
</html>

128
index.js Normal file
View File

@ -0,0 +1,128 @@
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 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;
res.json(sysInfo);
});
});
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." });
}
});

1114
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "arnweb-api",
"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.",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"repository": {
"type": "git",
"url": "https://gitea.arnweb.nl/arne/arnweb-api/"
},
"keywords": [
"api",
"game",
"arnweb"
],
"author": "McArn",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"game-server-query": "^1.0.10",
"markdown-it": "^10.0.0",
"os": "^0.1.1",
"socket.io": "^2.3.0",
"striptags": "^3.1.1",
"systeminformation": "^4.16.0"
}
}