Protokolle von TeamSpeak 3
Dieses Dokument enthält Informationen zu allen Protokollen, die TeamSpeak außer Query und Sprache noch benutzt.
Ergänzungen und Obsoletes zum Thema TeamSpeak 3.1-beta1 und 2 sind farblich hervorgehoben.
Inhaltsverzeichnis
Protobuf
Dieser Abschnitt beschreibt das Datenformat Protobuf, das TeamSpeak an vielen Stellen verwendet. Dafür muss man zunächst einmal zwei Datentypen kennen (Protobuf kennt noch zwei weitere, die TeamSpeak nicht nutzt):
BigNum (aka Varint)
Der wichtigste Datentyp heißt BigNum (von Google als Varint bezeichnet) und ist eine theoretisch unendlich große Zahl. Ist diese Zahl 127 oder kleiner, schreibt man sie als Byte. Ansonsten schreibt man ein Byte mit den niederwertigsten 7 Bits der Zahl (also MOD 128
oder AND 127
) OR 128
und durchläuft die Methode erneut mit der Zahl SHR 7
(oder DIV 128
).
procedure f(x)
begin
while True do
begin
if x < 128 then
begin
WriteByte(x);
Exit;
end
else
begin
WriteByte(x mod 128 or 128);
x := x shr 7;
end;
end;
end;
Die Implementierung kann auch rekursiv geschehen:
procedure f(x)
begin
if x < 128 then
WriteByte(x)
else
begin
WriteByte(x mod 128 or 128);
f(x shr 7);
end;
end;
Binärdaten mit Längenpräfix
Der Datentyp beginnt mit einem BigNum, das die Länge angibt, gefolgt von den Daten. Die Daten sind meist Strings, oft finden sich hier auch Daten, die selbst im hier beschriebenen Datenformat Protobuf sind.
Das Dateiformat selbst
Im Dateiformat selbst wiederholen sich bis zum Ende Datei Paare aus stets einem BigNum Identifikator und anschließend Daten.
Der Identifikator enthält zwei Informationen: AND 7
(oder MOD 8
) enthält er den folgenden Datentyp:
- BigNum
- 64-Bit-Zahl
- Binärdaten mit Längenpräfix
- veraltet
- veraltet
- 32-Bit-Zahl
- frei
- frei
Nimmt man den Identifikator SHR 3
(oder DIV 8
) enthält er die Nummer des Feldes, also praktisch dessen Namen. Die Nummer beginnt bei 1. TeamSpeak selbst vergibt die Nummer nur einmal, auch wenn es durch verschiedene Datentypen unterschiedliche Identifikatoren gibt. Wohl aber werden Indentifikatoren (bei gleichem Datentyp) doppelt vergeben, wenn mehrere gleichartige Daten gespeichert werden (Arrays).
Anschließend kommen wie gesagt die Daten entsprechend des zuvor spezifizierten Datentyps.
Updates
Bis Client 3.0.0-beta7 erfolgten Updates, indem der Client eine 1
(Protokoll-Version, unabhängig ob Beta-Teilnahme aktiv oder nicht) per UDP an update.teamspeak.com:17384
schickte. Über das Antwortformat ist nichts bekannt.
Seit 3.0.0-beta8 erfolgten Updates, indem der Client eine 2
(Anmerkungen wie oben) per UDP an update.teamspeak.com:17384
schickte. Zurück bekam er einen String wie 1321432557,1,1,1
, was der Versions-Timestamp und einige Flags sind (vermutlich Booleans zur Gültigkeit der Angabe für Stable, Beta und Alpha).
Zur Zeit von Client 3.0.3 erfolgten Updates, indem der Client eine 3
(Anmerkungen wie oben) per UDP an update.teamspeak.com:17384
schickte. Zurück bekam er einen String. Darin sind (in dieser Reihenfolge und durch Komma getrennt) die stabile, Beta und Alpha-Version des Clients sowie eines alten Servers (3.0.10.1) zu finden. Angegeben sind jeweils Timestamp und Name, getrennt durch Raute. Am Ende kommt ein Komma und die Zahl 29
.
Der aktuelle Client lädt sich diese Datei herunter. Darin ist (in dieser Reihenfolge) eine total veraltete Serverversion (3.0.10, also älter als im alten Format) sowie die stabile, Beta und Alpha-Version des Clients. Früher wurde diese Datei verwendet, die vergleichbar aufgebaut ist.
Diese Dateien sind in Protobuf aufgebaut.
- BigNum: immer 2
- Binärdaten mit Längenpräfix (tritt für jede Versionsart einmal auf): in Protobuf kodierte Daten
- Binärdaten mit Längenpräfix: Name der Versionsart (String)
- BigNum: Build
- Binärdaten mit Längenpräfix: Version (String)
- BigNum: immer 2
Die anschließend heruntergeladenen Updater-Images befinden sich auf mehreren Mirrors. Images seit Version 3.0.11 finden sich hier, Images von 3.0.3 bis 3.0.13.1 hier. Zum Einsatz kommt unverschlüsseltes HTTP, aber es gibt eine Signatur für alle INI-Dateien.
Als Listendateiformat kommt ein INI-Format zur Anwendung. Es ist an sich selbsterklärend.
Das Dateiformat ist gzip, auch wenn man aufgrund der Erweiterung auf compress
tippen würde. Später scheint zudem der Erweiterung zufolge LZMA2 zur Anwendung zu kommen, 7-Zip kann diese Dateien aber nicht öffnen. In den INIs ist weiterhin nur gzip verlinkt.
Da der offizielle Updater nur Updates auf die aktuellste Version durchführen kann, habe ich Anydate programmiert, ein Programm, das beliebige Updates und Downdates (sowie Neuinstallationen) in beliebigen Ordnern durchführen kann.
Dateitransfers
Um eine Datei zu übertragen, schickt man den vom Server mittels ftinitupload
oder ftinitdownload
erhaltenen Schlüssel an die ebenfalls erhaltene IP und Port. Kein Escapen, nichts davor, nichts danach.
Wenn du etwas hochladen möchtest, schickst du anschließend die Daten einfach hinterher. Beim Herunterladen bekommst du die Daten vom Server geschickt.
TSDNS
Zur Verwendung von TSDNS wird die Eingabe in Kleinbuchstaben und anschließend in UTF-8 oder CESU-8 umgewandelt. Das wird dann ergänzt um die ASCII-Zeichen 10, 13, 13, 13, 10 einfach per TCP an den TSDNS-Server auf Port 41144 geschickt.
TSDNS gibt die IP zurück. Es gilt der erste Treffer in der Konfigurationsdatei. Soll der vom Nutzer angegebene Port beibehalten werden (er wird sonst überschrieben), wird $PORT
als Port zurückgegeben. Kennt der Server das Ergebnis nicht (entweder durch absichtliches Setzen in der Konfiguration oder weil die DNS fehlt), gibt er den Text 404
zurück. Der TSDNS-Server kann sich auch entschließen, eine Anfrage nicht zu beantworten, sodass dann die Hierachie (siehe unten) weiter abgearbeitet wird. Das funktioniert nicht bei SRV TSDNS, wo die Nichtantwort eines TSDNS-Servers zum Scheitern der Verbindung führt. Daraus ergibt sich folgender Spezialfall: Das absichtliche Nichtbeantworten einer TSDNS-Anfrage ist äquivalent zum Scheitern, zumindest wenn nur ein TSDNS-Server vorhanden ist.
Für weitere Informationen empfiehlt sich das Lesen der TSDNS-Dokumentation und -Beispieldatei, welche dem Server beiliegen.
Server-Nickname (3.1.6+)
Seit 3.1.6 gibt es Server-Nicknames. Einige Informationen stehen hier.
Das Feature ruft bei Namen ohne Punkte (eigentlich für Computernamen genutzt, die jedoch seit 3.0.20 nicht mehr aufgelöst werden), https://named.myteamspeak.com/lookup?name=
auf, gefolgt vom Query. HTTPS ist Pflicht, HTTP geht nicht! Groß- und Kleinschreibung des Namens wird von diesem Server nicht beachtet. Zurückgegeben wird einfach die Domain (Port ist optional und in dem Fall mit Doppelpunkt getrennt angehängt, sonst wird 9987 angenommen, zumal der Nutzer keinen Port angeben kann) zurückgegeben, kodiert in UTF-8. Anschließend folgt damit die ganz normale Auflösung dieses Ergebnisses, als hätte es der Nutzer eingegeben.
Beim Ändern von Einträgen gibt es eine deutliche Verzögerung, bis diese funktionieren.
Tabelle aller UCS-2-Zeichen: (XLSX-Download der detailierten Tabelle)
(rot = nicht unterstützt, grün = unterstützt, weiß = nicht belegt, grau = nicht zugeordnet)
DNS-Auflösung
TeamSpeak hält sich nicht wirklich an irgendwelche RFCs. Das fängt schon bei den Grundlagen an: Der Client haut nämlich alle Lookups auf einmal raus (offenbar ist aber A vor AAAA), was per RFC verboten wurde. Er wartet dann bis zu 5 Sekunden und wertet anschließend das Ergebnis in der folgenden Reihenfolge aus:
- SRV TS3: Schlägt den SRV-Record von
_ts3._udp.EINGABE
nach. Der mittels SRV TS3 angegebene Port überschreibt die Eingabe des Benutzers. - SRV TSDNS: Der Client schlägt hier
_tsdns._tcp.DOMAIN
nach, wobei die nachzuschlagenen Domains weiter unten erklärt werden. Wenn du eine Domain für eine Website und mehrere auf einem anderen Server gehostete TeamSpeak-Server verwenden möchtest, ist SRV TSDNS deine einzige Möglichkeit, diese zu erreichen. - TSDNS: Fragt Domains auf Port 41144 nach. Welche Domains, wird weiter unten erklärt.
- DNS: Fragt die eingegebene Domain per normalem AAAA-, A-Record ab. Das Nachschlagen des CNAME-Records erfolgt nur implizit.
Grundsätzlich ist TS sehr fehlertolerant, da es selbst auch viele Fehler macht. Beispielsweise kann SRV auf einen CNAME zeigen. SRV kann jedoch nicht auf eine IP zeigen.
Die nach der Reihenfolge oben erste vollständige Lösung wird anschließend verwendet. Es werden keine weiteren Auflösungen probiert, falls die Verbindung fehlschlägt. Eine Redudanz ist somit nicht möglich, lizenztechnisch nicht erlaubt und Serverduplikate werden vom Licensing-Server abgeschaltet.
SRV-Records
SRV ist die einfachste Möglichkeit, einen Port festzulegen. TeamSpeak unterstützt Weight, Priority und IDNs werden bei Verwendung von SRV nicht in Punycode kodiert, sondern es werden folgende Umwandlungen durchgeführt:.
(decidedly unavailable) nicht.
- ASCII-Zeichen (<128) werden in Kleinbuchstaben umgewandelt.
- Der Text wird nach UTF-8 oder CESU-8 konvertiert.
- Alle Buchstaben werden in Kleinbuchstaben umgewandelt.
- Der Text wird nach UTF-8 oder CESU-8 konvertiert.
Das Ergebnis ist natürlich kompletter Blödsinn.
Mit Version 3.1b2 fallen die ersten beiden Umwandlungen weg. Stattdessen werden diese Umwandlungen auch für A benutzt.
Übersicht der DNS-Querys nach Client-Version
„∘“ ist als „nach“ zu lesen; die Auswertung erfolgt somit von unten nach oben. Man könnte die Funktionen also auch in eine Zeile schreiben, die Kringel durch öffnende Klammern ersetzen und schließende am Ende ergänzen.
Lowercase bezeichnet die Unicode-fähige Lowercase-Funktion, AsciiLowercase diejenige Funktion, die nur ASCII-Zeichen zu Kleinbuchstaben macht und den Rest übernimmt.
Version | DNS-AAAA-RR- Queryformat | DNS-A-RR- Queryformat | DNS-SRV-RR- Queryformat | TSDNS- Queryformat | einfaches TSDNS | SRV: IP gültig | TSDNS: Do- main gültig | Computer- namen |
---|---|---|---|---|---|---|---|---|
bis 3.0.0-b37 (21 Dec 2010) | AsciiLowercase | nein | ja | |||||
3.0.0-rc1 (10 May 2011) | AsciiLowercase | UTF8Encode∘ AsciiLowercase | ja | ja | ja | |||
3.0.0-rc2 (08 Jun 2011) bis 3.0.7 (21 Jun 2012) | PunycodeEncode∘ AsciiLowercase | UTF8Encode∘ AsciiLowercase | ja | ja | ja | |||
3.0.8 (12 Jul 2012) bis 3.0.16 (04 Aug 2014) | PunycodeEncode∘ AsciiLowercase | UTF8Encode∘ Lowercase∘ UTF8Encode∘ AsciiLowercase | UTF8Encode∘ AsciiLowercase | ja | ja | ja | ja | |
3.0.17 (04 Aug 2015) bis 3.0.19.4 (14 Jul 2016) | PunycodeEncode∘ Lowercase | UTF8Encode∘ Lowercase∘ UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase | ja | ja | ja | ja | |
3.0.20 (10 Jun 2016) gab’s nur für Win32 | UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase + 0x0A0D0D0D0A | nein | nein | nein | nein | |
3.1-b1 (17 Aug 2016) bis 3.1-b2 (26 Aug 2016) | UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase | UTF8Encode∘ Lowercase + 0x0A0D0D0D0A | nein | nein | nein | nein |
3.1-b3 (29 Sep 2016) | PunycodeEncode∘ Lowercase | PunycodeEncode∘ Lowercase | PunycodeEncode∘ Lowercase | UTF8Encode + 0x0A0D0D0D0A | Warnung | nein | nein | nein |
seit 3.1-b4 (13 Oct 2016) | PunycodeEncode∘ Lowercase | PunycodeEncode∘ Lowercase | PunycodeEncode∘ Lowercase | UTF8Encode∘ Lowercase + 0x0A0D0D0D0A | Warnung | nein | nein | nein |
Anmerkungen:
- Der Query für den TSDNS-Server selbst ist ein DNS-A-RR-Query.
- Die 3.0-Reihe akzeptiert IPs als Ziel von SRV-RRs. Das ist falsch und wurde in 3.1 korrigiert. 3.1 akzeptiert jedoch wie seine Vorgänger CNAMEs als Ziel von SRV-RRs. Das ist auch falsch.
- Aussagen zu Versionen vor (nicht eingeschlossen) 3.0.16 stützen sich nur auf Changelogs und nicht auf eigene Tests.
- 3.0.20 unterstützt IPv6 nur per IPv6-Adresse. Es gibt keine AAAA-Auflösung in 3.0.20 (die Klammer-Syntax aus YaTQA hilft auch nicht).
- Der Schwanz von TSDNS ab Version 3.0.20 teilt dem Server mit, dass der Client IPv6 und Redudanz unterstützt. Während Redudanz in der INI mittels Leerzeichen angegeben wird, wird Redundanz mit Komma getrennt zurückgegeben...
Domains, die TSDNS und SRV TSDNS nachschlagen
- bis 3.0.19.4: TSDNS und SRV TSDNS erstellen eine Liste der vier höchsten Ebenen der Eingabedomain und schlagen diese nach, beginnend mit der untersten Ebene (im schlimmsten Fall also die Fourth-Level-Domain). Sollte sich eine Domain auf dieser Liste befinden, wird sie nicht nachgeschlagen, zählt aber zum erwähnten Limit von maximal vier Ebenen. Gibt man nur eine Top-Level-Domain an, wird diese auf via SRV nachgeschlagen, auch wenn sie auf der Liste steht.
- 3.0.20 bis 3.1-b1: TSDNS gibt es nicht. SRV TSDNS schlägt die Second-Level-Domain der Eingabedomain nach. (Das funktioniert selbstverständlich bei Domains, die erst auf dritter Ebene vergeben werden, nicht.) Gibt man eine Top-Level-Domain an, schlägt SRV gar nichts nach.
- 3.1-b2: TSDNS gibt es nicht. SRV TSDNS schlägt die höchste Ebene der Eingabedomain nach, die nicht auf dieser Liste steht.
- seit 3.1-b3: TSDNS und SRV TSDNS schlagen die zwei höchsten Ebenen der Eingabedomain nach, die nicht auf dieser Liste steht. Es beginnt anders als 3.0.x mit der höchsten Ebene.
Welches System ist das beste für mich?
Je nachdem, wie viele Server du hast, welche Ports sie nutzen und ob du andere Dienste wie eine Website auf derselben Domain (Subdomains sind eigene Domains) hast, ergeben sich unterschiedliche Konstellationen. Die entsprechende Übersicht gibt es als Diagramm und als Tabelle.
Als Diagramm
Als Tabelle
Die folgende Tabelle listet das effizienteste System auf, um dein Ziel zu erreichen. Es sind jeweils weitere möglich (außer im Fall unten rechts), aber nicht zu empfehlen.
Server | Die Dienste auf der Domain (inkl. TS) befinden sich auf... | |
---|---|---|
...derselben IP | ...unterschiedlichen IPs | |
1 Server Standardport | A oder CNAME | SRV TS3 |
1 Server anderer Port Portangabe nicht nötig | SRV TS3 | SRV TS3 |
mehrere Server -oder- 1 Server anderer Port Portangabe nötig | A oder CNAME | SRV TSDNS |
Wie man sieht ist TSDNS allein völlig sinnlos. Es ist als SRV TSDNS allerdings deine einzige Möglichkeit, wenn du einen anderen Dienst wie beispielsweise eine Website auf einer anderen IP besitzt über ihre Domain Server mit verschiedenen Ports ansprechen möchtest.
Blacklist
Der Client schickt ein Paket mit dem Text ip4:
gefolgt von der aufgelösten IP-Adresse als Text per UDP an blacklist.teamspeak.com:17385
.
Zurück erhält man stets ein Paket mit 13 ASCII-Zeichen des Formats x,13371337133
, wobei x den Status angibt:
0
: Der Server steht auf der Blacklist, das heißt, Clients können sich nicht verbinden. Laut TeamSpeak dient das nicht zum Kampf gegen Softwarepiraterie, sondern auch zum Schutz gegen Server, die Malware verbreiten.1
: Der Server ist OK.2
: Der Server ist auf der Greylist, das heißt, Clients bekommen eine Meldung. Dies soll verhindern, dass Nutzer bestraft werden, die einen Server bei einem nicht authorisierten Hoster gemietet haben.
Weitere Informationen finden sich im Forum.
Erhält der Client keine Antwort, verbindet er sich trotzdem. Das liegt wohl daran, dass der Blacklist-Server oft geDDoSt wird/wurde.
Beispiel 1
Anfrage: ip4:212.224.114.71
Antwort: 1,13371337133
Beispiel 2
Anfrage: ip4:84.200.62.245
Antwort: 2,13371337133
Beispiel 3
Anfrage: ip4:2a02:2970:1002::9eea
Antwort: keine
Blacklist2 (3.1.6+)
Der ganze Spaß ist nicht mehr so einfach zu verstehen. Zunächst einmal wird auf jeden Fall ein HTTPS-POST-Request (HTTP geht nicht) zu blacklist2.teamspeak.com
aufgebaut. Gesendet wird folgender Header (Absätze von mir zur Verdeutlichung eingefügt):
POST /check HTTP/1.1\r\n
(auch
Host: blacklist2.teamspeak.com\r\n
User-Agent: TeamHttp/1.1\r\n
Connection: keep-alive\r\nclose
funktioniert, obwohl TeamSpeak keep-alive
verwendet und bei manchen anderen Feldern pingelig ist)
Content-Type: application/x-ts3blacklist\r\n
Länge
Content-Length:\r\n
\r\n
Anschließend kommen die Daten. Die Daten sehen wie folgt aus:
BlacklistInfoRequest
ip_address
domain_name
virtual_server_id
public_license_id
(in Benutzung seit Server 3.1.0)port
timestamp
valid_token_present
(derzeit nicht in Benutzung)slots_ok
(derzeit nicht in Benutzung)
So steht es zumindest im Quellcode. Bei Servern der 3.0-Reihe fehlt aber die Hälfte davon. Das Paket ist als Protobuf aufgebaut:
- Binärdaten mit Längenpräfix: Adresse in binärer Form (siehe dazu auch die Erklärung zur Kanonisierung von IPv6-Adressen unten)
- Binärdaten mit Längenpräfix (falls vom Nutzer verwendet): Domain oder Nickname (UTF-8, ausdrücklich nicht CESU-8!)
- Binärdaten mit Längenpräfix: Server-UID (der übliche Base64-String)
- Binärdaten mit Längenpräfix (falls 3.1.0-Server): öffentlicher Lizenzschlüssel als Base64 (keine Ahnung, wie der sich berechnet, aber scheint der SHA-256 von irgendwas zu sein oder die erste Hälfte eines SHA-512), gleich für alle Server auf einer Lizenz und für alle Clients
- BigNum: Port
- BigNum: Unix-Timestamp (UTC) der Anfrage
- BigNum: unbekannt
- BugNum: unbekannt, bisher sehe ich da immer nur 1 und kann ausschließen, dass dieses und das vorherige Feld entgegen ihrer Namen (siehe oben) sich auf diese Arten verändern lassen:
- Serverversion 3.0 oder 3.1
- Lizenztypen
- 1024 Slots auf einem unlizenzierten TeaSpeak-Server
- 37 von 31 Slots auf einem unlizenzierten TeaSpeak-Server
IP und Server-UID sind verpflichtend, der Rest ist optional.
Zurück gibt’s 8 Bytes (durch Cloudflare zudem jede Menge Müll im HTTP-Header, u.a. ein Cookie) im Protobuf-Format. Diese vier BigNum-Felder stehen für:
status_ip
IP-Adressestatus_domain
Domain, hier gibt es auch (oder nur?) Wildcard-Bans für Subdomainsstatus_virtual_server_id
Server-UID (wurde früher ausschließlich und wenn ich mich richtig erinnere nur für IPs genutzt)Status_public_license_id
[sic!]
Lizenzkey, habe ich aber noch nie in Benutzung gesehen sondern immer nur auf 3 (für OK, siehe nächste Liste)
Als BigNum-Datenwert wird für jedes Feld angegeben:
INVALID
(ungültig)BLACKLISTED
GREYLISTED
NOT_LISTED
(OK oder Feld in Anfrage nicht angegeben)
Sobald ein Feld auf Blacklist steht, verweigert der Client die Verbindung. Der Client cacht das Ergebnis, wahrscheinlich auf IP-Basis. Verbindet man sich auf einen ausschließlich per Domain gebannten Server, kann man sich erst nach einiger Zeit oder nach einem Neustart des Clients zu der IP verbinden. Während ein gecachtes Ergebnis die Verbindung verhindert (wie bei Blacklist1), muss der Client sich für die zwingend nötige UID erst verbinden.
How To: Kanonische IPv6-Adresse (TeamSpeak-Edition)
IPv6-Adressen kann man bekanntlich kürzen, indem man an höchstens einer Stelle aufeinanderfolgende Nuller-Blöcke entfernt. Beispiel:
2a01:7e0:0:417:59:1337:cad:5e
ist dasselbe wie2a01:7e0::417:59:1337:cad:5e
.2a05:8b81:1000:17d:0:0:0:0
ist dasselbe wie2a05:8b81:1000:17d::
.
So weit, so gut. TeamSpeak schafft es jedoch in Version 3.1.6 und 3.1.7 nicht, die Kurzform für die Blacklist2 wieder in die Langform umzuwandeln, und zwar an zwei Stellen:
- Ausgelassene Blöcke werden nicht durch
0
(bzw.0000
) ersetzt sondern durch3030
. Möglicherweise hat TeamSpeak hier versucht, ein Byte als Char zu speichern (0x30
entspricht der Ziffer 0)... - Wird der siebte Block der IP-Adresse ausgelassen, wird der achte durch
3030
ersetzt. Warum auch immer.
Dieselbe IP-Adresse mit mindestens einem Nuller-Block kann immer auf verschiedene Arten (oder gar nicht) gekürzt werden, was wegen der falschen Kanonisierung zu unterschiedlichen Blacklist2-IP-Abfragen in TeamSpeak führt, obwohl es sich wie gesagt um dieelbe IP-Adresse handelt.
In 3.1.8-beta1 ist dieser Bug behoben.
Weblist (Server)
Das Weblist-Reporting läuft mittels UDP an weblist.teamspeak.com:2010
. Der Aufbau eines Pakets ist immer gleich und zwar wie folgt:
- 1 Byte: immer 1 (Version?)
- 2 Bytes: fortlaufende Nummer (identisch für Anfrage und Antwort, beginnt bei 1)
- 1 Byte: Paket-Typ (1 für Schlüssel-Anforderung, 2 für Daten)
- Nutzlast (optional)
Die Aktualisierung des Weblist-Eintrags erfolgt stets in folgenden vier Schritten:
- Als erstes wird ein Schlüssel angefordert, indem entsprechendes Paket ohne Nutzlast geschickt wird.
- Der Schlüssel wird zurückgegeben und ist eine zufällige 32-Bit-Zahl. Man erhält stets eine neue Version
- Die Serverdaten werden durch folgende Nutzlast aktualisiert:
- 4 Bytes: gerade erhaltener Schlüssel
- 2 Bytes: Port
- 2 Bytes: Slots
- 2 Bytes: Clients (ohne Query-Clients)
- 1 Byte: Flags
- 6 Bits: immer 0
- 1 Bit: 1 falls Gast einen Channel erstellen kann (hierbei ist es egal, was für ein Channel-Typ erstellt werden kann), 0 falls nicht
- 1 Bit: 1 falls der Server ein Passwort hat, 0 falls nicht
- 1 Byte: Länge des Servernamens in Bytes, 0 falls nicht geändert
- Servername in UTF-8 oder CESU-8
- Als Antwort erhält man ein Paket mit einem Byte als Nutzlast. Der Wert 0 steht für OK. Hat der Weblist-Server einen zwischenzeitlich vergessen, z.B. weil es zu Fehlern kam, fordert er mit einer 7 den Servernamen an.
Die Byte-Folge ist Little Endian, die Bitfolge (auch für die Flags) ist Big Endian.
Der TS3-Server unternimmt alle 10 Minuten einen Versuch, die Serverliste zu aktualisieren. Erhält er keine Antwort, versucht er es nach 1,3 Sekunden erneut. Erhält er wieder keine Antwort, versucht er es weitere 2 Sekunden später erneut. Beide Male wird die Paket-ID nicht weiter hochgezählt. Erhält er auch diesmal keine Antwort, lässt er es bleiben. Das Intervall von 10 Minuten wird dadurch nicht verschoben.
Wird ein virtueller Server heruntergefahren, wird dies der Serverliste nicht mitgeteilt.
Weblist (Client)
Die Weblist-Abfrage läuft mittels TCP an weblist.teamspeak.com:2010
.
Mit mehr habe ich mich noch nicht befasst.
Abzeichen (Badges)
Abzeichen werden auf dem Server als GUID gespeichert. Außer der GUID wird aber für den Abruf der Bilder, die im Ordner cache\badges
gecacht werden, noch ein Dateiname benötigt, der auch einzig und allein den Dateinamen im Cache angibt.
Diese Dateinamen stehen in einer Liste. Diese Liste ist binär kodiert und wird unverändert (als varchar
) in der Datei settings.db
gespeichert. In derselben Tabelle (badges
) wird auch ein Timestamp gespeichert, der entgegen des Namens nicht den Timestamp der Liste angibt sondern die Zeit, zu der sie neu heruntergeladen werden soll. Dies ist derzeit (3.1b6) 24 Stunden nach dem Download. Beide Informationen (Daten und Timestamp) sind jeweils mit einem Timestamp versehen, ohne dass ich dessen Sinn wüsste.
Das Dateiformat
Die Datei ist gemäß Protobuf aufgebaut:
- BigNum: Revisionsnummer?
(Auf jeden Fall nicht die Anzahl, denn derzeit (März 2018) ist der Wert 15, aber es gibt nur 13 Abzeichen.) - BigNum: Unix-Timestamp, vermutlich der letzten Änderung
- Binärdaten mit Längenpräfix (tritt für jedes Abzeichen einmal auf): in Protobuf kodierte Daten
- Binärdaten mit Längenpräfix: GUID (36 Zeichen langer String, davon sind 4 Zeichen Bindestriche und 32 Hex-Ziffern)
- Binärdaten mit Längenpräfix: Name (UTF-8)
- Binärdaten mit Längenpräfix: URL-Basis (wird um
_64.png
für das Abzeichen-Fenster bzw..svg
(früher_16.png
) für den Serverbaum ergänzt; myTeamSpeak ergänzt sie um_details.svg
(früher.svg
) für eine teilweise anders aussehende Vektorversion) - Binärdaten mit Längenpräfix: Beschreibung (UTF-8)
- BigNum: Unix-Timestamp, vermutlich der letzten Änderung
- BigNum: keine Ahnung, es kommen die Werte 1 bis 3 vor
Liste der Abzeichen
Die Abzeichen-Liste ist jetzt ihre eigene Unterseite.
Abzeichen (Badges) auf einer Instanz deaktivieren
Da das jetzt sehr oft gefragt wurde, hier eine Anleitung, wie man Badges los wird. Der Trick ist sehr einfach, funktioniert aber nicht bei einem selber.
- Lade dir einen binärsicheren Editor herunter. Ich benutze Notepad++. Der Windows-Editor, WordPad oder ähnlich sind nicht binärsicher! Alle Hex-Editoren sind binärsicher.
- Öffne das TeamSpeak-Server-Programm
- Suche nach
client_badges
- Ersetze (nicht löschen!) eines der gefundenen Zeichen durch irgendein ein anderes
- Jetzt nur noch speichern
Quick computer science!
Anhang
Liste der Toplevel-Domains (3.1-b2+)
siehe hier
Anders als in 3.0.x löst TeamSpeak 3.1 (inkl. 3.1-b1) grundsätzlich keine Toplevel-Domains auf. Das ergibt Sinn, weil wohl kaum jemand in seinem lokalen Netzwerk Second-Level-Domains (also Domainnamen mit Punkt) und eine SRV-fähige Namensauflösung verwendet. In der TeamSpeak-3.1-Reihe wurden Lookups von Rechnernamen im lokalen Netzwerk (also ohne echtes DNS) entfernt.
In 3.1-b2 ist dann die oben verlinkte Liste enthalten. Obwohl Toplevel-Domains nicht aufgelöst werden, sind ausschließlich auf zweiter Ebene vergebene Domains in der Liste enthalten, die im Client gespeichert ist. Die Liste ist im Client übrigens im Punycode-Format gespeichert. Der Client unterstützte von 3.0.20 bis 3.1-b2 Punycode allerdings überhaupt nicht. Mit 3.1-b3 wurde Punycode-Unterstützung wieder hinzugefügt.
Liste der Toplevel-Domains (3.0.20 und 3.1-b1)
TeamSpeak 3.0.20 und 3.1-b1 schauen schlichtweg keine Toplevel-Domains nach. Problem: Es gibt Domains, die (nur) auf dritter Ebene vergeben werden (.il
, .ua
, .za
) oder wurden (.uk
[bis Juli 2014], .nz
[bis März 2015], .au
[unbekannt], .ni
[bis Oktober 2017]).
In diesen Versionen (3.0.20 bin ich mir nicht 100% sicher) wurden zudem lokale Lookups nach Rechnernamen in der Domäne entfernt.
Liste der Toplevel-Domains (3.0.x)
Stand dieser in Clientversion 3.0.18.1 (und vermutlich allen anderen bis einschließlich 3.0.19.4) enthaltenen Liste ist Anfang Oktober 2007. Es fehlen einige der seither eingeführten TLDs (.xxx
, .post
, beide St. Martins (wobei eine davon nicht zugewiesen ist), Saint-Barthélemy), sämtliche neuen TLDs und die inzwischen entstandenen Länder wie Südsudan und die Nachfolgestaaten der Niederländischen Antillen. Es fehlen Domains, die nicht verwendet werden (.um
, .eh
). Die nicht mehr vorhandene TLD .an
ist wegen des Alters der Liste noch enthalten. Auch .gb
ist enthalten.
Die Test-IDNs sind Domains, die das Wort „Test“ in verschiedenen Sprachen und Schriften enthalten. Einzige Domain war das entsprechende Wort für „Beispiel“. Auch diese TLDs gibt nicht mehr, genauer gesagt seit dem 31. Oktober 2013.
Domain | IDN-Klartext | Sprache (ggf. Schrift) | Bedeutung [Gebiet abhängig von] |
---|---|---|---|
aero | Luftfahrt | ||
arpa | Arpanet | ||
asia | Asien | ||
biz | |||
cat | Katalonien [Spanien] | ||
com | |||
coop | Genossenschaften | ||
edu | Vereinigte Staaten | ||
gov | Vereinigte Staaten | ||
info | |||
int | Internationale Organisationen | ||
jobs | Jobs | ||
mil | Vereinigte Staaten | ||
mobi | Mobile Websites | ||
museum | Museen | ||
name | |||
net | |||
org | |||
pro | |||
tel | Kontaktinformationen | ||
travel | Reise | ||
ac | Vereinigtes Königreich | ||
ad | Andorra | ||
ae | Vereinigte Arabische Emirate | ||
af | Afghanistan | ||
ag | Antigua und Barbuda | ||
ai | Anguilla [Vereinigtes Königreich] | ||
al | Albanien | ||
am | Armenien | ||
an | Niederländische Antillen (existiert nicht mehr) | ||
ao | Angola | ||
aq | Antarktis | ||
ar | Argentinien | ||
as | Amerikanisch-Samoa [Vereinigte Staaten] | ||
at | Österreich | ||
au | Australien | ||
aw | Aruba [Niederlande] | ||
ax | Åland [Finnland] | ||
az | Aserbaidschan | ||
ba | Bosnien und Herzegowina | ||
bb | Barbados | ||
bd | Bangladesch | ||
be | Belgien | ||
bf | Burkina Faso | ||
bg | Bulgarien | ||
bh | Bahrain | ||
bi | Burundi | ||
bj | Benin | ||
bm | Bermuda [Vereinigtes Königreich] | ||
bn | Brunei | ||
bo | Bolivien | ||
br | Brasilien | ||
bs | Bahamas | ||
bt | Bhutan | ||
bv | Bouvetinseln [Norwegen] | ||
bw | Botswana | ||
by | Weißrussland | ||
bz | Belize | ||
ca | Kanada | ||
cc | Kokosinseln [Australien] | ||
cd | Demokratische Republik Kongo-Kinshasa | ||
cf | Zentralafrikanische Republik | ||
cg | Republik Kongo-Brazzaville | ||
ch | Schweiz | ||
ci | Elfenbeinküste | ||
ck | Cookinseln [Neuseeland] | ||
cl | Chile | ||
cm | Kamerun | ||
cn | China | ||
co | Kolumbien | ||
cr | Costa Rica | ||
cu | Kuba | ||
cv | Kap Verde | ||
cx | Weihnachtsinsel [Australien] | ||
cy | Zypern | ||
cz | Tschechien | ||
de | Deutschland | ||
dj | Dschibuti | ||
dk | Dänemark | ||
dm | Dominica | ||
do | Dominikanische Republik | ||
dz | Algerien | ||
ec | Ecuador | ||
ee | Estland | ||
eg | Ägypten | ||
er | Eritrea | ||
es | Spanien | ||
et | Äthiopien | ||
eu | Europa | ||
fi | Finnland | ||
fj | Fidschi | ||
fk | Falklandinseln [Vereinigtes Königreich] | ||
fm | Föderierte Staaten von Mikronesien | ||
fo | Färöer [Dänemark] | ||
fr | Frankreich | ||
ga | Gabun | ||
gb | Vereinigtes Königreich | ||
gd | Grenada | ||
ge | Georgien | ||
gf | Französisch-Guayana | ||
gg | Guernsey [Vereinigtes Königreich] | ||
gh | Ghana | ||
gi | Gibraltar [Vereinigtes Königreich] | ||
gl | Grönland [Dänemark] | ||
gm | Gambia | ||
gn | Guinea | ||
gp | Guadeloupe [Frankreich] | ||
gq | Äquatorialguinea | ||
gr | Griechenland | ||
gs | Südgeorgien und die Südlichen Sandwichinseln [Vereinigtes Königreich] | ||
gt | Guatemala | ||
gu | Guam [Vereinigte Staaten] | ||
gw | Guinea-Bissau | ||
gy | Guyana | ||
hk | Hongkong [China] | ||
hm | Heard und McDonaldinseln [Australien] | ||
hn | Honduras | ||
hr | Kroatien | ||
ht | Haiti | ||
hu | Ungarn | ||
id | Indonesien | ||
ie | Republik Irland | ||
il | Israel | ||
im | Insel Man [Vereinigtes Königreich] | ||
in | Indien | ||
io | Britisches Territorium im Indischen Ozean [Vereinigtes Königreich] | ||
iq | Irak | ||
ir | Iran | ||
is | Island | ||
it | Italien | ||
je | Jersey [Vereinigtes Königreich] | ||
jm | Jamaika | ||
jo | Jordanien | ||
jp | Japan | ||
ke | Kenia | ||
kg | Kirgisistan | ||
kh | Kambodscha | ||
ki | Kiribati | ||
km | Komoren | ||
kn | St. Kitts und Nevis | ||
kp | Nordkorea | ||
kr | Südkorea | ||
kw | Kuwait | ||
ky | Kaimaninseln [Vereinigtes Königreich] | ||
kz | Kasachstan | ||
la | Laos | ||
lb | Libanon | ||
lc | St. Lucia | ||
li | Liechtenstein | ||
lk | Sri Lanka | ||
lr | Liberia | ||
ls | Lesotho | ||
lu | Luxemburg | ||
lt | Litauen | ||
lv | Lettland | ||
ly | Libyen | ||
ma | Marokko | ||
mc | Monaco | ||
md | Moldau | ||
me | Montenegro | ||
mg | Madagaskar | ||
mh | Marshallinseln | ||
mk | Mazedonien | ||
ml | Mali | ||
mm | Myanmar | ||
mn | Mongolei | ||
mo | Macau [China] | ||
mp | Nördliche Marianen [Vereinigte Staaten] | ||
mq | Martinique [Frankreich] | ||
mr | Mauritanien | ||
ms | Montserrat [Vereinigtes Königreich] | ||
mt | Malta | ||
mu | Mauritius | ||
mv | Malediven | ||
mw | Malawi | ||
mx | Mexiko | ||
my | Malaysia | ||
mz | Mosambik | ||
na | Namibia | ||
nc | Neukaledonien [Frankreich] | ||
ne | Niger | ||
nf | Norfolkinsel [Australien] | ||
ng | Nigeria | ||
ni | Nicaragua | ||
nl | Niederlande | ||
no | Norwegen | ||
np | Nepal | ||
nr | Nauru | ||
nu | Niue [Neuseeland] | ||
nz | Neuseeland | ||
om | Oman | ||
pa | Panama | ||
pe | Peru | ||
pf | Französisch-Polynesien [Frankreich] | ||
pg | Papua-Neuguinea | ||
ph | Philippinen | ||
pk | Pakistan | ||
pl | Polen | ||
pm | Saint-Pierre und Miquelon [Frankreich] | ||
pn | Pitcairninseln [Vereinigtes Königreich] | ||
pr | Puerto Rico | ||
ps | Palästinensische Autonomiegebiete [Israel] | ||
pt | Portugal | ||
pw | Palau | ||
py | Paraguay | ||
qa | Katar | ||
re | Réunion [Frankreich] | ||
ro | Rumanien | ||
rs | Serbien | ||
ru | Russland | ||
rw | Ruanda | ||
sa | Saudi-Arabien | ||
sb | Salomoninseln | ||
sc | Seychellen | ||
sd | Sudan | ||
se | Schweden | ||
sg | Singapur | ||
sh | St. Helena [Vereinigtes Königreich] | ||
si | Slowenien | ||
sj | Spitzbergen und Jan Mayen [Norwegen] | ||
sk | Slowakei | ||
sl | Sierra Leone | ||
sm | San Marino | ||
sn | Senegal | ||
so | Somalia | ||
sr | Suriname | ||
st | São Tomé und Príncipe | ||
su | Russland | ||
sv | El Salvador | ||
sy | Syrien | ||
sz | Swasiland | ||
tc | Turks- und Caicosinseln [Vereinigtes Königreich] | ||
td | Tschad | ||
tf | Französische Süd- und Antarktisgebiete [Frankreich] | ||
tg | Togo | ||
tj | Thailand | ||
tk | Tadschikistan | ||
tl | Tokelau [Neuseeland] | ||
tm | Osttimor | ||
tn | Turkmenistan | ||
tp | Tunesien | ||
to | Tonga | ||
tr | Türkei | ||
tt | Trinidad und Tobago | ||
tv | Tuvalu | ||
tw | Republik China [China] | ||
tz | Tansania | ||
ua | Ukraine | ||
ug | Uganda | ||
uk | Vereinigtes Königreich | ||
us | Vereinigte Staaten | ||
uy | Uruguay | ||
uz | Usbekistan | ||
va | Vatikanstadt | ||
vc | St. Vincent und die Grenadinen | ||
ve | Venezuela | ||
vg | Britische Jungferninseln [Vereinigtes Königreich] | ||
vi | Amerikanische Jungferninseln [Vereinigte Staaten] | ||
vn | Vietnam | ||
vu | Vanuatu | ||
wf | Wallis und Futuna [Frankreich] | ||
ws | Westsamoa | ||
ye | Jemen | ||
yt | Mayotte [Frankreich] | ||
za | Südafrika | ||
zm | Sambia | ||
zw | Simbabwe | ||
xn--fiqs8s | 中国 | Chinesisch (vereinfacht) | China |
xn--fiqz9s | 中國 | Chinesisch (traditionell) | China |
xn--fzc2c9e2c | ලංකා | Sinhala | Sri Lanka |
xn--j6w193g | 香港 | Chinesisch | Hongkong [China] |
xn--kprw13d | 台湾 | Chinesisch (vereinfacht) | Republik China [China] |
xn--kpry57d | 台灣 | Chinesisch (traditionell) | Republik China [China] |
xn--mgbaam7a8h | امارات | Arabisch | Vereinigte Arabische Emirate |
xn--mgbayh7gpa | الاردن | Arabisch | Jordanien |
xn--mgberp4a5d4ar | السعودية | Arabisch | Saudi-Arabien |
xn--o3cw4h | ไทย | Thai | Thailand |
xn--p1ai | рф | Russisch (kyrillisch) | Russland |
xn--pgbs0dh | تونس | Arabisch | Tunesien |
xn--wgbh1c | مصر | Arabisch | Ägypten |
xn--wgbl6a | قطر | Arabisch | Katar |
xn--xkc2al3hye2a | இலங்கை | Tamil | Sri Lanka |
xn--ygbi2ammx | فلسطين | Arabisch | Palästinensische Autonomiegebiete [Israel] |
xn--0zwm56d | 测试 | Chinesisch (vereinfacht) | IDN-Test |
xn--11b5bs3a9aj6g | परीक्षा | Hindi (Devanagari) | IDN-Test |
xn--80akhbyknj4f | испытание | Russisch (kyrillisch) | IDN-Test |
xn--9t4b11yi5a | 테스트 | Koreanisch (Hangul) | IDN-Test |
xn--deba0ad | טעסט | Jiddisch (hebräisch) | IDN-Test |
xn--g6w251d | 測試 | Chinesisch (traditionell) | IDN-Test |
xn--hgbk6aj7f53bba | آزمایشی | Persisch | IDN-Test |
xn--hlcj6aya9esc7a | பரிட்சை | Tamil | IDN-Test |
xn--jxalpdlp | δοκιμή | Griechisch | IDN-Test |
xn--kgbechtv | إختبار | Arabisch | IDN-Test |
xn--zckzah | テスト | Japanisch | IDN-Test |