New Docker Structure

This commit is contained in:
Starystars67
2023-12-06 12:08:49 +00:00
parent 691c8afe87
commit 97cd0c9444
36 changed files with 1972 additions and 1072 deletions

72
src/routes.js Normal file
View File

@@ -0,0 +1,72 @@
var express = require('express');
var router = express.Router();
function mainRoutes(router) {
router.get('/', function (req, res) {
res.render('index.ejs');
});
router.get('/servers', function (req, res) {
res.render('servers.ejs');
});
router.get('/stats', function (req, res) {
res.render('stats.ejs');
});
router.get('/ping', function (req, res) {
res.send('OK');
});
}
module.exports = function (app) {
try {
mainRoutes(router)
} catch (e) {
console.error(e)
}
app.use('/', router)
app.use(handle404)
app.use(handleErrors)
app.use(clientErrorHandler)
}
function handleErrors(err, req, res) {
const status = err.status || 500
res.status(err.status)
if (status === 429) {
res.render('429', { layout: false })
return
}
if (status === 500) {
res.render('500', { layout: false })
return
}
if (status === 503) {
res.render('503', { layout: false })
return
}
winston.warn(err.stack)
res.json({
message: err.message,
error: err,
})
}
function handle404(req, res) {
return res.status(404).send('404')
}
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
res.status(500).send({ error: 'Something failed!' })
} else {
next(err)
}
}

File diff suppressed because it is too large Load Diff

631
src/static/css/styles.css Normal file
View File

@@ -0,0 +1,631 @@
/* --------- NAVBAR // GLOBAL --------- */
* {
font-family: "Fira Sans", "Helvetica", Arial, sans-serif, serif;
box-sizing: border-box;
padding: 0;
margin: 0;
}
.container {
padding: 0 20px;
}
.mobile-container {
width: 250px;
max-width: 480px;
margin: auto;
background-color: rgb(236, 188, 132);
max-height: 500px;
color: white;
border-radius: 10px;
overflow: hidden;
z-index: 1000;
}
/*.topnav {*/
/* overflow: hidden;*/
/* position: relative;*/
/*}*/
/*.topnav #links {*/
/* display: none;*/
/*}*/
/*.topnav a {*/
/* color: white;*/
/* padding: 14px 16px;*/
/* text-decoration: none;*/
/* font-size: 17px;*/
/* display: hidden;*/
/*}*/
/*.topnav a.icon {*/
/* display: hidden;*/
/* position: absolute;*/
/* right: 0;*/
/* top: 0;*/
/*}*/
.nav {
position: fixed;
z-index: 100;
height: 80px;
font-weight: 400px;
overflow: visable;
background-color: rgb(236, 188, 132);
width: 100%;
line-height: 1;
transition: box-shadow .2s ease;
}
.nav .links{
display: flex;
height: 100%;
float: right;
}
.nav a {
color: #161923;
text-decoration: none;
transition: background-color .2s ease;
}
.nav .links li {
height: 100%;
padding-top: 20px;
list-style: none;
font-size: 16px;
}
/* li{
display: list-item;
text-align: -webkit-match-parent;
padding: 10px;
} */
nav li {
display: list-item;
text-align: -webkit-match-parent;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 40px;
}
.logo-link {
display: flex;
height: 100%;
margin-left: -15px;
padding: 20px 15px;
align-items: center;
align-content: center;
}
.topnav {
display: none;
overflow: hidden;
position: relative;
}
.topnav #burger-links {
display: hidden;
}
.topnav a {
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
display: hidden;
}
.topnav a.icon {
display: hidden;
position: fixed;
right: 0;
top: 0;
}
.logo-text {
font-size: 20px;
margin-left: 15px;
}
.logo-image {
width: 200px;
/*height: 200px;*/
/*border-radius: 50%;*/
/*margin-top: -57px;*/
}
.burger-menu {
display: none;
}
@media screen and (max-width: 990px) {
.navbar-links {
display: none;
}
.burger-menu {
display: block;
margin-top: 25px;
float: right;
}
/*.topnav {*/
/* display: block;*/
/* overflow: hidden;*/
/* position: relative;*/
/*}*/
/*.topnav #myLinks {*/
/* display: hidden;*/
/*}*/
/*.topnav a {*/
/* padding: 14px 16px;*/
/* text-decoration: none;*/
/* font-size: 17px;*/
/* display: block;*/
/*}*/
/*.topnav a.icon {*/
/* display: block;*/
/* position: absolute;*/
/* right: 0;*/
/* top: 0;*/
/*}*/
}
@media screen and (max-width: 575px) {
.burger-menu {
display: block;
margin-top: -25px;
float: right;
}
}
@media screen and (max-width: 360px) {
.burger-menu {
display: block;
margin-top: -43%;
float: right;
}
}
@media screen and (max-width: 411px) {
.burger-menu {
display: block;
margin-top: -38%;
float: right;
}
}
@media screen and (max-width: 320px) {
.burger-menu {
display: block;
margin-top: -50%;
float: right;
}
}
@media screen and (max-width: 375px) {
.burger-menu {
display: block;
margin-top: -42%;
float: right;
}
}
@media screen and (max-width: 414px) {
.burger-menu {
display: block;
margin-top: -37%;
float: right;
}
}
@media screen and (max-width: 375px) {
.burger-menu {
display: block;
margin-top: -41%;
float: right;
}
}
@media screen and (max-width: 767px) {
.text {
display: none;
}
.logo-link {
display: flex;
height: 100%;
align-items: center;
align-content: center;
}
.logo-text {
margin: 0 auto;
}
}
/* ----------- IMAGE AND DOWNLOAD ----------- */
.main-content {
display: flex;
position: relative;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
height: calc(100vh - 80px);
overflow: hidden;
background: linear-gradient(-45deg, rgba(22, 25, 35, 0.35) 0%, rgba(22, 25, 35, 0.95) 100%) center center/100%, url(../img/beamng-mp-landing.png) center top/cover;
color: #fefee1;
}
.main-content .introduction {
width: 100%;
position: absolute;
transition: transform .2s ease;
transform: translateX(0);
}
p {
display: block;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0px;
margin-inline-end: 0px;
color: #c8cdbb;
}
.main-content .lead {
font-size: 30px;
font-weight: 300;
font-family: verdana;
}
.middle-xs {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.center-xs {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center;
}
.main-content .buttons-wrapper {
display: flex;
flex-direction: column;
align-items: flex-end;
align-content: flex-end;
}
.main-content .buttons-wrapper .buttons .download-client {
display: block;
position: relative;
padding: 15px 25px 15px 25px;
cursor: pointer;
color: #fefee1;
border: none;
text-shadow: 0 0 1px rgba(22, 25, 35, 0.5);
background: radial-gradient(circle, rgba(150, 204, 0, 0.8), rgba(150, 204, 0, 0.65)) center/100%;
transition: box-shadow .2s ease;
font-size: 27px;
font-weight: 300;
line-height: 1;
border-radius: 3px;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
min-width: 260px;
}
.description {
display: block;
font-size: 12px;
font-weight: 200;
opacity: .9;
}
@media screen and (max-width: 600px) {
#button {
display: none;
}
}
/* --------- Features ---------*/
.features article.col-lg-3 {
padding: 0 35px;
}
.features article {
margin-top: 50px;
font-size: 15px;
color: #c8cdbb;
}
section {
padding-bottom: 50px;
}
/* @media only screen and {min-width: 75em}
.col-lg-3 {
-ms-flex-preferred-size: 25%;
flex-basis: 25%;
max-width: 25%;
}
@media only screen and {min-width: 75em}
.col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-offset-0, .col-lg-offset-1, .col-lg-offset-2, .col-lg-offset-3, .col-lg-offset-4, .col-lg-offset-5, .col-lg-offset-6, .col-lg-offset-7, .col-lg-offset-8, .col-lg-offset-9, .col-lg-offset-10, .col-lg-offset-11, .col-lg-offset-12 {
box-sizing: border-box;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
padding-right: 0.5rem;
padding-left: 0.5rem;
}
@media only screen and {min-width: 64em}
.col-md-6 {
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
max-width: 50%;
}
@media only screen and {min-width: 64em}
.col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md-offset-0, .col-md-offset-1, .col-md-offset-2, .col-md-offset-3, .col-md-offset-4, .col-md-offset-5, .col-md-offset-6, .col-md-offset-7, .col-md-offset-8, .col-md-offset-9, .col-md-offset-10, .col-md-offset-11, .col-md-offset-12 {
box-sizing: border-box;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
padding-right: 0.5rem;
padding-left: 0.5rem;
}
@media only screen and {min-width: 48em}
.col-sm-6 {
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
max-width: 50%;
}
@media only screen and {min-width: 48em}
.col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-offset-0, .col-sm-offset-1, .col-sm-offset-2, .col-sm-offset-3, .col-sm-offset-4, .col-sm-offset-5, .col-sm-offset-6, .col-sm-offset-7, .col-sm-offset-8, .col-sm-offset-9, .col-sm-offset-10, .col-sm-offset-11, .col-sm-offset-12 {
box-sizing: border-box;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
padding-right: 0.5rem;
padding-left: 0.5rem;
} */
/* #features {
font-size: 16px;
font-weight: 300;
color: #fefee1;
background-color: #161923;
} */
body {
font-size: 16px;
font-weight: 300;
color: #fefee1;
background-color: #161923 !important;
}
/* --------- Bridge ---------- */
.container-fluid, .container {
margin-right: auto;
margin-left: auto;
}
hr {
margin-top: 50px;
border-top: 1px solid rgba(250, 255, 225, 0.15);
}
figure {
max-width: 100%;
}
img {
margin-left: 40%;
width: 572px;
height: 332px;
}
figure img {
max-width: 100%;
border-radius: 3px;
filter: contrast(0.75);
transition: filter .2s ease;
width: 572px;
height: 332px;
}
figure {
display: block;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 40px;
margin-inline-end: 40px;
}
@media only screen and (min-width: 75em)
.middle-lg {
-webkit-box-align: center;
align-items: center;
}
@media screen and (max-width: 600px) { /* Phones */
figure img {
width: 336px;
height: 189px;
}
img {
margin-left: 6%;
}
}
@media screen and (max-width: 768px) { /* Ipad */
img {
margin-left: 10%;
}
}
@media screen and (max-width: 1024px) { /* Ipad Pro */
img {
margin-left: 6%;
}
}
@media screen and (max-width: 1444px) { /* Responsive help */
img {
margin-left: 6%;
}
}
@media only screen and (min-width: 75em)
.col-lg-6 {
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
max-width: 50%;
}
.user-features-list {
display: inline-block;
margin-top: 50px;
}
@media screen and (max-width: 500px) {
.user-features-list {
display: inline-block;
margin-top: 50px;
padding-left: 50px;
}
}
.user-features-list li {
text-align: left;
font-size: 30px;
font-weight: 200;
}
section ul li {
margin-bottom: 9.80392px;
color: #c8cdbb;
}
/* --------- FAQ ---------- */
#faq h1 {
text-align: center;
margin-top: 50px;
font-size: 40px;
font-weight: 100;
line-height: 1;
color: #fefee1;
}
.faq h3 {
position: relative;
margin: 25px 0 0 0;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
color: #fefee1;
}
h3 {
font-weight: 400;
font-size: 20px;
line-height: 1.2;
}
/* -------- FOOTER -------- */
footer {
min-height: 150px;
background-color: #403F4C;
padding-left: 25px;
}
.text-white {
color: #fff !important;
}
.row {
max-width: 100%;
}
/* .row {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
} */
.text-right {
text-align: right !important;
}
.list-inline {
padding-left: 0;
list-style: none;
}
.py-5 {
padding-bottom: 3rem !important;
}
.row {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}
footer .container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
footer .row {
width: 100%;
justify-content: space-around;
}
.row i {
font-size: 22px;
margin: 0 3px;
}
@media screen and (max-width: 600px) {
.container {
width: 100%;
}
footer .container {
width: 80%;
margin: 0 auto;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
src/static/img/flags.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

362
src/static/js/scripts.js Normal file
View File

@@ -0,0 +1,362 @@
$(function () {
$.getJSON("https://backend.beammp.com/servers-info", function (data) {
$('#Servers-List').empty();
//console.log("Data Received:")
//console.log(data)
$.each(data, function (k, v) {
//var v = data[k][Object.keys(data[k])[0]]
//console.log(v)
$('#Servers-List').append(`
<tr>
<td>${getCountryName(v.location)}</td>
<td>${formatServerName(v.sname)}</td>
<td>${SmoothMapName(v.map)}</td>
<td>${v.players}/${v.maxplayers}</td>
</tr>`
);
});
$('#dataTable').DataTable();
});
});
var styleMap = {
'^0': 'color:#000000',
'^1': 'color:#0000AA',
'^2': 'color:#00AA00',
'^3': 'color:#00AAAA',
'^4': 'color:#AA0000',
'^5': 'color:#AA00AA',
'^6': 'color:#FFAA00',
'^7': 'color:#AAAAAA',
'^8': 'color:#555555',
'^9': 'color:#5555FF',
'^a': 'color:#55FF55',
'^b': 'color:#55FFFF',
'^c': 'color:#FF5555',
'^d': 'color:#FF55FF',
'^e': 'color:#FFFF55',
'^f': 'color:#FFFFFF',
'^l': 'font-weight:bold',
'^m': 'text-decoration:line-through',
'^n': 'text-decoration:underline',
'^o': 'font-style:italic',
};
function applyCode(string, codes) {
var elem = document.createElement('span');
string = string.replace(/\x00*/g, '');
for (var i = 0, len = codes.length; i < len; i++) {
elem.style.cssText += styleMap[codes[i]] + ';';
}
elem.innerHTML = string;
return elem;
}
function formatServerName(string) {
var codes = string.match(/\^.{1}/g) || [],
indexes = [],
apply = [],
tmpStr,
deltaIndex,
noCode,
final = document.createDocumentFragment(),
i;
for (i = 0, len = codes.length; i < len; i++) {
indexes.push(string.indexOf(codes[i]));
string = string.replace(codes[i], '\x00\x00');
}
if (indexes[0] !== 0) {
final.appendChild(applyCode(string.substring(0, indexes[0]), []));
}
for (i = 0; i < len; i++) {
indexDelta = indexes[i + 1] - indexes[i];
if (indexDelta === 2) {
while (indexDelta === 2) {
apply.push(codes[i]);
i++;
indexDelta = indexes[i + 1] - indexes[i];
}
apply.push(codes[i]);
} else {
apply.push(codes[i]);
}
if (apply.lastIndexOf('^r') > -1) {
apply = apply.slice(apply.lastIndexOf('^r') + 1);
}
tmpStr = string.substring(indexes[i], indexes[i + 1]);
final.appendChild(applyCode(tmpStr, apply));
}
$('#TEMPAREA').html(final);
return $('#TEMPAREA').html();;
}
function SmoothMapName(map) {
if (map != "Any Map") {
map = map.replace("/info.json", "")
map = map.split('/').pop().replace(/\s*/g, '')
map = map.replace(/_/g, " ")
map = map.replace(/-/g, " ")
map = toTitleCase(map)
}
return map
}
function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}
var isoCountries = {
'AF': 'Afghanistan',
'AX': 'Aland Islands',
'AL': 'Albania',
'DZ': 'Algeria',
'AS': 'American Samoa',
'AD': 'Andorra',
'AO': 'Angola',
'AI': 'Anguilla',
'AQ': 'Antarctica',
'AG': 'Antigua And Barbuda',
'AR': 'Argentina',
'AM': 'Armenia',
'AW': 'Aruba',
'AU': 'Australia',
'AT': 'Austria',
'AZ': 'Azerbaijan',
'BS': 'Bahamas',
'BH': 'Bahrain',
'BD': 'Bangladesh',
'BB': 'Barbados',
'BY': 'Belarus',
'BE': 'Belgium',
'BZ': 'Belize',
'BJ': 'Benin',
'BM': 'Bermuda',
'BT': 'Bhutan',
'BO': 'Bolivia',
'BA': 'Bosnia And Herzegovina',
'BW': 'Botswana',
'BV': 'Bouvet Island',
'BR': 'Brazil',
'IO': 'British Indian Ocean Territory',
'BN': 'Brunei Darussalam',
'BG': 'Bulgaria',
'BF': 'Burkina Faso',
'BI': 'Burundi',
'KH': 'Cambodia',
'CM': 'Cameroon',
'CA': 'Canada',
'CV': 'Cape Verde',
'KY': 'Cayman Islands',
'CF': 'Central African Republic',
'TD': 'Chad',
'CL': 'Chile',
'CN': 'China',
'CX': 'Christmas Island',
'CC': 'Cocos (Keeling) Islands',
'CO': 'Colombia',
'KM': 'Comoros',
'CG': 'Congo',
'CD': 'Congo, Democratic Republic',
'CK': 'Cook Islands',
'CR': 'Costa Rica',
'CI': 'Cote D\'Ivoire',
'HR': 'Croatia',
'CU': 'Cuba',
'CY': 'Cyprus',
'CZ': 'Czech Republic',
'DK': 'Denmark',
'DJ': 'Djibouti',
'DM': 'Dominica',
'DO': 'Dominican Republic',
'EC': 'Ecuador',
'EG': 'Egypt',
'SV': 'El Salvador',
'GQ': 'Equatorial Guinea',
'ER': 'Eritrea',
'EE': 'Estonia',
'ET': 'Ethiopia',
'FK': 'Falkland Islands (Malvinas)',
'FO': 'Faroe Islands',
'FJ': 'Fiji',
'FI': 'Finland',
'FR': 'France',
'GF': 'French Guiana',
'PF': 'French Polynesia',
'TF': 'French Southern Territories',
'GA': 'Gabon',
'GM': 'Gambia',
'GE': 'Georgia',
'DE': 'Germany',
'GH': 'Ghana',
'GI': 'Gibraltar',
'GR': 'Greece',
'GL': 'Greenland',
'GD': 'Grenada',
'GP': 'Guadeloupe',
'GU': 'Guam',
'GT': 'Guatemala',
'GG': 'Guernsey',
'GN': 'Guinea',
'GW': 'Guinea-Bissau',
'GY': 'Guyana',
'HT': 'Haiti',
'HM': 'Heard Island & Mcdonald Islands',
'VA': 'Holy See (Vatican City State)',
'HN': 'Honduras',
'HK': 'Hong Kong',
'HU': 'Hungary',
'IS': 'Iceland',
'IN': 'India',
'ID': 'Indonesia',
'IR': 'Iran, Islamic Republic Of',
'IQ': 'Iraq',
'IE': 'Ireland',
'IM': 'Isle Of Man',
'IL': 'Israel',
'IT': 'Italy',
'JM': 'Jamaica',
'JP': 'Japan',
'JE': 'Jersey',
'JO': 'Jordan',
'KZ': 'Kazakhstan',
'KE': 'Kenya',
'KI': 'Kiribati',
'KR': 'Korea',
'KW': 'Kuwait',
'KG': 'Kyrgyzstan',
'LA': 'Lao People\'s Democratic Republic',
'LV': 'Latvia',
'LB': 'Lebanon',
'LS': 'Lesotho',
'LR': 'Liberia',
'LY': 'Libyan Arab Jamahiriya',
'LI': 'Liechtenstein',
'LT': 'Lithuania',
'LU': 'Luxembourg',
'MO': 'Macao',
'MK': 'Macedonia',
'MG': 'Madagascar',
'MW': 'Malawi',
'MY': 'Malaysia',
'MV': 'Maldives',
'ML': 'Mali',
'MT': 'Malta',
'MH': 'Marshall Islands',
'MQ': 'Martinique',
'MR': 'Mauritania',
'MU': 'Mauritius',
'YT': 'Mayotte',
'MX': 'Mexico',
'FM': 'Micronesia, Federated States Of',
'MD': 'Moldova',
'MC': 'Monaco',
'MN': 'Mongolia',
'ME': 'Montenegro',
'MS': 'Montserrat',
'MA': 'Morocco',
'MZ': 'Mozambique',
'MM': 'Myanmar',
'NA': 'Namibia',
'NR': 'Nauru',
'NP': 'Nepal',
'NL': 'Netherlands',
'AN': 'Netherlands Antilles',
'NC': 'New Caledonia',
'NZ': 'New Zealand',
'NI': 'Nicaragua',
'NE': 'Niger',
'NG': 'Nigeria',
'NU': 'Niue',
'NF': 'Norfolk Island',
'MP': 'Northern Mariana Islands',
'NO': 'Norway',
'OM': 'Oman',
'PK': 'Pakistan',
'PW': 'Palau',
'PS': 'Palestinian Territory, Occupied',
'PA': 'Panama',
'PG': 'Papua New Guinea',
'PY': 'Paraguay',
'PE': 'Peru',
'PH': 'Philippines',
'PN': 'Pitcairn',
'PL': 'Poland',
'PT': 'Portugal',
'PR': 'Puerto Rico',
'QA': 'Qatar',
'RE': 'Reunion',
'RO': 'Romania',
'RU': 'Russian Federation',
'RW': 'Rwanda',
'BL': 'Saint Barthelemy',
'SH': 'Saint Helena',
'KN': 'Saint Kitts And Nevis',
'LC': 'Saint Lucia',
'MF': 'Saint Martin',
'PM': 'Saint Pierre And Miquelon',
'VC': 'Saint Vincent And Grenadines',
'WS': 'Samoa',
'SM': 'San Marino',
'ST': 'Sao Tome And Principe',
'SA': 'Saudi Arabia',
'SN': 'Senegal',
'RS': 'Serbia',
'SC': 'Seychelles',
'SL': 'Sierra Leone',
'SG': 'Singapore',
'SK': 'Slovakia',
'SI': 'Slovenia',
'SB': 'Solomon Islands',
'SO': 'Somalia',
'ZA': 'South Africa',
'GS': 'South Georgia And Sandwich Isl.',
'ES': 'Spain',
'LK': 'Sri Lanka',
'SD': 'Sudan',
'SR': 'Suriname',
'SJ': 'Svalbard And Jan Mayen',
'SZ': 'Swaziland',
'SE': 'Sweden',
'CH': 'Switzerland',
'SY': 'Syrian Arab Republic',
'TW': 'Taiwan',
'TJ': 'Tajikistan',
'TZ': 'Tanzania',
'TH': 'Thailand',
'TL': 'Timor-Leste',
'TG': 'Togo',
'TK': 'Tokelau',
'TO': 'Tonga',
'TT': 'Trinidad And Tobago',
'TN': 'Tunisia',
'TR': 'Turkey',
'TM': 'Turkmenistan',
'TC': 'Turks And Caicos Islands',
'TV': 'Tuvalu',
'UG': 'Uganda',
'UA': 'Ukraine',
'AE': 'United Arab Emirates',
'GB': 'United Kingdom',
'US': 'United States',
'UM': 'United States Outlying Islands',
'UY': 'Uruguay',
'UZ': 'Uzbekistan',
'VU': 'Vanuatu',
'VE': 'Venezuela',
'VN': 'Viet Nam',
'VG': 'Virgin Islands, British',
'VI': 'Virgin Islands, U.S.',
'WF': 'Wallis And Futuna',
'EH': 'Western Sahara',
'YE': 'Yemen',
'ZM': 'Zambia',
'ZW': 'Zimbabwe'
};
function getCountryName(countryCode) {
if (isoCountries.hasOwnProperty(countryCode)) {
return isoCountries[countryCode];
} else {
return countryCode;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6722
src/static/stylesheets/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
.text-red {
color: #c30000;
}
.font-weight-bold {
font-weight: bold;
}
div.dataTables_wrapper {
margin-top: 10px;
color: #d1ecfc;
}
div#Clients-Table_length {
margin-top: 5px;
}
label.col-md-4.control-label {
color: #a9c5d0;
}
.Print-Only {
display: none;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
<footer class="py-5">
<div class="container">
<div class="row">
<div class="col-6 col-sm-4 text-xs-center order-sm-2">
<a class="text-white" target="_blank" href="https://www.reddit.com/user/BeamNG-MP_Mod_Team">
<i class="fab fa-reddit"></i>
</a>
<a class="text-white" target="_blank" href="https://twitter.com/BeamMP_Mod_Team">
<i class="fab fa-twitter"></i>
</a>
<a class="text-white" target="_blank" href="https://www.facebook.com/BeamNGMP">
<i class="fab fa-facebook"></i>
</a>
</div>
<div class="col-6 justify-content-between col-sm-4 text-right text-xs-center order-sm-3">
<a class="text-white" target="_blank" href="https://github.com/BeamMP">
<i class="fab fa-github"></i>
</a>
<a class="text-white" target="_blank" href="https://discord.gg/beammp">
<i class="fab fa-discord"></i>
</a>
<a class="text-white" target="_blank" href="https://www.beamng.com/threads/beamng-drive-multiplayer-beamng-mp-formally-local-multiplayer-lua-based.63052/">
<i class="fa fa-envelope"></i>
</a>
</div>
</div>
<div class="col-12 col-sm-4 text-center py-4 order-sm-2">
<small class="text-white">&#xA9; 2020 - Present | BeamMP Mod Team All Rights Reserved</small>
<small class="ml-1">
<a href="https://forum.beammp.com/topic/95/privacy-policy-v1-0" target="_blank">Privacy Policy</a>
&middot;
<a href="https://forum.beammp.com/topic/94/terms-of-use-v1-0">Terms &amp; Conditions</a>
</small>
</div>
</div>
</footer>

View File

@@ -0,0 +1,95 @@
<div class="container">
<div class="row center-xs">
<div class="col-md-4 col-sm-4">
<a class="logo-img" href="/">
<div class="logo-image">
<img src="../img/beammp-logo.png" alt="BeamMP Logo" class="img-fluid"/>
</div>
</a>
</div>
<div class="col-md-8 col-sm-8">
<div class="burger-menu">
<button class="navbar-toggler toggler-example" type="button" data-toggle="collapse" data-target="#navbarSupportedContent1" aria-controls="navbarSupportedContent1" aria-expanded="false" aria-label="Toggle navigation"><span class="dark-blue-text"><i class="fas fa-bars fa-1x"></i></span></button>
</div>
<!-- Collapsible content -->
<div class="collapse navbar-collapse" id="navbarSupportedContent1">
<!-- Links -->
<div class="mobile-container">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="https://forum.beammp.com">Forum</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://wiki.beammp.com">Wiki</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/servers">Servers</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/stats">Statistics</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/BeamMP/BeamMP">GitHub</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://www.patreon.com/BeamMP">Patreon</a>
</li>
</ul>
</div>
</div>
<div class="mobile-container">
<div class="topnav mobile-links">
<div id="burger-links">
<a href="https://forum.beammp.com">Forum</a>
<a href="https://wiki.beammp.com">Docs</a>
<a href="/servers">Servers</a>
<a href="/stats">Statistics</a>
<a href="https://github.com/BeamMP/BeamMP">GitHub</a>
<a href="https://www.patreon.com/BeamMP">Patreon</a>
</div>
<a href="javascript:void(0);" class="icon" onclick="myFunction()">
<i class="fa fa-bars"></i>
</a>
</div>
</div>
<div class="navbar-links">
<ul class="links">
<li>
<a href="https://forum.beammp.com">
<span class="text">Forum</span>
</a>
</li>
<li>
<a href="https://wiki.beammp.com">
<span class="text">Docs</span>
</a>
</li>
<li>
<a href="/servers">
<span class="text">Servers</span>
</a>
</li>
<li>
<a href="/stats">
<span class="text">Statistics</span>
</a>
</li>
<li>
<a href="https://github.com/BeamMP/BeamMP">
<span class="text">Github</span>
</a>
</li>
<li>
<a href="https://www.patreon.com/BeamMP">
<span class="text">Patreon</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>

181
src/views/index.ejs Normal file
View File

@@ -0,0 +1,181 @@
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>BeamMP</title>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
<!-- <link rel="stylesheet" type="text/css" href="../static/css/styles.css"/>-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<script src="https://kit.fontawesome.com/90f05b466c.js" crossorigin="anonymous"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-160071688-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-160071688-1');
</script>
</head>
<body>
<nav class="nav">
<%- include('includes/nav.ejs') %>
</nav>
<header class="main-content" style="background-position: center center, center 0px;">
<div class="introduction" style="margin-top: 0px;">
<div class="container">
<div class="row center-xs middle-xs">
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">
<p class="lead">
<b>BeamMP</b> Bringing Multiplayer to BeamNG.drive!<br>
With a smooth and enjoyable experience.
</div>
<div id="button" class="col-lg-4 col-md-4 col-sm-4 buttons-wrapper hidden-xs">
<div class="buttons">
<button class="download-client js-show-story" onclick="downloadinstaller()" href="beamMP.zip" download>
<span class="text">Download Client</span>
<span class="description"> BeamMP_Installer.zip</span>
</button>
</div>
<div class="buttons mt-3">
<button class="download-client js-show-story" onclick="downloadserver()" href="beamMP.zip" download style="background: radial-gradient(circle,rgb(255 179 38 / 80%),rgb(255 176 0 / 65%)) center/100%;">
<span class="text">Download Server</span>
<span class="description"> BeamMP-Server</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<section id="features">
<div class="container">
<div class="row center-lg center-md center-sm center-xs features">
<article class="col-lg-3">
<h2>Stable Servers</h2>
BeamMP allows for stable servers,
with a variety of servers located accross the globe.
</article>
<article class="col-lg-3 col-md-6 col-sm-6 col-xs-12">
<h2> BeamNG.drive </h2> BeamMP uses the same maps, vehicles & mods
so you don't need to learn anything new!
</article>
<article class="col-lg-3 col-md-6 col-sm-6 col-xs-12">
<h2> Standalone </h2> BeamMP doesn't modify your original installation,
so you can play either singleplayer or multiplayer.
</article>
<article class="col-lg-3 col-md-6 col-sm-6 col-xs-12">
<h2> Sync quality </h2> BeamMP updates your vehicle position ~100 times per second,
allowing for a smooth overall experience.
</article>
</div>
</div>
<hr>
<div class="row middle-lg">
<div class="col-lg-6">
<figure>
<!-- <img src="../img/beammpservers.png">-->
<img src="../img/beammpservers.png">
</figure>
</div>
<div class="col-lg-6" style="text-align:center">
<ul class="user-features-list">
<li> Dedicated servers </li>
<li> The original BeamNG.Drive</li>
<li> Dedicated support team</li>
<li> 24/7 Global Access</li>
</ul>
</div>
</div>
</section>
<hr>
<section id="faq"><div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="container">
<!-- <div class="row"> -->
<h1>FAQ.</h1>
<div class="faq">
<h3 id="faq-heading">The server list is not showing up!</h3>
<p>Try restarting BeamMP as this can sometimes happen, if this fails to fix your issue please create a topic on our forum or visit the support channel on our discord</p>
<h3 id="faq-heading">How do I open a ticket in case something doesnt work or I have questions?</h3>
<p>Please check the <b>#how-to-use</b> channel in Discord and on our forum. Please give an accurate description of what youve done so the support team will help you in a fast and effective way. </p>
<h3 id="faq-heading">Help! Im getting error codes</h3>
<p>Please head over to our forum and see if anyone has had the issue before. It is likely that someone else has at some point and therefore there will also probably be a solution posted with it too in the replies. Altervatively visit our discord where the larger portion of community is currently based.</p>
<h3 id="faq-heading"> Does this work with pirated versions of BeamNG.drive?</h3>
<p>We dont know if it works with pirated versions of BeamNG.drive, but we <b>will not</b> provide any support to non legit copies of the game. Nor will we change to support it.</p>
<h3 id="faq-heading">How do I host a server?</h3>
<p>The server files required for hosting your own server can be found at the top of this page below the client download. You will also require a authentication key which can be found from <a href="https://beammp.com/k/keys">keymaster</a>. Further information around the setup can be found on our <a href="https://wiki.beammp.com/en/home/Server_Mod">wiki</a>.</p>
<h3 id="faq-heading">Can I use mods?</h3>
<p>Mods are supported, These are installed on the server. See our <a href="https://wiki.beammp.com/en/home/Server_Mod">wiki</a> for more infomation.</p>
</div>
</div>
</div>
</div>
</section>
<%- include('includes/footer.ejs') %>
<!-- <footer class="">
<div class="col-1 justify-content-between socials-left">
<ul class="list-inline">
<li class="col-xs-4 list-inline-item h3" data-toggle="tooltip" data-placement="top" title="" aria-label="Reddit" data-original-title="Reddit">
<a class="text-white" target="_blank" href="https://www.reddit.com/user/BeamNG-MP_Mod_Team">
<i class="fab fa-reddit"></i>
</a>
</li>
<li class="col-xs-4 list-inline-item h3" data-toggle="tooltip" data-placement="top" title="" aria-label="Twitter" data-original-title="Twitter">
<a class="text-white" target="_blank" href="https://twitter.com/BeamMP_Mod_Team">
<i class="fab fa-twitter"></i>
</a>
</li>
<li class="col-xs-4 list-inline-item h3" data-toggle="tooltip" data-placement="top" title="" aria-label="Facebook" data-original-title="Facebook">
<a class="text-white" target="_blank" href="https://www.facebook.com/BeamNGMP">
<i class="fab fa-facebook"></i>
</a>
</li>
</ul>
</div>
<div class="row middle-xs">
<hr>
<div class="col-lg-8 col-md-7 col-sm-6">
<p>BeamMP is not affiliated by BeamNG.Drive, Any trademarks belong to their respective owners.
</p>
</div>
<div class="copyright col-lg-4 col-md-5 col-sm-6">
<p class="righty"> © 2021 BeamMP Mod Team All Rights Reserved.
</p>
</div>
</div>
</footer> -->
<script>
function downloadinstaller() {
document.location.href ="/installer/BeamMP_Installer.zip";
//alert("Sorry this is coming soon, Therefore it is not available just yet. Please join the discord to get the latest version: https://discord.gg/beammp")
}
function downloadserver() {
document.location.href ="https://github.com/BeamMP/BeamMP-Server/releases/latest";
//alert("Sorry this is coming soon, Therefore it is not available just yet. Please join the discord to get the latest version: https://discord.gg/beammp")
}
function myFunction() {
var x = document.getElementById("burger-links");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
</script>
<script src="js/script.js"></script>
<!-- <script src="../static/js/script.js"></script>-->
</body>

68
src/views/servers.ejs Normal file
View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>BeamNG-MP-Servers</title>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
<link href="css/servers-styles.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" crossorigin="anonymous"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-160071688-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-160071688-1');
</script>
</head>
<body class="sb-nav-fixed">
<span id="TEMPAREA" style="display:none;"></span>
<nav class="nav" style="position: unset !important;">
<%- include('includes/nav.ejs') %>
</nav>
<div class="container-fluid">
<div id="layoutSidenav_content">
<h1 class="mt-4" style="color:white;">Server List</h1>
<div class="card mb-4">
<div class="card-header"><i class="fas fa-server mr-1"></i>BeamMP Server List</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Location</th>
<th>Server Name</th>
<th>Map</th>
<th>Players</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Location</th>
<th>Server Name</th>
<th>Map</th>
<th>Players</th>
</tr>
</tfoot>
<tbody id="Servers-List">
</tbody>
</table>
</div>
</div>
</div>
</div>
<%- include('includes/footer.ejs') %>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="js/scripts.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js" crossorigin="anonymous"></script>
</body>
</html>

192
src/views/stats.ejs Normal file
View File

@@ -0,0 +1,192 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="BeamMP Mod Team" />
<title>BeamMP | Statistics</title>
<link rel="stylesheet" type="text/css" href="css/styles.css"/>
<link href="css/servers-styles.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" crossorigin="anonymous"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-160071688-1"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-160071688-1');
</script>
</head>
<body>
<nav class="nav" style="position: unset !important;">
<%- include('includes/nav.ejs') %>
</nav>
<div class="container-fluid">
<div id="layoutSidenav_content">
<div class="row">
<div class="col-md-12">
<h1 class="mt-4" style="color:white;"><i class="fas fa-server mr-1"></i>BeamMP Statistics <h3 id="LivePlayerCount" style="color:white;"></h3></h1>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Highest Recorded Players</h5>
<p class="card-text text-muted" id="MAXPLAYERS"></p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Highest Recorded Servers</h5>
<p class="card-text text-muted" id="MAXSERVERS"></p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Todays Average Players</h5>
<p class="card-text text-muted" id="AVERAGES"></p
</div>
</div>
</div>
</div>
<div class="col-md-12">
<canvas id="myChart" width="100vw" height="770"></canvas>
</div>
</div>
<footer class="py-4 bg-light mt-auto">
<div class="container-fluid">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted">Copyright &copy; BeamMP Development Team 2021</div>
<div>
<a href="https://forum.beammp.com/topic/95/privacy-policy-v1-0">Privacy Policy</a>
&middot;
<a href="https://forum.beammp.com/topic/94/terms-of-use-v1-0">Terms &amp; Conditions</a>
</div>
</div>
</div>
</footer>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js" crossorigin="anonymous"></script>
<script type="text/javascript">
var chartData = {};
var GetChartData = function (period) {
$.ajax({
type: 'GET',
url: 'https://backend.beammp.com/stats-info',
data: {
period: (period) ? period : 'today',
},
dataType: 'json',
success: function (d) {
console.log(d)
var average = 0;
var Data = {}
Data.Players = []
Data.Servers = []
Data.v2Players = []
Data.v2Servers = []
Data.Labels = []
console.log(d.maxp, d.maxs)
console.log(d.v2history)
if (d.v2history) {
var count = 0
var tot = 0
d.v2history.forEach(function(item, index) {
Data.Labels.push(item.datetime)
Data.v2Players.push(item.players)
if (typeof(item.servers) == 'number') Data.v2Servers.push(item.servers);
if (typeof(item.servers) == 'object') Data.v2Servers.push(item.servers.count);
tot += parseInt(item.players)
count++;
});
average = tot / count
}
$('#MAXPLAYERS').text(d.maxp);
$('#MAXSERVERS').text(d.maxs);
$('#AVERAGES').text(Math.floor(average));
$('#LivePlayerCount').text(`Currently Online: ${d.v2history[d.v2history.length-1].players}`)
console.log(Data)
document.getElementById('myChart').innerHTML = '';
var ctx = document.getElementById('myChart').getContext('2d');
ctx.height = 770;
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: Data.Labels,
datasets: [{
label: 'Servers',
backgroundColor: 'rgba(255,0,0,0.1)',
borderColor: 'rgba(255,0,0,0.4)',
data: Data.v2Servers,
fill: false,
}, {
label: 'Players',
fill: false,
backgroundColor: 'rgba(0,0,255,0.1)',
borderColor: 'rgba(0,0,255,0.4)',
data: Data.v2Players,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: 'BeamMP Statistics'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
x: {
display: true,
scaleLabel: {
display: true,
labelString: 'Time'
}
},
y: {
display: true,
scaleLabel: {
display: true,
labelString: 'Count'
}
}
}
}
})
}
});
};
$(document).ready(function() {
GetChartData();
});
//const socket = io('./stats');
</script>
</body>
</html>

117
src/webserver.js Normal file
View File

@@ -0,0 +1,117 @@
/*
* oooooooooo. ooo ooooo ooooooooo.
* `888' `Y8b `88. .888' `888 `Y88.
* 888 888 .ooooo. .oooo. ooo. .oo. .oo. 888b d'888 888 .d88'
* 888oooo888' d88' `88b `P )88b `888P"Y88bP"Y88b 8 Y88. .P 888 888ooo88P'
* 888 `88b 888ooo888 .oP"888 888 888 888 8 `888' 888 888
* 888 .88P 888 .o d8( 888 888 888 888 8 Y 888 888
* o888bood8P' `Y8bod8P' `Y888""8o o888o o888o o888o o8o o888o o888o
* ========================================================================
* Updated: 2/11/22 22:17
* Copyright (c) 2019-2022 BeamMP Ltd. All rights reserved.
*/
require('dotenv').config()
const helmet = require("helmet");
var morgan = require('morgan');
const express = require('express')
const WebServer = express()
const routes = require('./routes')
const server = require('http').createServer(WebServer)
//////////////////////////////////////////////////////////////////////
// Cluster Handling
//////////////////////////////////////////////////////////////////////
const cluster = require('cluster');
if (!cluster.isMaster) {
cluster.worker.on('disconnect', function() {
console.log('Worker disconnected, closing server');
server.close(() => {
console.log('HTTP server closed')
})
});
}
//////////////////////////////////////////////////////////////////////
// Main Webserver
//////////////////////////////////////////////////////////////////////
;(app => {
'use strict'
module.exports.server = server
module.exports.app = app
module.exports.init = async (callback) => {
app.disable('x-powered-by')
if (process.env.DEBUG == "true") {
console.log('Request Logging Enabled.')
app.use(morgan('dev', {
/*skip: function (req, res) {
return res.statusCode == 200 || res.statusCode == 401
}*/
}))
}
app.use(helmet());
// CORS
app.use(allowCrossDomain)
// PROXY HANDLING
app.set('trust proxy', true);
// set the view engine to ejs
app.set('view engine', 'ejs');
app.use(express.static(require('path').join(__dirname, 'static')))
app.set("views", "./src/views")
routes(app)
if (typeof callback === 'function') callback()
}
module.exports.listen = (callback) => {
server.on('error', err => {
if (err.code === 'EADDRINUSE') {
console.error('Address in use, exiting...')
server.close()
} else {
console.error(err.message)
throw err
}
})
server.listen(process.env.PORT, '0.0.0.0', () => {
console.log('Backend is now listening on port: ' + process.env.PORT)
if (typeof callback === 'function') return callback()
})
}
})(WebServer)
function allowCrossDomain (req, res, next) {
const allowedOrigins = ['http://127.0.0.1:3599', 'http://localhost:3599', 'https://beammp.com', 'https://backend.beammp.com'];
const origin = req.headers['origin'];
console.log(origin)
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
//res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') // TODO: Update this to the keymaster domain
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
res.setHeader(
'Access-Control-Allow-Headers',
'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,authorization,X-RToken,X-Token,Origin'
)
res.setHeader('Content-Security-Policy', "frame-ancestors 'none';")
if (req.method === 'OPTIONS') {
res.sendStatus(200)
} else {
next()
}
}