Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
MicaLovesKPOP authored Jun 24, 2023
1 parent a8f4c78 commit 1320ddb
Showing 1 changed file with 285 additions and 0 deletions.
285 changes: 285 additions & 0 deletions ReplayLogger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
const fs = require('fs');
const path = require('path');

const logFilePath = path.join(__dirname, 'log.txt');

fs.unlink(logFilePath, (err) => {
if (err) {
return;
}
});

const usernameFilePath = path.join(__dirname, 'username.ini');
let replayFilePath;

fs.readFile(usernameFilePath, 'utf8', (err, data) => {
if (err) {
return;
}
const username = data.trim();
replayFilePath = `C:\\Users\\${username}\\AppData\\Local\\Crashday\\replays\\_!lastracereplay!_.rpl`;
console.log(`username.ini file path: ${usernameFilePath}`);
console.log(`Replay file path: ${replayFilePath}`);
});


const interval = setInterval(() => {
if (fs.existsSync(replayFilePath)) {
try {
// Get the modification date of the replay file
const replayFileStats = fs.statSync(replayFilePath);
const replayFileModDate = replayFileStats.mtime;

// Create the output directory
const outputDirName = replayFileModDate.toISOString().slice(0, 10);
const outputDirPath = path.join(path.dirname(replayFilePath), outputDirName);
if (!fs.existsSync(outputDirPath)) {
fs.mkdirSync(outputDirPath);
}

// Replace the desired output file name
const eventNumber = fs.readdirSync(outputDirPath).length + 1;
const gamemodeMatch = fs.readFileSync(replayFilePath, 'utf8').match(/gamevar=(\S+)/);
const gamemodeValue = gamemodeMatch ? gamemodeMatch[1] : 'unknown';
const outputFileName = `${outputDirName} ${getFormattedTime(replayFileModDate)} event${eventNumber} ${gamemodeValue}.log`;
const outputFilePath = path.join(outputDirPath, outputFileName);

// Read the .rpl file
fs.readFile(replayFilePath, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}

// Ignore the initial characters in the file
const startIndex = data.indexOf('RP#');
const trimmedTrackData = data.substring(startIndex);

// Extract the track value
const trackMatch = trimmedTrackData.match(/([0-9`~!@#$%^&()_+\-=[\]{};,. a-z]+?\.trk)/);
// console.log('trackMatch:', trackMatch);
const trackValue = trackMatch ? trackMatch[1] : 'unknown';

// Ignore the initial characters in the file
const endIndex = data.indexOf('\0', startIndex);
let trimmedData = trimmedTrackData.substring(startIndex);

// Remove blocks of null characters that are over 10 characters in size from trimmedData
trimmedData = trimmedData.replace(/\0{10,}/g, '');
console.log('trimmedData:', trimmedData.substring(0,2048));

// Extract the replay event details
const replayEventDetails = `Replay Event Details: ${outputFileName}\n\n`;

// Extract the gamemode value
const gamemodeValue = gamemodeMatch ? gamemodeMatch[1] : 'unknown';

// Extract the gamemode values
const gamemodeMatches = trimmedData.match(/gamemode\w+=(\d+)/g);
const gamemodeValues = gamemodeMatches ? gamemodeMatches.map(match => match.split('=')[1]) : [];

// Determine the gamemode value to display
let gamemodeValueToDisplay = '';
if (gamemodeValues.length === 0) {
gamemodeValueToDisplay = 'unknown';
} else if (gamemodeValues.every(value => value === 'unknown')) {
gamemodeValueToDisplay = 'unknown';
} else {
gamemodeValueToDisplay = gamemodeValues.join(', ');
}

// Format the extracted values
const gamemode = `Gamemode: ${gamemodeValue}, ${gamemodeValueToDisplay}\n`;
const trackName = `Track: ${trackValue}\n\n`;

// Extract the remaining non-player data
const damageMatch = trimmedData.match(/damagerealism=(-?\d+)/);
let damageValue;
if (damageMatch) {
switch (damageMatch[1]) {
case '-1':
damageValue = 'Disabled';
break;
case '0':
damageValue = 'Low';
break;
case '1':
damageValue = 'Medium';
break;
case '2':
damageValue = 'High';
break;
default:
damageValue = 'unknown';
}
} else {
damageValue = 'unknown';
}

const missilesMatch = trimmedData.match(/forcemissile\[\*\]=(\S+)/);
let missilesValue;
if (missilesMatch) {
switch (missilesMatch[1]) {
case 'none':
missilesValue = 'Disabled';
break;
case 'single':
missilesValue = 'Enabled, single';
break;
case 'double':
missilesValue = 'Enabled, double';
break;
default:
missilesValue = 'unknown';
}
} else {
missilesValue = 'unknown';
}

const minigunMatch = trimmedData.match(/forceminigun\[\*\]=(\S+)/);
let minigunValue;
if (minigunMatch) {
switch (minigunMatch[1]) {
case 'none':
minigunValue = 'Disabled';
break;
case 'force':
minigunValue = 'Enabled, single';
break;
case 'forcedouble':
minigunValue = 'Enabled, double';
break;
default:
minigunValue = 'unknown';
}
} else {
minigunValue = 'unknown';
}

const pickupsMatch = trimmedData.match(/forcepickups=(\d+)/);
let pickupsValue;
if (pickupsMatch) {
switch (pickupsMatch[1]) {
case '0':
pickupsValue = 'Disabled';
break;
case '1':
pickupsValue = 'Enabled';
break;
default:
pickupsValue = 'unknown';
}
} else {
pickupsValue = 'unknown';
}

const nitroMatch = trimmedData.match(/forcenitro\[\*\]=(\S+)/);
let nitroValue;
if (nitroMatch) {
switch (nitroMatch[1]) {
case 'abnitro':
nitroValue = 'Enabled';
break;
case 'none':
nitroValue = 'Disabled';
break;
default:
nitroValue = 'unknown';
}
} else {
nitroValue = 'unknown';
}

// Extract the timeofday value
const timeofdayMatch = trimmedData.match(/forcetimeofday=(\S+)/);
const timeofdayValue = timeofdayMatch ? timeofdayMatch[1] : '';

// Format the extracted value
const timeofday = timeofdayValue ? `Ambience: ${timeofdayValue}\n` : '';
const damage = `Damage: ${damageValue}\n`;
const missiles = `Missiles: ${missilesValue}\n`;
const minigun = `Minigun: ${minigunValue}\n\n`;

const pickups = `Pickups: ${pickupsValue}\n`;
const nitro = `Nitro: ${nitroValue}\n`;

// Extract the additional data
let additionalData = '';

const additionalDataRegex = /(force\w+)\[(\d+|\*)\]=(\S+)/g;
let match;
while ((match = additionalDataRegex.exec(trimmedData)) !== null) {
const [_, key, index, value] = match;
if (!index.startsWith('76561') && key !== 'forcemines' && key !== 'forceaiskill' && key !== 'gamevar' && key !== 'gamemodevalue' && key !== 'timeofday' && key !== 'damagerealism' && key !== 'forcemissile' && key !== 'forceminigun' && key !== 'forcepickups' && key !== 'forcenitro') {
additionalData += `${key}[${index}]: ${value}\n`;
}
}
additionalData += '\n';

// Extract the player data
const playerData = extractPlayerData(trimmedData);

// Format the players line
let players;
if (playerData && playerData.length > 0) {
players = `Players (${playerData.length}):`;
} else {
players = 'Players (unknown):';
}

// Format the player list
let playerList = '';
if (playerData && playerData.length > 0) {
for (const player of playerData) {
const playerName = player.name.replace(/\\\d/g, '');
const playerInfo = `\n- ${playerName}\n Car: ${player.car}\n Car Color: ${player.carcolor}\n Cartunings: ${player.cartunings}\n Wheels: ${player.wheel}\n Analog Steering: ${player.analogsteering}\n Steering Speed: ${player.steeringspeed}\n`; // excluded: Nitro Color: ${player.nitrocolor}\n
playerList += playerInfo;
}
} else {
playerList += ' unknown';
}

// Combine the players line and player list
const playersAndList = `${players}${playerList}`;

// Combine all the extracted data
const replayDetails = replayEventDetails + gamemode + trackName + damage + missiles + minigun + pickups + nitro + timeofday + additionalData + playersAndList;

// Write the data to the output file
fs.writeFile(outputFilePath, replayDetails, 'utf8', (err) => {
if (err) {
console.error(err);
return;
}

console.log(`Replay details saved to ${outputFileName}`);
});
});

// Helper function to get the formatted time
function getFormattedTime(date) {
return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' }).replace(/:/g, '.');
}

// Helper function to extract the player data
function extractPlayerData(data) {
const playerData = [];
const playerRegex = /forcecar\[(\d+)\]=(\S+) forcesteeringspeed\[\1\]=(\S+) forceanalogsteer\[\1\]=(\S+) forcedrivername\[\1\]=(.+?) forcecarcolor\[\1\]=(\S+) forcenitrocolor\[\1\]=(\S+) forcecartunings\[\1\]=(.+?) forcewheel\[\1\]=(.+?) /g;
let match;
while ((match = playerRegex.exec(data)) !== null) {
const [_, id, car, steeringspeed, analogsteering, name, carcolor, nitrocolor, cartunings, wheel] = match;
const playerName = name.replace(/\\./g, '').replace(/\|/g, ' ');
playerData.push({ id, car, steeringspeed, analogsteering, name: playerName, carcolor, nitrocolor, cartunings, wheel });
}
return playerData.length > 0 ? playerData : null;
}

// Move the replay file to the output directory
fs.renameSync(replayFilePath, path.join(outputDirPath, outputFileName.replace('.log', '.rpl')));
} catch (err) {
console.error(err);
}
} else {
console.log('Replay file not found');
}
}, 10000);

0 comments on commit 1320ddb

Please sign in to comment.