parent
7aba6aa58e
commit
074e186b0e
@ -0,0 +1,813 @@
|
|||||||
|
const mysql = require('mysql')
|
||||||
|
const Spawner = require('child_process');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const request = require('request');
|
||||||
|
const cheerio = require('cheerio');
|
||||||
|
|
||||||
|
|
||||||
|
class Child
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} userID -User's Hash
|
||||||
|
*/
|
||||||
|
constructor(userID)
|
||||||
|
{
|
||||||
|
this.ID = userID;
|
||||||
|
this.child = Spawner.fork('./worker.js',[this.ID]);
|
||||||
|
this.birth = process.uptime();
|
||||||
|
this.timeOut = setTimeout(() => {
|
||||||
|
this.child.kill('SIGINT');
|
||||||
|
},2*60*60*1000);
|
||||||
|
}
|
||||||
|
get EOL()
|
||||||
|
{
|
||||||
|
const EOL = Math.trunc((this.timeOut._idleTimeout - ((process.uptime()*1000)-this.birth))/1000);
|
||||||
|
return EOL>0?EOL:0;
|
||||||
|
}
|
||||||
|
getMapData()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.child.send('MapData');
|
||||||
|
this.child.on('message', m=>
|
||||||
|
{
|
||||||
|
if(typeof m == Object)
|
||||||
|
{
|
||||||
|
resolve(m.name);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
waitStart()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
var status = setInterval(() => {
|
||||||
|
if(this.isOpen)
|
||||||
|
{
|
||||||
|
clearInterval(status);
|
||||||
|
resolve(true)
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
createMapImage()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.child.send('MapImage')
|
||||||
|
this.child.on('message', m=>
|
||||||
|
{
|
||||||
|
if(typeof m == String && m === 'Done')
|
||||||
|
{
|
||||||
|
resolve(m);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
getConsole()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.child.send('Console')
|
||||||
|
this.child.on('message', m=>
|
||||||
|
{
|
||||||
|
resolve(m);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}module.exports.Child = Child;
|
||||||
|
|
||||||
|
|
||||||
|
class playerCache
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} Name
|
||||||
|
* @param {String} SteamID
|
||||||
|
* @param {Number} Ping
|
||||||
|
* @param {String} Address IP
|
||||||
|
* @param {Number} ConnectedSeconds
|
||||||
|
* @param {Number} Health
|
||||||
|
* @param {Object} Teammates ??'Not in a team'
|
||||||
|
* @param {String} Position ??'Not spawned yet'
|
||||||
|
*/
|
||||||
|
constructor(Name, SteamID, Ping, Address,ConnectedSeconds, Health, Teammates, Position)
|
||||||
|
{
|
||||||
|
this.Displayname = Name;
|
||||||
|
this.SteamID = SteamID;
|
||||||
|
this.Address = Address;
|
||||||
|
this.Health = Health;
|
||||||
|
this.Teammates = Teammates??'NOT IN A TEAM';
|
||||||
|
this.Position = Position??'NOT SPAWNED YET';
|
||||||
|
this.Ping = Ping;
|
||||||
|
this.ConnectedSeconds = ConnectedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}module.exports.playerCache = playerCache;
|
||||||
|
|
||||||
|
|
||||||
|
class ServerCache
|
||||||
|
{
|
||||||
|
constructor(ID,Hostname,MaxPlayers, GameTime, Framerate, NetworkIn, NetworkOut, Seed, WorldSize)
|
||||||
|
{
|
||||||
|
this.ID = ID;
|
||||||
|
this.Hostname=Hostname;
|
||||||
|
this.MaxPlayers =MaxPlayers;
|
||||||
|
this.GameTime = GameTime;
|
||||||
|
this.Framerate = Framerate;
|
||||||
|
this.NetworkIn = NetworkIn;
|
||||||
|
this.NetworkOut = NetworkOut;
|
||||||
|
this.Seed = Seed;
|
||||||
|
this.WorldSize = WorldSize;
|
||||||
|
this.Console = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get WorldData ()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Seed:this.Seed,
|
||||||
|
Size:this.WorldSize,
|
||||||
|
Time:this.GameTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get NetWorkData ()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
Framerate:this.Framerate,
|
||||||
|
In:this.NetworkIn,
|
||||||
|
Out:this.NetworkIn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get ConsoleData ()
|
||||||
|
{
|
||||||
|
return this.Console;
|
||||||
|
}
|
||||||
|
get BasicData ()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
HostName:this.Hostname,
|
||||||
|
MaxPlayers:this.MaxPlayers,
|
||||||
|
GameTime:this.GameTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}module.exports.ServerCache = ServerCache;
|
||||||
|
|
||||||
|
|
||||||
|
class pChild
|
||||||
|
{
|
||||||
|
|
||||||
|
constructor(ip, port, pw)
|
||||||
|
{
|
||||||
|
this.ip = ip;
|
||||||
|
this.port = port;
|
||||||
|
this.pw = pw;
|
||||||
|
this.child = Spawner.fork('./pWorker.js');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @argument {*} - Anything
|
||||||
|
*/
|
||||||
|
sendData()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < arguments.length; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be used with programmed commands
|
||||||
|
* @param {String} command - Command to be sent
|
||||||
|
*/
|
||||||
|
send(command)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.child.send({'command':command, 'ip':this.ip, 'port':this.port, 'pw':this.pw});
|
||||||
|
this.child.on('message', (m)=>
|
||||||
|
{
|
||||||
|
if(typeof m=='string')
|
||||||
|
{
|
||||||
|
if(m ==='end')
|
||||||
|
{
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reject("Worker didn't respond to querry.")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
close ()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
resolve(this.child.disconnect());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}module.exports.pChild = pChild;
|
||||||
|
class rustChild
|
||||||
|
{
|
||||||
|
constructor(size, seed)
|
||||||
|
{
|
||||||
|
this.child = Spawner.exec(`cmd /c updateServer.bat ${size} ${seed}`)
|
||||||
|
}
|
||||||
|
}module.exports.rustChild = rustChild;
|
||||||
|
|
||||||
|
|
||||||
|
class DBConnection
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
this.connection = mysql.createConnection(
|
||||||
|
{
|
||||||
|
host:'localhost',
|
||||||
|
user:'root',
|
||||||
|
password:'root',
|
||||||
|
database:'legendary'
|
||||||
|
})
|
||||||
|
this.connection.connect();
|
||||||
|
|
||||||
|
}
|
||||||
|
close()
|
||||||
|
{
|
||||||
|
setTimeout(() =>
|
||||||
|
{
|
||||||
|
this.connection.destroy();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
//User
|
||||||
|
get Users()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.connection.query('Select * from administrator', (e, r, f)=>
|
||||||
|
{
|
||||||
|
if(!e)
|
||||||
|
{
|
||||||
|
let aux = JSON.parse(JSON.stringify(r))
|
||||||
|
var payload =[];
|
||||||
|
|
||||||
|
for( var i = 0; i<aux.length; i++)
|
||||||
|
{
|
||||||
|
payload.push(aux[i].Hash)
|
||||||
|
}
|
||||||
|
resolve(payload);
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reject(e)
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
hasSVData(Hash)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.UData(Hash).then(
|
||||||
|
m=>
|
||||||
|
{
|
||||||
|
|
||||||
|
if(m.Server=='No server')
|
||||||
|
{
|
||||||
|
reject(false)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolve(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
UData(HASH)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.connection.query(`SELECT * FROM administrator WHERE Hash = '${HASH}' `, (e, r, f)=>
|
||||||
|
{
|
||||||
|
if(e)reject(e);
|
||||||
|
r = JSON.parse(JSON.stringify(r))[0];
|
||||||
|
resolve({
|
||||||
|
id:r.A_ID,
|
||||||
|
Hash:r.Hash,
|
||||||
|
Email:r.EHash,
|
||||||
|
Server:r.IP || 'No server',
|
||||||
|
Port: JSON.stringify(r.Port) || 'No server',
|
||||||
|
SPW:r.sv_pw,
|
||||||
|
Epoch:r.Epoch
|
||||||
|
})
|
||||||
|
this.close();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get_ID(hash)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
|
||||||
|
//User
|
||||||
|
this.Users.then((x)=>
|
||||||
|
{
|
||||||
|
for(var i =0; i<x.length; i++)
|
||||||
|
{
|
||||||
|
if(x[i]==hash)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.UData(hash).then((m)=>
|
||||||
|
{
|
||||||
|
resolve(m.id);
|
||||||
|
})
|
||||||
|
.catch(()=>reject('no ID for this hash'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(m=>
|
||||||
|
{
|
||||||
|
console.log(m);
|
||||||
|
reject('no ID for this HASH');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getCommands(Hash)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.get_ID(Hash).then(id=>
|
||||||
|
{
|
||||||
|
this.connection.query(`Select * from legendary.timed_com where administrator_A_ID = '${id}'`, (e, r, f)=>
|
||||||
|
{
|
||||||
|
if(e)reject(e);
|
||||||
|
resolve(JSON.parse(JSON.stringify(r)));
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand(Hash, Command, Loop, Send, tz)
|
||||||
|
{
|
||||||
|
this.get_ID(Hash).then(id=>
|
||||||
|
{
|
||||||
|
|
||||||
|
this.connection.query(`INSERT INTO legendary.timed_com (\`Command\`, \`Loop\`, \`Send\`, \`administrator_A_ID\`) VALUES ('${Command}', '${Loop}', '${Send}', '${id}')`);
|
||||||
|
this.close();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCommand(id)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.connection.query(`DELETE FROM legendary.timed_com WHERE (T_ID = ${id});`, (e, r, f)=>
|
||||||
|
{
|
||||||
|
if(e)reject(e)
|
||||||
|
if(r.affectedRows>0)resolve()
|
||||||
|
})
|
||||||
|
this.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
editCommand(id, Command, Loop, Send, tz)
|
||||||
|
{
|
||||||
|
this.connection.query(`UPDATE legendary.timed_com SET \`Command\` = '${Command}', \`Loop\` = '${Loop}',\`Send\` = '${Send}' WHERE (T_ID = '${id}')`)
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
addUser(Hash, EHash, Epoch)
|
||||||
|
{
|
||||||
|
if(Hash||EHash||Epoch)
|
||||||
|
{
|
||||||
|
this.connection.query(`INSERT INTO legendary.administrator (Hash, EHash, Epoch) VALUES ('${Hash}', '${EHash}', '${Epoch}')`)
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUser(HASH, NewHASH)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.get_ID(HASH).then((m)=>
|
||||||
|
{
|
||||||
|
this.connection.query(`UPDATE administrator SET Hash='${NewHASH}' WHERE A_ID = ${m}`);
|
||||||
|
this.close();
|
||||||
|
resolve(NewHASH);
|
||||||
|
}).catch((err)=>reject(err));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
addServer(HASH, IP, PW, PORT)
|
||||||
|
{
|
||||||
|
//needs to know what user should it be connected to
|
||||||
|
this.connection.query(`INSERT INTO adminsitrator (ServerIP, ServerPW, ServerPort) VALUES ('${HASH}', '${IP}','${PW}', '${PORT}')`)
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateServer(Hash, IP, PW, PORT)
|
||||||
|
{
|
||||||
|
this.get_ID(Hash).then((id)=>
|
||||||
|
{
|
||||||
|
this.connection.query(`UPDATE administrator SET IP = '${IP}', sv_pw = '${PW}', port='${PORT}' WHERE A_ID = ${id}`);
|
||||||
|
this.close();
|
||||||
|
}).catch(e=>console.log('error',e))
|
||||||
|
}
|
||||||
|
get_Players(Hash)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.connection.query(`SELECT * FROM player INNER JOIN time ON player.p_id = time.player_p_id
|
||||||
|
where administrator_a_id = (SELECT A_ID FROM administrator WHERE Hash = '${Hash}')
|
||||||
|
order by player_p_id asc;`,(e,r,f)=>
|
||||||
|
{
|
||||||
|
if(e)reject(e);this.close;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// console.log('Classes: DBConnection: Get_Players: r: ', r);
|
||||||
|
r = JSON.parse(JSON.stringify(r));
|
||||||
|
resolve(r)
|
||||||
|
|
||||||
|
} catch (err)
|
||||||
|
{
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
this.close;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}module.exports.DBConnection = DBConnection;
|
||||||
|
|
||||||
|
class _Crypto
|
||||||
|
{
|
||||||
|
constructor(User, Password)
|
||||||
|
{
|
||||||
|
this.salt = 'H$44Q3RVCd9X8Ef63tB4';
|
||||||
|
this.secret = 'mYFUZX9NSx7K74r7Jh@O';
|
||||||
|
this.pepper = String.fromCharCode(this.getRandomInt(65, 90));
|
||||||
|
this.password = Password;
|
||||||
|
this.user = User;
|
||||||
|
this.algorithm = 'aes-192-cbc';
|
||||||
|
|
||||||
|
}
|
||||||
|
get Hash() // to use on register
|
||||||
|
{
|
||||||
|
return this.hash()
|
||||||
|
}
|
||||||
|
hash(p)
|
||||||
|
{
|
||||||
|
if(!p)
|
||||||
|
{
|
||||||
|
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt+this.pepper).digest('hex');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt+p).digest('hex');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eHash(Email)
|
||||||
|
{
|
||||||
|
return new Buffer.from(Email).toString('base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypt(eHash)
|
||||||
|
{
|
||||||
|
return new Buffer.from(eHash, 'base64').toString('utf8');
|
||||||
|
}
|
||||||
|
getRandomInt(min, max)
|
||||||
|
{
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
|
}
|
||||||
|
compare() // to use on login
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
new DBConnection().Users
|
||||||
|
.then((Users)=>
|
||||||
|
{
|
||||||
|
for(var i=0; i<26;i++)
|
||||||
|
{
|
||||||
|
const nPepper = String.fromCharCode(65+i);
|
||||||
|
const hash = this.hash(nPepper);
|
||||||
|
for(var j = 0; j<Users.length; j++)
|
||||||
|
{
|
||||||
|
if(Users[j]==hash) resolve(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reject(false);
|
||||||
|
})
|
||||||
|
.catch((m)=>
|
||||||
|
{
|
||||||
|
console.log('error'+m);
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}module.exports._Crypto = _Crypto;
|
||||||
|
|
||||||
|
|
||||||
|
class Epoch
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Number} Days - Must be and integer.
|
||||||
|
*/
|
||||||
|
constructor(Days)
|
||||||
|
{
|
||||||
|
this.Days = (Days*(24*60*60));
|
||||||
|
this.epoch = this.epocher();
|
||||||
|
}
|
||||||
|
epocher()
|
||||||
|
{
|
||||||
|
return Math.floor(this.Days + Date.now()/1000)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {String} time - Must follow the format of '18:12'.
|
||||||
|
*/
|
||||||
|
sEpoch(time)
|
||||||
|
{
|
||||||
|
let hours = time.split(':')[0];
|
||||||
|
let minutes = time.split(':')[1];
|
||||||
|
return Math.floor(this.next(hours, minutes)/1000);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Number} time - Must be and integer.
|
||||||
|
*/
|
||||||
|
toDate(time)
|
||||||
|
{
|
||||||
|
//console.log('classes:toDate:', time)
|
||||||
|
const d = new Date(time*1000);
|
||||||
|
return d.getHours()+':'+ d.getMinutes();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the next possible time for the command to be sent. Meaning if the hours inputed by the user
|
||||||
|
* have already gone past this day then the epoch will be set for the next.
|
||||||
|
* If not the epoch will be created like usual.
|
||||||
|
*
|
||||||
|
* @param {Number} hours
|
||||||
|
* @param {Number} minutes
|
||||||
|
*/
|
||||||
|
next(hours, minutes)
|
||||||
|
{
|
||||||
|
var d= new Date();
|
||||||
|
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), hours, minutes, 0, 0).getTime();
|
||||||
|
//console.log('Classes:Next:',hours, minutes, payload)
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}module.exports.Epoch = Epoch;
|
||||||
|
|
||||||
|
class IPTranslator
|
||||||
|
{
|
||||||
|
constructor(IP)
|
||||||
|
{
|
||||||
|
this.IP = IP;
|
||||||
|
}
|
||||||
|
translate()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
request(`http://ip-api.com/json/${this.IP}`, (e,r,b)=>
|
||||||
|
{
|
||||||
|
var body
|
||||||
|
if(!e)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
body = JSON.parse(b);
|
||||||
|
} catch (error) {
|
||||||
|
console.log('IP Transalator: Bad Parse.');
|
||||||
|
resolve('Err')
|
||||||
|
}
|
||||||
|
resolve(body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolve( {'status':'error'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CC()
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
this.translate().then(m=>resolve(m.countryCode)).catch(e=>
|
||||||
|
{
|
||||||
|
console.log('IP Translator: CountryCode:'+e);
|
||||||
|
reject(e);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}module.exports.IPTranslator = IPTranslator;
|
||||||
|
|
||||||
|
class VAC
|
||||||
|
{
|
||||||
|
constructor(SteamID)
|
||||||
|
{
|
||||||
|
this.SteamID = SteamID;
|
||||||
|
}
|
||||||
|
get ban()
|
||||||
|
{
|
||||||
|
return new Promise((resolve,reject)=>
|
||||||
|
{
|
||||||
|
request(`http://vacbanned.com/engine/check?qsearch=${this.SteamID}`, (e,r,b)=>
|
||||||
|
{
|
||||||
|
if(e)reject('VAC: Request:'+e)
|
||||||
|
const $ = cheerio.load(b);
|
||||||
|
// console.log('Worker: VAC: body: ', $('td').text());
|
||||||
|
$('.strong').remove()
|
||||||
|
request(`http://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=DCA47FAA9F3D1485FA8C1F4FA15A5266&steamid=${this.SteamID}&format=json`, (e,r,steamb)=>
|
||||||
|
{
|
||||||
|
if(e)reject('VAC: FS: Request:'+e)
|
||||||
|
var fs;
|
||||||
|
let aux
|
||||||
|
//console.log('Vac class: SteamAPI', steamb)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
aux = JSON.parse(steamb)['response'].games;
|
||||||
|
} catch (error)
|
||||||
|
{
|
||||||
|
console.log('JSON parse error: ',error);
|
||||||
|
}
|
||||||
|
if(aux)
|
||||||
|
{
|
||||||
|
for (let i = 0; i < aux.length; i++)
|
||||||
|
{
|
||||||
|
// console.log('VAC: FS: Request2: '+aux[i].appid, '252490');
|
||||||
|
if(aux[i].appid)
|
||||||
|
{
|
||||||
|
if(aux[i].appid=='252490')
|
||||||
|
{
|
||||||
|
i = aux.length;
|
||||||
|
fs = 'NO'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fs='Yes'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var vac;
|
||||||
|
try {
|
||||||
|
vac = $('td').text().replace(/ /g, '').split('Hex)')[1].replace(/\n/g, 'SPLIT').split('SPLIT')[1];
|
||||||
|
} catch (error) {
|
||||||
|
vac = 'Error';
|
||||||
|
}
|
||||||
|
let payload = {
|
||||||
|
'vac':vac,
|
||||||
|
'fs':fs
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('VAC: Payload: ', payload)
|
||||||
|
resolve(payload);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var vac;
|
||||||
|
try {
|
||||||
|
vac = $('td').text().replace(/ /g, '').split('Hex)')[1].replace(/\n/g, 'SPLIT').split('SPLIT')[1];
|
||||||
|
} catch (error) {
|
||||||
|
vac = 'Error';
|
||||||
|
}
|
||||||
|
let payload = {
|
||||||
|
'vac':vac,
|
||||||
|
'fs':fs
|
||||||
|
}
|
||||||
|
resolve(payload);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}module.exports.VAC = VAC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use it to transform an hour value into miliseconds.
|
||||||
|
* @param {Number} Hours - Hours to transform
|
||||||
|
*/
|
||||||
|
function hours(Hours)
|
||||||
|
{
|
||||||
|
return Hours*60*60*1000;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function writes a cookie on the client side.
|
||||||
|
* Primary use: Store users Hash for every other page.
|
||||||
|
* @argument {Response} res - Response: express response object.
|
||||||
|
* @argument {String} name - Name of the cookie.
|
||||||
|
* @argument {*} value - Value of the cookie.
|
||||||
|
*/
|
||||||
|
exports.baker = (res, name, value) =>
|
||||||
|
{
|
||||||
|
return new Promise((resolve,reject)=>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res.cookie(name, '',{maxAge:0});
|
||||||
|
res.cookie(name, value, {maxAge:hours(2),path:'/',secure:false,httpOnly:false});
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash used on register to check if there is already a user with the same credentials.
|
||||||
|
* @param {String} user - User's email
|
||||||
|
* @param {String} password - User's Password
|
||||||
|
* @param {String} hash - User's identifying hash
|
||||||
|
*/
|
||||||
|
exports.bouncer = (user, password, hash) =>
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
new _Crypto(user, password).compare().then(m=>
|
||||||
|
{
|
||||||
|
if(hash)
|
||||||
|
{
|
||||||
|
if(m==hash)
|
||||||
|
{
|
||||||
|
resolve(m)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reject('You are on a different account.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resolve(m)
|
||||||
|
}
|
||||||
|
}).catch(m=>
|
||||||
|
{
|
||||||
|
reject(m)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reduces the number of decimal cases to the required value.
|
||||||
|
|
||||||
|
* @param {Number} num - The number you want to cut to size.
|
||||||
|
* @param {Number} decimal - Ammount of decimal cases.
|
||||||
|
*/
|
||||||
|
exports.toFixed = (num, decimal)=>
|
||||||
|
{
|
||||||
|
decimal = decimal || 0;
|
||||||
|
decimal = Math.pow(10, decimal);
|
||||||
|
return Math.floor(num * decimal) / decimal;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Transforms a value into a 0-1 value given the max value it could take.
|
||||||
|
* @param {Number} val - Value to transform to percentage
|
||||||
|
* @param {Number} max - Maximum the value could be
|
||||||
|
*/
|
||||||
|
exports.toPercent = (val, max)=>
|
||||||
|
{
|
||||||
|
return val/max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the timezone difference to a time.
|
||||||
|
* @param {String} time - Must follow 'HH:MM' format.
|
||||||
|
* @param {Number} offSet - Number of minutes from gmt+0.
|
||||||
|
*/
|
||||||
|
exports.removeTZ = (time, offSet)=>
|
||||||
|
{
|
||||||
|
var h = parseInt(time.split(':')[0]);
|
||||||
|
var maux = parseInt(time.split(':')[1]);
|
||||||
|
var m = maux - offSet;
|
||||||
|
var d = new Date();
|
||||||
|
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), h, m, 0, 0).toString().split(' ')[4].split(' ')[0].slice(0,-3);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds timezone difference to a time.
|
||||||
|
* @param {String} time - Must follow 'HH:MM' format.
|
||||||
|
* @param {Number} offset - Number of minutes from gmt+0.
|
||||||
|
*/
|
||||||
|
exports.addTZ = (time, offset) =>
|
||||||
|
{
|
||||||
|
offset = parseInt(offset);
|
||||||
|
let h = parseInt(time.split(':')[0]);
|
||||||
|
let m = parseInt(time.split(':')[1])+offset;
|
||||||
|
var d= new Date();
|
||||||
|
return payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDay(), h, m, 0, 0).toString().split(' ')[4].split(' ')[0].slice(0,-3);
|
||||||
|
}
|
@ -1,38 +0,0 @@
|
|||||||
.App {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-link {
|
|
||||||
color: #61dafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes App-logo-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import logo from './logo.svg';
|
|
||||||
import './App.css';
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<header className="App-header">
|
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
|
||||||
<p>
|
|
||||||
Edit <code>src/App.js</code> and save to reload.
|
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
className="App-link"
|
|
||||||
href="https://reactjs.org"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Learn React
|
|
||||||
</a>
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,8 +0,0 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
render(<App />);
|
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
@ -0,0 +1,43 @@
|
|||||||
|
.Frame
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
position: fixed;
|
||||||
|
left:0%;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
gap: 1px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
.Title
|
||||||
|
{
|
||||||
|
border: 1px solid rgba(240, 248, 255, 0);
|
||||||
|
width: 100%;
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
color:ivory;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family:Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
font-size: small;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-top: 0.25em;
|
||||||
|
|
||||||
|
}
|
||||||
|
.btControl
|
||||||
|
{
|
||||||
|
background-color: rgb(22, 27, 28);
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 1px solid black;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color:ivory;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
top:-23%;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
.container
|
||||||
|
{
|
||||||
|
position: relative;
|
||||||
|
width: 14em;
|
||||||
|
top: 15em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: stretch;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
span
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
color:ivory;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bt
|
||||||
|
{
|
||||||
|
width: auto;
|
||||||
|
height: 2em;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0);
|
||||||
|
color:ivory;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.Login
|
||||||
|
{
|
||||||
|
float:left;
|
||||||
|
position: relative;
|
||||||
|
left:2em;
|
||||||
|
}
|
||||||
|
.Register
|
||||||
|
{
|
||||||
|
float:right;
|
||||||
|
position: relative;
|
||||||
|
right: 1em;
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
.Frame
|
|
||||||
{
|
|
||||||
display: flex;
|
|
||||||
position: fixed;
|
|
||||||
right: 0%;
|
|
||||||
}
|
|
||||||
.minimize
|
|
||||||
{
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border: 1px solid black;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
color:ivory;
|
|
||||||
|
|
||||||
}
|
|
||||||
.Maximize
|
|
||||||
{
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border: 1px solid black;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
color:ivory;
|
|
||||||
|
|
||||||
}
|
|
||||||
.Close
|
|
||||||
{
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border: 1px solid black;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
color:ivory;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
position: relative;
|
|
||||||
top:-23%;
|
|
||||||
}
|
|
@ -0,0 +1,19 @@
|
|||||||
|
import Login from "../Components/Login";
|
||||||
|
const { cookieSlicer } = require("../lib");
|
||||||
|
|
||||||
|
function Home() {
|
||||||
|
var Hash = cookieSlicer(document.cookie,'Hash');
|
||||||
|
console.log(Hash)
|
||||||
|
return (
|
||||||
|
<div className="BODY">
|
||||||
|
{Hash ? (
|
||||||
|
<h1>Welcome back!</h1>
|
||||||
|
//TODO: Actual Page
|
||||||
|
) : (
|
||||||
|
<Login/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Home;
|
@ -0,0 +1,176 @@
|
|||||||
|
import crypto from 'crypto';
|
||||||
|
|
||||||
|
export class _Crypto
|
||||||
|
{
|
||||||
|
constructor(User, Password)
|
||||||
|
{
|
||||||
|
this.salt = 'H$44Q3RVCd9X8Ef63tB4';
|
||||||
|
this.secret = 'mYFUZX9NSx7K74r7Jh@O';
|
||||||
|
this.pepper = String.fromCharCode(this.getRandomInt(65, 90));
|
||||||
|
this.password = Password;
|
||||||
|
this.user = User;
|
||||||
|
this.algorithm = 'aes-192-cbc';
|
||||||
|
|
||||||
|
}
|
||||||
|
get Hash() // to use on register
|
||||||
|
{
|
||||||
|
return this.hash()
|
||||||
|
}
|
||||||
|
hash(p)
|
||||||
|
{
|
||||||
|
|
||||||
|
return crypto.createHmac('sha256', this.secret).update(this.user+this.password+this.salt + (p?p:this.pepper) ).digest('hex');
|
||||||
|
|
||||||
|
}
|
||||||
|
eHash(Email)
|
||||||
|
{
|
||||||
|
return new Buffer.from(Email).toString('base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypt(eHash)
|
||||||
|
{
|
||||||
|
return new Buffer.from(eHash, 'base64').toString('utf8');
|
||||||
|
}
|
||||||
|
getRandomInt(min, max)
|
||||||
|
{
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
|
}
|
||||||
|
//TODO: compare(hash)
|
||||||
|
//Get hash from db run through the peper possibilties and see if there is a match.
|
||||||
|
//return hash if true, null if false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Epoch
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Number} Days - Must be and integer.
|
||||||
|
*/
|
||||||
|
constructor(Days)
|
||||||
|
{
|
||||||
|
this.Days = (Days*(24*60*60));
|
||||||
|
this.epoch = this.epocher();
|
||||||
|
}
|
||||||
|
epocher()
|
||||||
|
{
|
||||||
|
return Math.floor(this.Days + Date.now()/1000)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {String} time - Must follow the format of '18:12'.
|
||||||
|
*/
|
||||||
|
sEpoch(time)
|
||||||
|
{
|
||||||
|
let hours = time.split(':')[0];
|
||||||
|
let minutes = time.split(':')[1];
|
||||||
|
return Math.floor(this.next(hours, minutes)/1000);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Number} time - Must be and integer.
|
||||||
|
*/
|
||||||
|
toDate(time)
|
||||||
|
{
|
||||||
|
//console.log('classes:toDate:', time)
|
||||||
|
const d = new Date(time*1000);
|
||||||
|
return d.getHours()+':'+ d.getMinutes();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the next possible time for the command to be sent. Meaning if the hours inputed by the user
|
||||||
|
* have already gone past this day then the epoch will be set for the next.
|
||||||
|
* If not the epoch will be created like usual.
|
||||||
|
*
|
||||||
|
* @param {Number} hours
|
||||||
|
* @param {Number} minutes
|
||||||
|
*/
|
||||||
|
next(hours, minutes)
|
||||||
|
{
|
||||||
|
var d= new Date();
|
||||||
|
var payload = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), hours, minutes, 0, 0).getTime();
|
||||||
|
//console.log('Classes:Next:',hours, minutes, payload)
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use it to transform an hour value into miliseconds.
|
||||||
|
* @param {Number} Hours - Hours to transform
|
||||||
|
*/
|
||||||
|
function hours(Hours)
|
||||||
|
{
|
||||||
|
return Hours*60*60*1000;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function writes a cookie on the client side.
|
||||||
|
* Primary use: Store users Hash for every other page.
|
||||||
|
* @argument {Response} res - Response: express response object.
|
||||||
|
* @argument {String} name - Name of the cookie.
|
||||||
|
* @argument {*} value - Value of the cookie.
|
||||||
|
*/
|
||||||
|
export function baker(res, name, value)
|
||||||
|
{
|
||||||
|
return new Promise((resolve,reject)=>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res.cookie(name, '',{maxAge:0});
|
||||||
|
res.cookie(name, value, {maxAge:hours(2),path:'/',secure:false,httpOnly:false});
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash used on register to check if there is already a user with the same credentials.
|
||||||
|
* @param {String} user - User's email
|
||||||
|
* @param {String} password - User's Password
|
||||||
|
* @param {String} hash - User's identifying hash
|
||||||
|
*/
|
||||||
|
export function bouncer (user, password, hash)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject)=>
|
||||||
|
{
|
||||||
|
//!Crypto compare needs to be reworked so this is legacy code not supposed to work
|
||||||
|
// new _Crypto(user, password).compare().then(m=>
|
||||||
|
// {
|
||||||
|
// if(hash)
|
||||||
|
// {
|
||||||
|
// if(m==hash)
|
||||||
|
// {
|
||||||
|
// resolve(m)
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// reject('You are on a different account.')
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// resolve(m)
|
||||||
|
// }
|
||||||
|
// }).catch(m=>
|
||||||
|
// {
|
||||||
|
// reject(m)
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function cookieSlicer(cookie, id)
|
||||||
|
{
|
||||||
|
cookie = cookie.split(';');
|
||||||
|
var result = new Map();
|
||||||
|
for(var item of cookie)
|
||||||
|
{
|
||||||
|
let aux = item.split('=');
|
||||||
|
result.set(aux[0], aux[1]);
|
||||||
|
}
|
||||||
|
return id?result.get(id):result;
|
||||||
|
}
|
Before Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in new issue