diff --git a/database.js b/database.js index 9ad38d7..2037112 100644 --- a/database.js +++ b/database.js @@ -1,5 +1,41 @@ const config = require('./config/config.js'); const mysql = require('mysql'); +const logger = require('./logger')(__filename); + +/** + * Checks if database server is online by connecting and disconnecting + * @returns boolean + */ +exports.checkIfDatabaseIsOnline = function(){ + try{ + let connection = mysql.createConnection({ + host: config.dbConfig.host, + port: config.dbConfig.port, + user: config.dbConfig.username, + password: config.dbConfig.password, + database: config.dbConfig.database + }); + + connection.connect(); + + connection.ping(function (err) { + if(err) { + //Bit dirty, but works + logger.error("Could not connect to database! Please check config and database!"); + process.exit(1); + } + }); + + connection.end(); + } + catch (e) { + return false; + } + + return true; +}; + + /** * Returns the steam64id for the connected ts uid @@ -66,7 +102,13 @@ exports.getTsuid = function(steam64id){ return reject(err); } - resolve(result[0].tsuid); + + if(result.length > 0){ + if(result[0].hasOwnProperty("tsuid")){ + resolve(result[0].tsuid); + } + } + resolve(null); }); connection.commit(); @@ -221,7 +263,7 @@ exports.isRegisteredByTsUid = function (tsuid) { connection.connect(); - let sql = "SELECT COUNT(steam64id) AS 'idCount' FROM profiles WHERE tsuid = ?"; + let sql = "SELECT COUNT(steam64id) AS 'idCount' FROM profiles WHERE tsuid = ? AND active = 1"; let inserts = [tsuid]; sql = mysql.format(sql, inserts); @@ -249,9 +291,10 @@ exports.isRegisteredByTsUid = function (tsuid) { /** * Checks if user is registered by checking given steam64id - * @param steam64id + * @param steam64id The steam64id to look for + * @param inactive Show also inactive */ -exports.isRegisteredBySteam64Id = function (steam64id) { +exports.isRegisteredBySteam64Id = function (steam64id, inactive = false) { return new Promise((resolve, reject) => { let connection = mysql.createConnection({ host: config.dbConfig.host, @@ -264,6 +307,11 @@ exports.isRegisteredBySteam64Id = function (steam64id) { connection.connect(); let sql = "SELECT COUNT(steam64id) AS 'idCount' FROM profiles WHERE steam64id = ?"; + + if(!inactive){ + sql += " AND active = 1"; + } + let inserts = [steam64id]; sql = mysql.format(sql, inserts); diff --git a/index.js b/index.js index 83e1629..f572d57 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ const Teamspeak = require('./teamspeak'); const Steam = require('./steam'); +const database = require("./database"); const fs = require('fs'); const logDir = "logs"; @@ -17,11 +18,18 @@ if(!fs.existsSync("config/config.js")){ } console.log("The bot was not configured! Please configure it properly and then try again!"); - return; + process.exit(1); } + +if(!database.checkIfDatabaseIsOnline()){ + console.log("Could not connect to database! Please check config and database!"); + process.exit(1); +} + + let ts = new Teamspeak(); -let steam = new Steam(ts); +let steam = new Steam(); steam.startSteam(); ts.startTeamspeak(); \ No newline at end of file diff --git a/steam.js b/steam.js index a9f766f..fe045fe 100644 --- a/steam.js +++ b/steam.js @@ -17,15 +17,13 @@ class Steam { /** * Constructor - * @param teamspeak An instance of teamspeak.js so we can access Teamspeak methods */ - constructor(teamspeak){ + constructor(){ this.SteamClient = new steamApi.SteamClient(); this.SteamUser = new steamApi.SteamUser(this.SteamClient); this.SteamGC = new steamApi.SteamGameCoordinator(this.SteamClient, 730); this.SteamFriends = new steamApi.SteamFriends(this.SteamClient); this.CSGOCli = new csgo.CSGOClient(this.SteamUser, this.SteamGC, true); - this.Teamspeak = teamspeak; } @@ -82,7 +80,7 @@ class Steam { logger.debug(`Relationship event from ${steam64id}, status=${relationshipStatus}`); // Check if user is registered - let isRegistered = await database.isRegisteredBySteam64Id(steam64id); + let isRegistered = await database.isRegisteredBySteam64Id(steam64id, true); if(isRegistered) { // Accept Steam friend request and set user as active in database @@ -142,6 +140,20 @@ class Steam { await exchangeChannel.postMessage(`update_rank ${tsUid} ${rankId}`); } + break; + case "update_tick_get_rank": { + let tsUid = cmd[1]; + let steam64id = await database.getSteam64Id(tsUid); + + if(steam64id == null){ + return; + } + + let rankId = await this.getCSGORankOfSteam64id(steam64id); + + await exchangeChannel.postMessage(`update_tick_update_rank ${tsUid} ${rankId}`); + } + break; } } diff --git a/teamspeak.js b/teamspeak.js index d20e6c5..f19d9fd 100644 --- a/teamspeak.js +++ b/teamspeak.js @@ -34,7 +34,7 @@ class Teamspeak { * Sends a message to the provided tsUid * @param tsUid * @param message - * @return Returns if successful + * @return Promise{boolean} */ async messageUser(tsUid, message){ //We first need to get the TeamspeakClient @@ -52,6 +52,55 @@ class Teamspeak { + //Returns the Channel ID for a given CSGO Rank ID + static getRankGroupFromRankId(rankId){ + switch (rankId) + { + case "0": + return config.tsRankSgids.unranked; + case "1": + return config.tsRankSgids.silver_1; + case "2": + return config.tsRankSgids.silver_2; + case "3": + return config.tsRankSgids.silver_3; + case "4": + return config.tsRankSgids.silver_4; + case "5": + return config.tsRankSgids.silver_elite; + case "6": + return config.tsRankSgids.silver_elite_master; + case "7": + return config.tsRankSgids.gold_nova_1; + case "8": + return config.tsRankSgids.gold_nova_2; + case "9": + return config.tsRankSgids.gold_nova_3; + case "10": + return config.tsRankSgids.gold_nova_master; + case "11": + return config.tsRankSgids.master_guardian_1; + case "12": + return config.tsRankSgids.master_guardian_2; + case "13": + return config.tsRankSgids.master_guardian_elite; + case "14": + return config.tsRankSgids.distinguished_master_guardian; + case "15": + return config.tsRankSgids.legendary_eagle; + case "16": + return config.tsRankSgids.legendary_eagle_master; + case "17": + return config.tsRankSgids.supreme_master; + case "18": + return config.tsRankSgids.global_elite; + default: + return config.tsRankSgids.unranked; + } + } + + + async setRank(tsUid, csgoRankId){ //We first need to get the TeamspeakClient let tsClientList = await this.ts3.clientList({client_type: 0, client_unique_identifier: tsUid}); @@ -61,73 +110,7 @@ class Teamspeak { if(tsClientList.length > 0) { let tsClient = tsClientList[0]; - let newCsgoRankSgid = null; - - //Get the ranks sgid - switch (csgoRankId) - { - case "0": - newCsgoRankSgid = config.tsRankSgids.unranked; - break; - case "1": - newCsgoRankSgid = config.tsRankSgids.silver_1; - break; - case "2": - newCsgoRankSgid = config.tsRankSgids.silver_2; - break; - case "3": - newCsgoRankSgid = config.tsRankSgids.silver_3; - break; - case "4": - newCsgoRankSgid = config.tsRankSgids.silver_4; - break; - case "5": - newCsgoRankSgid = config.tsRankSgids.silver_elite; - break; - case "6": - newCsgoRankSgid = config.tsRankSgids.silver_elite_master; - break; - case "7": - newCsgoRankSgid = config.tsRankSgids.gold_nova_1; - break; - case "8": - newCsgoRankSgid = config.tsRankSgids.gold_nova_2; - break; - case "9": - newCsgoRankSgid = config.tsRankSgids.gold_nova_3; - break; - case "10": - newCsgoRankSgid = config.tsRankSgids.gold_nova_master; - break; - case "11": - newCsgoRankSgid = config.tsRankSgids.master_guardian_1; - break; - case "12": - newCsgoRankSgid = config.tsRankSgids.master_guardian_2; - break; - case "13": - newCsgoRankSgid = config.tsRankSgids.master_guardian_elite; - break; - case "14": - newCsgoRankSgid = config.tsRankSgids.distinguished_master_guardian; - break; - case "15": - newCsgoRankSgid = config.tsRankSgids.legendary_eagle; - break; - case "16": - newCsgoRankSgid = config.tsRankSgids.legendary_eagle_master; - break; - case "17": - newCsgoRankSgid = config.tsRankSgids.supreme_master; - break; - case "18": - newCsgoRankSgid = config.tsRankSgids.global_elite; - break; - default: - newCsgoRankSgid = config.tsRankSgids.unranked; - break; - } - + let newCsgoRankSgid = Teamspeak.getRankGroupFromRankId(csgoRankId); //Remove the user from all previous ranks let clientInfo = await tsClient.getInfo(); @@ -178,19 +161,26 @@ class Teamspeak { switch (cmd[0].toLocaleLowerCase()) { //Help command case "!help": { - ev.invoker.message("!register - Verknüpft deine TS-Identität mit deinem Steamprofil!"); - ev.invoker.message("!status - Zeigt, ob du bereits verknüpft bist!"); - ev.invoker.message("!update - Überprüft sofort, ob sich dein Rang geändert hat!"); + await client.message("!register - Verknüpft deine TS-Identität mit deinem Steamprofil!"); + await client.message("!status - Zeigt, ob du bereits verknüpft bist!"); + await client.message("!update - Überprüft sofort, ob sich dein Rang geändert hat!"); } break; //Register command case "!register": { + //Check if user is already registered + if(await database.isRegisteredByTsUid(client.uniqueIdentifier)) + { + await client.message("Du bist bereits registriert! Benutze !update um deinen Rang sofort zu updaten."); + return; + } + //Args lenght checke B if (cmd.length !== 2) { - client.message("!register "); - return null; + await client.message("!register "); + return; } logger.debug(`User ${client.nickname} issued register command`); @@ -220,11 +210,28 @@ class Teamspeak { //update command case "!update": { + let isRegistered = await database.isRegisteredByTsUid(client.uniqueIdentifier); + + if(isRegistered){ + exchangeChannel.postMessage(`request_update ${ev.invoker.uniqueIdentifier}`); + } + else{ + await client.message("Du bist noch nicht registriert! Bitte registriere dich erst mit !register"); + } + } + break; + - //TODO: CHECK IF USER IS REGISTERED + //status command + case "!status": { + let isRegistered = await database.isRegisteredByTsUid(client.uniqueIdentifier); - exchangeChannel.postMessage(`request_update ${ev.invoker.uniqueIdentifier}`); - //TODO: IMPLEMENT + if(isRegistered){ + await client.message("Du bist registriert! Benutze !update um deinen Rang zu updaten!"); + } + else{ + await client.message("Du bist noch nicht registriert! Benutze !register um dich zu registrieren!"); + } } break; } @@ -244,6 +251,30 @@ class Teamspeak { .catch((err) => {console.log(err)}); } break; + case "update_tick_update_rank": { + let tsUid = cmd[1]; + let csgoRankId = cmd[2]; + let rankChannelId = Teamspeak.getRankGroupFromRankId(csgoRankId); + let client = await this.ts3.getClientByUID(tsUid); + let clientGroups = client.servergroups; + + let clientIsInGroup = false; + + // Iterate through server groups and check if the client is in the server group for his rank + // If he is not clientIsInGroup will be false and the update process will be triggered + for(let i = 0; i < clientGroups.length; i++){ + let group = clientGroups[i].toString(); + if(group === rankChannelId.toString()){ + clientIsInGroup = true; + } + } + + // Trigger update process + if(!clientIsInGroup){ + this.setRank(tsUid, csgoRankId); + } + } + break; } } @@ -307,9 +338,36 @@ class Teamspeak { //Registering exchangeChannelListener exchangeChannel.addEventListener('message', (msg) => {this.exchangeChannelMessageReceived(msg).catch((err) => {console.log(err)})}); + + //Start the update tick + setInterval(() => { + this.updateTick().catch( () => { + logger.error("An error occurred during update tick!"); + }); + }, config.botConfig.checkIntervalTime * 1000 * 60); } + + + /** + * Updates the rank of all registered players currently online + */ + async updateTick() { + //get all clients online + let onlineClients = await this.ts3.clientList({client_type: 0}); + + for(let i = 0; i < onlineClients.length; i++){ + let client = onlineClients[i]; + + //check if client is registered + if(!await database.isRegisteredByTsUid(client.uniqueIdentifier)){ + return; + } + + await exchangeChannel.postMessage(`update_tick_get_rank ${client.uniqueIdentifier}`); + } + } } module.exports = Teamspeak; \ No newline at end of file