Skip to content
This repository has been archived by the owner on Feb 4, 2025. It is now read-only.

Commit

Permalink
[MOD] logging events and errors to JSON files, log.html page for view…
Browse files Browse the repository at this point in the history
…ing logs, various updates to logic
  • Loading branch information
redfellow committed Nov 4, 2020
1 parent f247078 commit a8f4c9b
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 14 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,15 @@
\.history/

node_modules/

errors.json

lastpost.log

lastshow.log

log.json

package-lock.json

user.json
77 changes: 65 additions & 12 deletions civ-handler.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const moment = require("moment");

module.exports = {

startApp: function (app) {
Expand All @@ -6,26 +8,77 @@ module.exports = {

setInterval(function () {
console.log(new Date(), `[✔] civ-handler >> root > still listening for POSTs..`)
}, 1500000)
}, APP_ALIVE_INTERVAL)
},

handleAlive: function (req, res) {
console.log(new Date(), `[✔] civ-handler >> app.get > Alive request received`)
res.status(200).send({
timestamp: new Date(),
message: `[⚠] civ-handler >> handleAlive > Alive request handled`
})
},

showLog: function (req, res) {
const fs = require('fs')
const forwarded = req.headers['x-forwarded-for']
const ip = forwarded ? forwarded.split(/, /)[0] : req.connection.remoteAddress

console.log(new Date(), `[✔] civ-handler >> app.get > Log request received from ${ip}`)

res.render(__dirname + "/log.html", {
moment: moment,
SENT_MESSAGES : SENT_MESSAGES,
ERRORS : ERRORS
});

fs.writeFile('lastshow.log', ip, (err) => {
if (err) throw err;
});
},

handlePost: function (req, res) {
const fs = require('fs')
const forwarded = req.headers['x-forwarded-for']
const ip = forwarded ? forwarded.split(/, /)[0] : req.connection.remoteAddress
console.log(new Date(), `[✔] civ-handler >> app.post > POST received`, req.body)
CIV.setVars(req.body);

CIV.setVars(req.body, ip);
CIV.setHook()
CIV.duplicateCheck()

if ("errorMsg" in VARS === false) CIV.sendDiscordMessage(req, res)
else CIV.handleError(req, res)
else CIV.handleError(req, res, ip)

fs.writeFile('log.json', JSON.stringify(SENT_MESSAGES), (err) => {
if (err) throw err;
});

fs.writeFile('errors.json', JSON.stringify(ERRORS), (err) => {
if (err) throw err;
});

var lastpostData = JSON.stringify({
ip: ip,
post: req.body
});

fs.writeFile('lastpost.log', lastpostData, (err) => {
if (err) throw err;
});
},


setVars: function (json) {
setVars: function (json, ip) {
var date = new Date();
VARS = {
time: moment().format("DD.MM.YYYY - H:mm:ss"),
epoch: moment().valueOf(),
game: json.value1,
player: USER_MAP[json.value2] || json.value2,
playerRaw: json.value2,
turn: json.value3,
ip: ip
}

VARS.msgTitle = `Hey ${VARS.player}, it's your turn to play!`
Expand All @@ -41,7 +94,7 @@ module.exports = {
return
}
}

VARS.errorMsg = `'${VARS.game}' could not be matched to any of the defined HOOKS`
},

Expand All @@ -66,30 +119,30 @@ module.exports = {
message: `[✔] civ-handler >> handlePost > request passed to discord successfully`,
VARS: VARS,
POSTRequestHeaders: req.headers,
remoteAddress: req.connection.remoteAddress
})
},


handleError: function (req, res) {
handleError: function (req, res, ip) {
console.warn(new Date(), `[⚠] civ-handler >> handleError > ${VARS.errorMsg}`)
if (typeof VARS.hook === "object") delete VARS.hook
res.status(500).send({
ERRORS[new Date().valueOf()] = VARS;
res.status(400).send({
timestamp: new Date(),
message: `[⚠] civ-handler >> handleError > ${VARS.errorMsg}`,
VARS: VARS,
POSTRequestHeaders: req.headers,
remoteAddress: req.connection.remoteAddress
remoteAddress: ip
})
},



duplicateCheck: function() {
VARS.hash = `${VARS.game}-${VARS.player}-${VARS.turn}`.replace(/ /g, "-").toLowerCase()
VARS.hash = `${VARS.game}-${VARS.playerRaw}-${VARS.turn}`.replace(/ /g, "-").toLowerCase()

if (SENT_MESSAGES[VARS.hash] !== true) {
SENT_MESSAGES[VARS.hash] = true;
if (!SENT_MESSAGES[VARS.hash]) {
SENT_MESSAGES[VARS.hash] = VARS;
}
else {
VARS.errorMsg = `'${VARS.hash}' was already sent, skipping duplicate.`
Expand Down
225 changes: 225 additions & 0 deletions log.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<!doctype html>

<html lang="en">

<head>
<meta charset="utf-8">
<title>Civilization 6 - Play by Cloud Webhook logs</title>

<link href="https://unpkg.com/[email protected]/dist/css/tabulator_midnight.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"
integrity="sha512-rmZcZsyhe0/MAjquhTgiUcb4d9knaFc7b5xAfju483gbEXTkeJRUMIPk6s3ySZMYUHEcjKbjLjyddGWMrNEvZg=="
crossorigin="anonymous"></script>
<style>
@import 'https://fonts.googleapis.com/css?family=Open+Sans';

html {
font-size: 10px;
background: radial-gradient(circle at top, #333 , #000);
color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
min-height: 100vh;
}

body {
line-height: 2rem;
font-size: 1.6rem;
max-width: 1440px;
padding: 3.5rem;
margin: 0 auto;
}

h1 {
margin-top: 0;
margin-bottom: 4rem;
color: #bf4d3b;
font-size: 1.45em;
text-align: center;
font-weight: 800;
}

h2 {
font-size: 1.2em;
font-weight: 300;
margin-top: 0;
margin-bottom: 0.5rem;
}

* {
text-shadow: 0 1px 0 rgba(0, 0, 0, .5);
}

.tabulator-table {
min-width: 100%;
}

.tabulator-header {
margin-bottom: 1rem;
border-radius: 3px;
border: 1px solid #00000040 !important;
font-weight: 500 !important;

}

.tabulator-table {
background: none !important;
}

.tabulator-tableHolder {
border-radius: 3px;
border: 1px solid #00000040 !important;
}

.tabulator-row {
background-color: rgba(30,30,34,.85);
}

.tabulator-row:nth-child(2n) {
background-color: rgba(43,43,49,.85);
}

.tabulator-headers .tabulator-col-title {
padding: 1rem;
text-transform: capitalize;
}

.tabulator-header .tabulator-col {
background: rgba(61, 55, 55, .85) !important;
}

.tabulator-col,
.tabulator-cell {
color: rgba(255,255,255,0.90) !important;
border-color: #000 !important;
font-size: 0.9em !important;
}

.tabulator-cell {
border-color: #000 !important;
font-size: 1.1em;
font-weight: 400 !important;
padding: 0.5rem 2rem !important;
}

.tabulator {
box-shadow: 3px 6px 16px #00000030;
background: none;
border: none;
margin: 0 0 2rem 0;
}

.tabulator-row.tabulator-selectable:hover {
background-color: #334;
cursor: pointer;
}
</style>

</head>

<body>
<h1>Civilization 6 - Play by Cloud Webhook logs</h1>

<h2>Handled events</h2>

<table id="logTable">
<thead>
<tr>
<th>Epoch</th>
<th>Game</th>
<th>Turn</th>
<th>Player</th>
<th>IP</th>
<th>ID</th>
</tr>
</thead>

<% Object.keys(SENT_MESSAGES).forEach(function(key) { %>
<tr>
<td> <%= SENT_MESSAGES[key].epoch %> </td>
<td> <%= SENT_MESSAGES[key].game %> </td>
<td> <%= SENT_MESSAGES[key].turn %> </td>
<td> <%= SENT_MESSAGES[key].playerRaw %> </td>
<td> <%= SENT_MESSAGES[key].ip %> </td>
<td> <%= SENT_MESSAGES[key].hash %> </td>
</tr>
<% }) %>
</table>

<h2>Errors</h2>

<table id="errorTable">
<thead>
<tr>
<th>Epoch</th>
<th>ID</th>
<th>Error</th>
</tr>
</thead>

<% Object.keys(ERRORS).forEach(function(key) { %>
<tr>
<td> <%= ERRORS[key].epoch %> </td>
<td> <%= ERRORS[key].hash %> </td>
<td> <%= ERRORS[key].errorMsg %> </td>
</tr>
<% }) %>
</table>

<script>
requestAnimationFrame(function() {
new Tabulator("#logTable", {
layout: "fitDataStretch",
columnMinWidth: 185,
autoColumns: true,
autoColumnsDefinitions: [{
field: "epoch",
title: "Time",
formatter: "datetime",
formatterParams: {
inputFormat: "x",
outputFormat: "DD.MM.YYYY HH:mm:ss",
}
},{
field: "ip",
title: "IP Address"
},{
field: "id",
title: "Event ID"
}],
initialSort: [{
column: "epoch",
dir: "desc"
}]
});
});
requestAnimationFrame(function() {
new Tabulator("#errorTable", {
layout: "fitDataStretch",
columnMinWidth: 185,
autoColumns: true,
autoColumnsDefinitions: [{
field: "epoch",
title: "Time",
formatter: "datetime",
formatterParams: {
inputFormat: "x",
outputFormat: "DD.MM.YYYY HH:mm:ss",
}
},{
field: "id",
title: "Event ID"
},{
field: "error",
title: "Error message"
}],
initialSort: [{
column: "epoch",
dir: "desc"
}]
});
});
</script>
</body>

</html>
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
"main": "server.js",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.10.8",
"ejs": "^3.1.5",
"express": "^4.17.1",
"fs": "0.0.1-security",
"json-middleware": "^1.0.2",
"npm": "^6.8.0",
"moment": "^2.27.0",
"npm": "^6.14.8",
"webhook-discord": "^3.1.2"
}
}
Loading

0 comments on commit a8f4c9b

Please sign in to comment.