示例#1
0
 return () => {
     const globalBuilder = {
         End: () => nextBuilder
     };
     for (let op of WASM.description.value_type) {
         globalBuilder[util.toJavaScriptName(op)] = (module, field, mutability) => {
             assert.isString(module, `Import global module should be a string, got "${module}"`);
             assert.isString(field, `Import global field should be a string, got "${field}"`);
             assert.isString(mutability, `Import global mutability should be a string, got "${mutability}"`);
             section.data.push({ globalDescription: { type: op, mutability: _normalizeMutability(mutability) }, module, field, kind: "Global" });
             return _errorHandlingProxyFor(globalBuilder);
         };
     }
     return _errorHandlingProxyFor(globalBuilder);
 };
示例#2
0
 this[section] = function() {
     const s = this._addSection(section);
     const globalBuilder = {
         End: () => this,
         GetGlobal: (type, initValue, mutability) => {
             s.data.push({ type, op: "get_global", mutability: _normalizeMutability(mutability), initValue });
             return _errorHandlingProxyFor(globalBuilder);
         }
     };
     for (let op of WASM.description.value_type) {
         globalBuilder[util.toJavaScriptName(op)] = (initValue, mutability) => {
             s.data.push({ type: op, op: op + ".const", mutability: _normalizeMutability(mutability), initValue });
             return _errorHandlingProxyFor(globalBuilder);
         };
     }
     return _errorHandlingProxyFor(globalBuilder);
 };
示例#3
0
const _createFunctionBuilder = (func, builder, previousBuilder) => {
    let functionBuilder = {};
    for (const op in WASM.description.opcode) {
        const name = util.toJavaScriptName(op);
        const value = WASM.description.opcode[op].value;
        const ret = WASM.description.opcode[op]["return"];
        const param = WASM.description.opcode[op].parameter;
        const imm = WASM.description.opcode[op].immediate;

        const checkStackArgs = builder._checked ? _checkStackArgs : () => {};
        const checkStackReturn = builder._checked ? _checkStackReturn : () => {};
        const checkImms = builder._checked ? _checkImms : () => {};

        functionBuilder[name] = (...args) => {
            let nextBuilder;
            switch (name) {
            default:
                nextBuilder = functionBuilder;
                break;
            case "End":
                nextBuilder = previousBuilder;
                break;
            case "Block":
            case "Loop":
            case "If":
                nextBuilder = _createFunctionBuilder(func, builder, functionBuilder);
                break;
            }

            // Passing a function as the argument is a way to nest blocks lexically.
            const continuation = args[args.length - 1];
            const hasContinuation = typeof(continuation) === "function";
            const imms = hasContinuation ? args.slice(0, -1) : args; // FIXME: allow passing in stack values, as-if code were a stack machine. Just check for a builder to this function, and drop. https://bugs.webkit.org/show_bug.cgi?id=163422
            checkImms(op, imms, imm, ret);
            checkStackArgs(op, param);
            checkStackReturn(op, ret);
            const stackArgs = []; // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
            func.code.push({ name: op, value: value, arguments: stackArgs, immediates: imms });
            if (hasContinuation)
                return _errorHandlingProxyFor(continuation(nextBuilder).End());
            return _errorHandlingProxyFor(nextBuilder);
        };
    };

    return _errorHandlingProxyFor(functionBuilder);
}
exports.handleCommand = function (src, command, commandData, tar, channel) {
    var html_escape = require("utilities.js").html_escape;
    var poChannel = SESSION.channels(channel);
    if (poChannel.operators === undefined) {
        poChannel.operators = [];
    }
    if (command === "cauth") {
        if (typeof SESSION.channels(channel).operators !== "object") {
            SESSION.channels(channel).operators = [];
        }
        if (typeof SESSION.channels(channel).admins !== "object") {
            SESSION.channels(channel).admins = [];
        }
        if (typeof SESSION.channels(channel).masters !== "object") {
            SESSION.channels(channel).masters = [];
        }
        if (typeof SESSION.channels(channel).members !== "object") {
            SESSION.channels(channel).members = [];
        }
        if (commandData === "~") {
            var data = {
                members: SESSION.channels(channel).members,
                operators: SESSION.channels(channel).operators,
                admins: SESSION.channels(channel).admins,
                owners: SESSION.channels(channel).masters
            };
            sys.sendMessage(src, "+cauth: " + JSON.stringify(data), channel);
            return;
        }
        var x, ownersArr = [], adminsArr = [], modsArr = [], membersArr = [];
        for (x = 0; x < SESSION.channels(channel).masters.length; x++) {
            if (sys.isInChannel(sys.id(SESSION.channels(channel).masters[x]), channel)) {
                ownersArr.push("<b><font color='" + script.getColor(sys.id(SESSION.channels(channel).masters[x])) + "'>" + html_escape(sys.name(sys.id(SESSION.channels(channel).masters[x]))) + "</font></b>");
            } else {
                ownersArr.push(html_escape(SESSION.channels(channel).masters[x]));
            }
        }
        for (x = 0; x < SESSION.channels(channel).admins.length; x++) {
            if (sys.isInChannel(sys.id(SESSION.channels(channel).admins[x]), channel)) {
                adminsArr.push("<b><font color='" + script.getColor(sys.id(SESSION.channels(channel).admins[x])) + "'>" + html_escape(sys.name(sys.id(SESSION.channels(channel).admins[x]))) + "</font></b>");
            } else {
                adminsArr.push(html_escape(SESSION.channels(channel).admins[x]));
            }
        }
        for (x = 0; x < SESSION.channels(channel).operators.length; x++) {
            if (sys.isInChannel(sys.id(SESSION.channels(channel).operators[x]), channel)) {
                modsArr.push("<b><font color='" + script.getColor(sys.id(SESSION.channels(channel).operators[x])) + "'>" + html_escape(sys.name(sys.id(SESSION.channels(channel).operators[x]))) + "</font></b>");
            } else {
                modsArr.push(html_escape(SESSION.channels(channel).operators[x]));
            }
        }
        for (x = 0; x < SESSION.channels(channel).members.length; x++) {
            if (sys.isInChannel(sys.id(SESSION.channels(channel).members[x]), channel)) {
                membersArr.push("<b><font color='" + script.getColor(sys.id(SESSION.channels(channel).members[x])) + "'>" + html_escape(sys.name(sys.id(SESSION.channels(channel).members[x]))) + "</font></b>");
            } else {
                membersArr.push(html_escape(SESSION.channels(channel).members[x]));
            }
        }
        channelbot.sendHtmlMessage(src, "The channel members of " + sys.channel(channel) + " are:", channel);
        channelbot.sendHtmlMessage(src, "Owners: " + ownersArr.join(", "), channel);
        channelbot.sendHtmlMessage(src, "Admins: " + adminsArr.join(", "), channel);
        channelbot.sendHtmlMessage(src, "Mods: " + modsArr.join(", "), channel);
        if (SESSION.channels(channel).inviteonly >= 1 || SESSION.channels(channel).members.length >= 1) {
            channelbot.sendHtmlMessage(src, "Members: " + membersArr.join(", "), channel);
        }
        return;
    }
    if (command === "register") {
        if (!sys.dbRegistered(sys.name(src))) {
            channelbot.sendMessage(src, "You need to register on the server before registering a channel to yourself for security reasons!", channel);
            return;
        }
        if (sys.auth(src) < 1 && script.isOfficialChan(channel)) {
            channelbot.sendMessage(src, "You don't have sufficient authority to register this channel!", channel);
            return;
        }
        if (poChannel.masters.length === 0) {
            if (poChannel.admins.length > 0) {
                if (poChannel.admins.contains(sys.name(src).toLowerCase())) {
                    poChannel.register(sys.name(src));
                    channelbot.sendAll(sys.name(src) + " has taken the empty owner position by admin.", channel);
                    return;
                }
            } else {
                if (poChannel.operators.length > 0) {
                    if (poChannel.operators.contains(sys.name(src).toLowerCase())) {
                        poChannel.register(sys.name(src));
                        channelbot.sendAll(sys.name(src) + " has taken the empty owner position by moderator.", channel);
                        return;
                    }
                } else {
                    if (poChannel.members.length > 0) {
                        if (poChannel.members.contains(sys.name(src).toLowerCase())) {
                            poChannel.register(sys.name(src));
                            channelbot.sendAll(sys.name(src) + " has taken the empty owner position by member.", channel);
                            return;
                        }
                    } else {
                        poChannel.register(sys.name(src));
                        channelbot.sendMessage(src, "You registered this channel successfully. Take a look of /commands channel", channel);
                        channelbot.sendAll(sys.name(src) + " has registered the channel.", channel);
                        return;
                    }
                    channelbot.sendMessage(src, "Only a channel member can register.", channel);
                    return;
                }
                channelbot.sendMessage(src, "Only a channel operator can register.", channel);
                return;
            }
            channelbot.sendMessage(src, "Only a channel admin can register.", channel);
            return;
        }
        channelbot.sendMessage(src, "This channel is already registered.", channel);
        return;
    }
    if (command === "crules" || command === "channelrules") {
        var x, rules = poChannel.getRules();
        if (rules.length === 0) {
            channelbot.sendMessage(src, "No rules defined for this channel, server rules may apply", channel);
            return;
        }
        sys.sendMessage(src, "*** " + sys.channel(channel) + " channel rules ***", channel);
        for (x = 0; x < rules.length; x++) {
            var rule = rules[x].split("\n");
            sys.sendMessage(src, rule[0], channel);
            if (rule[1].length > 0) {
                sys.sendMessage(src, rule[1], channel);
            }
        }
        return;
    }
    if (command === "passcauth") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Use /passcauth [name]", channel);
            return;
        }
        var oldName = sys.name(src).toLowerCase();
        var action = commandData.split("*"); //useless, but doesn't break comptability, can still use /passcauth name*position but position just won't do anything
        var newName = action[0].toLowerCase();
        if (sys.id(newName) === undefined) {
            channelbot.sendMessage(src, "Your target is offline", channel);
            return;
        }
        if (!sys.dbRegistered(newName)) {
            channelbot.sendMessage(src, "That account isn't registered so you can't give it channel authority!", channel);
            return;
        }
        if (sys.ip(sys.id(newName)) !== sys.ip(src)) {
            channelbot.sendMessage(src, "Both accounts must be on the same IP to switch!", channel);
            return;
        }
        if (poChannel.isChannelOwner(src)) {
            if (poChannel.masters.indexOf(newName) > -1) {
                channelbot.sendMessage(src, newName + " is already a Channel Owner!", channel);
                return;
            }
            poChannel.masters.splice(poChannel.masters.indexOf(oldName), 1);
            poChannel.masters.push(newName);
            channelbot.sendAll(sys.name(src) + " transferred their Channel Owner to " + newName + "!", channel);
            return;
        }
        if (poChannel.isChannelAdmin(src)) {
            if (poChannel.admins.indexOf(newName) > -1) {
                channelbot.sendMessage(src, newName + " is already a Channel Admin!", channel);
                return;
            }
            poChannel.admins.splice(poChannel.admins.indexOf(oldName), 1);
            poChannel.admins.push(newName);
            channelbot.sendAll(sys.name(src) + " transferred their Channel Admin to " + newName + "!", channel);
            return;
        }
        if (poChannel.isChannelOperator(src)) {
            if (poChannel.operators.indexOf(newName) > -1) {
                channelbot.sendMessage(src, newName + " is already a Channel Mod!", channel);
                return;
            }
            poChannel.operators.splice(poChannel.operators.indexOf(oldName), 1);
            poChannel.operators.push(newName);
            channelbot.sendAll(sys.name(src) + " transferred their Channel Mod to " + newName + "!", channel);
            return;
        }
        if (poChannel.isChannelMember(src)) {
            if (poChannel.members.indexOf(newName) > -1) {
                channelbot.sendMessage(src, newName + " is already a Channel Member!", channel);
                return;
            }
            poChannel.members.splice(poChannel.members.indexOf(oldName), 1);
            poChannel.members.push(newName);
            channelbot.sendAll(sys.name(src) + " transferred their Channel Membership to " + newName + "!", channel);
            return;
        }
        channelbot.sendMessage(src, "You don't have sufficient channel auth to pass that position.", channel);
        return;
    }

    if (command === "topic") {
        //Mods shouldn't be able to change topic of private channels
        if (poChannel.isChannelOperator(src) || (sys.auth(src) === 1 && script.isPOChannel(channel))) {
            SESSION.channels(channel).setTopic(src, commandData);
        } else {
            SESSION.channels(channel).setTopic(src);
        }
        return;
    }

    if (command === "topicadd") {
        if (commandData !== undefined && SESSION.channels(channel).topic.length > 0) {
            SESSION.channels(channel).setTopic(src, SESSION.channels(channel).topic + Config.topic_delimiter + commandData);
            return;
        }
        channelbot.sendMessage(src, "Please enter a topic to add after.", channel);
        return;
    }
    if (command === "removepart" || command === "removeparts") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Correct usage is /" + command + " [number]. Separate multiple part numbers with a space.", channel);
            return;
        }
        var i,
            parts = commandData.indexOf(":") !== -1 ? commandData.split(":") : commandData.split(" "),
            topic = SESSION.channels(channel).topic,
            duplicates = [];
        topic = topic.split(Config.topic_delimiter);
        for (i = 0; i < parts.length; i++) {
            var part = parseInt(parts[i], 10),
                pospart = topic.length + part + 1;
            if (part < 0 && pospart > 0) {
                parts.splice(i, 1, pospart);
                duplicates.push(pospart);
                continue;
            }
            if (isNaN(part) || part > topic.length || pospart < 0) {
                channelbot.sendMessage(src, "Parts must be a number from 1 to " + topic.length + "!", channel);
                return;
            }
            if (duplicates.indexOf(part) !== -1) {
                channelbot.sendMessage(src, "You can't remove part " + part + " twice!", channel);
                return;
            }
            duplicates.push(part);
        }
        // Sort by largest numbers first to avoid interfering with earlier parts after removal
        parts.sort(function (a, b) { return b - a; }).forEach(function (part) {
            topic.splice(part - 1, 1);
        });
        SESSION.channels(channel).setTopic(src, topic.join(Config.topic_delimiter));
        return;
    }
    if (command === "topicparts") {
        var topic = SESSION.channels(channel).topic;
        if (typeof topic === "string" && topic !== "") {
            var i = 0;
            topic = topic.split(Config.topic_delimiter).map(function (part) {
                return "<font color='blue'><b>[" + (++i) + "]</b></font> " + part;
            }).join(Config.topic_delimiter);
            // HTML isn't necessary, but it makes the number more obvious
            sys.sendHtmlMessage(src, "<font color='#3DAA68'><timestamp/> <b>±" + Config.channelbot + ":</b></font> Topic for this channel is: " + topic, channel);
        } else {
            channelbot.sendMessage(src, "No topic set for this channel.", channel);
        }
        return;
    }
    if (command === "updatepart") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please enter the topic number spaced with the text to change.", channel);
            return;
        }
        var topic = SESSION.channels(channel).topic;
        topic = topic.split(Config.topic_delimiter);
        var pos = commandData.indexOf(" ");
        if (pos === -1) {
            return;
        }
        if (isNaN(commandData.substring(0, pos)) || commandData.substring(0, pos) - 1 < 0 || commandData.substring(0, pos) - 1 > topic.length - 1) {
            return;
        }
        topic[commandData.substring(0, pos) - 1] = commandData.substr(pos + 1);
        SESSION.channels(channel).setTopic(src, topic.join(Config.topic_delimiter));
        return;
    }

    if (!poChannel.isChannelOperator(src)) {
        return "no command";
    }

    if (command === "lt" || command === "lovetap") {
        if (tar === undefined) {
            normalbot.sendMessage(src, "Choose a valid target for your love!", channel);
            return;
        }
        var colour = script.getColor(src);
        sendChanHtmlAll("<font color='" + colour + "'><timestamp/> *** <b>" + utilities.html_escape(sys.name(src)) + "</b> love taps " + commandData + ".</font>", channel);
        sys.kick(tar, channel);
        return;
    }
    if (command === "ck" || command === "chankick") {
        if (tar === undefined || !sys.isInChannel(tar, channel)) {
            normalbot.sendMessage(src, "Choose a valid target to kick", channel);
            return;
        }
        normalbot.sendAll(sys.name(src) + " kicked " + commandData + " from the channel!", channel);
        sys.kick(tar, channel);
        return;
    }
    if (command === "invite") {
        if (tar === undefined) {
            channelbot.sendMessage(src, "Choose a valid target for invite!", channel);
            return;
        }
        if (sys.isInChannel(tar, channel) && SESSION.channels(channel).canJoin(tar) === "allowed") {
            channelbot.sendMessage(src, "Your target already sits here!", channel);
            return;
        }
        if (SESSION.channels(channel).canJoin(tar) === "banned") {
            channelbot.sendMessage(src, "Your target is banned from this channel!", channel);
            return;
        }
        var now = (new Date()).getTime();
        if (typeof SESSION.users(tar).inviteDelay === "object" && SESSION.users(tar).inviteDelay.hasOwnProperty(sys.ip(src)) && now < SESSION.users(tar).inviteDelay[sys.ip(src)]) {
            channelbot.sendMessage(src, "Please wait before sending another invite!", channel);
            return;
        }
        if (!sys.isInChannel(tar, channel)) {
            channelbot.sendMessage(tar, sys.name(src) + " would like you to join #" + sys.channel(channel) + "!");
        }
        var guardedChans = [staffchannel, sachannel, watchchannel, revchan];
        if ((sys.auth(tar) < SESSION.channels(channel).inviteonly || guardedChans.indexOf(channel) !== -1) && SESSION.channels(channel).canJoin(tar) !== "allowed") {
            poChannel.issueAuth(src, commandData, "member");
        } else {
            channelbot.sendMessage(src, "Your target was invited.", channel);
        }
        if (typeof SESSION.users(tar).inviteDelay !== "object") {
            SESSION.users(tar).inviteDelay = {};
        }
        SESSION.users(tar).inviteDelay[sys.ip(src)] = (new Date()).getTime() + 8000;
        return;
    }
    if (command === "member") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to make a member!", channel);
            return;
        }
        poChannel.issueAuth(src, commandData, "member");
        return;
    }
    if (command === "uninvite" || command === "demember" || command === "deinvite" || command === "dismember") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to remove membership from!", channel);
            return;
        }
        poChannel.takeAuth(src, commandData, "member");
        if (tar !== undefined) {
            if (sys.isInChannel(tar, channel) && (command === "uninvite" || command === "deinvite")) {
                sys.kick(tar, channel);
                channelbot.sendAll("And " + commandData + " was gone!", channel);
            }
        }
        return;
    }
    if (command === "cmeon") {
        script.meon(src, sys.channel(channel));
        return;
    }
    if (command === "cmeoff") {
        /*if (channel === 0 || channel == tourchannel) {
            normalbot.sendMessage(src, "/me can't be turned off here.", channel);
            return;
        }*/
        script.meoff(src, sys.channel(channel));
        return;
    }
    if (command === "csilence" || command === "csilenceoff") {
        if (command === "csilenceoff" || commandData === "off") {
            script.silenceoff(src, sys.channel(channel));
        } else {
            if (commandData === undefined) {
                commandData = "permanent";
            }
            script.silence(src, commandData, sys.channel(channel));
        }
        return;
    }
    if (command === "cmute") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to mute in the channel!", channel);
            return;
        }
        var i = commandData.indexOf(":"),
            j = commandData.lastIndexOf(":"),
            time = 0,
            reason = "",
            tarName = "";
        if (i !== -1) {
            tarName = commandData.substring(0, i);
            var timeString = commandData.substring(j + 1, commandData.length);
            if (timeString !== "" && !isNaN(timeString.replace(/s\s|m\s|h\s|d\s|w\s|s|m|h|d|w/gi, ""))) {
                time = getSeconds(timeString);
            } else {
                time = 0;
                reason = commandData.slice(i + 1);
                j = i;
            }
            if (i !== j) {
                reason = commandData.substring(i + 1, j);
            }
        } else {
            tarName = commandData;
        }
        if (sys.dbIp(tarName) === undefined) {
            normalbot.sendMessage(src, "This user doesn't exist.", channel);
            return;
        }
        poChannel.mute(src, tarName, {"time": time, "reason": reason}, SESSION.users(src).smute.active);
        return;
    }
    if (command === "cunmute") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to unmute in the channel!", channel);
        }
        poChannel.unmute(src, commandData);
        return;
    }
    if (command === "cmutes") {
        var cmutelist = poChannel.getReadableList("mutelist", sys.os(src), commandData);
        if (cmutelist !== "") {
            sys.sendHtmlMessage(src, cmutelist, channel);
        } else if (commandData !== undefined) {
            channelbot.sendMessage(src, "No users muted in this channel have \"" + commandData +  "\" in their name.", channel);
        } else {
            channelbot.sendMessage(src, "No one is muted on this channel.", channel);
        }
        return;
    }
    if (command === "cbans") {
        var cbanlist = poChannel.getReadableList("banlist", sys.os(src), commandData);
        if (cbanlist !== "") {
            sys.sendHtmlMessage(src, cbanlist, channel);
        } else if (commandData !== undefined) {
            channelbot.sendMessage(src, "No users banned in this channel have \"" + commandData +  "\" in their name.", channel);
        } else {
            channelbot.sendMessage(src, "No one is banned on this channel.", channel);
        }
        return;
    }

    if (!poChannel.isChannelAdmin(src)) {
        return "no command";
    }

    if (command === "op") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to give channel operator permissions!", channel);
            return;
        }
        poChannel.issueAuth(src, commandData, "mod");
        return;
    }
    if (command === "deop") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to remove channel operator permissions!", channel);
            return;
        }
        poChannel.takeAuth(src, commandData, "mod");
        return;
    }
    if (command === "inviteonly") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, poChannel.inviteonly === 0 ? "This channel is public!" : "This channel is invite only for users below auth level " + poChannel.inviteonly, channel);
            return;
        }
        var value = -1;
        if (commandData === "off") {
            value = 0;
        } else if (commandData === "on") {
            value = 3;
        } else {
            value = parseInt(commandData, 10);
        }
        var message = poChannel.changeParameter(src, "invitelevel", value);
        normalbot.sendAll(message, channel);
        return;
    }
    if (command === "ctoggleflood") {
        poChannel.ignoreflood = !poChannel.ignoreflood;
        channelbot.sendMessage(src, "Now " + (poChannel.ignoreflood ? "" : "dis") + "allowing excessive flooding.", channel);
        return;
    }
    if (command === "ctoggleswear") {
        poChannel.allowSwear = !poChannel.allowSwear;
        channelbot.sendAll(sys.name(src) + " " + (poChannel.allowSwear ? "" : "dis") + "allowed swearing.", poChannel.id);
        return;
    }
    if (command === "ctogglecaps") {
        poChannel.ignorecaps = !poChannel.ignorecaps;
        channelbot.sendMessage(src, "Now " + (poChannel.ignorecaps ? "" : "dis") + "allowing excessive CAPS-usage.", channel);
        return;
    }
    if (command === "cban") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to ban from the channel!", channel);
            return;
        }
        var i = commandData.indexOf(":"),
            j = commandData.lastIndexOf(":"),
            time = 0,
            reason = "",
            tarName = "";
        if (i !== -1) {
            tarName = commandData.substring(0, i);
            var timeString = commandData.substring(j + 1, commandData.length);
            if (timeString !== "" && !isNaN(timeString.replace(/s\s|m\s|h\s|d\s|w\s|s|m|h|d|w/gi, ""))) {
                time = getSeconds(timeString);
            } else {
                time = 0;
                reason = commandData.slice(i + 1);
                j = i;
            }
            if (i !== j) {
                reason = commandData.substring(i + 1, j);
            }
        } else {
            tarName = commandData;
        }
        if (sys.dbIp(tarName) === undefined) {
            normalbot.sendMessage(src, "This user doesn't exist.", channel);
            return;
        }
        poChannel.ban(src, tarName, {"time": time, "reason": reason});
        return;
    }
    if (command === "cunban") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to unban from the channel!", channel);
            return;
        }
        poChannel.unban(src, commandData);
        return;
    }

    if (!poChannel.isChannelOwner(src) && sys.auth(src) < 2) {
        return "no command";
    }

    if (command === "deregister") {
        if (commandData === undefined) {
            poChannel.takeAuth(src, sys.name(src), "owner");
        } else {
            poChannel.takeAuth(src, commandData, "owner");
        }
        return;
    }

    if (!poChannel.isChannelOwner(src)) {
        return "no command";
    }

    if (command === "admin") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to give channel admin permissions!", channel);
            return;
        }
        poChannel.issueAuth(src, commandData, "admin");
        return;
    }
    if (command === "deadmin") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to remove channel admin permissions!", channel);
            return;
        }
        poChannel.takeAuth(src, commandData, "admin");
        return;
    }
    if (command === "owner") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to give channel owner permissions!", channel);
            return;
        }
        poChannel.issueAuth(src, commandData, "owner");
        return;
    }
    if (command === "deowner") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please specify a valid target to remove channel owner permissions!", channel);
            return;
        }
        poChannel.takeAuth(src, commandData, "owner");
        return;
    }
    if (command === "addrule") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Use /addrule name:description.", channel);
            return;
        }
        commandData = commandData.split(":");
        if (commandData.length !== 2) {
            channelbot.sendMessage(src, "Use /addrule name:description.", channel);
            return;
        }
        var returnVal = poChannel.addRule(commandData[0], commandData[1]);
        if (returnVal) {
            channelbot.sendMessage(src, returnVal, channel);
        } else {
            channelbot.sendMessage(src, "You added a rule", channel);
        }
        return;
    }
    if (command === "removerule") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Please enter a rule number to remove.", channel);
            return;
        }
        var returnVal = poChannel.removeRule(commandData);
        if (returnVal) {
            channelbot.sendMessage(src, returnVal, channel);
        } else {
            channelbot.sendMessage(src, "You removed a rule", channel);
        }
        return;
    }
    if (command === "editrule") {
        if (commandData === undefined) {
            channelbot.sendMessage(src, "Use /editrule index:name:description", channel);
            return;
        }
        commandData = commandData.split(":");
        if (commandData.length !== 3) {
            channelbot.sendMessage(src, "Use /editrule index:name:description", channel);
            return;
        }
        var returnVal = poChannel.editRule(commandData[0], commandData[1], commandData[2]);
        if (returnVal) {
            channelbot.sendMessage(src, returnVal, channel);
        } else {
            channelbot.sendMessage(src, "You edited a rule", channel);
        }
        return;
    }

    return "no command";
};
示例#5
0
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import * as utilities from 'utilities.js';

const _mapValues = from => {
    let values = {};
    for (const key in from)
        values[key] = from[key].value;
    return values;
};

export const description = utilities.json("wasm.json");
export const type = Object.keys(description.type);
const _typeSet = new Set(type);
export const isValidType = v => _typeSet.has(v);
export const typeValue = _mapValues(description.type);
const _valueTypeSet = new Set(description.value_type);
export const isValidValueType = v => _valueTypeSet.has(v);
const _blockTypeSet = new Set(description.block_type);
export const isValidBlockType = v => _blockTypeSet.has(v);
export const externalKindValue = _mapValues(description.external_kind);
export const sections = Object.keys(description.section);
export const sectionEncodingType = description.section[sections[0]].type;

export function* opcodes(category = undefined) {
    for (let op in description.opcode)
        if (category !== undefined && description.opcode[op].category === category)
exports.handleCommand = function (src, command, commandData, tar, channel) {
    var arraySlice = require("utilities.js").arraySlice;
    var getTimeString = require("utilities.js").getTimeString;
    var find_tier = require("utilities.js").find_tier;
    // loop indices
    var i, x;
    // temp array
    var ar;
    if (command === "commands" || command === "command") {
        if (commandData === undefined) {
            sys.sendMessage(src, "*** Commands ***", channel);
            for (x = 0; x < this.help.length; ++x) {
                sys.sendMessage(src, this.help[x], channel);
            }
            sys.sendMessage(src, "*** Other Commands ***", channel);
            sys.sendMessage(src, "/commands channel: To know of channel commands", channel);
            if (sys.auth(src) > 0 || SESSION.users(src).tempMod) {
                sys.sendMessage(src, "/commands mod: To know of moderator commands", channel);
            }
            if (sys.auth(src) > 1 || SESSION.users(src).tempAdmin) {
                sys.sendMessage(src, "/commands admin: To know of admin commands", channel);
            }
            if (sys.auth(src) > 2 || isSuperAdmin(src)) {
                sys.sendMessage(src, "/commands owner: To know of owner commands", channel);
            }
            var module, pluginhelps = getplugins("help-string");
            for (module in pluginhelps) {
                if (pluginhelps.hasOwnProperty(module)) {
                    var help = typeof pluginhelps[module] === "string" ? [pluginhelps[module]] : pluginhelps[module];
                    for (i = 0; i < help.length; ++i) {
                        sys.sendMessage(src, "/commands " + help[i], channel);
                    }
                }
            }
            return;
        }

        commandData = commandData.toLowerCase();
        if ( (commandData === "mod" && sys.auth(src) > 0 || SESSION.users(src).tempMod) ||
             (commandData === "admin" && sys.auth(src) > 1 || SESSION.users(src).tempAdmin) ||
             (commandData === "owner" && (sys.auth(src) > 2  || isSuperAdmin(src))) ||
             (commandData === "channel") ) {
            sys.sendMessage(src, "", channel);
            sys.sendMessage(src, "*** " + utilities.capitalize(commandData.toLowerCase()) + " commands ***", channel);
            var list = require(commandData + "commands.js").help;
            if (typeof list !== "function") {
                list.forEach(function (help) {
                    sys.sendMessage(src, help, channel);
                });
            } else {
                list(src, channel);
            }
        }
        callplugins("onHelp", src, commandData, channel);
        return;
    }
    if (command === "intier") {
        if (commandData === undefined) {
            battlebot.sendMessage(src, "Please enter a tier.", channel);
            return;
        }
        if (find_tier(commandData) === null) {
            battlebot.sendMessage(src, commandData + " tier doesn't exist on the server.", channel);
            return;
        }
        var x,
            tierInput = find_tier(commandData),
            playerIdArray = sys.playerIds(),
            usersFoundArray = [];
        for (x = 0; x < playerIdArray.length; x++) {
            if (!sys.loggedIn(playerIdArray[x]) || sys.away(playerIdArray[x])) {
                continue;
            }
            if (sys.hasTier(playerIdArray[x], tierInput)) {
                usersFoundArray.push(sys.name(playerIdArray[x]));
            }
        }
        if (usersFoundArray.length === 0) {
            battlebot.sendMessage(src, "No unidled players found in that tier.", channel);
        } else {
            var sliceAmount = 10,
                users = arraySlice(usersFoundArray.shuffle(), sliceAmount).join(", ");
            battlebot.sendMessage(src, "Found " + usersFoundArray.length + "/" + sliceAmount + " unidled random players in " + tierInput + ": " + users, channel);
        }
        return;
    }
    if ((command === "me" || command === "rainbow") && !SESSION.channels(channel).muteall) {
        if (SESSION.channels(channel).meoff) {
            normalbot.sendMessage(src, "/me was turned off.", channel);
            return;
        }
        if (commandData === undefined) {
            return;
        }
        if (channel === sys.channelId("Trivia") && SESSION.channels(channel).triviaon) {
            sys.sendMessage(src, "±Trivia: Answer using \\a, /me not allowed now.", channel);
            return;
        }
        if (usingBannedWords() || repeatingOneself() || capsName()) {
            sys.stopEvent();
            return;
        }
        if (SESSION.users(src).smute.active) {
            sys.playerIds().forEach(function (id) {
                if (sys.loggedIn(id) && SESSION.users(id).smute.active && sys.isInChannel(src, channel)) {
                    var colour = script.getColor(src);
                    sys.sendHtmlMessage(id, "<font color='" + colour + "'><timestamp/> *** <b>" + utilities.html_escape(sys.name(src)) + "</b> " + commandData + "</font>", channel);
                }
            });
            sys.stopEvent();
            script.afterChatMessage(src, "/" + command + " " + commandData, channel);
            return;
        }
        SESSION.channels(channel).beforeMessage(src, "/me " + commandData);
        commandData = utilities.html_escape(commandData);
        var messagetosend = commandData;
        if (typeof CAPSLOCKDAYALLOW !== "undefined" && CAPSLOCKDAYALLOW) {
            var date = new Date();
            if ((date.getDate() === 22 && date.getMonth() === 9) || (date.getDate() === 28 && date.getMonth() === 5)) { // October 22nd & June 28th
                messagetosend = messagetosend.toUpperCase();
            }
        }
        if (channel === sys.channelId("Tohjo Falls") && script.reverseTohjo) {
            messagetosend = messagetosend.split("").reverse().join("");
        }
        if (command === "me") {
            var colour = script.getColor(src);
            sendChanHtmlAll("<font color='" + colour + "'><timestamp/> *** <b>" + utilities.html_escape(sys.name(src)) + "</b> " + messagetosend + "</font>", channel);
        } else if (command === "rainbow") {
            if (script.isOfficialChan(channel) && sys.auth(src) < 1) {
                return;
            }
            var auth = 1 <= sys.auth(src) && sys.auth(src) <= 3;
            var coloursArray = ["#F85888", "#F08030", "#F8D030", "#78C850", "#98D8D8", "#A890F0", "#C183C1"];
            var colour = sys.rand(0, coloursArray.length);
            var randColour = function () {
                var returnVal = coloursArray[colour];
                colour = colour + 1;
                if (colour === coloursArray.length) {
                    colour = 0;
                }
                return returnVal;
            };
            var toSend = ["<timestamp/><b>"];
            if (auth) {
                toSend.push("<span style='color:" + randColour() + "'>+</span><i>");
            }
            var i, name = sys.name(src);
            for (i = 0; i < name.length; ++i) {
                toSend.push("<span style='color:" + randColour() + "'>" + utilities.html_escape(name[i]) + "</span>");
            }
            toSend.push("<span style='color:" + randColour() + "'>:</b></span> ");
            if (auth) {
                toSend.push("</i>");
            }
            toSend.push(messagetosend);
            sendChanHtmlAll(toSend.join(""), channel);
        }
        script.afterChatMessage(src, "/" + command + " " + commandData, channel);
        return;
    }
    if (command === "contributors") {
        sys.sendMessage(src, "", channel);
        sys.sendMessage(src, "*** CONTRIBUTORS ***", channel);
        sys.sendMessage(src, "", channel);
        var x;
        for (x in script.contributors.hash) {
            if (script.contributors.hash.hasOwnProperty(x)) {
                sys.sendMessage(src, x + "'s contributions: " + script.contributors.get(x), channel);
            }
        }
        sys.sendMessage(src, "", channel);
        return;
    }
    if (command === "league") {
        if (!Object.keys(script.league).length) {
            return;
        }
        sys.sendMessage(src, "", channel);
        sys.sendMessage(src, "*** Pokemon Online League ***", channel);
        sys.sendMessage(src, "", channel);
        ar = script.league;
        for (x = 0; x < ar.length; ++x) {
            if (ar[x].length > 0) {
                sys.sendHtmlMessage(src, "<span style='font-weight: bold'>" + utilities.html_escape(ar[x][0].toCorrectCase()) + "</span> - " + ar[x][1].format(utilities.html_escape(ar[x][0])) + " " + (sys.id(ar[x][0]) !== undefined ? "<span style='color: green'>(online)</span>" : "<span style='color: red'>(offline)</span>"), channel);
            }
        }
        sys.sendMessage(src, "", channel);
        return;
    }
    if (command === "rules" || command === "rule") {
        if (commandData === "mafia") {
            require("mafia.js").showRules(src, channel);
            return;
        }
        var norules = (rules.length - 1) / 2; //formula for getting the right amount of rules
        if (commandData !== undefined && !isNaN(commandData) && commandData > 0 && commandData < norules) {
            var num = parseInt(commandData, 10);
            num = (2 * num) + 1; //gets the right rule from the list since it isn't simply y=x it's y=2x+1
            sys.sendMessage(src, rules[num], channel);
            sys.sendMessage(src, rules[num + 1], channel);
            return;
        }
        var rule;
        for (rule = 0; rule < rules.length; rule++) {
            sys.sendMessage(src, rules[rule], channel);
        }
        return;
    }
    if (command === "players") {
        if (commandData) {
            commandData = commandData.toLowerCase();
        }
        if (["windows", "linux", "android", "mac", "webclient"].indexOf(commandData) !== -1) {
            var count = 0;
            sys.playerIds().forEach(function (id) {
                if (sys.os(id) === commandData) {
                    count += 1;
                }
            });
            countbot.sendMessage(src, "There are  " + count + " " + commandData + " players online", channel);
            return;
        }
        if (commandData === "top" || commandData === "max") {
            countbot.sendMessage(src, "Max number of players online was " + sys.getVal("MaxPlayersOnline") + ".", channel);
            return;
        }
        countbot.sendMessage(src, "There are " + sys.numPlayers() + " players online.", channel);
        return;
    }
    if (command === "ranking") {
        var announceTier = function (tier) {
            var rank = sys.ranking(sys.name(src), tier);
            if (rank === undefined) {
                rankingbot.sendMessage(src, "You are not ranked in " + tier + " yet!", channel);
            } else {
                var wins = sys.ratedWins(sys.name(src), tier);
                rankingbot.sendMessage(src, "Your rank in " + tier + " is " + rank + "/" + sys.totalPlayersByTier(tier) + " [" + sys.ladderRating(src, tier) + " points / " + sys.ratedBattles(sys.name(src), tier) + " battles, " + wins + " win" + (wins !== 1 ? "s" : "") + "]!", channel);
            }
        };
        if (commandData !== undefined) {
            commandData = utilities.find_tier(commandData);
            if (sys.totalPlayersByTier(commandData) === 0) {
                rankingbot.sendMessage(src, commandData + " is not even a tier.", channel);
            } else {
                announceTier(commandData);
            }
        } else {
            [0, 1, 2, 3, 4, 5].slice(0, sys.teamCount(src))
                .map(function (i) { return sys.tier(src, i); })
                .filter(function (tier) { return tier !== undefined; })
                .sort()
                .filter(function (tier, index, array) { return tier !== array[index - 1]; })
                .forEach(announceTier);
        }
        return;
    }
    if (command === "battlecount") {
        if (!commandData || commandData.indexOf(":") === -1) {
            rankingbot.sendMessage(src, "Usage: /battlecount name:tier", channel);
            return;
        }
        var stuff = commandData.split(":");
        var name = stuff[0];
        var tier = utilities.find_tier(stuff[1]);
        var rank = sys.ranking(name, tier);
        if (!tier) {
            rankingbot.sendMessage(stuff[1] + " is not a tier", channel);
            return;
        }
        if (rank === undefined) {
            rankingbot.sendMessage(src, "They are not ranked in " + tier + " yet!", channel);
        } else {
            var wins = sys.ratedWins(name, tier);
            rankingbot.sendMessage(src, name + "'s rank in " + tier + " is " + rank + "/" + sys.totalPlayersByTier(tier) + " [" + sys.ratedBattles(name, tier) + " battles, " + wins + " win" + (wins !== 1 ? "s" : "") + "]!", channel);
        }
        return;
    }
    if (command === "auth") {
        var doNotShowIfOffline = ["loseyourself", "oneballjay"];
        var filterByAuth = function (level) {
            return function (name) {
                return sys.dbAuth(name) === level;
            };
        };
        var printOnlineOffline = function (name) {
            if (sys.id(name) === undefined) {
                if (doNotShowIfOffline.indexOf(name) === -1) {
                    sys.sendMessage(src, name, channel);
                }
            } else {
                sys.sendHtmlMessage(src, "<timestamp/><font color = " + script.getColor(sys.id(name)) + "><b>" + name.toCorrectCase() + "</b></font>", channel);
            }
        };
        var authListArray = sys.dbAuths().sort();
        if (commandData !== "~") {
            sys.sendMessage(src, "", channel);
        }
        switch (commandData) {
        case "owners":
            sys.sendMessage(src, "*** Owners ***", channel);
            authListArray.filter(filterByAuth(3)).forEach(printOnlineOffline);
            break;
        case "admins":
        case "administrators":
            sys.sendMessage(src, "*** Administrators ***", channel);
            authListArray.filter(filterByAuth(2)).forEach(printOnlineOffline);
            break;
        case "mods":
        case "moderators":
            sys.sendMessage(src, "*** Moderators ***", channel);
            authListArray.filter(filterByAuth(1)).forEach(printOnlineOffline);
            break;
        case "~":
            var ret = {};
            ret.owners = authListArray.filter(filterByAuth(3));
            ret.administrators = authListArray.filter(filterByAuth(2));
            ret.moderators = authListArray.filter(filterByAuth(1));
            sys.sendMessage(src, "+auth: " + JSON.stringify(ret), channel);
            return;
        default:
            sys.sendMessage(src, "*** Owners ***", channel);
            authListArray.filter(filterByAuth(3)).forEach(printOnlineOffline);
            sys.sendMessage(src, '', channel);
            sys.sendMessage(src, "*** Administrators ***", channel);
            authListArray.filter(filterByAuth(2)).forEach(printOnlineOffline);
            sys.sendMessage(src, '', channel);
            sys.sendMessage(src, "*** Moderators ***", channel);
            authListArray.filter(filterByAuth(1)).forEach(printOnlineOffline);
        }
        sys.sendMessage(src, '', channel);
        return;
    }
    if (command === "sametier") {
        if (commandData === "on") {
            battlebot.sendMessage(src, "You enforce same tier in your battles.", channel);
            SESSION.users(src).sametier = true;
        } else if (commandData === "off") {
            battlebot.sendMessage(src, "You allow different tiers in your battles.", channel);
            SESSION.users(src).sametier = false;
        } else {
            battlebot.sendMessage(src, "Currently: " + (SESSION.users(src).sametier ? "enforcing same tier" : "allow different tiers") + ". Use /sametier on/off to change it!", channel);
        }
        script.saveKey("forceSameTier", src, SESSION.users(src).sametier * 1);
        return;
    }
    if (command === "idle") {
        if (commandData === undefined) {
            battlebot.sendMessage(src, "You are currently " + (sys.away(src) ? "idling" : "here and ready to battle") + ". Use /idle on/off to change it.", channel);
            return;
        }
        if (commandData.toLowerCase() === "on") {
            battlebot.sendMessage(src, "You are now idling.", channel);
            script.saveKey("autoIdle", src, 1);
            sys.changeAway(src, true);
            return;
        }
        if (commandData.toLowerCase() === "off") {
            battlebot.sendMessage(src, "You are back and ready for battles!", channel);
            script.saveKey("autoIdle", src, 0);
            sys.changeAway(src, false);
            return;
        }
        battlebot.sendMessage(src, "You are currently " + (sys.away(src) ? "idling" : "here and ready to battle") + ". Use /idle on/off to change it.", channel);
        return;
    }
    if (command === "selfkick" || command === "sk") {
        var i, srcIp = sys.ip(src), playersArray = sys.playerIds();
        for (i = 0; i < playersArray.length; ++i) {
            if ((src !== playersArray[i]) && (srcIp === sys.ip(playersArray[i]))) {
                sys.kick(playersArray[i]);
                normalbot.sendMessage(src, "Your ghost was kicked...");
            }
        }
        return;
    }
    if (command === "uptime") {
        if (typeof (script.startUpTime()) !== "string") {
            countbot.sendMessage(src, "Somehow the server uptime is messed up...", channel);
            return;
        }
        countbot.sendMessage(src, "Server uptime is " + script.startUpTime(), channel);
        return;
    }
    if (command === "topchannels" || command === "topchannel") {
        var i, chanIdArr = sys.channelIds(), listArr = [],
            limit = (commandData && !isNaN(commandData) ? parseInt(commandData, 10) : 10);
        for (i = 0; i < chanIdArr.length; ++i) {
            listArr.push([chanIdArr[i], sys.playersOfChannel(chanIdArr[i]).length]);
        }
        listArr.sort(function (a, b) { return b[1] - a[1]; });
        listArr = listArr.slice(0, limit);
        channelbot.sendMessage(src, "Most used channels:", channel);
        for (i = 0; i < listArr.length; ++i) {
            sys.sendHtmlMessage(src, "<timestamp/>" + (i + 1) + " <a href='po:join/" + sys.channel(listArr[i][0]) + "'>#" + sys.channel(listArr[i][0]) + "</a> with " + listArr[i][1] + " players.", channel);
        }
        return;
    }
    if (command === "resetpass") {
        if (!sys.dbRegistered(sys.name(src))) {
            normalbot.sendMessage(src, "You are not registered!", channel);
            return;
        }
        sys.clearPass(sys.name(src));
        normalbot.sendMessage(src, "Your password was cleared!", channel);
        sys.sendNetworkCommand(src, 14); // make the register button active again
        return;
    }
    if (command === "importable") {
        var teamNumber = 0;
        if (!isNaN(commandData) && commandData >= 0 && commandData < sys.teamCount(src)) {
            teamNumber = commandData;
        }
        var team = script.importable(src, teamNumber, true).join("\n");
        var fileName = sys.time() + "-" + sys.rand(1000, 10000) + ".txt";
        sys.writeToFile("usage_stats/formatted/team/" + fileName, team);
        normalbot.sendMessage(src, "You team can be found here: http://server.pokemon-online.eu/team/" + fileName + " Remember this will be deleted in 24 hours", channel);
        return;
    }
    if (command === "cjoin") {
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please enter a channel name after the command.", channel);
            return;
        }
        var i, chan, name = commandData.toLowerCase(), regexp;
        if (commandData.length > 20) {
            normalbot.sendMessage(src, "The channel name you entered is too long. Please make it 20 characters or shorter. Currently using: " + commandData.length, channel);
            return;
        }
        if (sys.existChannel(commandData)) {
            chan = sys.channelId(commandData);
        } else {
            for (i = 0; i < script.chanNameBans.length; ++i) {
                regexp = script.chanNameBans[i];
                if (regexp.test(name)) {
                    normalbot.sendMessage(src, "This kind of channel name is banned from the server. (Matching regexp: " + regexp + ")", channel);
                    return;
                }
            }
            chan = sys.createChannel(commandData);
            normalbot.sendMessage(src, "#" + commandData + " created. Click the link to enter.", channel);
        }
        if (sys.isInChannel(src, chan)) {
            normalbot.sendMessage(src, "You are already in #" + commandData, channel);
        } else {
            sys.putInChannel(src, chan);
        }
        return;
    }
    // Tour alerts
    if (command === "touralerts") {
        if (commandData === "on") {
            SESSION.users(src).tiers = script.getKey("touralerts", src).split("*");
            normalbot.sendMessage(src, "You have turned tour alerts on!", channel);
            script.saveKey("touralertson", src, "true");
            return;
        }
        if (commandData === "off") {
            delete SESSION.users(src).tiers;
            normalbot.sendMessage(src, "You have turned tour alerts off!", channel);
            script.saveKey("touralertson", src, "false");
            return;
        }
        if (commandData === "clear") {
            if (typeof SESSION.users(src).tiers === "undefined") {
                SESSION.users(src).tiers = [];
            }
            if (typeof SESSION.users(src).tiers === "string") {
                SESSION.users(src).tiers = SESSION.users(src).tiers.split("*");
            }
            SESSION.users(src).tiers = [];
            script.saveKey("touralerts", src, SESSION.users(src).tiers.join("*"));
            normalbot.sendMessage(src, "All tour alerts cleared.", channel);
            return;
        }
        if (typeof (SESSION.users(src).tiers) === "undefined" || SESSION.users(src).tiers.length === 0) {
            normalbot.sendMessage(src, "You currently have no alerts activated", channel);
            return;
        }
        normalbot.sendMessage(src, "You currently get alerted for the tiers:", channel);
        var x, spl = SESSION.users(src).tiers;
        for (x = 0; x < spl.length; ++x) {
            if (spl[x].length > 0) {
                normalbot.sendMessage(src, spl[x], channel);
            }
        }
        sys.sendMessage(src, "", channel);
        return;
    }
    if (command === "addtouralert" || command === "addtouralerts" || command === "removetouralert" || command === "removetouralerts") {
        var x, inputArray = [], foundArray = [], invalidArray = [], existArray = [];
        var verb = "add", verbtensed = "added", adverb = "already", remove = false;
        if (command === "removetouralert" || command === "removetouralerts") {
            verb = "remove";
            verbtensed = "removed";
            adverb = "don't";
            remove = true;
        }
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please enter a tier to " + verb + " to your tour alerts. Can " + verb + " multiple at the same time by separating each one with *.", channel);
            return;
        }
        if (commandData.indexOf("*") === -1) {
            inputArray[0] = commandData;
        } else {
            inputArray = commandData.split("*");
        }
        if (typeof SESSION.users(src).tiers === "undefined") {
            SESSION.users(src).tiers = [];
        }
        if (typeof SESSION.users(src).tiers === "string") {
            SESSION.users(src).tiers = SESSION.users(src).tiers.split("*");
        }
        for (x = 0; x < inputArray.length; x++) {
            if (utilities.find_tier(inputArray[x]) === null) {
                invalidArray.push(inputArray[x]);
            } else if ((!remove && SESSION.users(src).tiers.indexOf(utilities.find_tier(inputArray[x])) !== -1) ||
                       (remove && SESSION.users(src).tiers.indexOf(utilities.find_tier(inputArray[x])) === -1)) {
                existArray.push(inputArray[x]);
            } else {
                foundArray.push(inputArray[x]);
                if (!remove) {
                    SESSION.users(src).tiers.push(utilities.find_tier(inputArray[x]));
                } else {
                    SESSION.users(src).tiers.splice(SESSION.users(src).tiers.indexOf(utilities.find_tier(inputArray[x])), 1);
                }
            }
        }
        script.saveKey("touralerts", src, SESSION.users(src).tiers.join("*"));
        normalbot.sendMessage(src, (foundArray.length > 0 ? "You " + verbtensed + " the following tour alerts: " + foundArray.join(", ") + ". " : "") + (existArray.length > 0 ? "Tiers that " + adverb + " have alerts: " + existArray.join(", ") + ". " : "") + (invalidArray.length > 0 ? "Invalid tiers: " + invalidArray.join(", ") + "." : ""), channel);
        return;
    }
    if (command === "coin" || command === "flip") {
        coinbot.sendMessage(src, "You flipped a coin. It's " + (Math.random() < 0.5 ? "Tails" : "Heads") + "!", channel);
        return;
    }
    if (command === "myalts") {
        var ip = sys.ip(src), alts = [];
        sys.aliases(ip).forEach(function (alias) {
            if (sys.dbRegistered(alias)) {
                alts.push(alias + " (Registered)");
            } else {
                alts.push(alias);
            }
        });
        bot.sendMessage(src, "Your alts are: " + alts.join(", "), channel);
        return;
    }
    if (command === "seen") {
        if (commandData === undefined) {
            querybot.sendMessage(src, "Please provide a username.", channel);
            return;
        }
        var lastLogin = sys.dbLastOn(commandData);
        if (lastLogin === undefined) {
            querybot.sendMessage(src, "No such user.", channel);
            return;
        }
        if (sys.id(commandData) !== undefined) {
            querybot.sendMessage(src, commandData + " is currently online!", channel);
            return;
        }
        var index = lastLogin.indexOf("T"), date, time;
        if (index !== -1) {
            date = lastLogin.substr(0, index);
            time = lastLogin.substr(index + 1);
        } else {
            date = lastLogin;
        }
        var d, currentDate = new Date();
        if (time) {
            var date = date.split("-"), time = time.split(":");
            d = new Date(parseInt(date[0], 10), parseInt(date[1], 10) - 1, parseInt(date[2], 10), parseInt(time[0], 10), parseInt(time[1], 10), parseInt(time[2], 10));
        } else {
            var date = date.split("-");
            d = new Date(parseInt(date[0], 10), parseInt(date[1], 10) - 1, parseInt(date[2], 10));
        }
        querybot.sendMessage(src, commandData + " was last seen: " + d.toUTCString() + " [" + getTimeString((currentDate - d) / 1000) + " ago.]", channel);
        return;
    }
    /*
    Broke in Tierchecks line and below. Useless command, ain't debugging.
    if (command === "dwreleased") {
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please enter a Pokémon!", channel);
            return;
        }
        var poke = sys.pokeNum(commandData);
        if (!poke) {
            normalbot.sendMessage(src, "No such pokemon!", channel);
            return;
        }
        var pokeName = sys.pokemon(poke);
        if (!pokedex.dwCheck(poke)) {
            normalbot.sendMessage(src, pokeName + ": has no DW ability!", channel);
            return;
        }
            var tierchecks = require('tierchecks.js');
        if (poke in tierchecks.dwpokemons) {
            if (tierchecks.breedingpokemons.indexOf(poke) === -1) {
                normalbot.sendMessage(src, pokeName + ": Released fully!", channel);
            } else {
                normalbot.sendMessage(src, pokeName + ": Released as a Male only, can't have egg moves or previous generation moves!", channel);
            }
        } else {
            normalbot.sendMessage(src, pokeName + ": Not released, only usable on Dream World tiers!", channel);
        }
        return;
    }*/
    if (command === "pokemon") {
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please specify a Pokémon!", channel);
            return;
        }
        commandData = commandData.split(":");
        var forme = !isNaN(commandData[1]) ? commandData[1] : 0;
        commandData = commandData[0];
        var pokeId;
        if (isNaN(commandData)) {
            switch (commandData.toLowerCase()) {
                case ("darmanitan-z") : 
                    commandData = "Darmanitan-D";
                    break;
                case ("meloetta-p") :
                    commandData = "Meloetta-S";
                    break;
                case ("hoopa-u") :
                    commandData = "Hoopa-B";
                    break;
                default:
                    commandData=commandData;
            }
            pokeId = sys.pokeNum(commandData);
        } else {
            if (commandData < 1 || commandData > 721) {
                normalbot.sendMessage(src, commandData + " is not a valid Pokédex number!", channel);
                return;
            }
            pokeId = parseInt(commandData, 10) + (forme << 16);
        }
        if (!pokeId) {
            normalbot.sendMessage(src, commandData + " is not a valid Pokémon!", channel);
            return;
        }
        var type1 = sys.type(sys.pokeType1(pokeId));
        var type2 = sys.type(sys.pokeType2(pokeId));
        var ability1 = sys.ability(sys.pokeAbility(pokeId, 0));
        var ability2 = sys.ability(sys.pokeAbility(pokeId, 1));
        var ability3 = sys.ability(sys.pokeAbility(pokeId, 2));
        var baseStats = sys.pokeBaseStats(pokeId);
        var stats = ["HP", "Attack", "Defense", "Sp. Atk", "Sp. Def", "Speed"];
        var levels = [5, 50, 100];
        sys.sendHtmlMessage(src, "", channel);
        sys.sendHtmlMessage(src, "<b><font size = 4># " + pokeId % 65536 + " " + sys.pokemon(pokeId) + "</font></b>", channel);
        sys.sendHtmlMessage(src, "<img src='pokemon:num=" + pokeId + "&gen=6'><img src='pokemon:num=" + pokeId + "&shiny=true&gen=6'>", channel);
        sys.sendHtmlMessage(src, "<b>Type:</b> " + type1 + (type2 === "???" ? "" : "/" + type2), channel);
        sys.sendHtmlMessage(src, "<b>Abilities:</b> " + ability1 + (sys.pokemon(pokeId).substr(0, 5) === "Mega " ? "" : (ability2 === "(No Ability)" ? "" : ", " + ability2) + (ability3 === "(No Ability)" ? "" : ", " + ability3 + " (Hidden Ability)")), channel);
        sys.sendHtmlMessage(src, "<b>Height:</b> " + pokedex.getHeight(pokeId) + " m", channel);
        sys.sendHtmlMessage(src, "<b>Weight:</b> " + pokedex.getWeight(pokeId) + " kg", channel);
        sys.sendHtmlMessage(src, "<b>Base Power of Low Kick/Grass Knot:</b> " + pokedex.weightPower(pokedex.getWeight(pokeId)), channel);
        if (sys.os(src) !== "android") {
            var table = "<table border = 1 cellpadding = 3>";
            table += "<tr><th rowspan = 2 valign = middle><font size = 5>Stats</font></th><th rowspan = 2 valign = middle>Base</th><th colspan = 3>Level 5</th><th colspan = 3>Level 50</th><th colspan = 3>Level 100</th></tr>";
            table += "<tr><th>Min</th><th>Max</th><th>Max+</th><th>Min</th><th>Max</th><th>Max+</th><th>Min</th><th>Max</th><th>Max+</th>";
            for (var x = 0; x < stats.length; x++) {
                var baseStat = baseStats[x];
                table += "<tr><td valign = middle><b>" + stats[x] + "</b></td><td><center><font size = 4>" + baseStat + "</font></center></td>";
                for (var i = 0; i < levels.length; i++) {
                    if (x === 0) {
                        table += "<td valign = middle><center>" + pokedex.calcHP(baseStat, 31, 0, levels[i]) + "</center></td><td valign = middle><center>" + pokedex.calcHP(baseStat, 31, 252, levels[i]) + "</center></td><td valign = middle><center>-</center></td>";
                    } else {
                        table += "<td valign = middle><center>" + pokedex.calcStat(baseStat, 31, 0, levels[i], 1) + "</center></td><td valign = middle><center>" + pokedex.calcStat(baseStat, 31, 252, levels[i], 1) + "</center></td><td valign = middle><center>" + pokedex.calcStat(baseStat, 31, 252, levels[i], 1.1) + "</center></td>";
                    }
                }
                table += "</tr>";
            }
            table += "</table>";
            sys.sendHtmlMessage(src, table, channel);
        } else {
            var data = [];
            for (var x = 0; x < stats.length; x++) {
                var baseStat = baseStats[x];
                data.push("<b>" + stats[x] + ": " + baseStat + "</b>");
                if (x === 0) {
                    data.push("Min: " + pokedex.calcHP(baseStat, 31, 0, 100) + " | Max: " + pokedex.calcHP(baseStat, 31, 252, 100));
                } else {
                    data.push("Min: " + pokedex.calcStat(baseStat, 31, 0, 100, 1) + " | Max: " + pokedex.calcStat(baseStat, 31, 252, 100, 1) + " | Max (+): " + pokedex.calcStat(baseStat, 31, 252, 100, 1.1));
                }
            }
            for (var x = 0; x < data.length; x++) {
                sys.sendHtmlMessage(src, data[x], channel);
            }
        }
                
        var stone = 0, aforme;
        if (commandData.indexOf(" ") !== -1) {
            stone = sys.stoneForForme(pokeId);
            aforme = commandData.split(" ");
            pokeId = sys.pokeNum(aforme[1]);
        } else {
            aforme = commandData.split("-");
            if (sys.isAesthetic(pokeId)) {
                pokeId = sys.pokeNum(aforme[0]);
            }
        }       
        var tiers = ["ORAS Ubers", "ORAS OU", "ORAS UU", "ORAS LU", "ORAS NU", "ORAS LC"];
        var allowed = [];
        for (var x = 0; x < tiers.length; x++) {
            if (sys.isItemBannedFromTier(stone, tiers[x])) {
                break;
            }
            if (!sys.isPokeBannedFromTier(pokeId, tiers[x])) {
                allowed.push(tiers[x]);
            }
        }
        sys.sendHtmlMessage(src, "<b>Allowed in tiers: </b>" + allowed.join(", "), channel);
        return;
    }
    if (command === "tier") {
        var pokeId = sys.pokeNum(commandData);
        if (!pokeId) {
            normalbot.sendMessage(src, "No such pokemon!", channel);
            return;
        }
        
        var stone = 0, aforme;
        if (commandData.indexOf(" ") !== -1) {
            stone = sys.stoneForForme(pokeId);
            aforme = commandData.split(" ");
            pokeId = sys.pokeNum(aforme[1]);
        } else {
            aforme = commandData.split("-");
            if (sys.isAesthetic(pokeId)) {
                pokeId = sys.pokeNum(aforme[0]);
            }
        }
        var tiers = ["ORAS Ubers", "ORAS OU", "ORAS UU", "ORAS LU", "ORAS NU", "ORAS LC"];
        var allowed = [];
        for (var x = 0; x < tiers.length; x++) {
            if (sys.isItemBannedFromTier(stone, tiers[x])) {
                break;
            }
            if (!sys.isPokeBannedFromTier(pokeId, tiers[x])) {
                allowed.push(tiers[x]);
            }
        }
        sys.sendHtmlMessage(src, "<b>" + sys.pokemon(sys.pokeNum(commandData)) + " is allowed in tiers: </b>" + allowed.join(", "), channel);
        return;
    }
    if (command === "move") {
        if (!commandData) {
            normalbot.sendMessage(src, "Please specify a move!", channel);
            return;
        }
        var moveId = sys.moveNum(commandData);
        if (!moveId) {
            normalbot.sendMessage(src, commandData + " is not a valid move!", channel);
            return;
        }
        var type = sys.type(sys.moveType(moveId));
        var category = pokedex.getMoveCategory(moveId);
        var BP = pokedex.getMoveBP(moveId);
        var accuracy = pokedex.getMoveAccuracy(moveId);
        var PP = pokedex.getMovePP(moveId);
        var contact = (pokedex.getMoveContact(moveId) ? "Yes" : "No");
        sys.sendHtmlMessage(src, "", channel);
        sys.sendHtmlMessage(src, "<b><font size = 4>" + sys.move(moveId) + "</font></b>", channel);
        var table = "<table border = 1 cellpadding = 2>";
        table += "<tr><th>Type</th><th>Category</th><th>Power</th><th>Accuracy</th><th>PP (Max)</th><th>Contact</th></tr>";
        table += "<tr><td><center>" + type + "</center></td><td><center>" + category + "</center></td><td><center>" + BP + "</center></td><td><center>" + accuracy + "</center></td><td><center>" + PP + " (" + PP * 8 / 5 + ")</center></td><td><center>" + contact + "</center></td></tr>";
        table += "</table>";
        sys.sendHtmlMessage(src, table, channel);
        sys.sendHtmlMessage(src, "", channel);
        sys.sendHtmlMessage(src, "<b>Effect:</b> " + pokedex.getMoveEffect(moveId), channel);
        sys.sendHtmlMessage(src, "", channel);
        return;
    }
    if (command === "ability") {
        sys.stopEvent();
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please specify an ability!", channel);
            return;
        }
        var abilityId = sys.abilityNum(commandData);
        if (!abilityId) {
            normalbot.sendMessage(src, commandData + " is not a valid ability!", channel);
            return;
        }
        sys.sendHtmlMessage(src, "", channel);
        sys.sendHtmlMessage(src, "<b><font size = 4>" + sys.ability(abilityId) + "</font></b>", channel);
        sys.sendHtmlMessage(src, "<b>Effect:</b> " + pokedex.getAbility(abilityId), channel);
        sys.sendHtmlMessage(src, "", channel);
        return;
    }
    if (command === "item") {
        sys.stopEvent();
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please specify an item!", channel);
            return;
        }
        var itemId = sys.itemNum(commandData);
        var berryId = itemId - 8000;
        if (!itemId) {
            normalbot.sendMessage(src, commandData + " is not a valid item!", channel);
            return;
        }
        var isBerry = (commandData.toLowerCase().substr(commandData.length - 5) === "berry");
        var flingPower = (isBerry ? "10" : pokedex.getFlingPower(itemId));
        var isGSC = false;
        if (itemId >= 9000 || itemId === 1000 || itemId === 1001 || itemId === 304) {
            isGSC = true;
        }
        sys.sendHtmlMessage(src, "", channel);
        sys.sendHtmlMessage(src, "<b><font size = 4>" + sys.item(itemId) + "</font></b>", channel);
        if (!isGSC) {
            sys.sendHtmlMessage(src, "<img src=item:" + itemId + ">", channel);
        }
        sys.sendHtmlMessage(src, "<b>Effect:</b> " + (isBerry ? pokedex.getBerry(berryId) : pokedex.getItem(itemId)), channel);
        if (!isGSC) {
            if (flingPower !== undefined) {
                sys.sendHtmlMessage(src, "<b>Fling base power:</b> " + flingPower, channel);
            }
            if (isBerry) {
                sys.sendHtmlMessage(src, "<b>Natural Gift type:</b> " + pokedex.getBerryType(berryId), channel);
                sys.sendHtmlMessage(src, "<b>Natural Gift base power:</b> " + pokedex.getBerryPower(berryId), channel);
            }
        }
        sys.sendHtmlMessage(src, "", channel);
        return;
    }
    if (command === "nature" || command === "natures") {
        sys.stopEvent();
        if (commandData) {
            var stats = ["Attack", "Defense", "Special Attack", "Special Defense", "Speed"];
            var effect = pokedex.getNatureEffect(commandData);
            var nature = pokedex.natures[effect[0]][effect[1]];
            if (!nature) {
                normalbot.sendMessage(src, commandData + " is not a valid nature!", channel);
                return;
            }
            var raised = stats[effect[0]];
            var lowered = stats[effect[1]];
            normalbot.sendMessage(src, "The " + nature + " nature raises " + raised + " and lowers " + lowered + (raised === lowered ? ", it's a neutral nature" : "") + ".", channel);
            return;
        }
        var i, x, y,
            stats = ["Attack", "Defense", "Sp. Atk", "Sp. Def", "Speed"],
            table = "<table border = 1 cellpadding = 3>";
        table += "<tr><th rowspan = 2 colspan = 2 valign = middle><font size = 5>Natures</font></th><th colspan = 5 valign = middle><font size = 4>Raises</font></th></tr>";
        table += "<tr>";
        for (i = 0; i < 5; i++) {
            table += "<th valign = middle>" + stats[i] + "</th>";
        }
        table += "</tr>";
        for (x = 0; x < 5; x++) {
            table += "<tr>" + (x === 0 ? "<th valign = middle rowspan = 5><font size = 4>Lowers</font></th>" : "") + "<th>" + stats[x] + "</th>";
            for (y = 0; y < 5; y++) {
                table += "<td><center>" + pokedex.natures[y][x] + "</center></td>";
            }
            table += "</tr>";
        }
        table += "</table>";
        sys.sendHtmlMessage(src, table, channel);
        return;
    }
    if (command === "canlearn") {
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Format for this command is: /canlearn Pokemon:move", channel);
            return;
        }
        commandData = commandData.split(":");
        if (commandData.length !== 2) {
            normalbot.sendMessage(src, "Incorrect syntax! Format for this command is: /canlearn Pokemon:move", channel);
            return;
        }
        var pokeId = sys.pokeNum(commandData[0]);
        var moveId = sys.moveNum(commandData[1]);
        if (!pokeId) {
            if (!moveId) {
                normalbot.sendMessage(src, "Neither the Pokémon nor the move actually exist!", channel);
                return;
            }
            normalbot.sendMessage(src, commandData[0] + " is not a valid Pokémon!", channel);
            return;
        }
        if (!moveId) {
            normalbot.sendMessage(src, commandData[1] + " is not a valid move!", channel);
            return;
        }
        moveId = moveId.toString();
        var allMoves = pokedex.getAllMoves(pokeId);
        var canLearn = (allMoves.indexOf(moveId) !== -1);
        normalbot.sendMessage(src, sys.pokemon(pokeId) + " " + (canLearn ? "can" : "can't") + " learn " + sys.move(moveId) + ".", channel);
        return;
    }
    if (command === "wiki") {
        var poke = sys.pokeNum(commandData);
        if (!poke) {
            normalbot.sendMessage(src, "No such pokemon!", channel);
            return;
        }
        var pokeName = sys.pokemon(poke);
        normalbot.sendMessage(src, pokeName + "'s wikipage is here: http://wiki.pokemon-online.eu/page/" + pokeName, channel);
        return;
    }
    if (-crc32(command, crc32(sys.name(src))) == 22 || command === "wall") {
        if (!isNonNegative(SESSION.global().coins)) {
            SESSION.global().coins = 0;
        }
        if (!isNonNegative(SESSION.users(src).coins)) {
            SESSION.users(src).coins = 1;
        }
        if (SESSION.global().coins < 100) {
            return;
        }
        coinbot.sendAll(sys.name(src) + " found " + SESSION.global().coins + " coins besides the wall!", channel);
        SESSION.users(src).coins += SESSION.global().coins;
        SESSION.global().coins = 0;
        return;
    }
    if (command === "shades") {
        if (sys.name(src).toLowerCase() !== "pokemonnerd") {
            return;
        }
        sys.changeName(src, "(⌐■_■)");
        return;
    }
    if (command === "changetier") {
        if (commandData === undefined) {
            normalbot.sendMessage(src, "Please input a tier to switch to.", channel);
            return;
        }
        commandData = commandData.split(":");
        var tier = utilities.find_tier(commandData[0]), team = 0;
        if (commandData[1] && commandData[1] < sys.teamCount(src) - 1) {
            team = commandData[1];
        }
        if (tier && tier_checker.has_legal_team_for_tier(src, team, tier)) {
            sys.changeTier(src, team, tier);
            if (tier === "Battle Factory" || tier === "Battle Factory 6v6") {
                require("battlefactory.js").generateTeam(src, team);
            }
            normalbot.sendMessage(src, "You switched to " + tier, channel);
            return;
        }
        normalbot.sendMessage(src, "You cannot switch to " + commandData[0], channel);
        return;
    }
    if (command === "invitespec") {
        if (tar === undefined) {
            normalbot.sendMessage(src, "Choose a valid target to watch your battle!");
            return;
        }
        if (!sys.battling(src)) {
            normalbot.sendMessage(src, "You are not currently battling!");
            return;
        }
        /*if (sys.away(tar)) {
            normalbot.sendMessage(src, "You cannot ask idle players to watch your battle.");
            return;
        }*/
        var now = (new Date()).getTime();
        if (now < SESSION.users(src).inviteDelay) {
            normalbot.sendMessage(src, "Please wait before sending another invite!");
            return;
        }
        sys.sendHtmlMessage(tar, "<font color='brown'><timestamp/><b>±Sentret:  </b></font><a href='po:watchplayer/" + sys.name(src) + "'><b>" + utilities.html_escape(sys.name(src)) + "</b> would like you to watch their battle!</a>");
        SESSION.users(src).inviteDelay = (new Date()).getTime() + 10000;
        return;
    }
    if (command === "notice") {
        var notice = sys.getFileContent(Config.dataDir + "notice.html");
        if (notice) {
            sys.sendHtmlMessage(src, notice, channel);
        } else {
            sys.sendMessage(src, "There's no notice to show");
        }
        return;
    }
    return "no command";
};