⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chat.cc

📁 Unix下的MUD客户端程序
💻 CC
📖 第 1 页 / 共 4 页
字号:
        if (!ok)            writeChat("No connections are waiting for your accept.\n");            } else if (!strcmp(name, "snoop")) {        if (!arg[0])            writeChat("Snoop whom?");        else {            ChatConnection *c = findConnection(arg);            if (!arg[0])                writeChat("No such connection as '%s'", arg);            else {                c->sendCommand(cmdSnoop, "");            }        }            } else if (!strcmp(name, "to")) {        char name[MAX_INPUT_BUF];        arg = one_argument(arg,name, false);                if (!name[0] || !arg[0])            writeChat("Chat what and to whom?");        else {            ChatConnection *c = findConnection(name);            if (!c)                writeChat("No such connection: %s", name);            else {                if (!strncasecmp(arg, "emote ", 6)) {                    arg += 6;                    c->sendTextPersonal(arg, true);                } else                    c->sendTextPersonal(arg, false);                            }        }            } else if (!strcmp(name, "all")) {        if (!arg[0])            writeChat ("Chat WHAT to all?");        else {            bool emote = false;            if (!strncasecmp(arg, "emote ", 6)) {                emote = true;                arg += 6;            }            const char *colored = sanitize(arg,strlen(arg), 1024);                        FOREACH(ChatConnection*,c,connections)                c->sendTextEverybody(arg, emote);                        if (!emote)                writeChatText("You chat to all: '%s%c%c'", colored, SET_COLOR, config->getOption(opt_chat_chatcolor));            else                writeChatText("[emote to all] %s %s%c%c.", ~CHAT_NAME, colored, SET_COLOR, config->getOption(opt_chat_chatcolor));        }            } else if (!strcmp(name, "icon")) {        if (access(arg, R_OK) != 0)            writeChat("Can't find %s: %m",arg);        else {            writeChat("chat.icon updated to %s and sent", arg);            FOREACH(ChatConnection*,c,connections)                c->sendIcon(arg);        }            } else if (!strcmp(name, "reject")) {        bool ok = false;                FOREACH(ChatConnection *, c, connections) {            const char *desc = c->shortDescription();            if (c->rejectConnection()) {                ok = true;                writeChat("Connection from %s rejected", desc);                break;            }        }                if (!ok)            output->printf("No connections are waiting for your accept.\n");            } else if (!strcmp(name, "afk")) {        is_afk = !is_afk;        if (is_afk)  {            if (strcmp(arg, "quiet"))                writeChat("You are now AFK");        }        else {            if (strcmp(arg,"quiet"))                writeChat("You are no longer AFK");        }        FOREACH(ChatConnection*,c,connections)            c->sendStatus();            } else if (!strcmp(name, "flags")) {        char name[MAX_INPUT_BUF];        arg = one_argument(arg, name, true);        if (!arg[0])            writeChat("Set flags to what?");        else {            ChatConnection * c = findConnection(name);            if (!c)                writeChat("No such connection as '%s'", name);            else {                int flags = c->getFlags();                const char *res = adjustFlags(arg, flags);                if (res)                    writeChat("Error setting flags: %s", res);                else {                    writeChat("Flags for %s set to %s", c->shortDescription(), flagString(flags, false));                    c->setFlags(flags);                }                            }        }    }    else        status->setf("Unknown chat command: chat.%s", name);}void ChatServerSocket::computeIPAddress() {    const char *addr = findIPAddress();    if (!addr) {        writeChat("System active, but could not determine IP address. Port %d", getLocalPort());        embed_interp->set("chatIP", "");    } else {        writeChat("System active. Listening on %s port %d", addr, getLocalPort());        ip = addr;        embed_interp->set("chatIP", addr);    }}void ChatServerSocket::handleSnooping(const char *data, int len) {    FOREACH(ChatConnection *,c,connections)        if (c->getFlags() & flagSnoopedBy)            c->sendCommand(cmdSnoopData,data,len);}void ChatServerSocket::create(int base_port) {    int port,res=0;    ChatServerSocket *s = new ChatServerSocket;        for (port = base_port; port < base_port+10; port++) {        res = s->bind(port);        if (res == EADDRINUSE)            continue;        else if (res == 0)            break;    }        if (res == EADDRINUSE)        writeChat("Cannot bind chat port, all ports %d to %d are in use", base_port, base_port+9);    else if (res != 0)        writeChat("Error ocurred during chat port bind: %s", strerror(res));    else { // OK        s->computeIPAddress();        embed_interp->set("chatPort", s->getLocalPort());        chatServerSocket = s;        return;    }        delete s;}ChatConnection::ChatConnection (int fd, struct sockaddr_in *remote) : Socket(fd,remote) {    state = invalid;    flags = 0;    inactive_since = 0;    pgpKey = NULL;    person_status = active;        if (remote) {        accepted = true;        connect_time = current_time;    }    else        accepted = false;}ChatConnection::~ChatConnection() {    chatServerSocket->connections.remove(this);    delete[] pgpKey;}void ChatConnection::idle() {    if (state == connecting && current_time >= timeout)        close ("connect timeout");    else if (state == requesting && current_time >= timeout)        close ("negotation timeout");}const char* ChatConnection::shortDescription() const {    return Sprintf("%s@%s", name.len() ? ~name : "?", !strcmp(getRemoteIP(), "0.0.0.0") ? "<none>" : getRemoteIP());}void ChatConnection::close(const char *reason) {    writeChat("Closing connection to %s (%s)", shortDescription(), reason);    delete this;}void ChatConnection::handleIncoming() {    if (CDEBUG) writeChat("Incoming connection from %s", shortDescription());    state = incoming_chatname;    // Now wait for the request    // @@ Handle connection spamming here}void ChatConnection::connectionEstablished() {    state = requesting;    timeout = current_time + 60;    ip = getRemoteIP();    if (CDEBUG) writeChat("Connected to %s, now negotating", shortDescription());    requestConnection();}void ChatConnection::connect (const char *hostname, int port, int _protocol) {    writeChat ("Trying to connect to %s port %d%s", hostname, port, _protocol == mudmaster ? " (mudmaster)" : "");    state = connecting;    int res;        if ((res = Socket::connect(hostname, port, true)) != 0) {        writeChat("Error connecting to %s: %s", hostname, res == ENOENT ? "No such host" : strerror(res));        delete this;    } else {        timeout = current_time + 60;        remote_port = port;    }    protocol = (Protocol)_protocol;}void ChatConnection::errorEncountered(int) {    writeChat("Error ocurred while talking to %s: %s", shortDescription(), getErrorText());    delete this;}const char* ChatConnection::longDescription(bool verbose) {    StaticBuffer buf;    char *s = buf;        s += sprintf(s, "%c%c%-12s ", protocol == zchat ? 'Z' : ' ', accepted ? '<' : '>', name.len() ? ~name : "<unknown>");        if (ip.len()) {        s += sprintf(s, " %16s %4d ", ~ip, remote_port);    } else {        s += sprintf(s, " %16s %4d ", getRemoteServerIP(), getRemoteServerPort());    }        if (verbose)        s += sprintf(s, "%-14.14s ", ~version);        if (verbose) {        if (person_status == afk  || person_status == inactive)            s += sprintf(s, person_status == afk ? "AFK:%-3d" : "Inc:%-3d", (current_time - inactive_since)/60);        else            s += sprintf(s,  person_status == inactive ? "inact" : "     ");    } else {        s += sprintf(s, "%c", person_status == afk ? 'A' : person_status == inactive ? 'I' : ' ' );    }    s += sprintf(s, "%s ", flagString(flags, true));    if (group.len())        s += sprintf(s, "[%s]", ~group);        if (state == invalid)        s += sprintf(s, verbose ? "INVALID STATE" : "????");    else if (state == connecting)        s += sprintf(s, verbose ? "Connecting (timeout: %lds)" : "C%.3d", timeout - current_time);    else if (state == requesting)        s += sprintf(s, verbose ? "Connected, requesting permission (timeout: %lds)" : "P%.3d", timeout-current_time);    else if (state == connected)        s += sprintf(s, verbose ? "Connected" : "    ");    else if (state == waiting_command_header)        s += sprintf(s, verbose ? "Waiting for %d more command header bytes" : "Cmd%d" , 4-command_header_received);    else if (state == waiting_command_data) {        if (verbose)            s += sprintf(s, "Waiting for %d more bytes of command %d", data_length, pending_command);        else            s += sprintf(s, "D%.3x", data_length);    }    else if (state == waiting_data)        s += sprintf(s, verbose ? "Waiting for old-style data" : "Data");    else if (state == incoming_chatname)        s += sprintf(s, verbose ? "Accepted, awaiting protocol/chatname" : "Acc1");    else if (state == incoming_address)        s += sprintf(s, verbose ? "Accepted, awaiting address/port" : "Acc2");    else if (state == awaiting_confirmation) {        if (verbose)            s += sprintf(s, "Waiting for your accept (%cchat.accept)", CMDCHAR);        else            s += sprintf(s, "Cnfr");    }    else {        s += sprintf(s, verbose ? "Unknown state: %d" : "I%d", state);    }        return buf;}void ChatConnection::inputReady() {    assert (state != invalid);try_again:    if (pendingInput() <= 0)        return;        // Two states require us to read some lines    if (state == incoming_chatname) {        const char *line = readLine();        if (line) {            char protocol_name[64], chat_name[64], chat_id[64];            if (!strncmp(line, "CHAT", strlen("CHAT"))) { // MudMaster chat protocol                protocol = mudmaster;                if (2 != sscanf(line, "%64[^:]:%64[^\n]", protocol_name, chat_name)) {                    close(Sprintf("Invalid MudMaster protocol line: \"%-.128s\"", line));                    return;                }                chat_id[0] = NUL;            } else if (!strncmp(line, "ZCHAT", strlen("ZCHAT"))) { // Zugg's extensions                protocol = zchat;                if (3 != sscanf(line, "%64[^:]:%64[^\t]\t%64[^\n]", protocol_name, chat_name, chat_id)) {                    close(Sprintf("Invalid ZCHAT protocol \"line: %-.128s\"", line));                    return;                }            } else {                close(Sprintf("Invalid protocol: : %-.128s", line));                return;            }                        name = chat_name;            id = chat_id;                        if (CDEBUG) writeChat("%s: uses protocol %s", shortDescription(), protocol_name);                        // Wait for hostname/port            state = incoming_address;            goto try_again;        }    } else if (state == incoming_address) {        const char *line;        char linebuf[1024];        // mudmaster doesn't seem to send a newline at the end of the address line.        if (protocol == mudmaster) {            int count = read(linebuf,sizeof(linebuf));            if (count <= 0)                return;                        linebuf[count] = NUL;            line = linebuf;        } else {            line = readLine();        }                if (line) {            char ip_address[128], port_number[128];            const char *port_start;            if (strlen(line) < 12 || strlen(line) > 63)                close(Sprintf("Line with IP address/port impossibly short or long: %-.128s", line));            else {                port_start = line+strlen(line) - 5; // grr, why this weirdness                strncpy(ip_address, line, port_start-line);                ip_address[port_start-line] = NUL;                                strcpy(port_number, port_start);                remote_port = atoi(port_number);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -