From 3f86ab488e46468506dfc26dd2187093d662a04d Mon Sep 17 00:00:00 2001 From: MrKritio Date: Sat, 17 Aug 2024 00:46:46 +0200 Subject: [PATCH] =?UTF-8?q?f=C3=B8rste=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.js | 35 +++++++++++++++++++++++++++++++ elo.js | 10 +++++++++ events.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ main.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ player.js | 22 ++++++++++++++++++++ 5 files changed, 180 insertions(+) create mode 100644 database.js create mode 100644 elo.js create mode 100644 events.js create mode 100644 main.js create mode 100644 player.js diff --git a/database.js b/database.js new file mode 100644 index 0000000..701a6af --- /dev/null +++ b/database.js @@ -0,0 +1,35 @@ +// database.js +const mysql = require('mysql2/promise'); + +const dbConfig = { + host: "95.217.113.161", + user: "Likima", + password: "27As$r0q1", + database: "jedaiito", + charset: "utf8" +}; + +const pool = mysql.createPool({ + ...dbConfig, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0 +}); + +async function updatePlayerElo(player) { + const connection = await pool.getConnection(); + try { + const updateQuery = ` + UPDATE players + SET elo = ? + WHERE guid = ? + `; + await connection.query(updateQuery, [player.elo, player.guid]); + } finally { + connection.release(); + } +} + +module.exports = { + updatePlayerElo, +}; diff --git a/elo.js b/elo.js new file mode 100644 index 0000000..1a486dc --- /dev/null +++ b/elo.js @@ -0,0 +1,10 @@ +// elo.js +function calculateElo(currentRating, opponentRating, actualScore, kFactor = 32) { + const expectedScore = 1 / (1 + Math.pow(10, (opponentRating - currentRating) / 400)); + const newRating = currentRating + kFactor * (actualScore - expectedScore); + return newRating; +} + +module.exports = { + calculateElo, +}; diff --git a/events.js b/events.js new file mode 100644 index 0000000..648455e --- /dev/null +++ b/events.js @@ -0,0 +1,54 @@ +// events.js +const events = require('events'); +const { calculateElo } = require('./elo'); +const { updatePlayerElo } = require('./database'); + +class GameEventEmitter extends events.EventEmitter {} + +const gameEventEmitter = new GameEventEmitter(); + +function handleRoundEnd(redScore, blueScore, playerScores, currentPlayers) { + console.log(`Round ended. Red: ${redScore}, Blue: ${blueScore}`); + + let winningTeam, losingTeam; + + if (redScore > blueScore) { + winningTeam = 'red'; + losingTeam = 'blue'; + } else if (blueScore > redScore) { + winningTeam = 'blue'; + losingTeam = 'red'; + } else { + console.log("It's a draw. No Elo change."); + return; + } + + const kFactor = 32; // You can adjust this as needed + + const winningPlayers = currentPlayers.filter(player => player.team === winningTeam); + const losingPlayers = currentPlayers.filter(player => player.team === losingTeam); + + const averageWinningElo = winningPlayers.reduce((acc, player) => acc + player.elo, 0) / winningPlayers.length; + const averageLosingElo = losingPlayers.reduce((acc, player) => acc + player.elo, 0) / losingPlayers.length; + + winningPlayers.forEach(async (player) => { + const individualPerformanceFactor = playerScores[player.id] / redScore; // Adjust based on individual contribution + player.elo = calculateElo(player.elo, averageLosingElo, 1 * individualPerformanceFactor, kFactor); + await updatePlayerElo(player); + }); + + losingPlayers.forEach(async (player) => { + const individualPerformanceFactor = playerScores[player.id] / blueScore; // Adjust based on individual contribution + player.elo = calculateElo(player.elo, averageWinningElo, 0 * individualPerformanceFactor, kFactor); + await updatePlayerElo(player); + }); + + console.log("Elo ratings updated."); +} + +gameEventEmitter.on('RoundEnd', handleRoundEnd); + +module.exports = { + gameEventEmitter, + handleRoundEnd, +}; diff --git a/main.js b/main.js new file mode 100644 index 0000000..c9cabad --- /dev/null +++ b/main.js @@ -0,0 +1,59 @@ +// main.js +const { spawn } = require('child_process'); +const { gameEventEmitter } = require('./events'); +const { Player } = require('./player'); + +let currentPlayers = []; +let playerScores = {}; + +function runCommand(command) { + const p = spawn('sh', ['-c', command], { stdio: 'pipe' }); + + p.stderr.on('data', (data) => { + const line = data.toString().trim(); + console.log(">>> " + line); + + if (line.startsWith('>>> red:') && line.includes(' blue:')) { + const redScore = parseInt(line.split('red:')[1].split(' ')[0]); + const blueScore = parseInt(line.split('blue:')[1]); + gameEventEmitter.emit('RoundEnd', redScore, blueScore, playerScores, currentPlayers); + playerScores = {}; // Reset playerScores after round end + } else if (line.startsWith('>>> score:')) { + const parts = line.split(' '); + const score = parseInt(parts[2]); + const clientId = parseInt(parts[6]); + const playerName = parts.slice(7).join(' '); + + const player = currentPlayers.find(p => p.id === clientId); + if (player) { + player.score = score; + playerScores[clientId] = score; + console.log(`Player ${playerName} (ID: ${clientId}) has a score of ${score}`); + } + } + + if (checkLine(line)) { + // Additional event handling can go here + gameEventEmitter.emit('SomeOtherEvent', line); + } + }); + + p.on('close', (code) => { + console.log(`Process exited with code ${code}`); + }); +} + +function checkLine(line) { + if (line.startsWith("Pl")) return true; + if (line.startsWith("Shut")) return true; + if (line.startsWith("ClientConne")) return true; + if (line.startsWith("ClientDisconn")) return true; + if (line.startsWith("Kill")) return true; + if (line.includes("say:")) return true; + if (line.startsWith("ClientUser")) return true; + if (line.startsWith("broadcast")) return true; + return false; +} + +// Running the game command +runCommand("sh start.sh"); diff --git a/player.js b/player.js new file mode 100644 index 0000000..a929978 --- /dev/null +++ b/player.js @@ -0,0 +1,22 @@ +// player.js +class Player { + constructor(id, ip, name, guid, elo = 1000, score = 0, team = '') { + this.id = id; + this.ip = ip; + this.name = name; + this.guid = guid; + this.elo = elo; + this.score = score; + this.team = team; + this.is_alive = true; + } +} + +function removeColorCodes(name) { + return name.replace(/\^\d/g, ''); +} + +module.exports = { + Player, + removeColorCodes, +};