Last active
July 14, 2017 15:06
-
-
Save benjamingwynn/98af4b42478a2c7067b4d59bd1ce4d9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const TeamspeakQuery = require('teamspeak-query') | |
, query = new TeamspeakQuery('127.0.0.1', 10011) | |
, TARGET_CLIENT = 1 | |
, TARGET_CHANNEL = 2 | |
, TARGET_SERVER = 3 | |
, Steam = require("steam-webapi") | |
, console = require("better-console") | |
, jsonfile = require("jsonfile") | |
, SQ_PASSWD = "oh boy this sure is a secret password" | |
let games = {}, clients = {}, gamegroups = {} | |
try { | |
games = jsonfile.readFileSync("games.json") | |
clients = jsonfile.readFileSync("clients.json") | |
gamegroups = jsonfile.readFileSync("gamegroups.json") | |
} catch (ex) { | |
console.warn("No files. Will make new ones.") | |
console.warn(ex) | |
} | |
setInterval(() => { | |
jsonfile.writeFileSync("games.json", games) | |
jsonfile.writeFileSync("clients.json", clients) | |
jsonfile.writeFileSync("gamegroups.json", gamegroups) | |
}, 30000) | |
// register API key | |
Steam.key = "oh wow look a totally valid api key" | |
// hello steam! | |
Steam.ready(function(err) { | |
if (err) { | |
console.warn("Failed to connect to Steam!") | |
console.error(err) | |
process.exit(1) | |
} | |
const steam = new Steam(); | |
console.info("We've logged into steam!") | |
// connect to the teamspeak server | |
query.send('login', 'serveradmin', SQ_PASSWD) | |
.then(() => query.send('use', 1)) | |
.then(() => query.send('servernotifyregister', { 'event': 'server' })) | |
.then(() => query.send("servernotifyregister", { "event": "textprivate" })) | |
.then(() => query.send("clientupdate", {"client_nickname": "TeamSteam"})) | |
.then(() => console.info("We've logged into our local Teamspeak server!")) | |
.catch(err => console.error('An error occured:', err)) | |
function replaceAll (current, replacement, target) { | |
return target.split(current).join(replacement) | |
} | |
function awaitSteamInput (client) { | |
function storeClientSteamID (steamid) { | |
// TODO: this is an ugly way to verify an id but whatever who cares | |
steam.getPlayerBans({ | |
"steamids": steamid, | |
}, function (error, data) { | |
if (error) { | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `WTF? Can't check bans. Steam is probably fucked.` | |
}) | |
throw error | |
} | |
if (data.players.length) { | |
console.log("verified ID!") | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `Done. Your Steam account is now linked.` | |
}) | |
client.steamid = steamid | |
} else { | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `Invalid client ID. Please try again...` | |
}) | |
awaitSteamInput(client) | |
} | |
}) | |
} | |
console.log("awaiting steam input message!") | |
query.once("textmessage", (data) => { | |
console.info("I got a response!") | |
console.log(data) | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `Please wait...` | |
}) | |
// this url parsing logic is kind of shit, but works, so who cares | |
let msg = data | |
.msg | |
.trim() | |
.toLowerCase() | |
.replace("[/url]", "") | |
.replace("[url]", "") | |
// remove last / from urls | |
if (msg.lastIndexOf("/") === msg.length - 1) { | |
msg = msg.substr(0, msg.length - 1) | |
} | |
if (msg.indexOf("://steamcommunity.com/profiles/") > -1) { | |
const id = msg | |
.replace("https://steamcommunity.com/profiles/", "") | |
.replace("http://steamcommunity.com/profiles/", "") | |
console.info("given id", id) | |
storeClientSteamID(id) | |
} else { | |
const nick = msg | |
.replace("https://steamcommunity.com/id/", "") | |
.replace("http://steamcommunity.com/id/", "") | |
console.info("given nick", nick) | |
// okay now lets ask steam if thats valid | |
console.log("resolveVanityURL", nick) | |
steam.resolveVanityURL({ | |
"vanityurl": nick | |
}, function(err, data) { | |
if (err) { | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `WTF? Can't get vanityurl. Steam is probably fucked.` | |
}) | |
throw err; | |
} | |
console.info(data) | |
// Not found handler | |
if (data.success === 42) { | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: "I couldn't find your steam profile. Try again..." | |
}).then(() => awaitSteamInput(client)) | |
} else if (data.success === 1 && data.steamid) { | |
storeClientSteamID(data.steamid) | |
} | |
}) | |
} | |
}) | |
} | |
function getGroupForGame (name, callback) { | |
// ts3 groups have a 30 character limit | |
const gameName = name.substr(0, 30) | |
if (gamegroups[gameName]) { | |
console.log("Returning game group from cache", gameName) | |
callback(null, gamegroups[gameName]) | |
} else { | |
query.send("servergrouplist", {}).then((sgl) => { | |
let found | |
sgl.name.forEach((name, index) => { | |
if (name === gameName) { | |
found = sgl.sgid[index] | |
} | |
}) | |
if (found) { | |
gamegroups[gameName] = found | |
callback(null, found) | |
} else { | |
console.log("group doesnt exist creating new group") | |
query.send("servergroupadd", { | |
"name": gameName | |
}).then((data) => { | |
// show after name! | |
query.send("servergroupaddperm", { | |
sgid: data.sgid, | |
permsid: "i_group_show_name_in_tree", | |
permvalue: 2, | |
permnegated: 0, | |
permskip: 0, | |
}) | |
// fix perms | |
query.send("servergroupaddperm", { | |
sgid: data.sgid, | |
permsid: "i_group_needed_modify_power", permvalue: 50, permnegated: 0, permskip: 0, | |
}) | |
gamegroups[gameName] = data.sgid | |
callback(null, data.sgid) | |
}).catch(callback) | |
} | |
}).catch(callback) | |
} | |
} | |
// on client connect | |
query.on('cliententerview', data => { | |
const uid = data.client_unique_identifier | |
if (!clients[uid]) { | |
console.log("Creating new data for", data.client_unique_identifier) | |
clients[uid] = { | |
"nick": data.client_nickname | |
} | |
} | |
const client = clients[uid] | |
// update information | |
client.clid = data.clid | |
client.nick = data.client_nickname | |
query.send("clientgetdbidfromuid", { | |
cluid: uid, | |
}).then((data) => { | |
console.log(data) | |
client.dbid = data.cldbid | |
}) | |
if (!client.steamid) { | |
query.send("sendtextmessage", { | |
targetmode: TARGET_CLIENT, | |
target: client.clid, | |
msg: `Hey ${client.nick}! To show everyone what game you're currently playing while you're on the Teamspeak server; please reply with your Steam ID or a link to your steam profile. | |
This won't work if your Steam account is private, and it won't access any information which isn't publically accessible.` | |
}).then(() => { | |
console.log("sent the message") | |
awaitSteamInput(client) | |
}) | |
} | |
console.log(data) | |
console.log(client.nick, "connected!") | |
}); | |
// every few seconds | |
// TODO: refactor? | |
setInterval(() => { | |
const steamids = [] | |
, clientKeys = Object.keys(clients) | |
clientKeys.forEach((clientID) => { | |
const client = clients[clientID] | |
console.log("client", client) | |
if (!client.steamid) { | |
// the client has no steam id | |
return | |
} | |
steam.getPlayerSummaries({ | |
"steamids": client.steamid, | |
}, (error, summaries) => { | |
const summary = summaries.players[0] | |
, name = summary.gameextrainfo | |
// console.warn("summary", summary) | |
if (client.lastgame === name) { | |
// we're still playing the same game | |
return | |
} | |
console.log("last game is not current game! removing game groups...") | |
// if we're not playing the game we think we're playing... | |
let queriesFinished = 0 | |
const nQueries = Object.keys(gamegroups).length | |
delete client.lastgame | |
function allDone () { | |
console.log("all pending server queries are finished...") | |
// if we're playing a new game | |
if (!name) { | |
console.log("we're playing the same game") | |
return | |
} | |
console.log("hey we're playing a new game!") | |
// save this game | |
client.lastgame = name | |
console.log("game name", name) | |
getGroupForGame(name, (err, groupid) => { | |
if (err) throw err | |
console.log("groupid", groupid) | |
query.send("servergroupaddclient", { | |
cldbid: client.dbid, | |
sgid: groupid | |
}).catch(err => console.error('An error occured at group add:', err)) | |
}) | |
} | |
if (nQueries === 0) { | |
allDone() | |
return | |
} | |
Object.keys(gamegroups).forEach((key) => { | |
const gid = gamegroups[key] | |
query.send("servergroupdelclient", { | |
cldbid: client.dbid, | |
sgid: gid | |
}) | |
.catch(err => console.log('An error occured at group del:', err)) | |
.then(() => { | |
queriesFinished += 1 | |
if (queriesFinished !== nQueries) { | |
// keep waiting | |
return | |
} | |
allDone() | |
}) | |
}) | |
}) | |
}) | |
}, 5000) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment