2020-03-30 11:44:18 +00:00
|
|
|
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
|
|
|
import {IdentitifyType} from "tc-shared/profiles/Identity";
|
|
|
|
import {TeaSpeakIdentity} from "tc-shared/profiles/identities/TeamSpeakIdentity";
|
|
|
|
import {AbstractServerConnection} from "tc-shared/connection/ConnectionBase";
|
|
|
|
import {ConnectionProfile} from "tc-shared/profiles/ConnectionProfile";
|
|
|
|
import {settings} from "tc-shared/settings";
|
|
|
|
import {ConnectParameters, DisconnectReason} from "tc-shared/ConnectionHandler";
|
|
|
|
|
|
|
|
export interface HandshakeIdentityHandler {
|
|
|
|
connection: AbstractServerConnection;
|
|
|
|
|
|
|
|
start_handshake();
|
|
|
|
register_callback(callback: (success: boolean, message?: string) => any);
|
|
|
|
}
|
|
|
|
|
|
|
|
declare const native_client;
|
|
|
|
export class HandshakeHandler {
|
|
|
|
private connection: AbstractServerConnection;
|
|
|
|
private handshake_handler: HandshakeIdentityHandler;
|
|
|
|
private failed = false;
|
|
|
|
|
|
|
|
readonly profile: ConnectionProfile;
|
|
|
|
readonly parameters: ConnectParameters;
|
|
|
|
|
|
|
|
constructor(profile: ConnectionProfile, parameters: ConnectParameters) {
|
|
|
|
this.profile = profile;
|
|
|
|
this.parameters = parameters;
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
setConnection(con: AbstractServerConnection) {
|
|
|
|
this.connection = con;
|
2019-02-23 13:15:22 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
initialize() {
|
|
|
|
this.handshake_handler = this.profile.spawn_identity_handshake_handler(this.connection);
|
|
|
|
if(!this.handshake_handler) {
|
|
|
|
this.handshake_failed("failed to create identity handler");
|
|
|
|
return;
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
this.handshake_handler.register_callback((flag, message) => {
|
|
|
|
if(flag)
|
|
|
|
this.handshake_finished();
|
|
|
|
else
|
|
|
|
this.handshake_failed(message);
|
|
|
|
});
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
get_identity_handler() : HandshakeIdentityHandler {
|
|
|
|
return this.handshake_handler;
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
startHandshake() {
|
|
|
|
this.handshake_handler.start_handshake();
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
on_teamspeak() {
|
|
|
|
const type = this.profile.selected_type();
|
|
|
|
if(type == IdentitifyType.TEAMSPEAK)
|
|
|
|
this.handshake_finished();
|
|
|
|
else {
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
if(this.failed) return;
|
2019-04-15 13:33:51 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
this.failed = true;
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_TEAMSPEAK_REQUIRED);
|
2019-02-23 13:15:22 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
private handshake_failed(message: string) {
|
|
|
|
if(this.failed) return;
|
2019-04-15 14:58:42 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
this.failed = true;
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_FAILED, message);
|
|
|
|
}
|
2019-04-15 14:58:42 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
private handshake_finished(version?: string) {
|
|
|
|
const _native = window["native"];
|
|
|
|
if(native_client && _native && _native.client_version && !version) {
|
|
|
|
_native.client_version()
|
|
|
|
.then( this.handshake_finished.bind(this))
|
|
|
|
.catch(error => {
|
|
|
|
console.error(tr("Failed to get version:"));
|
|
|
|
console.error(error);
|
|
|
|
this.handshake_finished("?.?.?");
|
|
|
|
});
|
|
|
|
return;
|
2019-04-15 14:58:42 +00:00
|
|
|
}
|
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
const git_version = settings.static_global("version", "unknown");
|
|
|
|
const browser_name = (navigator.browserSpecs || {})["name"] || " ";
|
|
|
|
let data = {
|
|
|
|
client_nickname: this.parameters.nickname || "Another TeaSpeak user",
|
|
|
|
client_platform: (browser_name ? browser_name + " " : "") + navigator.platform,
|
|
|
|
client_version: "TeaWeb " + git_version + " (" + navigator.userAgent + ")",
|
|
|
|
client_version_sign: undefined,
|
|
|
|
|
|
|
|
client_default_channel: (this.parameters.channel || {} as any).target,
|
|
|
|
client_default_channel_password: (this.parameters.channel || {} as any).password,
|
|
|
|
client_default_token: this.parameters.token,
|
|
|
|
|
|
|
|
client_server_password: this.parameters.password ? this.parameters.password.password : undefined,
|
|
|
|
client_browser_engine: navigator.product,
|
|
|
|
|
|
|
|
client_input_hardware: this.connection.client.client_status.input_hardware,
|
|
|
|
client_output_hardware: false,
|
|
|
|
client_input_muted: this.connection.client.client_status.input_muted,
|
|
|
|
client_output_muted: this.connection.client.client_status.output_muted,
|
|
|
|
};
|
|
|
|
|
|
|
|
//0.0.1 [Build: 1549713549] Linux 7XvKmrk7uid2ixHFeERGqcC8vupeQqDypLtw2lY9slDNPojEv//F47UaDLG+TmVk4r6S0TseIKefzBpiRtLDAQ==
|
|
|
|
|
|
|
|
if(version) {
|
|
|
|
data.client_version = "TeaClient ";
|
|
|
|
data.client_version += " " + version;
|
|
|
|
|
|
|
|
const os = require("os");
|
|
|
|
const arch_mapping = {
|
|
|
|
"x32": "32bit",
|
|
|
|
"x64": "64bit"
|
|
|
|
};
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
data.client_version += " " + (arch_mapping[os.arch()] || os.arch());
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
const os_mapping = {
|
|
|
|
"win32": "Windows",
|
|
|
|
"linux": "Linux"
|
2019-02-23 13:15:22 +00:00
|
|
|
};
|
2020-03-30 11:44:18 +00:00
|
|
|
data.client_platform = (os_mapping[os.platform()] || os.platform());
|
|
|
|
}
|
2019-02-23 13:15:22 +00:00
|
|
|
|
2020-03-30 11:44:18 +00:00
|
|
|
/* required to keep compatibility */
|
|
|
|
if(this.profile.selected_type() === IdentitifyType.TEAMSPEAK) {
|
|
|
|
data["client_key_offset"] = (this.profile.selected_identity() as TeaSpeakIdentity).hash_number;
|
2019-02-23 13:15:22 +00:00
|
|
|
}
|
2020-03-30 11:44:18 +00:00
|
|
|
|
|
|
|
this.connection.send_command("clientinit", data).catch(error => {
|
|
|
|
if(error instanceof CommandResult) {
|
|
|
|
if(error.id == 1028) {
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.SERVER_REQUIRES_PASSWORD);
|
|
|
|
} else if(error.id == 783 || error.id == 519) {
|
|
|
|
error.extra_message = isNaN(parseInt(error.extra_message)) ? "8" : error.extra_message;
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.IDENTITY_TOO_LOW, error);
|
|
|
|
} else if(error.id == 3329) {
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.HANDSHAKE_BANNED, error);
|
|
|
|
} else {
|
|
|
|
this.connection.client.handleDisconnect(DisconnectReason.CLIENT_KICKED, error);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
this.connection.disconnect();
|
|
|
|
});
|
2019-02-23 13:15:22 +00:00
|
|
|
}
|
|
|
|
}
|