TeamSpeak-3-Server-Query-Kommentare

Die Dokumentation von TeamSpeak 3 ist grausam. Diese Seite listet Fehler, Bugs und andere Dinge auf, die ich bei der Entwicklung von YaTQA bemerkt habe.

Inhaltsverzeichnis

Im Dokument wird eine auf der offiziellen Reihenfolge der Befehle basierende Strukturierung verwendet.

Allgemeines und Instanz I

login

Schlägt login fehl (also nicht sowas banales wie fehlende Parameter), wird man ausgeloggt, wenn man schon eingeloggt ist.

use

Das Benutzen eines nicht existierenden Servers gibt einen Fehler, dass dieser nicht laufen würde.

Entgegen dessen, was in der Serverquery-Manual zu serverlist steht, startet use nicht automatisch einen nicht laufenden Server virtuell. Das muss man explizit angeben (-virtual).

Es gibt eigentlich keinen Grund, diesen Befehl nicht mit -virtual zu verwenden. Der Schalter hat bei laufenden Servern keine Auswirkungen.

Einen Server virtuell zu benutzen, vernötigt auf der Lizenz keine Slots, aber einen laufenden Server.

Server I

serverlist

Entgegen der Serverquery-Manual startet use nicht automatisch einen nicht laufenden Server virtuell. Das muss man explizit angeben.

serverinfo

virtualserver_download_quota, virtualserver_upload_quota, virtualserver_max_download_total_bandwidth und virtualserver_max_upload_total_bandwidth geben eine Zahl im Bereich von UInt64 zurück (bei mir sind es 18.446.744.073.709.551.615 Bytes also 16 Exbibytes oder 16.777.216 Tebibytes). Die Int64-Zahl -1 wird binär genau so gespeichert (nämlich als 64 Einsen) und im Client auch als -1 angezeigt. Vermutlich ist die Zahlenangabe also falsch, genaues kann ich aber derzeit nicht sagen. Ich muss erstmal 16 EiB Traffic machen. ;) Das Ändern der Variable zu -1 führt jedoch zu Fehler 1540 (convert error).

serverrequestconnectioninfo

serverrequestconnectioninfo gibt insgesamt allerdings viel weniger Daten über die Verbindung zurück als serverinfo (mehr dazu siehe hier). So bricht serverinfo den Packetloss und seit der finalen Serverversion auch den Datentransfer, Ping und Paketverlust auf (Sprache, Verbindungserhaltung, Kontrollsequenzen). Früher gab es connection_filetransfer_bytes_sent_total und connection_filetransfer_bytes_received_total nur bei serverrequestconnectioninfo. Diese beiden geben den gesamten Dateitransfer seit Start an, während virtualserver_month_bytes_downloaded und virtualserver_month_bytes_uploaded nur den Dateitransfer des aktuellen Monats zählen.

serveredit

virtualserver_ask_for_privilegekey zu setzen hatte anfangs keinen Effekt (auch serverinfo zeigte weiterhin 0 an), inzwischen gibt es Fehler 1538 (invalid parameter). Das führt in Verbindung mit dem einem Bug zu einem Problem: Benutzt serveradmin den SA-Token, schlägt das zwar fehl, der Token ist aber weg und damit die einzige Möglichkeit, die Meldung loszuwerden.

servertemppasswordadd

Beide Zielchannel-Parameter sind optional. Anders als bei anderen Befehlen funktioniert tcid auch komplett ohne tcpw, falls der Channel kein Passwort hat.

Hat der Benutzer im normalen Standard-Channel b_virtualserver_join_ignore_password, funktionierte zunächst die Channelangabe eines Passworts nicht, inzwischen klappt das aber.

Servergruppen

servergroupdel

In der allgemeinen Syntax with force als notwendig angegeben, im Beispiel der QueryManual aber gar nicht bzw. bei dem von help aber nur teilweise verwendet. Die Funktion funktioniert tatsächlich, wenn dieser Parameter fehlt (und niemand in der Gruppe ist).

servergroupcopy

Der Parameter name darf nicht leer sein (oder gar fehlen), wenn man Gruppen über andere kopiert, auch wenn der Parameter von der Funktion nicht gebraucht wird und verschiedene Werte für name nicht zu unterschiedlichen Ergebnissen führen. Zudem muss, wenn man eine Gruppe überschreibt, der Parameter type dem Typ der Zielgruppe entsprechen, sonst gibt es Fehler 1538 (invalid parameter)

servergroupsbyclientid

Die übergebene cldbid wird bei jedem Datensatz mit zurückgegeben. Warum das so ist, ist unklar, denn die Funktion unterstützt für den gleichnamigen Parameter keine Arrays.

servergroupautoaddperm
servergroupautodelperm

Diesen beiden Funktionen funktionieren nur mit Gruppen, die keine Vorlagen- und Query-Gruppen sind. Um zu funktionieren, müssen sie alle Server vorübergehend starten, sprich man braucht, wenn man Server hat, die derzeit nicht aktiv sind, eine Lizenz für einen weiteren Server, wenn man ansonsten am Limit ist.

Beide Befehle benötigten b_permission_modify_power_ignore und in dem Fall funktioniert es sogar: Hat man das Recht, kann man mit servergroupautoaddperm wirklich alles setzen, was man denn so will. Hat man sich also versehentlich ein Recht weggenommen, hat aber noch b_permission_modify_power_ignore und einen i_group_auto_update_type, kann man sich das Recht einfach wieder geben.

Es sind auch Auto-Gruppen-IDs möglich, die nicht die Standarddinger aus {10, 15, ..., 50} sind.

In der QueryManual hat sich außerdem beim Beispiel für servergroupautodelperm ein Copy-Paste-Fehler eingeschlichen.

Server II

serversnapshotdeploy

Es gibt die Werte sid und virtualserver_port zurück.

Letzteres ist vor allem deshalb sinnvoll, weil virtualserver_port nicht aus dem Snapshot übernommen wird. Überschreibt man einen Server, bleibt der Port erhalten. Erstellt man einen neuen Server, wird er vom Server automatisch vergeben.

Der mit Version 3.0.12 eingeführte Schalter -mapping muss vor dem Snapshot kommen, wenn man ihn denn verwendet. Er produziert dann ein Array von ocid und ncid in der Ausgabe. Die Werte sind numerisch nach ocid aufsteigend sortiert, während die Reihenfolge der ncids abweichend kann, da diese Zahlen sich aus der Reihenfolge der Channel im Baum ergeben.

In der mir vorliegenden Version bilden die zuvor erwähnten normalen Parameter das erste Element des Arrays, und das eigentliche Array beginnt erst mit dem zweiten Element.

servernotifyregister

Es existiert der undokumentierte Parameter event=tokenused.

Bei ungültigen Werten für event verlangt der Server zunächst nach einem weiteren Parameter. Wird dieser dann in Form von id angegeben, gibt es einen Parameterfehler.

Der Wert des Parameters id muss nicht auf einen existierenden Channel verweisen. id=0 steht für jeden Channel und man erhält viele Events doppelt.

Ausführliche Erklärungen gibt es in der Notify-Dokumentation.

Instanz II

sendtextmessage

targetmode=2 (Channel) und targetmode=3 (Server) senden an ihren eigenen Channel bzw. Server. Eine Angabe von target ist nicht erforderlich und wird gegebenenfalls – sorry für dieses unbeabsichtigte Wortspiel – ignoriert.

Das Beispiel ist somit völlig sinnfrei, verursacht aber auch keinen Fehler.

logview (seit 3.0.1)

In Serverversion 3.0.1 wurde das Log von einem datenbankbasierten zu einem dateibasierten Log geändert. Gleichzeitig wurde der Maximalwert von lines von 500 auf 100 gesenkt. Dies ist zugleich der Standardwert.

Der optionale Parameter instance hat keine Auswirkungen, wenn kein Server gewählt ist. Ist ein Server gewählt und wird instance nicht angegeben, entspricht das instance=0, es wird also das Logbuch des virtuellen Servers zurückgegeben.

reverse=1 kehrt nur die Reihenfolge des l-Arrays um. Auswirkungen darauf, was überhaupt zurückgegeben wird, hat reverse nicht. Man kann also nicht vom Anfang der Datei lesen oder ähnliches.

begin_pos zeigt einsterminiert(!) auf das letzte(!) Zeichen in der Datei, das in der Ausgabe berücksichtigt werden soll. logview gibt von begin_pos aus die davor(!) in der Datei befindlichen Zeilen zurück. Zeigt begin_pos auf ein Absatzzeichen (habe nur 0x0A probiert, sollte mit 0x0D aber auch gehen), wird dies nicht gegen lines angerechnet. Angebrochene Zeilen zählen ansonsten als Zeile.

Wird begin_pos nicht angegeben, ist zu großer oder ist 0, wird das Ende der Datei genommen. Ist begin_pos gleich 1, führt das zu Fehler 1281 (database empty result set). Ist begin_pos kleiner als 0, gibt es Fehler 2052 /file input output error).

last_pos bezeichnet einsterminiert das in der Logdatei erste(!) Byte, das als Teil dieser Ausgabe genutzt wird. Wird begin_pos angegeben, ist somit begin_pos–last_pos = Summe(Länge(l(x))+1,x)–1. Zeigt begin_pos auf ein \n, ist die Summe um 1 kleiner als begin_pos–last_pos (das –1 am Ende der Gleichungwird zu –2).

Das Dateiformat der Logdateien wird möglicherweise in Version 3.0.12 von plattformabhängig/ASCII in Unix/UTF-8+BOM geändert. Die BOM (0xEFBBBF, unter Windows auch bekannt als ) ist dann integraler Bestandteil der ersten Zeile und zusammen mit dieser ausgegeben ausgegeben, wo sie Teil des Datums ist und entsprechende Dekoder durcheinanderbringen kann/wird.

Beispiel

2015-0:52)2015-02bit2015-0 123456454647484950515253545556888990919293949596979899
logview begin_pos=1 lines=1
Fehler 1281 (database empty result set)
logview begin_pos=2 lines=1
Ergebnis: 20
last_pos=0
logview begin_pos=48 lines=1
Ergebnis: komplette erste Zeile
last_pos=0
logview begin_pos=49 lines=1
Ergebnis: komplette erste Zeile
last_pos=0
logview begin_pos=50 lines=1
Ergebnis: komplette erste Zeile
last_pos=0
logview begin_pos=51 lines=1
Ergebnis: 2
last_pos=48

Channel

channellist

Auch hier gibt es wie bei clientlist die Möglichkeit, die Menge der Rückgabefelder pro Eintrag durch Schalter-Parameter zu erweitern. Mehr dazu siehe hier.

channelfind

Der einzige Parameter pattern ist, anders als im Query-Manual behauptet, nicht optional.

Die Groß- und Kleinschreibung ist wie eigentlich immer bei Strings egal. Es wird auch ohne Wildcards nach Teilstrings gesucht.

channeldelete

force ist optional.

Channelgruppen

channelgroupadd

Es gibt, entgegen der Erklärung in der QueryManual, keine Query-Channelgruppen.

channelgroupdel

In der allgemeinen Syntax wird force als notwendig angegeben, im Beispiel der QueryManual aber gar nicht bzw. bei dem von help aber nur teilweise verwendet. Die Funktion funktioniert tatsächlich, wenn dieser Parameter fehlt (und niemand in der Gruppe ist).

channelgroupcopy

Der Parameter name darf nicht leer sein (oder gar fehlen), wenn man Gruppen über andere kopiert, auch wenn der Parameter von der Funktion nicht gebraucht wird und verschiedene Werte für name nicht zu unterschiedlichen Ergebnissen führen. Zudem muss, wenn man eine Gruppe überschreibt, der Parameter type dem Typ der Zielgruppe entsprechen, sonst gibt es Fehler 1538 (invalid parameter)

Es gibt, entgegen der Erklärung in der QueryManual, keine Query-Channelgruppen.

Clients und Clientdatenbank

clientlist

Der -badges-Schalter wird auch in der neuen QueryManual vom 20. September 2013 nicht erwähnt. Mehr zu den Schaltern, mit denen sich mehr Details zurückgeben lassen, siehe hier.

clientfind

Die Groß- und Kleinschreibung ist wie eigentlich überall egal. Es wird nach Teilstrings gesucht.

clientedit

Entgegen der Dokumentation können nur client_description und client_is_talker bearbeitet werden. Letzteres funktioniert aber auch nur, wenn der Client eigentlich nicht reden kann.

Das Icon und die Needed View Power kann man über clientaddperm setzen. Weitere Infos siehe hier.

clientdblist

duration ist keine Dauer sondern die Anzahl der Einträge, die zurückgegeben werden. Es werden maximal 200 Einträge zurückgegeben. duration=-1 steht für das Maximum, andere negative Werte führen zu Fehler 1540 (convert error).

Der Rückgabewert dieser Funktion ist mächtiger als im Handbuch angegeben. Mehr dazu siehe hier.

clientdbinfo

Der Rückgabewert dieser Funktion ist viel mächtiger als im Handbuch angegeben. Mehr dazu siehe hier.

clientdbfind

Die Groß- und Kleinschreibung ist wie überall egal. Es wird hier aber nicht nach Teilstrings sondern nach regulären Ausdrücken gesucht. % ist dabei ein Platzhalter für beliebigen Text.

Dies alles gilt übrigens auch für die UID-Suche mit dem -uid-Schalter. Dessen Position ist übrigens egal.

clientdbedit

Warum braucht man dafür b_client_set_talk_power? Man kann einem Client, der nicht da ist, nicht erlauben, doch zu reden...

clientgetdbidfromuid

Dieser Befehl ist redundant mit clientdbfind -uid, benötigt aber laut Dokumentation keine Rechte.

clientgetnamefromuid

Dieser Befehl ist recht sinnfrei, da clientdbinfo wesentlich mächtiger ist (siehe oben). Die DBID kann man mit clientgetdbidfromuid oder clientgetdbidfromuid erhalten.

clientgetnamefromdbid

Dieser Befehl ist völlig sinnfrei, da clientdbinfo wesentlich mächtiger ist (siehe oben).

clientmove

Man kann sich damit auch selbst bewegen. Ich gehe davon aus, dass man dafür i_client_move_power nicht braucht. Außerdem dürfte die Liste allgemein etwas unvollständig sein (i_client_channel_join_permanent, ignore_password u.ä.).

clientkick

Die zu kickenden Clients müssen am Ende kommen, wenn es mehrere sind.

Das Beispiel in der QueryManual ist somit Blödsinn und würde nicht funktionieren. Am Anfang der QueryManual und mittels help gibt es ein funktionierendes Beispiel für die Funktion, ebenfalls mit Array.

clientpoke

Man kann nicht mehrere Clients gleichzeitig poken, wie es in der QueryManual angegeben ist. Unabhängig von der Reihenfolge der Parameter wird der erste Client angestupst. Die über help abgerufene Syntax ist hingegen richtig.

Client- und Client-Channel-Rechte

clientdelperm

Das Beispiel ist korrekt, die Syntax an sich auch, nur als Befehl wird channeldelperm benutzt.

Rechte allgemein

permissionlist

Der Schalter -new ist nicht zentral dokumentiert sondern steht nur im Changelog. Was der macht steht hier (en).

permidgetbyname

Der Befehl ist redundant mit permget, benötigt aber andere Rechte.

Die Funktion stört es nicht, mehrere gleiche Parameter zu übergeben.

Kann ein Recht nicht aufgelöst werden, schlägt die ganze Funktion fehl und es gibt keine Ausgabe, auch nicht wenn vorherige Rechte korrekt sind.

permoverview

Der Befehl unterstützt permsid als Parameter. Es gibt kein mir bekanntes permsid-Äquivalent zu permid=0 (ist ja auch nicht nötig). Arrays für permid bzw. permsid werden nicht unterstützt.

Die folgende Tabelle zeigt die Werte für die Parameterkürzel der Antwort (steht auch genau so in den serverseitigen Hilfetexten):

tBedeutungid1id2
0ServergruppeServergruppen-ID0
1Client (Serverbene)Client-Datenbank-ID0
2ChannelChannel-ID0
3ChannelgruppeChannel-IDChannelgruppen-ID
4Client (Channelebene)Channel-IDClient-Datenbank-ID

Die Werte sind nach Tier und dann PermID sortiert. Eine Version zur Rückgabe von PermSID existiert offenbar nicht. Auch wenn man eine PermSID oder -permsid übergibt, kommen PermIDs zurück.

Den Channel für Channel- und Channel-Client-Rechte anzugeben, ist ziemlich sinnfrei. Bei Channelgruppen ist es wegen der möglichen Vererbung interessant.

Es werden auch Rechte zurückgegeben, die durch Skips irrelevant sind.

permget

Unterstützt Arrays.

Die Funktion stört es nicht, mehrere gleiche Parameter zu übergeben.

permfind

Der Befehl unterstützt permsid als Parameter.

Die folgende Tabelle zeigt die Werte für die Parameterkürzel der Antwort (was aber nirgendwo offiziell dokumentiert ist):

tBedeutungid1id2
0ServergruppeServergruppen-ID0
1Client (Serverbene)0Client-Datenbank-ID
2Channel0Channel-ID
3ChannelgruppeChannelgruppen-ID0
4Client (Channelebene)Client-Datenbank-IDChannel-ID

Die Werte sind nach Tier und dann PermID sortiert. Eine Version zur Rückgabe von PermSID existiert offenbar nicht. Auch wenn man eine PermSID oder -permsid übergibt, kommen PermIDs zurück.

Anders als in der QueryManual suggeriert, unterscheiden sich die Rückgabewerte aller Tiers außer bei Servergruppen (siehe Tabelle oben).

Ein weiterer Unterschied ist, dass die jeweiligen Werte nicht zurückgegeben werden. Man weiß also lediglich, wo – aber nicht worauf – gesetzt wurde.

Die Verwendung von Arrays führt zu einem Absturz der Instanz. Da man keine Rechte hierfür braucht (die Funktion braucht für die Erfüllung ihrer angedachten Funktion aber die im Handbuch genannten Rechte), kann man damit nach Lust und Laune jeden Server abschießen, auf den man gerade keine Lust hat.

privilegekeyadd

tokencustomset ist ein in sich selbst parametrisierter String (mit Leerzeichen zwischen den Parametern, die im finalen Befehl escapet werden müssen), obwohl „set“ im Namen steckt, wodurch man auch ein Array erwarten könnte.

Es gibt einen Fehler im Handbuch: Die einzelnen Idents und Werte des Customsets müssen vorm Escapen des gesamten Strings zunächst einmal selbst escapet werden. Daher ist das Beispiel falsch und ergibt keinen wirklichen Sinn. Statt value=Sven\sPaulsen müsste es value=Sven\\sPaulsen heißen. In dem Fall würde nur „Sven“ in der Datenbank gespeichert, „Paulsen“ wird ignoriert.

Es sei noch darauf hingewiesen, dass Customsets gelöscht werden, sobald ein Token mit einem Customset verwendet wird. Soll vermutlich nicht so sein.

Bans und Beschwerden

Beschwerden heißen auf Englisch „complaint“.

Dateien

Erst einmal was ganz Allgemeines zum Thema Icons und Avatare, die in Channel 0 (kein Passwort) liegen. Der Dateiname sieht nämlich je nach Befehl völlig anders aus. Er setzt sich aus einer Basis und einer Variable zusammen, die natürlich noch zu escapen sind.

BefehlAvatareIcons
BasisVariableBasisVariable
ftinitupload/avatar_client_base64HashClientUID (nur eigener)/icon_vorzeichenlose 32-Bit-Zahl (CRC32 empfohlen)
ftinitdownload/avatar_client_base64HashClientUID/icon_vorzeichenlose 32-Bit-Zahl (CRC32 empfohlen)
ftgetfileinfo/avatar_client_base64HashClientUID/icon_vorzeichenlose 32-Bit-Zahl (CRC32 empfohlen)
ftgetfilelist//icons/
ftdeletefile/avatar_client_unique_identifier/icon_vorzeichenlose 32-Bit-Zahl (CRC32 empfohlen)

Diese Dateien haben jeweils keine Erweiterung.

ftinitupload
ftinitdownload

clientftfid ist ein theoretisch beliebiges Word (Zahl zwischen 0 und 65535). Der Server gibt es bei der Antwort unverändert zurück.

Diese Funktionen können an sich (also nicht so triviale Sachen wie fehlende Parameter) nicht selbst fehlschlagen, geben also immer Fehler-Code 0 (ok) aus. Schlagen die Funktionen fehl, werden stattdessen als normale Rückgabe die Daten zum Fehler zurückgeben. Die zurückgegebenen Felder sind clientftfid mit dem vom Benutzer angegebenen Wert, status für einen Fehlercode (z.B. 2565 für falsche Größe, 2051 für nicht vorhandene Datei, 2054 für falsche Pfadangabe), msg mit dem (englischen) Erklärungstext und size mit dem Wert 0.

ftinitupload führt vor Version 3.0.1 zum einem Absturz der Instanz, wenn man man eine Datei in Channel 0 hochlädt, die 0 Bytes groß ist und deren Name mit „/avatar_“ beginnt (ansonsten ist angeblich die Größe falsch). Ob das hinter dem „/avatar_“ überhaupt eine sinnvolle Angabe ist, ist dabei egal, es reicht auch jener String allein.

ftgetfilelist

Dateien, die kürzlich hochgeladen wurden, haben eine veraltete Größe.

Bei Dateien, die noch nicht ganz hochgeladen sind, gibt size die unvollständige und incompletesize die vollständige Größe an. Weil sinnvoll und so.

ftgetfileinfo

Dieser Befehl funktionierte früher nicht in Channel 0.

ftstop

Ich bin mir nicht sicher, ob dieser Befehl funktioniert und was er tun sollte... Eine laufende Übertragung – egal ob die eigene oder eine fremde – wird zumindest nicht abgebrochen.

Custominfo

Allgemeine Erklärungen siehe privilegekeyadd.

Halboffizielle Befehle

token*

tokenlist, tokenadd, tokendelete und tokenuse sind (deutlich kürzere und einfacher zu schreibende) Aliase für privilegekeylist, privilegekeyadd, privilegekeydelete und privilegekeyuse.

Die QueryManual listet ausschließlich privilegekey*, der Befehl help hingegen lange ausschließlich token*, obwohl er mit beidem funktionierte (die Ausgabe ist praktisch identisch, nur das Beispiel ist unterschiedlich). Inzwischen listet er beides.

Siehe auch diesen Thread.

clientgetuidfromclid

Dieser Befehl ist völlig sinnfrei, da clientinfo wesentlich mächtiger ist (siehe oben). Es wäre festzustellen, was er für Rechte benötigt, aber es dürften dieselben sein.

Außerdem fehlt er im QueryManual, wird aber von help aufgelistet.

servergroupbyclientid

Dieser Befehl wird bei help aufgelistet, existiert jedoch nicht. Es ist wohl nur ein Schreibfehler, da ein Client mehr als eine Servergruppe haben kann, der Befehl servergroupsbyclientid tatsächlich existiert und sogar im Hilfetext zu der Funktion sowohl für Syntax als auch Beispiel verwendet wird.

Der Parameter aus der Syntax im Hilfetext (sgid={clientDBID}) ergibt keinen Sinn, oder warum sollte man eine Client-Datenbank-ID als Servergruppen-ID verwenden?

Inoffizielle Befehle

plugincmd

Mir ist nicht ganz klar, wie man das benutzt, aber es funktioniert nur, wenn man auf einem virtuellen Server ist.

Die (Pflicht-)Parameter sind:

targetmode sei eine natürliche Zahl zwischen 0 und 3. Nur targetmode=2 benötigt den Parameter target, bei dem es sich um eine aktuelle Client-ID handeln muss.

Inzwischen darf der Befehl nicht mehr von Query-Clients verwendet werden.

dummy_newip
dummy_connectfailed

Das sind offenbar Dummys, wie der Name schon vermuten lässt. Man bekommt error id=0 msg=ok zurück.

dummy_connectionlost

Macht dasselbe wie logout, schlägt aber nicht fehl, wenn man nicht eingeloggt ist.

Wenn man auf einem Server ist, fliegt man vom Server (connection lost).

Man ist jetzt (aber nur wenn man auf einem Server war) weiterhin – aber unsichtbar – auf der Instanz und viele Funktionen (z.B. whoami, sendtextmessage) schlagen fehl, weil man keine gültige Client-ID hat, denn man ist ja nicht offiziell auf einem Server.

Man muss einen neuen Server wählen und wird erst durch login oder logout wieder sichtbar – und dass obwohl logout fehlschlägt! Auf virtuellen Servern ist man ausschließlich Mitglied der Gast-Query-Gruppe, auch auf neueren Servern, bei denen man eigentlich Servergast sein sollte.

connectioninfoautoupdate
setconnectioninfo

Keine Ahnung, was das ist, aber es funktioniert eh nicht mit Queryclients.

clientsitereport
verifyserverpassword
verifychannelpassword

Wenn man auf keinem Server ist, sagt es einem, man solle auf einen gehen.

Wenn man auf einem Server ist, sagt es einem, der Befehl würde nicht existieren.

Genial, oder?

channelcreateprivate

Führt zu Fehler 2 (not implemented).