First commit
This commit is contained in:
commit
5d1bb2ce58
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
103
css/styles.css
Normal file
103
css/styles.css
Normal 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
9
css/styles.css.map
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "AAAA,AAAA,IAAI,CAAC;EACD,WAAW,EAAE,+CAA+C;CAkF/D;;AAnFD,AAEI,IAFA,CAEA,GAAG,AAAA,cAAc,CAAC;EACd,WAAW,EAAE,iCAAiC;EAC9C,UAAU,EAAE,MAAM;CAMrB;;AAVL,AAKQ,IALJ,CAEA,GAAG,AAAA,cAAc,CAGb,EAAE,CAAC;EACC,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,OAAO;EACpB,MAAM,EAAE,IAAI;CACf;;AATT,AAYI,IAZA,CAYA,IAAI,AAAA,aAAa,CAAC;EACd,KAAK,EAAE,OAAO;EACd,SAAS,EAAE,KAAK;EAChB,MAAM,EAAE,QAAQ;EAChB,QAAQ,EAAE,QAAQ;EAClB,OAAO,EAAE,KAAK;EACd,OAAO,EAAE,GAAG;EACZ,aAAa,EAAE,GAAG;CAuCrB;;AA1DL,AAoBQ,IApBJ,CAYA,IAAI,AAAA,aAAa,CAQb,IAAI,CAAC;EACD,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,KAAK;CACf;;AAvBT,AAwBQ,IAxBJ,CAYA,IAAI,AAAA,aAAa,CAYb,CAAC,CAAC;EACE,KAAK,EAAE,KAAK;EACZ,eAAe,EAAE,SAAS;CAC7B;;AA3BT,AA4BQ,IA5BJ,CAYA,IAAI,AAAA,aAAa,CAgBb,IAAI,AAAA,YAAY,CAAC;EACb,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,YAAY;EACrB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,WAAW,EAAE,GAAG;EAChB,UAAU,EAAE,MAAM;CACrB;;AApCT,AAqCQ,IArCJ,CAYA,IAAI,AAAA,aAAa,CAyBb,IAAI,AAAA,YAAY,AAAA,IAAI,CAAC;EACjB,gBAAgB,EAAE,OAAO;CAC5B;;AAvCT,AAwCQ,IAxCJ,CAYA,IAAI,AAAA,aAAa,CA4Bb,IAAI,AAAA,YAAY,AAAA,KAAK,CAAC;EAClB,gBAAgB,EAAE,OAAO;CAC5B;;AA1CT,AA2CQ,IA3CJ,CAYA,IAAI,AAAA,aAAa,CA+Bb,IAAI,AAAA,YAAY,AAAA,OAAO,CAAC;EACpB,gBAAgB,EAAE,OAAO;CAC5B;;AA7CT,AA8CQ,IA9CJ,CAYA,IAAI,AAAA,aAAa,CAkCb,IAAI,AAAA,YAAY,AAAA,IAAI,CAAC;EACjB,gBAAgB,EAAE,OAAO;CAC5B;;AAhDT,AAiDQ,IAjDJ,CAYA,IAAI,AAAA,aAAa,CAqCb,IAAI,AAAA,YAAY,AAAA,MAAM,CAAC;EACnB,gBAAgB,EAAE,OAAO;CAC5B;;AAnDT,AAoDQ,IApDJ,CAYA,IAAI,AAAA,aAAa,CAwCb,IAAI,AAAA,YAAY,AAAA,OAAO,CAAC;EACpB,gBAAgB,EAAE,OAAO;CAC5B;;AAtDT,AAuDQ,IAvDJ,CAYA,IAAI,AAAA,aAAa,CA2Cb,GAAG,CAAC;EACA,WAAW,EAAE,GAAG;CACnB;;AAzDT,AA2DI,IA3DA,CA2DA,IAAI,AAAA,aAAa,AAAA,IAAI,CAAC;EAClB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,uBAAmB;CACxC;;AA9DL,AA+DI,IA/DA,CA+DA,IAAI,AAAA,aAAa,AAAA,KAAK,CAAC;EACnB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,uBAAmB;CACxC;;AAlEL,AAmEI,IAnEA,CAmEA,IAAI,AAAA,aAAa,AAAA,MAAM,CAAC;EACpB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,uBAAmB;CACxC;;AAtEL,AAuEI,IAvEA,CAuEA,IAAI,AAAA,aAAa,AAAA,OAAO,CAAC;EACrB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,sBAAkB;CACvC;;AA1EL,AA2EI,IA3EA,CA2EA,IAAI,AAAA,aAAa,AAAA,IAAI,CAAC;EAClB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,uBAAmB;CACxC;;AA9EL,AA+EI,IA/EA,CA+EA,IAAI,AAAA,aAAa,AAAA,OAAO,CAAC;EACrB,MAAM,EAAE,iBAAiB;EACzB,gBAAgB,EAAE,qBAAoB;CACzC",
|
||||||
|
"sources": [
|
||||||
|
"styles.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "styles.css"
|
||||||
|
}
|
84
css/styles.scss
Normal file
84
css/styles.scss
Normal 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
49
index.html
Normal 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
128
index.js
Normal 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
1114
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
package.json
Normal file
29
package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user