Reorganized structure of code

This commit is contained in:
seefo
2019-03-15 14:29:34 -04:00
parent 5e1e4f5de3
commit f9fff8aa82
21 changed files with 794 additions and 330 deletions

4
.idea/encodings.xml generated Executable file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

6
.idea/misc.xml generated Executable file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

8
.idea/modules.xml generated Executable file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/site.iml" filepath="$PROJECT_DIR$/.idea/site.iml" />
</modules>
</component>
</project>

12
.idea/site.iml generated Executable file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml generated Executable file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

393
.idea/workspace.xml generated Executable file
View File

@@ -0,0 +1,393 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="abd1a00f-a3c0-4242-8b34-68d3f50e7fe2" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/api/auth.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/createUser.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/sendMetrics.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/modules/DiscordBot.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/modules/ServerManager.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/utils.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app.js" beforeDir="false" afterPath="$PROJECT_DIR$/main.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config.json.example" beforeDir="false" afterPath="$PROJECT_DIR$/config.json.example" afterDir="false" />
<change beforePath="$PROJECT_DIR$/database.js" beforeDir="false" afterPath="$PROJECT_DIR$/database.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/init.sql" beforeDir="false" afterPath="$PROJECT_DIR$/init.sql" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/run.sh" beforeDir="false" afterPath="$PROJECT_DIR$/run.sh" afterDir="false" />
<change beforePath="$PROJECT_DIR$/setup.sh" beforeDir="false" afterPath="$PROJECT_DIR$/setup.sh" afterDir="false" />
</list>
<ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" />
<ignored path="$PROJECT_DIR$/tmp/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileEditorManager">
<splitter split-orientation="horizontal" split-proportion="0.5851301">
<split-first>
<leaf>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/api/auth.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="221">
<caret line="13" column="51" lean-forward="true" selection-start-line="13" selection-start-column="51" selection-end-line="13" selection-end-column="51" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/api/createUser.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" column="18" selection-start-line="2" selection-start-column="18" selection-end-line="2" selection-end-column="18" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/api/sendMetrics.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="188">
<caret line="20" lean-forward="true" selection-start-line="20" selection-end-line="20" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/modules/DiscordBot.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="18" column="40" lean-forward="true" selection-start-line="18" selection-start-column="40" selection-end-line="18" selection-end-column="40" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/modules/ServerManager.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="374">
<caret line="22" column="39" selection-start-line="22" selection-start-column="39" selection-end-line="22" selection-end-column="39" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/utils.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="85">
<caret line="5" column="22" selection-start-line="5" selection-start-column="19" selection-end-line="5" selection-end-column="26" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/init.sql">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="26" selection-start-line="10" selection-start-column="25" selection-end-line="10" selection-end-column="26" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/config.json.example">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" column="43" selection-start-line="8" selection-start-column="43" selection-end-line="8" selection-end-column="43" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/config.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="26" lean-forward="true" selection-start-line="10" selection-start-column="26" selection-end-line="10" selection-end-column="26" />
</state>
</provider>
</entry>
</file>
</leaf>
</split-first>
<split-second>
<leaf>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/database.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="4" column="14" selection-start-line="4" selection-end-line="4" selection-end-column="35" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/setup.sh">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" column="44" lean-forward="true" selection-start-line="7" selection-start-column="44" selection-end-line="7" selection-end-column="44" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/main.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="561">
<caret line="33" column="1" lean-forward="true" selection-start-line="33" selection-start-column="1" selection-end-line="33" selection-end-column="1" />
</state>
</provider>
</entry>
</file>
</leaf>
</split-second>
</splitter>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="JavaScript File" />
<option value="TypeScript File" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>getHash</find>
</findStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/config.json.example" />
<option value="$PROJECT_DIR$/run.sh" />
<option value="$PROJECT_DIR$/modules.js" />
<option value="$PROJECT_DIR$/utils.ts" />
<option value="$PROJECT_DIR$/api/createUser.js" />
<option value="$PROJECT_DIR$/utils.js" />
<option value="$PROJECT_DIR$/database.js" />
<option value="$PROJECT_DIR$/api/auth.js" />
<option value="$PROJECT_DIR$/setup.sh" />
<option value="$PROJECT_DIR$/config.json" />
<option value="$PROJECT_DIR$/modules/DiscordBot.js" />
<option value="$PROJECT_DIR$/main.js" />
<option value="$PROJECT_DIR$/modules/ServerManager.js" />
<option value="$PROJECT_DIR$/api/sendMetrics.js" />
</list>
</option>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="522" />
<option name="width" value="1405" />
<option name="height" value="1057" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="site" type="b2602c69:ProjectViewProjectNode" />
<item name="site" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="site" type="b2602c69:ProjectViewProjectNode" />
<item name="site" type="462c0819:PsiDirectoryNode" />
<item name="api" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="site" type="b2602c69:ProjectViewProjectNode" />
<item name="site" type="462c0819:PsiDirectoryNode" />
<item name="modules" type="462c0819:PsiDirectoryNode" />
</path>
<path>
<item name="site" type="b2602c69:ProjectViewProjectNode" />
<item name="site" type="462c0819:PsiDirectoryNode" />
<item name="public" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="nodejs_package_manager_path" value="npm" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="M:\swg-main\site" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="abd1a00f-a3c0-4242-8b34-68d3f50e7fe2" name="Default Changelist" comment="" />
<created>1552662480504</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1552662480504</updated>
<workItem from="1552662484119" duration="6180000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="6180000" />
</component>
<component name="ToolWindowManager">
<frame x="-8" y="-8" width="1936" height="1066" extended-state="6" />
<editor active="true" />
<layout>
<window_info id="Favorites" order="0" side_tool="true" />
<window_info active="true" content_ui="combo" id="Project" order="1" visible="true" weight="0.13277134" />
<window_info id="Structure" order="2" side_tool="true" weight="0.25" />
<window_info anchor="bottom" id="Docker" order="0" show_stripe_button="false" />
<window_info anchor="bottom" id="Terminal" order="1" />
<window_info anchor="bottom" id="Event Log" order="2" side_tool="true" />
<window_info anchor="bottom" id="Version Control" order="3" />
<window_info anchor="bottom" id="Message" order="4" />
<window_info anchor="bottom" id="TypeScript" order="5" weight="0.3290461" />
<window_info anchor="bottom" id="Find" order="6" weight="0.3290461" />
<window_info anchor="bottom" id="Run" order="7" />
<window_info anchor="bottom" id="Debug" order="8" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="9" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="10" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="11" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/modules.js">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/package.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="323">
<caret line="19" column="24" lean-forward="true" selection-start-line="19" selection-start-column="24" selection-end-line="19" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/run.sh">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="51">
<caret line="3" column="16" lean-forward="true" selection-start-line="3" selection-start-column="16" selection-end-line="3" selection-end-column="16" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/database.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="68">
<caret line="4" column="14" selection-start-line="4" selection-end-line="4" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/setup.sh">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" column="44" lean-forward="true" selection-start-line="7" selection-start-column="44" selection-end-line="7" selection-end-column="44" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="26" lean-forward="true" selection-start-line="10" selection-start-column="26" selection-end-line="10" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/api/createUser.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="34">
<caret line="2" column="18" selection-start-line="2" selection-start-column="18" selection-end-line="2" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/api/auth.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="221">
<caret line="13" column="51" lean-forward="true" selection-start-line="13" selection-start-column="51" selection-end-line="13" selection-end-column="51" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/init.sql">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="26" selection-start-line="10" selection-start-column="25" selection-end-line="10" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/config.json.example">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" column="43" selection-start-line="8" selection-start-column="43" selection-end-line="8" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/utils.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="85">
<caret line="5" column="22" selection-start-line="5" selection-start-column="19" selection-end-line="5" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/modules/DiscordBot.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="18" column="40" lean-forward="true" selection-start-line="18" selection-start-column="40" selection-end-line="18" selection-end-column="40" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/modules/ServerManager.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="374">
<caret line="22" column="39" selection-start-line="22" selection-start-column="39" selection-end-line="22" selection-end-column="39" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/main.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="561">
<caret line="33" column="1" lean-forward="true" selection-start-line="33" selection-start-column="1" selection-end-line="33" selection-end-column="1" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/api/sendMetrics.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="188">
<caret line="20" lean-forward="true" selection-start-line="20" selection-end-line="20" />
</state>
</provider>
</entry>
</component>
</project>

35
api/auth.js Executable file
View File

@@ -0,0 +1,35 @@
(function() {
var exports = module.exports = {};
const config = require('../config.json');
const database = require("../database.js");
const utils = require('../utils');
module.exports.registerEndpoint = function(app) {
app.post("/api/auth", function (req, res) {
var login = req.body;
console.log("New Login: \t" +
"User: " + login.user_name + ", " +
"IP: " + login.ip);
var loginHandler = function (err, user) {
if (user !== undefined && user !== null) {
if (user.password_hash === utils.getHash(login.user_password, user.password_salt)) {
res.send( { message: 'success' } );
} else {
res.send( { message: 'Invalid password' } );
}
} else {
if ( config.autoRegistration ) {
database.createUser(login.user_name, utils.getHash(login.user_password, "aaaa"), "@todo:email", loginHandler);
} else {
res.send( { message: 'Unknown username' } );
}
}
}
database.getUser(login.user_name, loginHandler);
});
}
}());

9
api/createUser.js Executable file
View File

@@ -0,0 +1,9 @@
(function() {
var exports = module.exports = {};
module.exports.registerEndpoint = function(app) {
app.post("/api/createUser", function (req, res) {
// @TODO: implement
res.json('success');
});
}
}());

55
api/sendMetrics.js Executable file
View File

@@ -0,0 +1,55 @@
(function() {
var exports = module.exports = {};
const timediff = require('timediff');
const utils = require('../utils');
exports.clusters = { };
exports.registerEndpoint = function(app) {
app.post("/api/sendMetrics", function (req, res) {
var metrics = req.body;
clusterName = metrics.clusterName;
var cluster = exports.clusters[clusterName];
if(cluster === undefined) {
cluster = { }
exports.clusters[clusterName] = cluster;
exports.clusters[clusterName].clusterStartTime = Date.now();
cluster.clusterUptime = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
}
cluster.clusterStatus = "N/A";
cluster.clusterLastLoad = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterPopulation = metrics.totalPlayerCount;
cluster.clusterLastUpdate = Date.now();
if(exports.clusters[clusterName].clusterStartTime == null) {
cluster.clusterStartTime = Date.now();
}
if (metrics.timeClusterWentIntoLoadingState > metrics.lastLoadingStateTime) {
cluster.clusterStatus = "Loading";
}
else if (metrics.lastLoadingStateTime > 0) {
cluster.clusterStatus = "Online";
var lastLoadDate = utils.dateFromUTSC(metrics.lastLoadingStateTime);
cluster.clusterLastLoad = timediff(lastLoadDate, Date.now(), 'DHmS');
}
else {
exports.clusters[clusterName].clusterStatus = "Offline";
cluster.clusterStartTime = null;
console.log("offline");
}
console.log("New Metrics: \t" +
"Cluster: " + clusterName + ", " +
"Status: " + cluster.clusterStatus + ", " +
"Players: " + cluster.clusterPopulation + ", " +
"Last Load: " + utils.readableTimeDiff(cluster.clusterLastLoad) + " ago, " +
"Uptime: " + utils.readableTimeDiff(cluster.clusterUptime));
res.json('success');
});
}
}());

190
app.js
View File

@@ -1,190 +0,0 @@
const express = require("express");
const bodyParser = require("body-parser");
const timediff = require('timediff');
const crypto = require('crypto');
const CONFIG = require('./config.json');
const database = require("./database.js");
const Discord = require('discord.js');
// ---------------------------------------------------------------
const client = new Discord.Client();
var app = express();
app.use(express.json());
app.use(express.static('public'))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// ---------------------------------------------------------------
function getHash(string, salt) {
var hash = crypto.createHash('sha1').update(string + salt).digest();
var salt = Buffer.from(salt, "utf8")
return Buffer.concat([hash, salt]).toString('base64');
}
function dateFromUTSC(utscTime) {
var d = new Date(0);
d.setUTCSeconds(utscTime);
return d;
}
function readableTimeDiff(timeDiff) {
var result = "";
if(timeDiff.days > 0) result += timeDiff.days + " days, ";
if(timeDiff.hours > 0) result += timeDiff.hours + " hours, ";
if(timeDiff.minutes > 0) result += timeDiff.minutes + " minutes, ";
return result + timeDiff.seconds + " seconds";
}
// ---------------------------------------------------------------
app.post("/api/auth", function (req, res) {
var login = req.body;
console.log("New Login: \t" +
"User: " + login.user_name + ", " +
"IP: " + login.ip);
var loginHandler = function (err, user) {
if (user !== undefined && user !== null) {
if (user.password_hash === getHash(login.user_password, user.password_salt)) {
res.send( { message: 'success' } );
} else {
res.send( { message: 'Invalid password' } );
}
} else {
if ( CONFIG.autoRegistration ) {
database.createUser(login.user_name, getHash(login.user_password, "aaaa"), "@todo:email", loginHandler);
} else {
res.send( { message: 'Unknown username' } );
}
}
}
database.getUser(login.user_name, loginHandler);
});
app.post("/api/createUser", function (req, res) {
// @TODO: implement
res.json('success');
});
var clusters = { };
app.post("/api/sendMetrics", function (req, res) {
var metrics = req.body;
clusterName = metrics.clusterName;
var cluster = clusters[clusterName];
if(cluster === undefined) {
cluster = { }
clusters[clusterName] = cluster;
clusters[clusterName].clusterStartTime = Date.now();
cluster.clusterUptime = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
}
cluster.clusterStatus = "N/A";
cluster.clusterLastLoad = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterPopulation = metrics.totalPlayerCount;
cluster.clusterLastUpdate = Date.now();
if(clusters[clusterName].clusterStartTime == null) {
cluster.clusterStartTime = Date.now();
}
if (metrics.timeClusterWentIntoLoadingState > metrics.lastLoadingStateTime) {
cluster.clusterStatus = "Loading";
}
else if (metrics.lastLoadingStateTime > 0) {
cluster.clusterStatus = "Online";
var lastLoadDate = dateFromUTSC(metrics.lastLoadingStateTime);
cluster.clusterLastLoad = timediff(lastLoadDate, Date.now(), 'DHmS');
}
else {
clusters[clusterName].clusterStatus = "Offline";
cluster.clusterStartTime = null;
console.log("offline");
}
console.log("New Metrics: \t" +
"Cluster: " + clusterName + ", " +
"Status: " + cluster.clusterStatus + ", " +
"Players: " + cluster.clusterPopulation + ", " +
"Last Load: " + readableTimeDiff(cluster.clusterLastLoad) + " ago, " +
"Uptime: " + readableTimeDiff(cluster.clusterUptime));
res.json('success');
});
// ---------------------------------------------------------------
if(CONFIG.discordBot) {
// Status checker
setInterval(function() {
for(var clusterName in clusters) {
let cluster = clusters[clusterName];
// if we haven't received an update in twice as long as the interval, the server isn't responding
if(Date.now() - cluster.clusterLastUpdate > (CONFIG.discordStatusInterval * 2 * 1000)) {
cluster.clusterStatus = "Offline";
cluster.clusterLastLoad = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterUptime = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterPopulation = 0;
cluster.clusterStartTime = null;
} else {
cluster.clusterUptime = timediff(cluster.clusterStartTime, Date.now(), 'DHmS');
}
}
}, 5 * 1000)
client.on('ready', () => {
var channel = client.channels.find("name", CONFIG.discordBotChannelName);
setInterval(function() {
for(var clusterName in clusters) {
let cluster = clusters[clusterName];
channel.sendMessage(
"**Cluster** `" + clusterName + "` " +
"**Status** `" + cluster.clusterStatus + "` " +
"**Players** `" + cluster.clusterPopulation + "` " +
"**Last Load** `" + readableTimeDiff(cluster.clusterLastLoad) + " ago` " +
"**Uptime** `" + readableTimeDiff(cluster.clusterUptime) + "` ");
}
}, CONFIG.discordStatusInterval * 1000)
});
client.login(CONFIG.discordBotToken);
}
// ---------------------------------------------------------------
if(CONFIG.restartServer) {
var cp = require("child_process");
setInterval(function() {
var cluster = clusters[CONFIG.restartClusterName];
if(cluster !== undefined) {
if(cluster.clusterStatus === "Offline") {
console.log("[****] Restarting server!!!");
cp.exec(CONFIG.restartCommand, {cwd: CONFIG.restartWorkingPath}, function(error,stdout,stderr){ });
if(CONFIG.discordBot) {
var channel = client.channels.find("name", CONFIG.discordBotChannelName);
channel.sendMessage("@here **Restarting cluster `" + CONFIG.restartClusterName + "` due to detected offline status!**");
}
}
} else {
console.log("[****] Starting server!!!");
cp.exec(CONFIG.restartCommand, {cwd: CONFIG.restartWorkingPath}, function(error,stdout,stderr){ });
}
}, 60 * 1000)
}
// ---------------------------------------------------------------
app.listen(3000);

22
config.json.example Normal file → Executable file
View File

@@ -1,15 +1,15 @@
{
"dbHost": "127.0.0.1",
"dbName": "swg",
"dbUser": "username",
"dbPassword": "password",
"autoRegistration": true,
"discordBot": true,
"discordBotToken": "token",
"discordBotChannelName": "channelName",
"discordStatusInterval": 30,
"restartServer": true,
"restartClusterName": "Bloodfin",
"restartWorkingPath": "/home/user/swg-main/",
"restartCommand": "./start_server.sh"
"dbUser": "username",
"dbPassword": "password",
"autoRegistration": true,
"discordBot": true,
"discordBotToken": "token",
"discordBotChannelName": "channelName",
"discordStatusInterval": 30,
"restartServer": true,
"restartClusterName": "Bloodfin",
"restartWorkingPath": "/home/user/swg-main/",
"restartCommand": "./start_server.sh"
}

10
database.js Normal file → Executable file
View File

@@ -1,14 +1,14 @@
(function() {
var exports = module.exports = {};
const CONFIG = require('./config.json');
const config = require('./config.json');
const mysql = require('mysql');
var con = mysql.createConnection({
host: CONFIG.dbHost,
database: CONFIG.dbName,
user: CONFIG.dbUser,
password: CONFIG.dbPassword
host: config.dbHost,
database: config.dbName,
user: config.dbUser,
password: config.dbPassword
});
// callback = function(err, user)

3
init.sql Normal file → Executable file
View File

@@ -1,5 +1,4 @@
CREATE DATABASE swgusers;
USE swgusers;
USE swg;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

34
main.js Executable file
View File

@@ -0,0 +1,34 @@
const express = require("express");
const bodyParser = require("body-parser");
var app = express();
app.use(express.json());
app.use(express.static('public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(3000);
// ---------------------------------------------------------------
var apis = {};
apis.apiAuth = require('./api/auth.js');
apis.apiAuth.registerEndpoint(app);
apis.apiCreateUser = require('./api/createUser.js');
apis.apiCreateUser.registerEndpoint(app);
apis.apiSendMetrics = require('./api/sendMetrics.js');
apis.apiSendMetrics.registerEndpoint(app);
// ---------------------------------------------------------------
const config = require('./config.json');
var managers = {};
managers.discordBot = require('./modules/DiscordBot.js');
managers.serverManager = require('./modules/ServerManager.js');
if(config.discordBot) {
managers.discordBot.startManager(apis, managers);
}
if(config.restartServer) {
managers.serverManager.startManager(apis, managers);
}

44
modules/DiscordBot.js Executable file
View File

@@ -0,0 +1,44 @@
(function() {
var exports = module.exports = {};
const discord = require('discord.js');
const client = new discord.Client();
const config = require('../config.json');
const utils = require('../utils');
const timediff = require('timediff');
module.exports.startManager = function(apis, managers) {
// Status checker
setInterval(function() {
for(var clusterName in apis.apiSendMetrics.clusters) {
let cluster = apis.apiSendMetrics.clusters[clusterName];
// if we haven't received an update in twice as long as the interval, the server isn't responding
if(Date.now() - cluster.clusterLastUpdate > (config.discordStatusInterval * 2 * 1000)) {
cluster.clusterStatus = "Offline";
cluster.clusterLastLoad = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterUptime = { "days": 0, "hours": 0, "minutes": 0, "seconds": 0 };
cluster.clusterPopulation = 0;
cluster.clusterStartTime = null;
} else {
cluster.clusterUptime = timediff(cluster.clusterStartTime, Date.now(), 'DHmS');
}
}
}, 5 * 1000)
client.on('ready', () => {
var channel = client.channels.find("name", config.discordBotChannelName);
setInterval(function() {
for(var clusterName in apis.apiSendMetrics.clusters) {
let cluster = apis.apiSendMetrics.clusters[clusterName];
channel.sendMessage(
"**Cluster** `" + clusterName + "` " +
"**Status** `" + cluster.clusterStatus + "` " +
"**Players** `" + cluster.clusterPopulation + "` " +
"**Last Load** `" + utils.readableTimeDiff(cluster.clusterLastLoad) + " ago` " +
"**Uptime** `" + utils.readableTimeDiff(cluster.clusterUptime) + "` ");
}
}, config.discordStatusInterval * 1000)
});
client.login(config.discordBotToken);
}
}());

28
modules/ServerManager.js Executable file
View File

@@ -0,0 +1,28 @@
(function() {
var exports = module.exports = {};
const cp = require("child_process");
const config = require('../config.json');
module.exports.startManager = function(apis, managers) {
setInterval(function() {
var cluster = apis.apiSendMetrics.clusters[config.restartClusterName];
if(cluster !== undefined) {
if(cluster.clusterStatus === "Offline") {
console.log("[****] Restarting server!!!");
cp.exec(config.restartCommand, {cwd: config.restartWorkingPath}, function(error,stdout,stderr){ });
if(config.discordBot) {
var channel = client.channels.find("name", config.discordBotChannelName);
channel.sendMessage("@here **Restarting cluster `" + config.restartClusterName + "` due to detected offline status!**");
}
}
} else {
console.log("[****] Starting server!!!");
cp.exec(config.restartCommand, {cwd: config.restartWorkingPath}, function(error,stdout,stderr){
console.log(error);
});
}
}, 15 * 1000)
}
}());

228
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
"requires": {
"mime-types": "2.1.18",
"mime-types": "~2.1.18",
"negotiator": "0.6.1"
}
},
@@ -29,20 +29,20 @@
"integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg=="
},
"body-parser": {
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
"version": "1.18.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
"integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
"requires": {
"bytes": "3.0.0",
"content-type": "1.0.4",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "1.1.2",
"http-errors": "1.6.3",
"iconv-lite": "0.4.19",
"on-finished": "2.3.0",
"qs": "6.5.1",
"raw-body": "2.3.2",
"type-is": "1.6.16"
"depd": "~1.1.2",
"http-errors": "~1.6.3",
"iconv-lite": "0.4.23",
"on-finished": "~2.3.0",
"qs": "6.5.2",
"raw-body": "2.3.3",
"type-is": "~1.6.16"
}
},
"bytes": {
@@ -98,11 +98,11 @@
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-11.3.2.tgz",
"integrity": "sha512-Abw9CTMX3Jb47IeRffqx2VNSnXl/OsTdQzhvbw/JnqCyqc2imAocc7pX2HoRmgKd8CgSqsjBFBneusz/E16e6A==",
"requires": {
"long": "4.0.0",
"prism-media": "0.0.2",
"snekfetch": "3.6.4",
"tweetnacl": "1.0.0",
"ws": "4.1.0"
"long": "^4.0.0",
"prism-media": "^0.0.2",
"snekfetch": "^3.6.4",
"tweetnacl": "^1.0.0",
"ws": "^4.0.0"
}
},
"ee-first": {
@@ -126,40 +126,47 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.16.3",
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"version": "4.16.4",
"resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
"integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
"requires": {
"accepts": "1.3.5",
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
"body-parser": "1.18.2",
"body-parser": "1.18.3",
"content-disposition": "0.5.2",
"content-type": "1.0.4",
"content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "1.1.2",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"etag": "1.8.1",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "1.1.2",
"on-finished": "2.3.0",
"parseurl": "1.3.2",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "2.0.3",
"qs": "6.5.1",
"range-parser": "1.2.0",
"safe-buffer": "5.1.1",
"proxy-addr": "~2.0.4",
"qs": "6.5.2",
"range-parser": "~1.2.0",
"safe-buffer": "5.1.2",
"send": "0.16.2",
"serve-static": "1.13.2",
"setprototypeof": "1.1.0",
"statuses": "1.4.0",
"type-is": "1.6.16",
"statuses": "~1.4.0",
"type-is": "~1.6.16",
"utils-merge": "1.0.1",
"vary": "1.1.2"
"vary": "~1.1.2"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"finalhandler": {
@@ -168,12 +175,12 @@
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"on-finished": "2.3.0",
"parseurl": "1.3.2",
"statuses": "1.4.0",
"unpipe": "1.0.0"
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"statuses": "~1.4.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
@@ -191,16 +198,19 @@
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "1.1.2",
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": "1.4.0"
"statuses": ">= 1.4.0 < 2"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
@@ -208,9 +218,9 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
"integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
},
"isarray": {
"version": "1.0.0",
@@ -243,16 +253,16 @@
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
},
"mime-db": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
"version": "1.38.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
"integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
},
"mime-types": {
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"version": "2.1.22",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
"integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
"requires": {
"mime-db": "1.33.0"
"mime-db": "~1.38.0"
}
},
"moment": {
@@ -310,18 +320,18 @@
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"proxy-addr": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
"integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
"requires": {
"forwarded": "0.1.2",
"ipaddr.js": "1.6.0"
"forwarded": "~0.1.2",
"ipaddr.js": "1.8.0"
}
},
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"range-parser": {
"version": "1.2.0",
@@ -329,37 +339,14 @@
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raw-body": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
"integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.2",
"iconv-lite": "0.4.19",
"http-errors": "1.6.3",
"iconv-lite": "0.4.23",
"unpipe": "1.0.0"
},
"dependencies": {
"depd": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
},
"http-errors": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
"requires": {
"depd": "1.1.1",
"inherits": "2.0.3",
"setprototypeof": "1.0.3",
"statuses": "1.4.0"
}
},
"setprototypeof": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
}
}
},
"readable-stream": {
@@ -367,13 +354,13 @@
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~1.0.6",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.0.3",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
@@ -381,24 +368,29 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"requires": {
"debug": "2.6.9",
"depd": "1.1.2",
"destroy": "1.0.4",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"etag": "1.8.1",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "1.6.3",
"http-errors": "~1.6.2",
"mime": "1.4.1",
"ms": "2.0.0",
"on-finished": "2.3.0",
"range-parser": "1.2.0",
"statuses": "1.4.0"
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.4.0"
}
},
"serve-static": {
@@ -406,9 +398,9 @@
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"requires": {
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"parseurl": "1.3.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.2",
"send": "0.16.2"
}
},
@@ -437,7 +429,7 @@
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
"safe-buffer": "~5.1.0"
}
},
"timediff": {
@@ -445,7 +437,7 @@
"resolved": "https://registry.npmjs.org/timediff/-/timediff-1.1.1.tgz",
"integrity": "sha1-ZkN6+bCUAicR596FDssAqfNAfTg=",
"requires": {
"moment": "2.22.1"
"moment": "^2.9.0"
}
},
"tweetnacl": {
@@ -459,7 +451,7 @@
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "2.1.18"
"mime-types": "~2.1.18"
}
},
"unpipe": {
@@ -487,8 +479,8 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
"integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
"requires": {
"async-limiter": "1.0.0",
"safe-buffer": "5.1.1"
"async-limiter": "~1.0.0",
"safe-buffer": "~5.1.0"
}
}
}

4
package.json Normal file → Executable file
View File

@@ -2,7 +2,7 @@
"name": "swg-site",
"version": "1.0.0",
"description": "",
"main": "app.js",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
@@ -15,7 +15,7 @@
"homepage": "https://bitbucket.org/seefoe/swg-site#readme",
"dependencies": {
"discord.js": "^11.3.2",
"express": "^4.16.3",
"express": "^4.16.4",
"mysql": "^2.15.0",
"timediff": "^1.1.1"
}

2
run.sh
View File

@@ -1,5 +1,5 @@
killall node
while [ : ]
do
node app.js
node main.js
done

View File

@@ -3,4 +3,6 @@ sudo apt-get install curl mysql-server -y
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
npm install express
npm install express
mysql -u root -ppassword swgusers < init.sql

27
utils.js Executable file
View File

@@ -0,0 +1,27 @@
(function() {
var exports = module.exports = {};
const crypto = require('crypto');
module.exports.getHash = function(string, salt) {
var hash = crypto.createHash('sha1').update(string + salt).digest();
var salt = Buffer.from(salt, "utf8")
return Buffer.concat([hash, salt]).toString('base64');
};
module.exports.dateFromUTSC = function(utscTime) {
var d = new Date(0);
d.setUTCSeconds(utscTime);
return d;
};
module.exports.readableTimeDiff = function(timeDiff) {
var result = "";
if(timeDiff.days > 0) result += timeDiff.days + " days, ";
if(timeDiff.hours > 0) result += timeDiff.hours + " hours, ";
if(timeDiff.minutes > 0) result += timeDiff.minutes + " minutes, ";
return result + timeDiff.seconds + " seconds";
};
}());