namespace Modals { export interface BanEntry { server_id: number; banid: number; name?: string; name_type?: number; unique_id?: string; ip?: string; hardware_id?: string; reason: string; invoker_name: string; invoker_unique_id?: string; invoker_database_id?: number; timestamp_created: Date; timestamp_expire: Date; enforcements: number; flag_own?: boolean; } export interface BanListManager { addbans : (ban: BanEntry[]) => void; clear : (ban?: any) => void; modal: Modal; } export function openBanList(client: ConnectionHandler) { let update; const modal = spawnBanListModal(() => update(), () => { spawnBanCreate(client, undefined, result => { if(result.server_id < 0) result.server_id = undefined; console.log(tr("Adding ban %o"), result); client.serverConnection.send_command("banadd", { ip: result.ip, name: result.name, uid: result.unique_id, hwid: result.hardware_id, banreason: result.reason, time: result.timestamp_expire.getTime() > 0 ? (result.timestamp_expire.getTime() - result.timestamp_created.getTime()) / 1000 : 0, sid: result.server_id }).then(() => { update(); }).catch(error => { //TODO tr createErrorModal(tr("Failed to add ban"), "Failed to add ban.Reason: " + (error instanceof CommandResult ? error.extra_message || error.message : error)).open(); }); }); }, ban => { console.log(tr("Editing ban %o"), ban); spawnBanCreate(client, ban, result => { console.log(tr("Apply edit changes %o"), result); if(result.server_id < 0) result.server_id = undefined; client.serverConnection.send_command("banedit", { banid: result.banid, ip: result.ip, name: result.name, uid: result.unique_id, hwid: result.hardware_id, banreason: result.reason, time: result.timestamp_expire.getTime() > 0 ? (result.timestamp_expire.getTime() - result.timestamp_created.getTime()) / 1000 : 0, sid: result.server_id }).then(() => { update(); }).catch(error => { //TODO tr createErrorModal(tr("Failed to edit ban"), "Failed to edit ban.Reason: " + (error instanceof CommandResult ? error.extra_message || error.message : error)).open(); }); }); }, ban => { console.log(tr("Deleting ban %o"), ban); client.serverConnection.send_command("bandel", { banid: ban.banid, sid: ban.server_id }).then(() => { update(); }).catch(error => { //TODO tr createErrorModal(tr("Failed to delete ban"), "Failed to delete ban.Reason: " + (error instanceof CommandResult ? error.extra_message || error.message : error)).open(); }); }); const single_handler: connection.SingleCommandHandler = { command: "notifybanlist", function: command => { const json = command.arguments; console.log(tr("Got banlist: %o"), json); let bans: BanEntry[] = []; for(const entry of json) { /* notify[index]["sid"] = elm->serverId; notify[index]["banid"] = elm->banId; if(allow_ip) notify[index]["ip"] = elm->ip; else notify[index]["ip"] = "hidden"; notify[index]["name"] = elm->name; notify[index]["uid"] = elm->uid; notify[index]["lastnickname"] = elm->name; //Maybe update? notify[index]["created"] = chrono::duration_cast(elm->created.time_since_epoch()).count(); if (elm->until.time_since_epoch().count() != 0) notify[index]["duration"] = chrono::duration_cast(elm->until - elm->created).count(); else notify[index]["duration"] = 0; notify[index]["reason"] = elm->reason; notify[index]["enforcements"] = elm->triggered; notify[index]["invokername"] = elm->invokerName; notify[index]["invokercldbid"] = elm->invokerDbId; notify[index]["invokeruid"] = elm->invokerUid; */ bans.push({ server_id: parseInt(entry["sid"]), banid: parseInt(entry["banid"]), ip: entry["ip"], name: entry["name"], unique_id: entry["uid"], hardware_id: entry["hwid"], timestamp_created: new Date(parseInt(entry["created"]) * 1000), timestamp_expire: new Date(parseInt(entry["duration"]) > 0 ? parseInt(entry["created"]) * 1000 + parseInt(entry["duration"]) * 1000 : 0), invoker_name: entry["invokername"], invoker_database_id: parseInt(entry["invokercldbid"]), invoker_unique_id: entry["invokeruid"], reason: entry["reason"], enforcements: parseInt(entry["enforcements"]), flag_own: entry["invokeruid"] == client.getClient().properties.client_unique_identifier }); } modal.addbans(bans); return false; } }; client.serverConnection.command_handler_boss().register_single_handler(single_handler); modal.modal.close_listener.push(() => { client.serverConnection.command_handler_boss().remove_single_handler(single_handler); }); update = () => { //TODO test permission modal.clear(); client.serverConnection.send_command("banlist", { sid: 0 }); //Global ban list client.serverConnection.send_command("banlist").catch(error => { if(error instanceof CommandResult) { } else { console.error(error); } }); }; update(); } export function spawnBanListModal(callback_update: () => any, callback_add: () => any, callback_edit: (entry: BanEntry) => any, callback_delete: (entry: BanEntry) => any) : BanListManager { let result: BanListManager = {} as any; let entries: BanEntry[] = []; const _callback_edit = ban_id => { for(const entry of entries) if(entry.banid == ban_id) { callback_edit(entry); return; } console.warn(tr("Missing ban entry with id %d"), ban_id); }; const _callback_delete = ban_id => { for (const entry of entries) if (entry.banid == ban_id) { callback_delete(entry); return; } console.warn(tr("Missing ban entry with id %d"), ban_id); }; let update_function: () => any; let modal: Modal; modal = createModal({ header: tr("Banlist"), body: () => { let template = $("#tmpl_ban_list").renderTag(); apply_filter(template.find(".entry-filter"), template.find(".filter-flag-force-own"), template.find(".filter-flag-highlight-own"), template.find(".ban-entry-list")); update_function = apply_buttons(template.find(".manage-buttons"), template.find(".entry-container .entries"), callback_add, _callback_edit, _callback_delete); template.find(".button-close").on('click', _ => modal.close()); template.find(".button-refresh").on('click', () => callback_update()); return template; }, footer: undefined, width: "80%", height: "80%" }); modal.open(); modal.close_listener.push(() => entries = []); const template_entry = $("#tmpl_ban_entry"); result.addbans = (bans: BanEntry[]) => { for(const entry of bans) { entries.push(entry); template_entry.renderTag(entry).appendTo(modal.htmlTag.find(".entry-container .entries")); } modal.htmlTag.find(".entry-filter").trigger("change"); update_function(); }; result.clear = () => { entries = []; modal.htmlTag.find(".entry-container .entries").children().detach(); update_function(); }; result.modal = modal; return result; } function apply_filter(input: JQuery, show_own_bans: JQuery, highlight_own_bans: JQuery, elements: JQuery) { input.on('keyup change', event => { const filter = (input.val() as string).trim(); const show_own_only = show_own_bans.prop("checked"); const highlight_own = highlight_own_bans.prop("checked"); console.log(tr("Search for filter %s"), filter); let shown = 0, hidden = 0; elements.find(".ban-entry").each((_idx, _entry) => { const entry = $(_entry); if(entry.hasClass("ban-entry-own")) { if(highlight_own) entry.addClass("ban-entry-own-bold"); else entry.removeClass("ban-entry-own-bold"); } else if(show_own_only) { if(entry.hide().hasClass("selected")) entry.trigger("click"); hidden++; return; } if(filter.length == 0 || entry.text().indexOf(filter) > 0) { entry.show(); shown++; } else { if(entry.hide().hasClass("selected")) entry.trigger("click"); hidden++; } }); $(".entry-count-info").text((shown + hidden) + " entries. " + shown + " entries shown"); }); show_own_bans.on('click', () => input.trigger('change')); highlight_own_bans.on('click', () => input.trigger('change')); } function apply_buttons(tag: JQuery, elements: JQuery, cb_add: () => any, cb_edit: (id: number) => any, cb_delete: (id: number) => any) : () => any { const update = () => { console.log(elements.find(".ban-entry.selected").length); $(".button-edit, .button-remove").prop("disabled", elements.find(".ban-entry.selected").length == 0); }; tag.find(".button-add").on('click', event => cb_add()); tag.find(".button-edit").on('click', event => { const selected = elements.find(".ban-entry.selected"); if(!selected) return; cb_edit(parseInt(selected.attr("ban-id"))); }); tag.find(".button-remove").on('click', event => { const selected = elements.find(".ban-entry.selected"); if(!selected) return; cb_delete(parseInt(selected.attr("ban-id"))); }); const element_selected = element => { elements.find(".ban-entry").removeClass("selected"); if(element.is(":visible")) element.addClass("selected"); update(); }; const click_handler = event => element_selected($(event.currentTarget)); const context_handler = event => { const element = $(event.currentTarget); element_selected(element); event.preventDefault(); spawn_context_menu(event.pageX, event.pageY, { name: "Edit", type: MenuEntryType.ENTRY, callback: () => cb_edit(parseInt(element.attr("ban-id"))) }, { name: "Delete", type: MenuEntryType.ENTRY, callback: () => cb_delete(parseInt(element.attr("ban-id"))) }); }; return () => { elements.find(".ban-entry").each((_idx, _entry) => { _entry.addEventListener("click", click_handler); _entry.addEventListener("contextmenu", context_handler) }); update(); }; } } /* name=WolverasdasdinDEV ip=WolverasdasdinDEV uid=WolverasdasdinDEV hwid=WolverasdasdinDEV Insult WolverinDEV Created: 1.1.2013 12:22 Expires: 1.21.2013 12:22 */