Permalink
Browse files

Initial commit

  • Loading branch information...
damongant committed Jan 17, 2013
1 parent a994ce6 commit e2570cbbad7b52f2d7de8f914044851c98ae78d9
Showing with 154 additions and 1 deletion.
  1. +39 −1 README.md
  2. +15 −0 package.json
  3. +100 −0 ts3sq.js
View
@@ -1,2 +1,40 @@
node-ts3sq
-==========
+==========
+node-ts3sq is a simple library to interact with the TeamSpeak3 ServerQuery Interface [documented here](http://media.teamspeak.com/ts3_literature/TeamSpeak%203%20Server%20Query%20Manual.pdf).
+
+Please do not use this library in production without careful review. I created it for my own needs and it's largely untested.
+Let me know if it ends up being used somewhere else!
+
+Code Example
+============
+
+ var ts = require('ts3sq');
+ //Lets connect for a start...
+ var client = new ts.ServerQuery('localhost', 10011);
+ client.on('ready', function() {
+ //...login...
+ client.execute('login <username> <passwprd>');
+ //...and switch to instance 4, better check if this was successful, so we use a callback this time.
+ client.execute('use 4', function(element) {
+ //element always has an "err" property, just like the query itself always returns an error, even if the action was successful.
+ });
+ //The first TS3 library for note to support notifications, the SQ isn't just request-reponse, hooray!
+ client.execute('servernotifyregister event=server');
+ });
+ client.on('notify', function(notification) {
+ if (notification.type == "notifycliententerview") {
+ console.log(notification.body[0].client_nickname + " has connected");
+ }
+ })
+
+ client.on('error', function(error){
+ // This is usually an error right from the TCP socket, the close event will most likely follow on the next tick
+ })
+
+ client.on('close', function(){
+ // Connection closed, for whatever reason.
+ })
+
+Installation
+============
+<code>npm install ts3sq<code>
View
@@ -0,0 +1,15 @@
+{
+ "name": "ts3sq",
+ "version": "0.1.2",
+ "description": "Simple TeamSpeak 3 ServerQuery",
+ "repository": "git://github.com/DamonGant/node-ts3sq.git",
+ "author": {
+ "name": "Alexander Schittler",
+ "email": "alexander@innovandalism.eu",
+ "url": "http://gant.blogs.innovandalism.eu"
+ },
+ "dependencies": {
+ "binary": ">=0.3.0"
+ },
+ "main": "ts3sq"
+}
View
100 ts3sq.js
@@ -0,0 +1,100 @@
+var net = require('net')
+ , binary = require('binary')
+ , events = require('events')
+ , sys = require('sys');
+
+ function ServerQuery(host, port) {
+ events.EventEmitter.call(this);
+
+ var ready = false;
+ var commandQueue = [];
+ var self = this;
+ var client = net.connect(port, host);
+
+ client.on('close', function(whyyy) {
+ self.emit('close', whyyy);
+ });
+
+ client.on('error', function(error) {
+ self.emit('error', error);
+ });
+
+ var b = binary()
+ .scan('line', new Buffer('\n'))
+ .loop(function (end,vars) {
+ var line = vars.line.toString();
+ line = line.trim();
+
+ if (ready)
+ onLine(line);
+ //Hacky. But works.
+ if (line.indexOf("Welcome") == 0) {
+ ready = true;
+ self.emit('ready');
+ }
+
+ this.scan('line', new Buffer('\n'))
+ });
+
+ client.pipe(b);
+
+ this.execute = function(command, cb) {
+ commandQueue.push({command: command, cb: cb, sent: false});
+ }
+
+ function onLine(line) {
+ if (line.indexOf("err") == 0) {
+ commandQueue[0].err = parseTs3(line);
+ var element = commandQueue.shift();
+ if (typeof element.cb == "function")
+ element.cb(element);
+ return;
+ }
+ if (line.indexOf("notify") == 0) {
+ var partPos = line.indexOf(' ');
+ var body = parseTs3(line.substring(partPos + 1));
+ var type = line.substring(0, partPos);
+ self.emit('notify', {type: type, body: body});
+ return;
+ }
+ //This is probably a response, since the server will send another line with the error code, don't shift and check for a CB
+ commandQueue[0].response = parseTs3(line);
+ }
+
+ setInterval(function() {
+ if (commandQueue.length == 0)
+ return;
+ if (commandQueue[0].sent == false) {
+ commandQueue[0].sent = true;
+ client.write(commandQueue[0].command.trim() + "\n", "utf8");
+ }
+ }, 10)
+
+ function parseTs3(body) {
+ //NEVER TOUCH
+ var nBody = [];
+ var items = body.split('|');
+ for (var i in items) {
+ var elements = items[i].split(' ');
+ nBody[i] = {};
+ for (var i2 in elements) {
+ var element = elements[i2].split('=');
+ if (typeof element[1] != "undefined") {
+ //unescape whitespaces, pipes and slashes
+ element[1] = element[1].replace(/\\s/g, ' ').replace(/\\p/g, '|').replace(/\\\\/g, '\\').replace(/\\\//g, '/');
+ }
+ nBody[i][element[0]] = element[1];
+ }
+ }
+ return nBody;
+ }
+}
+
+function escapeString(string) {
+ return string.replace(/ /g, "\\s").replace(/\//g, "\\/"); // Just spaces cause I'm lazy, send me a patch or something if you needed more than that
+}
+
+sys.inherits(ServerQuery, events.EventEmitter);
+
+exports.ServerQuery = ServerQuery;
+exports.escapeString = escapeString;

0 comments on commit e2570cb

Please sign in to comment.