Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- var net = require('net');
- var dgram = require('dgram');
- var sqlite3 = require('sqlite3').verbose();
- function openDb () {
- var db = new sqlite3.Database('bot.sqlite', function (err) {
- if (err) {
- console.log("Error opening database", err);
- }
- });
- return db;
- }
- var BOT_NAME = "[sgip]";
- var listservers = ['list1.digiex.net', 'list2.digiex.net'];
- var connections = {};
- var servers = [];
- var serverLookup = [];
- var database = {};
- //db.run("DROP TABLE serverinfo");
- //db.run("CREATE TABLE IF NOT EXISTS serverinfo (address TEXT NOT NULL UNIQUE, name TEXT, password TEXT, adminpassword TEXT, blacklistlevel INTEGER)");
- console.log('all ok');
- refreshDb(function () {
- startApiServer();
- scanServerlist();
- });
- function refreshDb (cb) {
- function checkCb () {
- var currentBlacklisted = [];
- for (var i in database) {
- if (database[i].blacklistlevel > 0) {
- currentBlacklisted.push(i);
- }
- }
- if (--cbcounter === 0) {
- console.log("Checking database...");
- for (var i in database) {
- var address = i;
- var serverinfo = database[i];
- var index = serverLookup.indexOf(address);
- if (currentBlacklisted.indexOf(address) !== -1 && database[i].blacklistlevel === 0) {
- console.log("Whitelisted", address);
- } else if (currentBlacklisted.indexOf(address) === -1 && database[i].blacklistlevel > 0) {
- console.log("Blacklisted", address);
- }
- if (index !== -1 && database[i].blacklistlevel > 0) {
- var server = servers[index];
- console.log("Closing connection to", address);
- var conn = connections[address];
- server.isConnected = false;
- conn.udp && conn.udp._handle && conn.udp.close();
- conn.client && conn.client._handle && conn.client.destroy();
- detachServer(index);
- }
- }
- if (typeof cb === 'function') {cb();}
- }
- }
- console.log("Refreshing database...");
- var cbcounter = 0;
- cbcounter++;
- var db = openDb();
- db.all("SELECT * FROM serverinfo", function (err, list) {
- for (var i = 0; i < list.length; i++) {
- database[list[i].address] = list[i];
- }
- checkCb();
- });
- db.close();
- };
- // Zero fill
- function zfs(v) {v=v+'';if(v.length == 1) return "0"+v; return v;};
- function Server (config) {
- if(!config) config = {};
- this.ip = config.ip;
- this.port = parseInt(config.port, 10) || 0;
- this.address = this.ip+":"+this.port;
- this['private'] = !!(config['private'] || false);
- this.gametype = parseInt(config.gametype, 10) || 0;
- this.version = new Buffer(4);
- if(Buffer.isBuffer(config.version)) {
- config.version.copy(this.version, 0, 0, 4);
- }
- else if(typeof config.version === 'string') {
- this.version.write(config.version, 0, 4, 'binary');
- }
- if(!config.capacity) config.capacity = [0, 0];
- this.capacity = [+config.capacity[0] || 0, +config.capacity[1] || 0];
- this.servername = config.servername || '';
- };
- Server.prototype.toJSON = function () {
- return {
- ip: this.ip,
- port: this.port,
- address: this.address,
- 'private': this['private'],
- gametype: this.gametype,
- version: this.version.toString('binary'),
- capacity: this.capacity,
- servername: this.servername
- };
- };
- function udpchecksum (buf) {
- var x = 1, y = 1, size = buf.length;
- for(var i = 2; i < size; i+=1) {
- x += buf[i];
- y += x;
- }
- buf[0] = x % 251;
- buf[1] = y % 251;
- return buf;
- };
- var disconnectMessages = {
- 1: "Server is full",
- 2: "Version different",
- 3: "Server is full",
- 4: "Error during handshaking",
- 5: "Feature not supported in shareware",
- 6: "Error downloading level",
- 7: "Connection lost",
- 8: "Winsock error",
- 9: "Connection timed out",
- 10:"Server stopped",
- 11:"Kicked off",
- 12:"Banned",
- 17:"Unauthorized file request",
- 18:"No splitscreeners allowed"
- };
- var actionSizes = {
- 0x01: 3,
- 0x02: 3,
- 0x03: 3,
- 0x04: 4,
- 0x05: 1,
- 0x06: 2,
- 0x07: 15,
- 0x08: 12,
- 0x09: 1,
- 0x0A: 3,
- 0x0B: 4,
- 0x0C: 4,
- 0x0D: 1,
- 0x0E: 10,
- 0x0F: 2,
- 0x15: 3,
- 0x19: 4,
- 0x1E: 21,
- 0x1A: 3
- }
- function attachServer (info) {
- var server = {
- info: new Server(info),
- client: {},
- isConnected: false
- };
- console.log('Add server '+server.info.address+' '+server.info.servername);
- var udpPort = 0;
- var udpCounter = 0;
- function connectFailed () {
- //console.log('CONNECT FAILED');
- server.isConnected = false;
- udp._handle && udp.close();
- detachServer(servers.indexOf(server));
- };
- function udpSend (data) {
- data[3] = (udpCounter++) % 256;
- data = udpchecksum(data);
- udp._handle && udp.send(data, 0, data.length, server.info.port, server.info.ip);
- };
- function joinServer () {
- /*if (server.info.address !== "80.78.216.229:10052") {
- connectFailed();
- return;
- }*/
- //connectFailed();
- //return;
- server.client.socketId = 0;
- server.client.playerId = 0;
- server.client.levelName = "";
- server.client.isPlus = false;
- server.client.players = [];
- server.client.game = {
- gamemode: 0,
- maxscore: 0,
- customMode: 0,
- ctf: {
- teams: [
- {score: 0, holder: -1},
- {score: 0, holder: -1}
- ]
- },
- time: {
- started: false,
- inPregame: false,
- inOvertime: false,
- timeLeft: 0,
- time: 0,
- autoCycle: false
- },
- isIdleserver: false,
- };
- var game = server.client.game;
- server.client.lastTimeUpdate = Date.now();
- // TODO: Get password from database
- var password = (database[server.info.address] && database[server.info.address].password) || "";
- var toSend = udpchecksum(new Buffer("yy"+"\x0A"+String.fromCharCode(password.length)+password));
- udp.send(toSend, 0, toSend.length, server.info.port, server.info.ip);
- udp.on('message', function (data, rinfo) {
- if (connections[rinfo.address+":"+rinfo.port] === conn) {
- var packetId = data[2];
- if (packetId === 0x02) {
- } else if (packetId === 0x07) { // Subpacket/action
- var i = 4;
- var packets = [];
- var ids = [];
- while (i < data.length) {
- var id = data[i];
- //console.log(id);
- if (!actionSizes[id] || i+actionSizes[id]+1 > data.length) break;
- packets.push(data.slice(i, i+actionSizes[id]+1));
- i += actionSizes[id] + 1;
- ids.push(id);
- }
- /*if (Array.prototype.indexOf.call(data.slice(4), 0x0E) > -1) {
- console.log("UDP ACTION: ", Array.prototype.indexOf.call(data.slice(4), 0x0E), data.slice(4));
- console.log(ids);
- }*/
- for (var key = 0; key < packets.length; key++) {
- var data = packets[key];
- //console.log(data);
- var subPacketId = data[0];
- //console.log(subPacketId);
- if (subPacketId === 0x03) { // Object destroyed/despawn
- } else if (subPacketId === 0x04) { // Player hit
- //sendChat("unknown packet");
- } else if (subPacketId === 0x07) { // Bullet
- } else if (subPacketId === 0x0E) { // Roast/kill/suicide
- //console.log("ROAST");
- var i = 1;
- var victimId = data[i++];
- var victimPoints = data.readUInt32LE(i); i+=4;
- var killerId = data[i++];
- var killerPoints = data.readUInt32LE(i); i+=4;
- var victim = server.client.players[victimId];
- var killer = server.client.players[killerId];
- if (victim && killer) {
- //sendChat(killerPoints+", "+victimPoints);
- if (victimId !== killerId) {
- killer.points = killerPoints;
- victim.points = victimPoints;
- //sendChat(killer.name+" roasted "+victim.name);
- //sendChat(killer.name+' got '+killer.points+' points');
- //sendChat(victim.name+' got '+victim.points+' points');
- } else {
- killer.points = killerPoints;
- //sendChat(killer.name+" ate it");
- //sendChat(killer.name+' got '+killer.points+' points');
- }
- } else {
- //sendChat("Unknown killer/victim player.", killerId, victimId);
- }
- } else if (subPacketId === 0x0F) { // Streetfightad
- var victimId = data[1];
- var killerId = data[2];
- var victim = server.client.players[victimId];
- var killer = server.client.players[killerId];
- if (victim && killer) {
- //sendChat(killer.name+" streetfighted "+victim.name);
- }
- } else if (subPacketId === 0x15) {
- } else if (subPacketId === 0x1E) {
- //console.log(data);
- var bluescore = data[5];
- var redscore = data[10];
- var blueHolder = data[20] > 0 ? data[21] : -1;
- var redHolder = data[17] > 0 ? data[18] : -1;
- game.ctf.teams[0].score = bluescore;
- game.ctf.teams[1].score = redscore;
- game.ctf.teams[0].holder = blueHolder;
- game.ctf.teams[1].holder = redHolder;
- //console.log('score: ', bluescore, redscore, 'holder: ', blueHolder, redHolder);
- } else {
- //console.log("GOT ACTION UDP", "0x"+subPacketId.toString(16), data);
- }
- }
- } else if (packetId === 0x09) { // Keep alive (JJ2+)
- var toSend = data;
- udpSend(toSend);
- } else if (packetId === 0x0B) {
- if (data[3] > 0) {
- startTCP();
- } else if (password) {
- //console.log("Wrong password '"+password+"' for "+server.info.servername);
- }
- } else {
- //console.log("UDP", data)
- }
- }
- });
- var extraPlusData = new Buffer(0);
- var sendChat = function (msg) {
- if(server.client.socketId) {
- var toSend = "\x1B"+String.fromCharCode(server.client.socketId)+"\x20"+msg;
- toSend = String.fromCharCode(toSend.length+1)+toSend;
- if(conn.client._handle) {
- conn.client.write(new Buffer(toSend, "binary"));
- return true;
- }
- }
- return false;
- };
- var getPlayerId = function (sock) {
- var result = [];
- for(var i=0; i < server.client.players.length; i+=1) {
- if(server.client.players[i] !== undefined && server.client.players[i].socketId === sock) {
- result.push(i);
- }
- }
- return result;
- };
- function startTCP () {
- var client = net.connect(server.info.port, server.info.ip);
- conn.client = client;
- client.on('connect', function () {
- clearTimeout(clientTimer);
- console.log('connected to '+server.info.address);
- var buf = new Buffer(9);
- buf.write("\x09\x0F", 0, 'binary');
- buf.writeUInt16LE(udpPort, 2);
- server.info.version.copy(buf, 4);
- buf.write("\x01", 8, 'binary');
- client.write(buf);
- });
- client.on('data', function (res) {
- // TODO: Clean up the code!
- var p = 0, j = res.length, res_a = [], l = 0;
- var special = false;
- while (p < j) {
- l = res[p];
- if (l === 0 && ++p < j) {
- l = res[p];
- var buf = new Buffer(l+1);
- buf[0] = l;
- res.copy(buf, 1, p+2, p+2+l);
- res_a.push(buf);
- p += 2;
- } else {
- if (p+l > j) {
- //console.log('oob', p, l, j, res);
- break;
- }
- res_a.push(res.slice(p, p+l));
- }
- p += l;
- }
- for (var key = 0; key < res_a.length; key++) { // Loops through packet array
- var data = res_a[key];
- //console.log(data);
- var packetId = data[1];
- if (packetId === 0x0D) { // Disconnect
- //console.log(data);
- var type = data[2];
- var message = disconnectMessages[type] || ("Unknown error |"+type);
- var playerid = getPlayerId(data[3]);
- var reason = data.length > 10 ? data.slice(10).toString('binary') : "";
- //console.log("Disconnected:", data[3], type, message, reason && "("+reason+")");
- for(var i = 0; i < playerid.length; i++) {
- if(type !== 7) {
- sendChat("§1"+server.client.players[playerid[i]].name+" left: |"+message +" |"+(reason && "("+reason+")"));
- }
- if (playerid[i] === server.client.playerId) {
- console.log("The bot was disconnected from", server.info.address, server.info.servername, message, reason && "("+reason+")");
- }
- delete server.client.players[playerid[i]];
- }
- } else if (packetId === 0x10) { // Server info
- var i = 2;
- server.client.socketId = data[i++];
- server.client.playerId = data[i++];
- var l = data[i++];
- server.client.levelName = data.slice(i, i + l).toString('binary');
- i += l;
- i+=8; // Skip CRC stuff
- server.client.game.gamemode = data[i++];
- server.client.game.maxscore = data[i++];
- if (data.length > i) {
- extraPlusData = data.slice(i);
- } else {
- client.destroy();
- connectFailed();
- return;
- }
- client.write("\x08\x3F\x20\x01\x00\x00\x03\x00"); // JJ2+ New
- //console.log("info?!1+", data.slice(i));
- var toSend = "\x0E\x01"+String.fromCharCode(server.client.playerId)+"\x01\x00"+"SGIP"+BOT_NAME+"\x00";
- toSend = String.fromCharCode(toSend.length+1)+toSend;
- client.write(toSend, 'binary');
- } else if(packetId === 0x11) { // Someone joins...
- var packetLength = data.length;
- var i=4; // Skip player amount
- var sockID = data[2];
- var playerid;
- var pname = "";
- var fur;
- var charTeam;
- while(packetLength>i) {
- playerid = data[i++];
- charTeam = data[i++];
- i++;
- fur = [data[i++], data[i++], data[i++], data[i++]];
- pname = "";
- while(data[i] != undefined) {pname+=String.fromCharCode(data[i++]);if(data[i]==0) break;}
- i+=1;
- server.client.players[playerid] = {
- charTeam: charTeam,
- fur: fur,
- name: pname,
- socketId: sockID,
- spectating: false,
- points: 0,
- deaths: 0,
- ping: -1
- };
- }
- } else if(packetId === 0x12) { // Playerlist
- var packetLength = data.length;
- var totalplayers = 0;
- var i = 3;
- while (packetLength>i) {
- var psock = data[i++];
- var pplayer = data[i++];
- var pcharTeam = data[i++];
- i++;
- var fur = [data[i++], data[i++], data[i++], data[i++]];
- var pname = "";
- while(data[i] != undefined) {pname+=String.fromCharCode(data[i++]);if(data[i]==0) break;}
- i += 1;
- totalplayers += 1;
- if (!server.client.players[pplayer]) {
- server.client.players[pplayer] = {
- spectating: false,
- points: 0,
- deaths: 0,
- ping: -1
- };
- }
- var player = server.client.players[pplayer];
- player.name = pname;
- player.fur = fur;
- player.charTeam = pcharTeam;
- player.socketId = psock;
- //roomBroadcast(JSON.stringify({'console': [(pplayer+1)+". "+pname, 1]}), roomId);
- }
- //console.log(server.client.players);
- //roomBroadcast(JSON.stringify({'console': [Array.prototype.slice.call(data, 2).join(" "), 1]}), roomId);
- } else if (packetId === 0x13) {
- if (server.isConnected) {
- continue;
- }
- console.log("Game init", server.info.address, server.info.servername);
- // ??
- //udp.send(new Buffer([0x0A, 0x15, 0x09, 0x00 ]), 0, 4, server.info.port, server.info.ip);
- var toSend = new Buffer(8);
- toSend[2] = 0x09;
- toSend[3] = server.client.socketId;
- extraPlusData.copy(toSend, 4, 4, 8);
- toSend = udpchecksum(toSend);
- udpSend(toSend);
- toSend = new Buffer(6);
- toSend[0] = 6;
- toSend[1] = 0x1A;
- extraPlusData.copy(toSend, 2, 0, 4);
- client.write(toSend);
- client.write("\x03\x42\x21", 'binary'); // Make bot spectate
- server.isConnected = true; // Important
- var startTime = Date.now();
- var udpTimer = setInterval(function () {
- var toSend = new Buffer([0, 0, 0x01, 0, server.client.playerId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
- udpSend(toSend);
- toSend = new Buffer(5+7);
- toSend.fill(0);
- toSend[2] = 0x09;
- toSend[4] = 0x07;
- toSend[5] = server.client.playerId;
- toSend[6] = 0x0C;
- toSend[7] = 0x20;
- toSend[8] = 0xA0;
- toSend[9] = 0x01;
- toSend[10] = 0x00;
- toSend[11] = 0x02;
- toSend = udpchecksum(toSend);
- udpSend(toSend);
- }, 1000);
- } else if(packetId === 0x16) { // Level cycle
- //console.log("CYCLE", data.slice(2));
- toSend = new Buffer(6);
- toSend[0] = 6;
- toSend[1] = 0x1A;
- data.copy(toSend, 2, data.length-10, data.length-10+4);
- //console.log("CYCLE RESPONSE", toSend);
- client.write(toSend);
- for (var i = 0; i < server.client.players.length; i++) {
- var player = server.client.players[i];
- if (player) {
- player.points = 0;
- player.deaths = 0;
- //console.log("Reset points/deaths for "+player.name);
- }
- }
- } else if (packetId === 0x17) { // End of level
- } else if (packetId === 0x18) { // Events update
- } else if (packetId === 0x1B) { // Chat
- } else if (packetId === 0x3F) { // Plus packet
- game.customMode = data[6];
- } else if (packetId === 0x40) { // Console message
- //console.log("Console: "+data.slice(3).toString('binary'));
- } else if (packetId === 0x41) {
- //console.log("SPECTATE", data.slice(2));
- //sendChat('got spectate packet: '+data[2].toString(2)+' ['+Array.prototype.slice.call(data, 2).join(", ")+']');
- var i = 2;
- var spectatePacketType = data[i++];
- if (spectatePacketType === 0) {
- //sendChat("zepectate: "+data[i++].toString(2)+" "+data[i++].toString(2)+" ["+Array.prototype.slice.call(data, 2).join(", ")+']');
- var unknown = data[i++];
- var binary = data[i++];
- for (var i = 0; i < server.client.players.length; i++) {
- var player = server.client.players[i];
- if (player) {
- var isSpec = ((binary >> player.socketId) & 1) === 1;
- if (isSpec !== player.spectating) {
- if (isSpec) {
- //sendChat(player.name+" is now spectating");
- player.points = 0;
- player.deaths = 0;
- //console.log("Reset points/deaths for "+player.name);
- } else {
- //sendChat(player.name+" is no longer spectating");
- }
- player.spectating = isSpec;
- }
- }
- }
- } else if (spectatePacketType === 1) {
- var spectateType = data[i++];
- var clientId = data[i++];
- var spectateId = data[i++];
- var playerIds = getPlayerId(clientId);
- //console.log("someone changed spec", data);
- var isSpec = spectateId !== 0xFE;
- for (var i = 0; i < playerIds.length; i++) {
- var player = server.client.players[playerIds[i]];
- if (player && isSpec !== player.spectating) {
- if (isSpec) {
- //sendChat(player.name+" is spectating");
- player.points = 0;
- player.deaths = 0;
- } else {
- //sendChat(player.name+" is no longer spectating");
- }
- player.spectating = isSpec;
- }
- }
- }
- /*if(data[0] === 5) {
- console.log("got spec list: "+data[2].toString(2), data.slice(3));
- //sendChat('got spec list: '+data[2].toString(2)+' ['+Array.prototype.slice.call(data, 2)+']');
- var binary = data[2];
- for (var i = 0; i < server.client.players.length; i++) {
- var player = server.client.players[i];
- if (player) {
- var isSpec = ((binary >> player.socketId) & 1) === 1;
- console.log(isSpec, player.spectating)
- if (isSpec !== player.spectating) {
- if (isSpec) {
- sendChat(player.name+" is spectating");
- } else {
- sendChat(player.name+" is no longer spectating");
- }
- player.spectating = isSpec;
- }
- }
- }
- }
- else {
- var playerIds = getPlayerId(data[2]);
- //console.log("someone changed spec", data);
- var isSpec = data[3] !== 0xFE;
- for (var i = 0; i < playerIds.length; i++) {
- var player = server.client.players[playerIds[i]];
- if (player && isSpec !== player.spectating) {
- if (isSpec) {
- sendChat(player.name+" is spectating");
- } else {
- sendChat(player.name+" is no longer spectating");
- }
- player.spectating = isSpec;
- }
- }
- }*/
- } else if (packetId === 0x45) { // Time
- var gameState = data[2];
- var gameStarted = !!(gameState & 1);
- var inPregame = !((gameState >> 1) & 1) && ((gameState >> 2) & 1);
- var inOvertime = !!(((gameState >> 1) & 1) && ((gameState >> 2) & 1));
- var timeLeft = data.readUInt32LE(3)/1000;
- var mins = Math.floor(timeLeft / 60);
- var secs = Math.floor(timeLeft) % 60;
- game.time.started = gameStarted;
- game.time.autoCycle = !!((gameState >> 1) & 1);
- game.time.inPregame = inPregame;
- game.time.inOvertime = inOvertime;
- game.time.timeLeft = timeLeft;
- server.client.lastTimeUpdate = Date.now();
- //console.log(timeLeft);
- //sendChat("§0|"+(gameStarted?(inPregame?"|||":"")+(inOvertime?"||":""):"|")+zfs(mins)+":"+zfs(secs)+" left");
- } else if (packetId === 0x49) { // Pings
- //sendChat("Pings: "+Array.prototype.slice.call(data, 2).join(", "));
- var i = 2;
- while (i < data.length) {
- var playerId = data[i++];
- var ping = data.readUInt16LE(i); i+=2;
- var player = server.client.players[playerId];
- if (player) {
- player.ping = ping;
- }
- }
- } else if (packetId === 0x4A) { // Gamemode and maxscore
- var gamemode = data[2];
- var customGamemode = data[3];
- var maxscore = data[4];
- game.gamemode = gamemode;
- game.maxscore = maxscore;
- game.customMode = customGamemode;
- //console.log(customGamemode > 0 ? "Custom gamemode: "+customGamemode : "Gamemode: "+gamemode, "maxscore: "+maxscore)
- } else if (packetId === 0x4C) { // Player stats
- var i = 2, len = data.length;
- while (i < len) {
- var playerId = data[i++];
- var points = data.readUInt32LE(i); i += 4;
- var deaths = data.readUInt32LE(i); i += 4;
- var player = server.client.players[playerId];
- if (player) {
- player.points = points;
- player.deaths = deaths;
- //sendChat(player.name+' got '+player.points+' points and '+player.deaths+' deaths');
- } else {
- sendChat("Unknown player "+playerId);
- }
- }
- } else if (packetId === 0x4D) { // Deaths
- //sendChat(Array.prototype.slice.call(data, 2).join(", "));
- var i = 2, len = data.length;
- while (i < len) {
- var playerId = data[i++];
- var deaths = data.readUInt32LE(i); i += 4;
- var player = server.client.players[playerId];
- if (player) {
- player.deaths = deaths;
- //sendChat(player.name+' got '+player.deaths+' deaths');
- } else {
- sendChat("Unknown player "+playerId);
- }
- }
- } else if (packetId === 0x50) { // TCP_SC_MISC
- } else if (packetId === 0x52) { // Idleserver
- game.isIdleserver = !!data[2];
- //sendChat("IDLESERVER IS "+(isIdleserver? "|ENABLED" : "||DISABLED"));
- } else {
- //console.log("TCP: 0x"+packetId.toString(16), data.slice(2));
- }
- //console.log("0x"+packetId.toString(16));
- }
- });
- client.on('error', function (err) {
- console.log("client "+err);
- });
- client.on('close', function () {
- console.log('Disconnected from', server.info.address, server.info.servername);
- connectFailed();
- });
- var clientTimer = setTimeout(function () {
- client.destroy();
- }, 3000);
- }
- };
- var conn = {};
- var query = udpchecksum(new Buffer("yy\x05\x00"));
- conn.udp = dgram.createSocket("udp4");
- var udp = conn.udp;
- var isFirst = true;
- udp.on('listening', function () {
- var rinfo = udp.address();
- //console.log("Listening on "+rinfo.address+":"+rinfo.port);
- udpPort = rinfo.port;
- udp.send(query, 0, query.length, server.info.port, server.info.ip);
- });
- udp.on('message', function (data, rinfo) {
- if (rinfo.address === server.info.ip && rinfo.port === server.info.port && isFirst) {
- isFirst = false;
- clearTimeout(queryTimer);
- server.info.version = data.slice(8, 8+4);
- server.info.capacity = [data[12], data[15]];
- server.info.gametype = data[14];
- server.info.servername = data.slice(17, 17+data[16]).toString('binary');
- joinServer();
- }
- });
- udp.on('error', function (err) {
- console.log('UDP '+err)
- });
- udp.bind();
- var queryTimer = setTimeout(function () {
- conn.udp.close();
- connectFailed();
- }, 3000);
- connections[server.info.address] = conn;
- servers.push(server);
- serverLookup.push(server.info.address);
- };
- function detachServer (index) {
- if (index > -1) {
- console.log('Remove server '+servers[index].info.address);
- var lookupIndex = serverLookup.indexOf(servers[index].info.address);
- //console.log("indices should be same:", index, lookupIndex);
- delete connections[servers[index].info.address];
- servers.splice(index, 1);
- serverLookup.splice(lookupIndex, 1);
- }
- };
- function handleServerlist (list, addresses) {
- for (var i = 0; i < servers.length; i++) {
- var server = servers[i];
- if(addresses.indexOf(server.info.address) === -1 && !connections[server.info.address]) {
- // remove/disconnect from server
- detachServer(i);
- } else {
- // server exists, do nothing?
- }
- }
- for (var i = 0; i < list.length; i++) {
- if (serverLookup.indexOf(addresses[i]) === -1 && !connections[addresses[i]]) {
- // add/connect to server
- attachServer(list[i]);
- } else {
- // server exists, do nothing?
- }
- }
- };
- function scanServerlist() {
- console.log(new Date()+" Scanning listservers...")
- var counter = 0;
- var list = [];
- var addresses = [];
- function handleListserver (listserver) {
- var buffers = "";
- var ls = net.connect(10053, listserver);
- var timeout = setTimeout(function () {
- console.log(listserver, "timeout");
- ls.destroy();
- }, 5*1000);
- ls.on('connect', function () {
- console.log(listserver, "connected");
- });
- ls.on('data', function (data) {
- clearTimeout(timeout);
- buffers += data.toString('binary');
- });
- ls.on('error', function (err) {
- clearTimeout(timeout);
- console.log(listserver, err);
- });
- ls.on('close', function () {
- console.log(listserver, "closed");
- clearTimeout(timeout);
- var buffer = new Buffer(buffers, 'binary');
- var i = 7;
- var len = buffer.length;
- while (i < len) {
- var l = buffer[i];
- var part = buffer.slice(i, i+l);
- i += l;
- var ip = [part[4], part[3], part[2], part[1]].join(".");
- var port = part.readUInt16LE(5);
- var address = ip+":"+port;
- var isBlacklisted = !(!database[address] || (database[address] && database[address].blacklistlevel === 0));
- if (addresses.indexOf(ip+":"+port) === -1 && !isBlacklisted) {
- var name = part.slice(7, l).toString('binary');
- addresses.push(address);
- list.push({ip: ip, port: port, servername: name});
- } else if (isBlacklisted) {
- console.log("Access to "+address+" was denied.");
- }
- }
- if (--counter === 0) {
- console.log("Found "+list.length+" servers");
- handleServerlist(list, addresses);
- setTimeout(function () {
- refreshDb(function () {
- scanServerlist();
- })
- }, 15*60*1000);
- }
- });
- };
- for (var i = 0; i < listservers.length; i++) {
- counter++;
- handleListserver(listservers[i]);
- }
- };
- function startApiServer () {
- var apiServer = net.createServer(function (client) {
- client.on('data', function (data) {
- try {
- var message = JSON.parse(data.toString('utf8'));
- } catch (e) {
- client.end("Invalid JSON");
- return;
- }
- var toSend = {error: 0};
- if (message.ip !== undefined && message.port !== undefined) {
- //console.log("Got API request");
- var index = serverLookup.indexOf(message.ip+":"+message.port);
- if (index !== -1) {
- var server = servers[index];
- if (server.isConnected) {
- server.client.game.time.time = server.client.game.time.timeLeft - (server.client.game.time.started? (Date.now() - server.client.lastTimeUpdate)/1000 : 0);
- toSend.players = server.client.players;
- toSend.game = server.client.game;
- } else {
- toSend.error = 2;
- }
- } else {
- //console.log("No such server: ", message.ip+":"+message.port, serverLookup);
- toSend.error = 1;
- }
- } else if (message.update !== undefined) {
- refreshDb();
- } else {
- toSend.error = 3;
- }
- client.end(JSON.stringify(toSend));
- });
- client.on('close', function () {
- //console.log('api client left');
- });
- client.on('error', function () {
- });
- });
- apiServer.listen(8007, 'localhost', function () {
- console.log('SGIP bot API server listening on localhost:8007');
- });
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement