diff --git a/css/frame/SelectInfo.css b/css/frame/SelectInfo.css new file mode 100644 index 00000000..a38c4a2f --- /dev/null +++ b/css/frame/SelectInfo.css @@ -0,0 +1,10 @@ +.select_info_table { } +.select_info_table tr { } +.select_info_table tr td { +} + +.select_info_table tr td:nth-child(1) { + font-weight: bold; + padding-right: 5px; + min-width: 20%; +} diff --git a/css/general.css b/css/general.css index 541eb448..c393609d 100644 --- a/css/general.css +++ b/css/general.css @@ -103,11 +103,6 @@ flex-direction: column; } -.info_key { - font-weight: bold; - padding-right: 5px; -} - /* The Modal (background) */ .modal { display: none; /* Hidden by default */ diff --git a/index.php b/index.php index 119db735..4d1f0a89 100644 --- a/index.php +++ b/index.php @@ -31,6 +31,7 @@ + diff --git a/js/FileManager.ts b/js/FileManager.ts index 6a58f041..35459b7b 100644 --- a/js/FileManager.ts +++ b/js/FileManager.ts @@ -227,7 +227,7 @@ class FileManager { transfer.remotePort = json["port"]; transfer.remoteHost = (json["ip"] ? json["ip"] : "").replace(/,/g, ""); if(!transfer.remoteHost || transfer.remoteHost == '0.0.0.0' || transfer.remoteHost == '127.168.0.0') - transfer.remoteHost = this.handle.serverConnection._remoteHost; + transfer.remoteHost = this.handle.serverConnection._remote_address.host; (transfer["_promiseCallback"] as (val: DownloadFileTransfer) => void)(transfer); this.pendingDownloadTransfers.remove(transfer); diff --git a/js/client.ts b/js/client.ts index 0352f9f6..f2d5b862 100644 --- a/js/client.ts +++ b/js/client.ts @@ -91,8 +91,8 @@ class TSClient { port = 9987; } console.log("Start connection to " + host + ":" + port); - this.channelTree.initialiseHead(addr); - this.serverConnection.startConnection(host, port, new HandshakeHandler(identity, name)); + this.channelTree.initialiseHead(addr, {host, port}); + this.serverConnection.startConnection({host, port}, new HandshakeHandler(identity, name)); } @@ -145,9 +145,9 @@ class TSClient { callback += "&default_connect_type=teamspeak"; break; } - callback += "&default_connect_url=" + encodeURIComponent(this.serverConnection._remoteHost + ":" + this.serverConnection._remotePort); + callback += "&default_connect_url=" + encodeURIComponent(this.serverConnection._remote_address.host + ":" + this.serverConnection._remote_address.port); - return "https://" + this.serverConnection._remoteHost + ":" + this.serverConnection._remotePort + "/?forward_url=" + encodeURIComponent(callback); + return "https://" + this.serverConnection._remote_address.host + ":" + this.serverConnection._remote_address.port + "/?forward_url=" + encodeURIComponent(callback); } handleDisconnect(type: DisconnectReason, data: any = {}) { diff --git a/js/connection.ts b/js/connection.ts index d7f51eca..73791a4e 100644 --- a/js/connection.ts +++ b/js/connection.ts @@ -31,8 +31,7 @@ class ReturnListener { class ServerConnection { _client: TSClient; - _remoteHost: string; - _remotePort: number; + _remote_address: ServerAddress; _socket: WebSocket; _connectionState: ConnectionState = ConnectionState.UNCONNECTED; _handshakeHandler: HandshakeHandler; @@ -62,19 +61,18 @@ class ServerConnection { return (this._retCodeIdx++).toString(); } - startConnection(host : string, port : number, handshake: HandshakeHandler, timeout: number = 1000) { + startConnection(address : ServerAddress, handshake: HandshakeHandler, timeout: number = 1000) { if(this._connectTimeoutHandler) { clearTimeout(this._connectTimeoutHandler); this._connectTimeoutHandler = null; this.disconnect(); } this.updateConnectionState(ConnectionState.CONNECTING); - this._remoteHost = host; - this._remotePort = port; + this._remote_address = address; this._handshakeHandler = handshake; this._handshakeHandler.setConnection(this); this._connected = false; - chat.serverChat().appendMessage("Connecting to " + host + ":" + port); + chat.serverChat().appendMessage("Connecting to " + address.host + ":" + address.port); const self = this; try { @@ -83,7 +81,7 @@ class ServerConnection { this._client.handleDisconnect(DisconnectReason.CONNECT_FAILURE); }, timeout); let sockCpy; - this._socket = (sockCpy = new WebSocket('wss:' + this._remoteHost + ":" + this._remotePort)); + this._socket = (sockCpy = new WebSocket('wss:' + address.host + ":" + address.port)); clearTimeout(this._connectTimeoutHandler); this._connectTimeoutHandler = null; if(this._socket != sockCpy) return; //Connect timeouted @@ -375,11 +373,19 @@ class ConnectionCommandHandler { this.connection._client.clientId = parseInt(json["aclid"]); this.connection._client.getClient().updateVariables({key: "client_nickname", value: json["acn"]}); + let updates: { + key: string, + value: string + }[] = []; for(let key in json) { if(key === "aclid") continue; if(key === "acn") continue; - this.connection._client.channelTree.server.updateProperty(key, json[key]); + + updates.push({key: key, value: json[key]}); } + this.connection._client.channelTree.server.updateVariables(...updates); + + chat.serverChat().name = this.connection._client.channelTree.server.properties["virtualserver_name"]; chat.serverChat().appendMessage("Connected as {0}", true, this.connection._client.getClient().createChatTag(true)); globalClient.onConnected(); @@ -712,27 +718,39 @@ class ConnectionCommandHandler { handleNotifyServerEdited(json) { json = json[0]; + let updates: { + key: string, + value: string + }[] = []; for(let key in json) { if(key === "invokerid") continue; if(key === "invokername") continue; if(key === "invokeruid") continue; if(key === "reasonid") continue; - this.connection._client.channelTree.server.updateProperty(key, json[key]); + updates.push({key: key, value: json[key]}); } + this.connection._client.channelTree.server.updateVariables(...updates); + if(this.connection._client.selectInfo.currentSelected == this.connection._client.channelTree.server) + this.connection._client.selectInfo.update(); } handleNotifyServerUpdated(json) { json = json[0]; + let updates: { + key: string, + value: string + }[] = []; for(let key in json) { if(key === "invokerid") continue; if(key === "invokername") continue; if(key === "invokeruid") continue; if(key === "reasonid") continue; - this.connection._client.channelTree.server.updateProperty(key, json[key]); + updates.push({key: key, value: json[key]}); } + this.connection._client.channelTree.server.updateVariables(...updates); let info = this.connection._client.selectInfo; if(info.currentSelected instanceof ServerEntry) info.update(); diff --git a/js/log.ts b/js/log.ts index d9a6dc1a..cf6bedd5 100644 --- a/js/log.ts +++ b/js/log.ts @@ -1,6 +1,7 @@ enum LogCategory { CHANNEL, CLIENT, + SERVER, PERMISSIONS, GENERAL, NETWORKING @@ -18,6 +19,7 @@ namespace log { let category_mapping = new Map([ [LogCategory.CHANNEL, "Channel "], [LogCategory.CLIENT, "Client "], + [LogCategory.SERVER, "Server "], [LogCategory.PERMISSIONS, "Permission "], [LogCategory.GENERAL, "General "], [LogCategory.NETWORKING, "Network "] diff --git a/js/proto.ts b/js/proto.ts index 84272883..1a5e1910 100644 --- a/js/proto.ts +++ b/js/proto.ts @@ -7,10 +7,13 @@ interface Array { interface JQuery { tmpl(values?: any) : JQuery; + render(values?: any) : string; + renderTag(values?: any) : JQuery; } interface JQueryStatic { spawn(tagName: K): JQuery; + views: any; } @@ -51,12 +54,11 @@ if(typeof ($) !== "undefined") { return $(document.createElement(tagName)); } } - if(!$.prototype.tmpl) { - $.prototype.tmpl = function (values?: any) : JQuery { - return this.render(values); + if(!$.prototype.renderTag) { + $.prototype.renderTag = function (values?: any) : JQuery { + return $(this.render(values)); } } - } if (!String.prototype.format) { diff --git a/js/ui/frames/SelectedItemInfo.ts b/js/ui/frames/SelectedItemInfo.ts index f5ece074..f5a49f0b 100644 --- a/js/ui/frames/SelectedItemInfo.ts +++ b/js/ui/frames/SelectedItemInfo.ts @@ -5,21 +5,21 @@ abstract class InfoManagerBase { private intervals: number[] = []; protected resetTimers() { - for(let interval of this.intervals) - clearInterval(interval); + for(let timer of this.timers) + clearTimeout(timer); } protected resetIntervals() { - for(let timer of this.timers) - clearTimeout(timer); + for(let interval of this.intervals) + clearInterval(interval); } protected registerTimer(timer: NodeJS.Timer) { this.timers.push(timer); } - protected registerInterval(interval: number) { - this.intervals.push(interval); + protected registerInterval(interval: T) { + this.intervals.push(interval as number); } abstract available(object: V) : boolean; @@ -41,9 +41,6 @@ class InfoBar { private current_selected?: ServerEntry | ChannelEntry | ClientEntry; private _htmlTag: JQuery; - private timers: NodeJS.Timer[] = []; - private intervals: number[] = []; - private current_manager: InfoManagerBase = undefined; private managers: InfoManagerBase[] = []; @@ -52,31 +49,30 @@ class InfoBar { this._htmlTag = htmlTag; this.managers.push(new ClientInfoManager()); - } + this.managers.push(new ChannelInfoManager()); + this.managers.push(new ServerInfoManager()); + //TODO music client + /* + this._htmlTag.append("Im a music bot!"); + let frame = $("#tmpl_music_frame" + (this.current_selected.properties.music_track_id == 0 ? "_empty" : "")).tmpl({ + thumbnail: "img/loading_image.svg" + }).css("align-self", "center"); - private createInfoTable(infos: any) : JQuery { - let table = $.spawn("table"); + if(this.current_selected.properties.music_track_id == 0) { - for(let key in infos) { - console.log("Display info " + key); - let entry = $.spawn("tr"); - entry.append($.spawn("td").addClass("info_key").html(key + ":")); - let value = $.spawn("td"); - console.log(infos[key]); - console.log( MessageHelper.formatElement(infos[key])); - MessageHelper.formatElement(infos[key]).forEach(e => e.appendTo(value)); - entry.append(value); - table.append(entry); - } + } else { - return table; + } + + this._htmlTag.append(frame); + */ } setCurrentSelected(entry: T) { if(this.current_selected == entry) return; if(this.current_manager) { - this.current_manager.finalizeFrame.call(this.current_manager, this.current_selected, this._htmlTag); + (this.current_manager as InfoManager).finalizeFrame.call(this.current_manager, this.current_selected, this._htmlTag); this.current_manager = null; this.current_selected = null; } @@ -90,10 +86,9 @@ class InfoBar { } } - console.log("Got info manager: %o", this.current_manager); - if(this.current_manager) { - this.current_manager.createFrame.call(this.current_manager, this.current_selected, this._htmlTag); - } else this.buildBar(); //FIXME Remove that this is just for now (because not all types are implemented) + console.log("Using info manager: %o", this.current_manager); + if(this.current_manager) + (this.current_manager as InfoManager).createFrame.call(this.current_manager, this.current_selected, this._htmlTag); } get currentSelected() { @@ -102,204 +97,7 @@ class InfoBar { update(){ if(this.current_manager && this.current_selected) - this.current_manager.updateFrame.call(this.current_manager, this.current_selected, this._htmlTag); - } - - private updateServerTimings() { - this._htmlTag.find(".uptime").text(formatDate((this.current_selected as ServerEntry).calculateUptime())); - } - - private updateClientTimings() { - this._htmlTag.find(".online").text(formatDate((this.current_selected as ClientEntry).calculateOnlineTime())); - } - - private buildBar() { - this._htmlTag.empty(); - if(!this.current_selected) return; - - - if(this.current_selected instanceof ServerEntry) { - if(this.current_selected.shouldUpdateProperties()) this.current_selected.updateProperties(); - - let version = this.current_selected.properties.virtualserver_version; - if(version.startsWith("TeaSpeak ")) version = version.substr("TeaSpeak ".length); - - this._htmlTag.append(this.createInfoTable({ - "Name": this.current_selected.properties.virtualserver_name, - "Address": "unknown", - "Type": "TeaSpeak", - "Version": version + " on " + this.current_selected.properties.virtualserver_platform, - "Uptime": "" + formatDate(this.current_selected.calculateUptime()) + "", - "Current Channels": this.current_selected.properties.virtualserver_channelsonline, - "Current Clients": this.current_selected.properties.virtualserver_clientsonline, - "Current Queries": this.current_selected.properties.virtualserver_queryclientsonline - })); - - this._htmlTag.append($.spawn("div").css("height", "100%")); - let requestUpdate = $.spawn("button"); - requestUpdate.css("min-height", "16px"); - requestUpdate.css("bottom", 0); - requestUpdate.text("update info"); - if(this.current_selected.shouldUpdateProperties()) - requestUpdate.css("color", "green"); - else { - requestUpdate.attr("disabled", "true"); - requestUpdate.css("color", "red"); - } - this._htmlTag.append(requestUpdate); - - const _server : ServerEntry = this.current_selected; - const _this = this; - requestUpdate.click(function () { - _server.updateProperties(); - _this.buildBar(); - }); - this.timers.push(setTimeout(function () { - requestUpdate.css("color", "green"); - requestUpdate.removeAttr("disabled"); - }, _server.nextInfoRequest - new Date().getTime())); - this.intervals.push(setInterval(this.updateServerTimings.bind(this),1000)); - } else if(this.current_selected instanceof ChannelEntry) { - let props = this.current_selected.properties; - this._htmlTag.append(this.createInfoTable({ - "Name": this.current_selected.createChatTag(), - "Topic": this.current_selected.properties.channel_topic, - "Codec": this.current_selected.properties.channel_codec, - "Codec Quality": this.current_selected.properties.channel_codec_quality, - "Type": ChannelType.normalize(this.current_selected.channelType()), - "Current clients": this.current_selected.channelTree.clientsByChannel(this.current_selected).length + " / " + (props.channel_maxclients == -1 ? "Unlimited" : props.channel_maxclients), - "Subscription Status": "unknown", - "Voice Data Encryption": "unknown" - })); - } else if(this.current_selected instanceof MusicClientEntry) { - this._htmlTag.append("Im a music bot!"); - let frame = $("#tmpl_music_frame" + (this.current_selected.properties.music_track_id == 0 ? "_empty" : "")).tmpl({ - thumbnail: "img/loading_image.svg" - }).css("align-self", "center"); - - if(this.current_selected.properties.music_track_id == 0) { - - } else { - - } - - this._htmlTag.append(frame); - //TODO - } else if(this.current_selected instanceof ClientEntry) { - this.current_selected.updateClientVariables(); - let version: string = this.current_selected.properties.client_version; - if(!version) version = ""; - let infos = { - "Name": this.current_selected.createChatTag(), - "Description": this.current_selected.properties.client_description, - "Version": MessageHelper.formatMessage("{0} on {1}", $.spawn("a").attr("title", version).text(version.split(" ")[0]), this.current_selected.properties.client_platform), - "Online since": $.spawn("a").addClass("online").text(formatDate(this.current_selected.calculateOnlineTime())), - "Volume": this.current_selected.audioController.volume * 100 + " %" - }; - if(this.current_selected.properties.client_teaforum_id > 0) { - infos["TeaSpeak Account"] = $.spawn("a") - .attr("href", "//forum.teaspeak.de/index.php?members/" + this.current_selected.properties.client_teaforum_id) - .attr("target", "_blank") - .text(this.current_selected.properties.client_teaforum_id); - } - this._htmlTag.append(this.createInfoTable(infos)); - - { - let serverGroups = $.spawn("div"); - serverGroups - .css("display", "flex") - .css("flex-direction", "column"); - - let header = $.spawn("div"); - header - .css("display", "flex") - .css("margin-top", "5px") - .css("align-items", "center"); - $.spawn("div").addClass("icon client-permission_server_groups").appendTo(header); - $.spawn("div").text("Server groups:").css("margin-left", "3px").css("font-weight", "bold").appendTo(header); - header.appendTo(serverGroups); - - for(let groupId of this.current_selected.assignedServerGroupIds()) { - let group = this.handle.groups.serverGroup(groupId); - if(!group) continue; - - let groupTag = $.spawn("div"); - groupTag - .css("display", "flex") - .css("margin-top", "1px") - .css("margin-left", "10px") - .css("align-items", "center"); - this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag); - $.spawn("div").text(group.name).css("margin-left", "3px").appendTo(groupTag); - groupTag.appendTo(serverGroups); - } - - this._htmlTag.append(serverGroups); - } - - { - let channelGroup = $.spawn("div"); - channelGroup - .css("display", "flex") - .css("flex-direction", "column") - .css("margin-bottom", "20px"); - - let header = $.spawn("div"); - header - .css("display", "flex") - .css("margin-top", "10px") - .css("align-items", "center"); - $.spawn("div").addClass("icon client-permission_channel").appendTo(header); - $.spawn("div").text("Channel group:").css("margin-left", "3px").css("font-weight", "bold").appendTo(header); - header.appendTo(channelGroup); - - let group = this.handle.groups.channelGroup(this.current_selected.assignedChannelGroup()); - if(group) { - let groupTag = $.spawn("div"); - groupTag - .css("display", "flex") - .css("margin-top", "1px") - .css("margin-left", "10px") - .css("align-items", "center"); - this.handle.fileManager.icons.generateTag(group.properties.iconid).appendTo(groupTag); - $.spawn("div").text(group.name) - .css("margin-left", "3px").appendTo(groupTag); - groupTag.appendTo(channelGroup); - - } - this._htmlTag.append(channelGroup); - } - - { - if(this.current_selected.properties.client_flag_avatar.length > 0) - this.handle.fileManager.avatars.generateTag(this.current_selected) - .css("max-height", "90%") - .css("max-width", "100%").appendTo(this._htmlTag); - } - - { - let spawnTag = (type: string, description: string) : JQuery => { - return $.spawn("div").css("display", "inline-flex") - .append($.spawn("div").addClass("icon_x32 client-" + type).css("margin-right", "5px")) - .append($.spawn("a").text(description).css("align-self", "center")); - }; - - if(!this.current_selected.properties.client_output_hardware) - spawnTag("hardware_output_muted", "Speakers/Headphones disabled").appendTo(this._htmlTag); - - - if(!this.current_selected.properties.client_input_hardware) - spawnTag("hardware_input_muted", "Microphone disabled").appendTo(this._htmlTag); - - if(this.current_selected.properties.client_output_muted) - spawnTag("output_muted", "Speakers/Headphones Muted").appendTo(this._htmlTag); - - if(this.current_selected.properties.client_input_muted) - spawnTag("input_muted", "Microphone Muted").appendTo(this._htmlTag); - } - - this.intervals.push(setInterval(this.updateClientTimings.bind(this),1000)); - } + (this.current_manager as InfoManager).updateFrame.call(this.current_manager, this.current_selected, this._htmlTag); } } @@ -314,13 +112,10 @@ class ClientInfoManager extends InfoManager { } updateFrame(client: ClientEntry, html_tag: JQuery) { + this.resetIntervals(); html_tag.empty(); - let properties: any = {}; - let version: string = client.properties.client_version; - if(!version) version = ""; - properties["client_name"] = client.createChatTag()[0]; properties["client_onlinetime"] = formatDate(client.calculateOnlineTime()); properties["sound_volume"] = client.audioController.volume * 100; @@ -355,9 +150,100 @@ class ClientInfoManager extends InfoManager { .text(client.properties.client_teaforum_id); } - let rendered = $($("#tmpl_selected_client").render([properties])); + let rendered = $("#tmpl_selected_client").renderTag([properties]); rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); }); html_tag.append(rendered); - console.log(properties); + + this.registerInterval(setInterval(() => { + html_tag.find(".update_onlinetime").text(formatDate(client.calculateOnlineTime())); + }, 1000)); } +} + +class ServerInfoManager extends InfoManager { + createFrame(server: ServerEntry, html_tag: JQuery) { + if(server.shouldUpdateProperties()) server.updateProperties(); + this.updateFrame(server, html_tag); + } + + updateFrame(server: ServerEntry, html_tag: JQuery) { + this.resetIntervals(); + html_tag.empty(); + let properties: any = {}; + + properties["server_name"] = $.spawn("a").text(server.properties.virtualserver_name); + properties["server_onlinetime"] = formatDate(server.calculateUptime()); + properties["server_address"] = server.remote_address.host + ":" + server.remote_address.port; + + for(let key in server.properties) + properties["property_" + key] = server.properties[key]; + + let rendered = $("#tmpl_selected_server").renderTag([properties]); + rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); }); + html_tag.append(rendered); + + this.registerInterval(setInterval(() => { + html_tag.find(".update_onlinetime").text(formatDate(server.calculateUptime())); + }, 1000)); + + + //TODO update button + /* + let requestUpdate = $.spawn("button"); + requestUpdate.css("min-height", "16px"); + requestUpdate.css("bottom", 0); + requestUpdate.text("update info"); + if(this.current_selected.shouldUpdateProperties()) + requestUpdate.css("color", "green"); + else { + requestUpdate.attr("disabled", "true"); + requestUpdate.css("color", "red"); + } + this._htmlTag.append(requestUpdate); + + const _server : ServerEntry = this.current_selected; + const _this = this; + requestUpdate.click(function () { + _server.updateProperties(); + _this.buildBar(); + }); + this.timers.push(setTimeout(function () { + requestUpdate.css("color", "green"); + requestUpdate.removeAttr("disabled"); + }, _server.nextInfoRequest - new Date().getTime())); + */ + } + + available(object: V): boolean { + return typeof object == "object" && object instanceof ServerEntry; + } +} + +class ChannelInfoManager extends InfoManager { + createFrame(channel: ChannelEntry, html_tag: JQuery) { + this.updateFrame(channel, html_tag); + } + + updateFrame(channel: ChannelEntry, html_tag: JQuery) { + this.resetIntervals(); + html_tag.empty(); + let properties: any = {}; + + properties["channel_name"] = channel.createChatTag(); + properties["channel_type"] = ChannelType.normalize(channel.channelType()); + properties["channel_clients"] = channel.channelTree.clientsByChannel(channel).length; + properties["channel_subscribed"] = true; //TODO + + for(let key in channel.properties) + properties["property_" + key] = channel.properties[key]; + + let rendered = $("#tmpl_selected_channel").renderTag([properties]); + rendered.find("node").each((index, element) => { $(element).replaceWith(properties[$(element).attr("key")]); }); + html_tag.append(rendered); + } + + available(object: V): boolean { + return typeof object == "object" && object instanceof ChannelEntry; + } + } \ No newline at end of file diff --git a/js/ui/server.ts b/js/ui/server.ts index 98746314..ce2fce62 100644 --- a/js/ui/server.ts +++ b/js/ui/server.ts @@ -1,27 +1,37 @@ /// -class ServerEntry { - channelTree: ChannelTree; - properties: any = { - virtualserver_name: "", - virtualserver_icon_id: 0, - virtualserver_version: "unknown", - virtualserver_platform: "unknown", - virtualserver_unique_identifier: "", +class ServerProperties { + virtualserver_name: string = ""; + virtualserver_icon_id: number = 0; + virtualserver_version: string = "unknown"; + virtualserver_platform: string = "unknown"; + virtualserver_unique_identifier: string = ""; - virtualserver_clientsonline: 0, - virtualserver_queryclientsonline: 0, - virtualserver_channelsonline: 0, - virtualserver_uptime: 0, - virtualserver_maxclients: 0 - }; + virtualserver_clientsonline: number = 0; + virtualserver_queryclientsonline: number = 0; + virtualserver_channelsonline: number = 0; + virtualserver_uptime: number = 0; + virtualserver_maxclients: number = 0 +} + +interface ServerAddress { + host: string; + port: number; +} + +class ServerEntry { + remote_address: ServerAddress; + channelTree: ChannelTree; + properties: ServerProperties; lastInfoRequest: number = 0; nextInfoRequest: number = 0; private _htmlTag: JQuery; - constructor(tree, name) { + constructor(tree, name, address: ServerAddress) { + this.properties = new ServerProperties(); this.channelTree = tree; + this.remote_address = address; this.properties.virtualserver_name = name; } @@ -70,15 +80,26 @@ class ServerEntry { ); } - updateProperty(key, value) : void { - console.log("Updating property " + key + " => '" + value + "' for the server"); - this.properties[key] = value; - if(key == "virtualserver_name") { - this.htmlTag.find(".name").text(value); - } else if(key == "virtualserver_icon_id") { - if(this.channelTree.client.fileManager && this.channelTree.client.fileManager.icons) - this.htmlTag.find(".icon_property").replaceWith(this.channelTree.client.fileManager.icons.generateTag(this.properties.virtualserver_icon_id).addClass("icon_property")); + updateVariables(...variables: {key: string, value: string}[]) { + let group = log.group(log.LogType.DEBUG, LogCategory.SERVER, "Update properties (%i)", variables.length); + + for(let variable of variables) { + if(typeof(this.properties[variable.key]) === "boolean") + this.properties[variable.key] = variable.value == "true" || variable.value == "1"; + else if(typeof (this.properties[variable.key]) === "number") + this.properties[variable.key] = parseInt(variable.value); + else + this.properties[variable.key] = variable.value; + group.log("Updating server " + this.properties.virtualserver_name + ". Key " + variable.key + " Value: '" + variable.value + "' (" + typeof (this.properties[variable.key]) + ")"); + if(variable.key == "virtualserver_name") { + this.htmlTag.find(".name").text(variable.value); + } else if(variable.key == "virtualserver_icon_id") { + if(this.channelTree.client.fileManager && this.channelTree.client.fileManager.icons) + this.htmlTag.find(".icon_property").replaceWith(this.channelTree.client.fileManager.icons.generateTag(this.properties.virtualserver_icon_id).addClass("icon_property")); + } } + + group.end(); } updateProperties() { @@ -92,7 +113,7 @@ class ServerEntry { } calculateUptime() : number { - if(this.properties.virtualserver_uptime == 0 || this.lastInfoRequest == 0) return Number.parseInt(this.properties.virtualserver_uptime); - return Number.parseInt(this.properties.virtualserver_uptime) + (new Date().getTime() - this.lastInfoRequest) / 1000; + if(this.properties.virtualserver_uptime == 0 || this.lastInfoRequest == 0) return this.properties.virtualserver_uptime; + return this.properties.virtualserver_uptime + (new Date().getTime() - this.lastInfoRequest) / 1000; } } \ No newline at end of file diff --git a/js/ui/view.ts b/js/ui/view.ts index 7de4e662..69dc69cb 100644 --- a/js/ui/view.ts +++ b/js/ui/view.ts @@ -48,8 +48,8 @@ class ChannelTree { ); } - initialiseHead(serverName: string) { - this.server = new ServerEntry(this, serverName); + initialiseHead(serverName: string, address: ServerAddress) { + this.server = new ServerEntry(this, serverName, address); this.server.htmlTag.appendTo(this.htmlTree); this.server.initializeListener(); } diff --git a/templates.html b/templates.html index 4741fedb..9acee66e 100644 --- a/templates.html +++ b/templates.html @@ -303,35 +303,55 @@ + + + + + + \ No newline at end of file