forked from MrGeorgen/2smart2wait
Initial commit
This commit is contained in:
64
src/.gitignore
vendored
Normal file
64
src/.gitignore
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
#secrets
|
||||
../secrets.json
|
||||
40
src/index.css
Normal file
40
src/index.css
Normal file
@ -0,0 +1,40 @@
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: rgb(16, 16, 26);
|
||||
}
|
||||
|
||||
h1, .content {
|
||||
margin: 0;
|
||||
color: rgb(228, 228, 228);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 128px;
|
||||
height: 32px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
font-family: sans-serif;
|
||||
border-radius: 5px;
|
||||
color: #e4e4e4;
|
||||
transition-duration: 0.3s;
|
||||
}
|
||||
|
||||
button.start {
|
||||
border: 3px solid #25c525;
|
||||
}
|
||||
|
||||
button.stop {
|
||||
border: 2px solid #f32727;
|
||||
}
|
||||
|
||||
.place, .ETA{
|
||||
display: inline-block;
|
||||
}
|
||||
75
src/index.html
Normal file
75
src/index.html
Normal file
@ -0,0 +1,75 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>2Bored2Wait</title>
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<h1>Place in queue: <div class="place">None</div> </h1>
|
||||
<h1>ETA: <div class="ETA">None</div> </h1>
|
||||
Password (leave blank if none) : <input type="password" class="password"><br>
|
||||
<button id="queueButton" class="start" onclick="start()">Start queuing</button><br><br>
|
||||
<input type="checkbox" class="restartQueue" onchange="toggleRestartQueue()"> Restart the queue if you're not connected at the end of it?
|
||||
</div>
|
||||
<script>
|
||||
setInterval(() => { //each second, update the info.
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/update", true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
const response = JSON.parse(this.responseText);
|
||||
document.getElementsByClassName("place")[0].innerHTML = response.place;
|
||||
document.getElementsByClassName("ETA")[0].innerHTML = response.ETA;
|
||||
document.getElementsByClassName("restartQueue")[0].checked = response.restartQueue
|
||||
const queueButton = document.getElementById('queueButton');
|
||||
if(response.inQueue){
|
||||
queueButton.innerHTML = "Stop queuing";
|
||||
queueButton.setAttribute('onclick', 'stop()');
|
||||
queueButton.className = 'stop';
|
||||
}else{
|
||||
queueButton.innerHTML = "Start queuing";
|
||||
queueButton.setAttribute('onclick', 'start()');
|
||||
queueButton.className = 'start';
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.setRequestHeader('XPassword', document.getElementsByClassName('password')[0].value)
|
||||
xhr.send();
|
||||
|
||||
}, 1000);
|
||||
|
||||
function start() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/start", true);
|
||||
xhr.setRequestHeader('XPassword', document.getElementsByClassName('password')[0].value)
|
||||
xhr.send();
|
||||
const queueButton = document.getElementById('queueButton');
|
||||
queueButton.innerHTML = "Stop queuing";
|
||||
queueButton.setAttribute('onclick', 'stop()');
|
||||
queueButton.setAttribute('onclick', 'stop()');
|
||||
queueButton.className = 'stop';
|
||||
}
|
||||
|
||||
function stop() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/stop", true);
|
||||
xhr.setRequestHeader('XPassword', document.getElementsByClassName('password')[0].value)
|
||||
xhr.send();
|
||||
const queueButton = document.getElementById('queueButton');
|
||||
queueButton.innerHTML = "Start queuing";
|
||||
queueButton.setAttribute('onclick', 'start()');
|
||||
queueButton.className = 'start';
|
||||
document.getElementsByClassName("place")[0].innerHTML = 'None';
|
||||
document.getElementsByClassName("ETA")[0].innerHTML = 'None';
|
||||
}
|
||||
|
||||
function toggleRestartQueue(){
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/togglerestart", true);
|
||||
xhr.setRequestHeader('XPassword', document.getElementsByClassName('password')[0].value)
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
50
src/json.minify.js
Normal file
50
src/json.minify.js
Normal file
@ -0,0 +1,50 @@
|
||||
module.exports = function(json) {
|
||||
|
||||
var tokenizer = /"|(\/\*)|(\*\/)|(\/\/)|\n|\r/g,
|
||||
in_string = false,
|
||||
in_multiline_comment = false,
|
||||
in_singleline_comment = false,
|
||||
tmp, tmp2, new_str = [], ns = 0, from = 0, lc, rc
|
||||
;
|
||||
|
||||
tokenizer.lastIndex = 0;
|
||||
|
||||
while (tmp = tokenizer.exec(json)) {
|
||||
lc = RegExp.leftContext;
|
||||
rc = RegExp.rightContext;
|
||||
if (!in_multiline_comment && !in_singleline_comment) {
|
||||
tmp2 = lc.substring(from);
|
||||
if (!in_string) {
|
||||
tmp2 = tmp2.replace(/(\n|\r|\s)*/g,"");
|
||||
}
|
||||
new_str[ns++] = tmp2;
|
||||
}
|
||||
from = tokenizer.lastIndex;
|
||||
|
||||
if (tmp[0] == "\"" && !in_multiline_comment && !in_singleline_comment) {
|
||||
tmp2 = lc.match(/(\\)*$/);
|
||||
if (!in_string || !tmp2 || (tmp2[0].length % 2) == 0) { // start of string with ", or unescaped " character found to end string
|
||||
in_string = !in_string;
|
||||
}
|
||||
from--; // include " character in next catch
|
||||
rc = json.substring(from);
|
||||
}
|
||||
else if (tmp[0] == "/*" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
||||
in_multiline_comment = true;
|
||||
}
|
||||
else if (tmp[0] == "*/" && !in_string && in_multiline_comment && !in_singleline_comment) {
|
||||
in_multiline_comment = false;
|
||||
}
|
||||
else if (tmp[0] == "//" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
||||
in_singleline_comment = true;
|
||||
}
|
||||
else if ((tmp[0] == "\n" || tmp[0] == "\r") && !in_string && !in_multiline_comment && in_singleline_comment) {
|
||||
in_singleline_comment = false;
|
||||
}
|
||||
else if (!in_multiline_comment && !in_singleline_comment && !(/\n|\r|\s/.test(tmp[0]))) {
|
||||
new_str[ns++] = tmp[0];
|
||||
}
|
||||
}
|
||||
new_str[ns++] = rc;
|
||||
return new_str.join("");
|
||||
};
|
||||
411
src/main.js
Normal file
411
src/main.js
Normal file
@ -0,0 +1,411 @@
|
||||
// imports
|
||||
const jsonminify = require("./json.minify.js"); // to remove comments from the config.json, because normally comments in json are not allowed
|
||||
const fs = require('fs');
|
||||
const mc = require('minecraft-protocol'); // to handle minecraft login session
|
||||
const webserver = require('./webserver.js'); // to serve the webserver
|
||||
const opn = require('opn'); //to open a browser window
|
||||
const secrets = require('../secrets.json'); // read the creds
|
||||
const config = JSON.parse(jsonminify(fs.readFileSync("../config.json", "utf8"))); // read the config
|
||||
const discord = require('discord.js');
|
||||
const {DateTime} = require("luxon");
|
||||
const https = require("https");
|
||||
const prompt = require("prompt");
|
||||
const ping = require('minecraft-server-util');
|
||||
const sleep = require("sleep-ms")
|
||||
var timedStart;
|
||||
var lastQueuePlace;
|
||||
var queueData;
|
||||
var secRun;
|
||||
var chunkData = [];
|
||||
var c = 0;
|
||||
webserver.restartQueue = config.reconnect.notConnectedQueueEnd;
|
||||
prioQueueLength();
|
||||
if (config.webserver) {
|
||||
webserver.createServer(config.ports.web); // create the webserver
|
||||
webserver.password = config.password
|
||||
}
|
||||
webserver.onstart(() => { // set up actions for the webserver
|
||||
startQueuing();
|
||||
});
|
||||
webserver.onstop(() => {
|
||||
stop();
|
||||
});
|
||||
|
||||
if (config.openBrowserOnStart && config.webserver) {
|
||||
opn('http://localhost:' + config.ports.web); //open a browser window
|
||||
}
|
||||
// lets
|
||||
var proxyClient; // a reference to the client that is the actual minecraft game
|
||||
let client; // the client to connect to 2b2t
|
||||
let server; // the minecraft server to pass packets
|
||||
|
||||
//comand prompt
|
||||
prompt.start();
|
||||
|
||||
function cmdInput() {
|
||||
prompt.get("cmd", function (err, result) {
|
||||
userInput(result.cmd, false);
|
||||
cmdInput()
|
||||
});
|
||||
}
|
||||
|
||||
// function to disconnect from the server
|
||||
function stop() {
|
||||
webserver.isInQueue = false;
|
||||
webserver.queuePlace = "None";
|
||||
webserver.ETA = "None";
|
||||
client.end(); // disconnect
|
||||
if (proxyClient) {
|
||||
proxyClient.end("Stopped the proxy."); // boot the player from the server
|
||||
}
|
||||
server.close(); // close the server
|
||||
dc.user.setActivity("Queue is stopped.");
|
||||
}
|
||||
|
||||
// function to start the whole thing
|
||||
function startQueuing() {
|
||||
var playerid;
|
||||
let startTime = DateTime.local();
|
||||
webserver.isInQueue = true;
|
||||
dc.user.setActivity("Starting the queue...");
|
||||
client = mc.createClient({ // connect to 2b2t
|
||||
host: config.minecraftserver.hostname,
|
||||
port: config.minecraftserver.port,
|
||||
username: secrets.username,
|
||||
password: secrets.password,
|
||||
version: config.minecraftserver.version
|
||||
});
|
||||
let finishedQueue = false;
|
||||
client.on("packet", (data, meta) => { // each time 2b2t sends a packet
|
||||
if (meta.name === "map_chunk") {
|
||||
chunkData.push(data);
|
||||
}
|
||||
if (!finishedQueue && meta.name === "playerlist_header" && config.minecraftserver.hostname === "2b2t.org") { // if the packet contains the player list, we can use it to see our place in the queue
|
||||
let headermessage = JSON.parse(data.header);
|
||||
let positioninqueue = headermessage.text.split("\n")[5].substring(25);
|
||||
let ETA = headermessage.text.split("\n")[6].substring(27);
|
||||
webserver.queuePlace = positioninqueue; // update info on the web page
|
||||
webserver.ETA = ETA;
|
||||
server.motd = `Place in queue: ${positioninqueue}`; // set the MOTD because why not
|
||||
if (webserver.queuePlace != "None") dc.user.setActivity("Pos: " + webserver.queuePlace + " ETA: " + webserver.ETA); //set the Discord Activity
|
||||
if (lastQueuePlace != webserver.queuePlace) {
|
||||
log("Position in Queue: " + webserver.queuePlace)
|
||||
}
|
||||
lastQueuePlace = webserver.queuePlace;
|
||||
}
|
||||
if (meta.name === "login") {
|
||||
playerid = data.entityId;
|
||||
}
|
||||
if (finishedQueue === false && meta.name === "chat") { // we can know if we're about to finish the queue by reading the chat message
|
||||
// we need to know if we finished the queue otherwise we crash when we're done, because the queue info is no longer in packets the server sends us.
|
||||
let chatMessage = JSON.parse(data.message);
|
||||
if (chatMessage.text && chatMessage.text === "Connecting to the server...") {
|
||||
if (webserver.restartQueue && proxyClient == null) { //if we have no client connected and we should restart
|
||||
stop();
|
||||
setTimeout(reconnect, 4000);
|
||||
} else {
|
||||
finishedQueue = true;
|
||||
webserver.queuePlace = "FINISHED";
|
||||
webserver.ETA = "NOW";
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (c<50) {
|
||||
console.log("meta: " + JSON.stringify(meta) + "\ndata: " + JSON.stringify(data));
|
||||
c++;
|
||||
}*/
|
||||
if (proxyClient) { // if we are connected to the proxy, forward the packet we recieved to our game.
|
||||
filterPacketAndSend(data, meta, proxyClient);
|
||||
}
|
||||
});
|
||||
|
||||
// set up actions in case we get disconnected.
|
||||
client.on('end', () => {
|
||||
if (proxyClient) {
|
||||
proxyClient.end("Connection reset by 2b2t server.\nReconnecting...");
|
||||
proxyClient = null
|
||||
}
|
||||
stop();
|
||||
log("Connection reset by 2b2t server. Reconnecting...");
|
||||
if (config.reconnect.onError) setTimeout(reconnect, 4000);
|
||||
});
|
||||
|
||||
client.on('error', (err) => {
|
||||
if (proxyClient) {
|
||||
proxyClient.end(`Connection error by 2b2t server.\n Error message: ${err}\nReconnecting...`);
|
||||
proxyClient = null
|
||||
}
|
||||
stop();
|
||||
log(`Connection error by 2b2t server. Error message: ${err} Reconnecting...`);
|
||||
if (config.reconnect.onError) setTimeout(reconnect, 4000);
|
||||
});
|
||||
|
||||
server = mc.createServer({ // create a server for us to connect to
|
||||
'online-mode': false,
|
||||
encryption: true,
|
||||
host: '0.0.0.0',
|
||||
port: config.ports.minecraft,
|
||||
version: config.MCversion,
|
||||
'max-players': maxPlayers = 1
|
||||
});
|
||||
|
||||
server.on('login', (newProxyClient) => { // handle login
|
||||
setTimeout(send, 50)
|
||||
newProxyClient.write('login', {
|
||||
entityId: playerid,
|
||||
levelType: 'default',
|
||||
gameMode: 0,
|
||||
dimension: 0,
|
||||
difficulty: 2,
|
||||
maxPlayers: server.maxPlayers,
|
||||
reducedDebugInfo: false
|
||||
});
|
||||
newProxyClient.write('position', {
|
||||
x: 0,
|
||||
y: 1.62,
|
||||
z: 0,
|
||||
yaw: 0,
|
||||
pitch: 0,
|
||||
flags: 0x00
|
||||
});
|
||||
|
||||
newProxyClient.on('packet', (data, meta) => { // redirect everything we do to 2b2t
|
||||
let chunkPos = {};
|
||||
if (meta.name === "position") {
|
||||
chunkPos.x = roundToZero(data.x / 16);
|
||||
chunkPos.z = roundToZero(data.z / 16);
|
||||
if (chunkPos.z !== chunkPos.lx || chunkPos.x !== chunkPos.lx) {
|
||||
|
||||
for (let i = 0; i < chunkData.length; i++) {
|
||||
if (chunkData[i].x < chunkPos.x - 10 || chunkData[i].x > chunkPos + 10 || chunkData[i].z < chunkPos.z - 10 || chunkData[i] > chunkPos.z + 10) { //if a cached chunk is outside of the render distance
|
||||
chunkData.splice(i, 1); // we delete it.
|
||||
}
|
||||
}
|
||||
}
|
||||
chunkPos.lx = chunkPos.x;
|
||||
chunkPos.lz = chunkPos.z;
|
||||
}
|
||||
filterPacketAndSend(data, meta, client);
|
||||
//console.log("meta: " + JSON.stringify(meta) + "\ndata: " + JSON.stringify(data))
|
||||
});
|
||||
|
||||
proxyClient = newProxyClient;
|
||||
});
|
||||
}
|
||||
|
||||
function send() {
|
||||
for (let i = 0; i < chunkData.length; i++) {
|
||||
proxyClient.write("map_chunk", chunkData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function log(logmsg) {
|
||||
if (config.logging) fs.appendFile('../2smart2wait.log', DateTime.local().toLocaleString({
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
}) + " " + logmsg + "\n", err => {
|
||||
if (err) console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
function reconnect() {
|
||||
ping(config.minecraftserver.hostname, config.minecraftserver.port)
|
||||
.then((response) => {
|
||||
startQueuing();
|
||||
})
|
||||
.catch((error) => {
|
||||
reconnect();
|
||||
});
|
||||
}
|
||||
|
||||
function prioQueueLength() {
|
||||
https.get("https://api.2b2t.dev/prioq", (resp) => {
|
||||
let qdata = '';
|
||||
resp.on('data', (chunk) => {
|
||||
qdata += chunk;
|
||||
});
|
||||
resp.on("end", () => {
|
||||
queueData = JSON.parse(qdata);
|
||||
secRun = true;
|
||||
})
|
||||
}).on("error", (err) => {
|
||||
log("prioQueue api error: " + err)
|
||||
});
|
||||
if (secRun) return queueData[1];
|
||||
}
|
||||
|
||||
//function to filter out some packets that would make us disconnect otherwise.
|
||||
//this is where you could filter out packets with sign data to prevent chunk bans.
|
||||
function filterPacketAndSend(data, meta, dest) {
|
||||
if (meta.name !== "keep_alive" && meta.name !== "update_time") { //keep alive packets are handled by the client we created, so if we were to forward them, the minecraft client would respond too and the server would kick us for responding twice.
|
||||
dest.write(meta.name, data);
|
||||
}
|
||||
}
|
||||
|
||||
function roundToZero(number) {
|
||||
if (number < 0) return Math.ceil(number);
|
||||
else return Math.floor(number);
|
||||
}
|
||||
|
||||
//the discordBot part starts here.
|
||||
if (config.discordBot) {
|
||||
var dc = new discord.Client()
|
||||
dc.on('ready', () => {
|
||||
dc.user.setActivity("Queue is stopped.");
|
||||
cmdInput();
|
||||
});
|
||||
|
||||
dc.on('message', msg => {
|
||||
if (msg.author.username !== dc.user.username) {
|
||||
userInput(msg.content, true, msg);
|
||||
}
|
||||
});
|
||||
dc.login(secrets.BotToken);
|
||||
}
|
||||
|
||||
function userInput(cmd, DiscordOrigin, discordMsg) {
|
||||
switch (cmd) {
|
||||
case "start":
|
||||
startQueuing();
|
||||
if (DiscordOrigin) discordMsg.channel.send({
|
||||
embed: {
|
||||
color: 3447003,
|
||||
author: {
|
||||
name: dc.user.username,
|
||||
icon_url: dc.user.avatarURL
|
||||
},
|
||||
fields: [{
|
||||
name: "Queue",
|
||||
value: `Queue is starting up.`
|
||||
}
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
icon_url: dc.user.avatarURL,
|
||||
text: "Author: Surprisejedi"
|
||||
}
|
||||
}
|
||||
});
|
||||
else console.log("Queue is starting up.")
|
||||
break;
|
||||
case "update":
|
||||
if (DiscordOrigin) discordMsg.channel.send({
|
||||
embed: {
|
||||
color: 3447003,
|
||||
author: {
|
||||
name: dc.user.username,
|
||||
icon_url: dc.user.avatarURL
|
||||
},
|
||||
title: "2bored2wait discord bridge",
|
||||
description: "Start and stop the queue from discord!",
|
||||
fields: [{
|
||||
name: "Position",
|
||||
value: `You are in position **${webserver.queuePlace}**.`
|
||||
},
|
||||
{
|
||||
name: "ETA",
|
||||
value: `Estimated time until login: **${webserver.ETA}**`
|
||||
}
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
icon_url: dc.user.avatarURL,
|
||||
text: "Author: Surprisejedi"
|
||||
}
|
||||
}
|
||||
});
|
||||
else console.log("Position: " + webserver.queuePlace + " Estimated time until login: " + webserver.ETA)
|
||||
break;
|
||||
case "stop":
|
||||
if (webserver.isInQueue) {
|
||||
stop();
|
||||
if (DiscordOrigin) discordMsg.channel.send({
|
||||
embed: {
|
||||
color: 3447003,
|
||||
author: {
|
||||
name: dc.user.username,
|
||||
icon_url: dc.user.avatarURL
|
||||
},
|
||||
fields: [{
|
||||
name: "Queue",
|
||||
value: `Queue is **stopped**.`
|
||||
}
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
icon_url: dc.user.avatarURL,
|
||||
text: "Author: Surprisejedi"
|
||||
}
|
||||
}
|
||||
});
|
||||
else console.log("Queue is stopped")
|
||||
} else {
|
||||
clearTimeout(timedStart);
|
||||
if (DiscordOrigin) discordMsg.channel.send({
|
||||
embed: {
|
||||
color: 3447003,
|
||||
author: {
|
||||
name: dc.user.username,
|
||||
icon_url: dc.user.avatarURL
|
||||
},
|
||||
fields: [{
|
||||
name: "Queue",
|
||||
value: `Queue timer is **stopped**.`
|
||||
}
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
icon_url: dc.user.avatarURL,
|
||||
text: "Author: MrGeorgen"
|
||||
}
|
||||
}
|
||||
});
|
||||
else console.log("Queue timer is stopped")
|
||||
}
|
||||
break;
|
||||
default:
|
||||
let startregex = /^start (\d|[0-1]\d|2[0-3]):[0-5]\d$/
|
||||
if (startregex.test(cmd)) {
|
||||
let starttimestring = msg.content.split(" ");
|
||||
let starttime = starttimestring[1].split(":");
|
||||
let currentTime = DateTime.local();
|
||||
let startdt = currentTime.set({hour: starttime[0], minute: starttime[1]});
|
||||
if (startdt.toMillis() < currentTime.toMillis()) sartdt = startdt.plus({days: 1});
|
||||
timedStart = setTimeout(startQueuing, startdt.toMillis() - currentTime.toMillis());
|
||||
dc.user.setActivity("Starting at " + starttimestring[1]);
|
||||
discordMsg.channel.send({
|
||||
embed: {
|
||||
color: 3447003,
|
||||
author: {
|
||||
name: dc.user.username,
|
||||
icon_url: dc.user.avatarURL
|
||||
},
|
||||
fields: [{
|
||||
name: "Queue",
|
||||
value: `Queue is starting at ` + starttimestring[1]
|
||||
}
|
||||
],
|
||||
timestamp: new Date(),
|
||||
footer: {
|
||||
icon_url: dc.user.avatarURL,
|
||||
text: "Author: MrGeorgen"
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (DiscordOrigin) discordMsg.channel.send("Error: Unknown command");
|
||||
else console.error("Unknown command")
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
startQueue: function () {
|
||||
startQueuing();
|
||||
},
|
||||
filterPacketAndSend: function () {
|
||||
filterPacketAndSend();
|
||||
},
|
||||
stop: function () {
|
||||
stop();
|
||||
}
|
||||
};
|
||||
55
src/webserver.js
Normal file
55
src/webserver.js
Normal file
@ -0,0 +1,55 @@
|
||||
//this module exposes functions and variables to control the HTTP server.
|
||||
const http = require('http'); //to serve the pages
|
||||
const fs = require('fs'); //to read the webpages from disk
|
||||
|
||||
module.exports = {
|
||||
createServer : (port) => {
|
||||
http.createServer((req, res) => {
|
||||
if (req.url === "/") { //main page of the web app
|
||||
res.writeHead(200, {'Content-type': 'text/html'});
|
||||
res.write(fs.readFileSync('index.html'));
|
||||
res.end();
|
||||
} else if(req.url === "/index.css") { //css file to make it not look like too much shit
|
||||
res.writeHead(200, {'Content-type': 'text/css'});
|
||||
res.write(fs.readFileSync('index.css'));
|
||||
res.end();
|
||||
} else if (module.exports.password == "" || req.headers.xpassword == module.exports.password) { //before doing any action, test if the provided password is correct.
|
||||
if(req.url === "/update") { //API endpoint to get position, ETA, and status in JSON format
|
||||
res.writeHead(200, {'Content-type': 'text/json'});
|
||||
res.write("{\"username\": \""+ module.exports.username +"\",\"place\": \""+ module.exports.queuePlace +"\",\"ETA\": \""+ module.exports.ETA +"\", \"inQueue\": " + module.exports.isInQueue+", \"restartQueue\":"+ module.exports.restartQueue+"}")
|
||||
res.end();
|
||||
} else if(req.url === "/start") { //API endpoint to start queuing
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
module.exports.onstartcallback();
|
||||
} else if(req.url === "/stop") { //API endpoint to stop queuing
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
module.exports.onstopcallback();
|
||||
} else if(req.url === "/togglerestart"){
|
||||
module.exports.restartQueue = !module.exports.restartQueue
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}
|
||||
}else{
|
||||
res.writeHead(403);
|
||||
res.end()
|
||||
}
|
||||
}).listen(port);
|
||||
},
|
||||
onstart: (callback) => { //function to set the action to do when starting
|
||||
module.exports.onstartcallback = callback;
|
||||
},
|
||||
onstop: (callback) => { //same but to stop
|
||||
module.exports.onstopcallback = callback;
|
||||
},
|
||||
queuePlace : "None", //our place in queue
|
||||
ETA: "None", //ETA
|
||||
isInQueue: false, //are we in queue?
|
||||
onstartcallback: null, //a save of the action to start
|
||||
onstopcallback: null, //same but to stop
|
||||
restartQueue: false, //when at the end of the queue, restart if no client is connected?
|
||||
password: "" //the password to use for the webapp
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user