4.7.2.1 dev version 1 collect logs

This commit is contained in:
SowinskiBraeden committed 2023-03-07 17:18:37 -08:00
1 parent e109701147
commit 51b7a8d1c3
6 files changed
+221 -7

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
const { EmbedBuilder } = require('discord.js');
module.exports = {
name: "debug",
debug: true,
global: true,
description: "debug",
usage: "",
permissions: {
channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"],
member: [],
},
options: [],
SlashCommand: {
/**
*
* @param {require("../structures/QuarksBot")} client
* @param {import("discord.js").Message} message
* @param {string[]} args
* @param {*} param3
*/
run: async (client, interaction, args, { GuildDB }, start) => {
client.updateLogs()
return interaction.send({ content: 'debugging...' })
},
},
}
+5
View File
@@ -9,6 +9,11 @@ module.exports = {
SupportServer: "https://discord.gg/KVFJCvvFtK", //Support Server Link SupportServer: "https://discord.gg/KVFJCvvFtK", //Support Server Link
Token: process.env.token || "", //Discord Bot Token Token: process.env.token || "", //Discord Bot Token
Scopes: ["identify", "guilds", "applications.commands"], //Discord OAuth2 Scopes Scopes: ["identify", "guilds", "applications.commands"], //Discord OAuth2 Scopes
Nitrado: {
ServerID: process.env.SERVER_ID,
UserID: process.env.USER_ID,
Auth: process.env.AUTH_KEY
},
IconURL: "", IconURL: "",
Colors: { Colors: {
Default: "#8a7c72", Default: "#8a7c72",
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "dayz-armbands", "name": "dayz-armbands",
"version": "0.0.1", "version": "4.7.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "dayz-armbands", "name": "dayz-armbands",
"version": "0.0.1", "version": "4.7.2",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@discordjs/rest": "^1.1.0", "@discordjs/rest": "^1.1.0",
+4 -4
View File
@@ -1,7 +1,7 @@
{ {
"name": "dayz-armbands", "name": "dayz-armbands",
"version": "4.7.2", "version": "4.7.2.1",
"description": "A Discord Bot to handle DayZ server flags and armbands for in game factions.", "description": "A General Purpose Discord Bot for DayZ Servers.",
"main": "index.js", "main": "index.js",
"nodemonConfig": { "nodemonConfig": {
"ignore": [ "ignore": [
@@ -11,8 +11,8 @@
}, },
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",
"dev": "node dev-index.js", "dev": "node index.js",
"debug": "nodemon dev-index.js" "debug": "nodemon index.js"
}, },
"author": "Braeden Sowinski", "author": "Braeden Sowinski",
"license": "ISC", "license": "ISC",
+18 -1
View File
@@ -3,8 +3,11 @@ const { Collection, Client, EmbedBuilder, Routes } = require('discord.js');
const MongoClient = require('mongodb').MongoClient; const MongoClient = require('mongodb').MongoClient;
const { REST } = require('@discordjs/rest'); const { REST } = require('@discordjs/rest');
const Logger = require("../util/Logger"); const Logger = require("../util/Logger");
const path = require("path"); const path = require("path");
const fs = require('fs'); const fs = require('fs');
const { Readable } = require('stream');
const { finished } = require('stream/promises');
class DayzArmbands extends Client { class DayzArmbands extends Client {
@@ -15,7 +18,7 @@ class DayzArmbands extends Client {
this.commands = new Collection(); this.commands = new Collection();
this.interactionHandlers = new Collection(); this.interactionHandlers = new Collection();
this.logger = new Logger(path.join(__dirname, "..", "logs/Logs.log")); this.logger = new Logger(path.join(__dirname, "..", "logs/Logs.log"));
if (this.config.Token === "") if (this.config.Token === "")
throw new TypeError( throw new TypeError(
"The config.js is not filled out. Please make sure nothing is blank, otherwise the bot will not work properly." "The config.js is not filled out. Please make sure nothing is blank, otherwise the bot will not work properly."
@@ -87,6 +90,20 @@ class DayzArmbands extends Client {
const client = this; const client = this;
} }
async updateLogs() {
const res = await fetch(`https://api.nitrado.net/services/${this.config.Nitrado.ServerID}/gameservers/file_server/download?file=/games/${this.config.Nitrado.UserID}/noftp/dayzxb/config/DayZServer_X1_x64.ADM`, {
headers: {
"Authorization": this.config.Nitrado.Auth
}
}).then(response =>
response.json().then(data => data)
).then(res => res);
const stream = fs.createWriteStream('./logs/server-logs.ADM');
const { body } = await fetch(res.data.token.url);
await finished(Readable.fromWeb(body).pipe(stream));
}
async connectMongo(mongoURI, dbo) { async connectMongo(mongoURI, dbo) {
let failed = false; let failed = false;
+163
View File
@@ -0,0 +1,163 @@
#!/usr/bin/env python3
import requests
import urllib
import json
import os
import re
from enum import Enum
from dotenv import load_dotenv
load_dotenv()
AUTH_KEY: str = os.getenv('AUTH_KEY')
SERVER_ID: str = os.getenv('SERVER_ID')
USER_ID: str = os.getenv('USER_ID')
AUTH_KEY: str = 'nrBQHGnTMMzQZbInit-C-DLYBtywLc-15GHLw9Zjj_K87V8L589BqAIPW8d9vh7Zc-NtyyL798YO9V9o2GT7gpug0GiiKR8wrE-b'
SERVER_ID: str = '12215784'
USER_ID: str = 'ni8434545_1'
class LogTemplates(Enum):
pos: str = '$time | Player "$gamertag" (id=$playerID pos=<$pos>)'
damage: str = '$time | Player "$gamertag" (DEAD) (id=$playerID pos=<3$pos>)[HP: 0] hit by Player "$killer" (id=$killerID pos=<$killerPOS>) into $areaHit for $damageVal damage ($bullet_type) with $weapon from $distance meters'
killed: str = '$time | Player "$gamertag" (DEAD) (id=$playerID pos=<3$pos>) killed by Player "$killer" (id=$killerID pos=<$killerPOS>) with $weapon from $distance meters'
connect: str = '$time | Player "$gamertag" is connected (id=$playerID)'
disconnect: str = '$time | Player "$gamertag" (id=$playerID pos=<$pos>) has been disconnected'
logFlags = [
"disconnected",
") placed ",
"connected",
"hit by",
"regained consciousne",
"is unconscious",
"killed by",
")Built ",
") folded",
")Player SurvivorBase",
") died.",
") committed suicide",
")Dismantled",
") bled"
]
players = {
'players': []
}
# Download Raw Logs off Nitrado
def getRawLogs():
data = requests.get(
f"https://api.nitrado.net/services/{SERVER_ID}/gameservers/file_server/download?file=/games/{USER_ID}/noftp/dayzxb/config/DayZServer_X1_x64.ADM",
headers={
"Authorization": AUTH_KEY
}).json()
print(data)
# url = data['data']['token']['url']
# if not os.path.exists('output'): os.mkdir('output')
# urllib.request.urlretrieve(url, "./output/logs.ADM")
# Convert Raw Logs into cleaned logs (only positional data logs)
def cleanLogs():
with open("./output/logs.ADM", "r") as logs:
lines = logs.readlines()
# Isolate Player logs (Removes Connect, Disconnect, place, hit)
with open("./output/clean.txt", "w") as logs:
for line in lines:
if not any(flag in line for flag in logFlags) and "| Player" in line.strip("\n"):
logs.write(line)
# Generate List of player names, id's and positions
def collectPlayerData():
with open('./output/clean.txt', 'r') as logs:
cleanLines = logs.readlines()
for line in cleanLines:
pattern = re.escape(LogTemplates.pos)
pattern = re.sub(r'\\\$(\w+)', r'(?P<\1>.*)', pattern)
data = re.match(pattern, line)
if data is None: break
query = {
'gamertag': data.groupdict()['gamertag'],
'playerID': data.groupdict()['playerID'],
'time': data.groupdict()['time']+' EST',
'pos': data.groupdict()['pos'].split(", "),
'posHistory': []
}
if len(players['players'])==0: players['players'].append(query)
else:
for i in range(len(players['players'])):
if players['players'][i]['gamertag']==data.groupdict()['gamertag']:
# Updates existing player data
for j in range(len(players['players'][i]['posHistory'])):
query['posHistory'].append({
'time': players['players'][i]['posHistory'][j]['time'],
'pos': players['players'][i]['posHistory'][j]['pos']
})
query['posHistory'].append({
'time': players['players'][i]['time'],
'pos': players['players'][i]['pos']
})
players['players'].remove(players['players'][i])
break
# Logs new player data
players['players'].append(query)
# Search Logs for Connected and Disconnected messages
def activeStatus():
with open("./output/logs.ADM", "r") as logs:
lines = logs.readlines()
for line in lines:
status = ""
update = False
if "\" is connected" in line.strip("\n") and "| Player" in line.strip("\n"):
status = "Online"
update = True
elif ") has been disconnected" in line.strip("\n") and "| Player" in line.strip("\n"):
status = "Offline"
update = True
if update:
beginPlayer = 19 # Player names always start here
if status=="Online": endPlayer = line.strip("\n").find("\" is")
if status=="Offline": endPlayer = line.strip("\n").find("\"(id=")
playerName = line.strip("\n")[beginPlayer:endPlayer]
playerFoundAndUpdated = False
for i in range(len(players['players'])):
if players['players'][i]['gamertag']==playerName:
players['players'][i]['connectionStatus'] = status
playerFoundAndUpdated = True
if not playerFoundAndUpdated:
# Get player ID
beginID = line.strip("\n").find('(id=')+4
endID = line.strip("\n").find(")")
playerID = line.strip("\n")[beginID:endID]
query = {
"gamertag": playerName,
"playerID": playerID,
"time": None,
"pos": [],
"posHistory": [],
"connectionStatus": "Online"
}
# Logs new player data
players["players"].append(query)
if __name__ == '__main__':
getRawLogs()
cleanLogs()
collectPlayerData()
activeStatus()
with open("./output/players.json", "w") as playerJSON:
json.dump(players, playerJSON, ensure_ascii=False, indent=2)