Author Topic: Sockets / web-access to mud  (Read 2426 times)

Offline Atomic

  • BFF
  • ***
  • Posts: 115
  • To infinity and beyond!
    • View Profile
Sockets / web-access to mud
« on: February 16, 2007, 08:34:47 am »
Of course, non-intelligent as I am, I haven't found anything yet to communicate with my
mud from outside the mud-environment.

Optionally I'd like to retrieve info from my mud like

- fingerplans
- status of the mud (uptime, reboot, etc.)
- any form of tracking (kills, deaths, toplists of players/cash/stats)

Where (what files) should I start my quests for the sockets?
Any examples of 'external' mudcommunications are most welcome.
Always remember that the early bird gets the worm first, but the fi...*SNAP*...second mouse gets the cheese.

Offline detah

  • BFF
  • ***
  • Posts: 190
  • Ruler of 2D
    • View Profile

Offline cratylus

  • Your favorite and best
  • Administrator
  • ***
  • Posts: 1024
  • Cratylus@Dead Souls <ds> np
    • View Profile
    • About Cratylus
Re: Sockets / web-access to mud
« Reply #2 on: February 16, 2007, 12:39:36 pm »
The mud comes with a built in http server, as I'm sure you already know. The code is in
/secure/lib/net/http.c . In that directory you'll find other servers like ftp and rcp which
are designed around the INET_D control mechanism. This allows for easy control like:

mudconfig inet enable
mudconfig http enable

but makes reading the code difficult, because the INET_D calls the server daemon which in turn
loads the specific server object, and by the time you work out the relationships you may be
old and grumpy like me. Following callbacks between objects like that can hurt.

If reviewing the code for the built in web server doesn't help, take a look at the following
examples. They are simple servers with no inheritance to obstruct their study. They work just
with efuns and sefuns.

As with my previous examples, please don't expect a dtailed explanation. I can demonstrate,
but I can't teach.

Code: [Select]
/*
 * This is a simple echo server. It just spews out what the
 * client types in. To disconnect the client types: quit
 * If your mud port is 6666, this will be on 6667
*/

#include <network.h>
int port = query_host_port()+1;

void StartServer();

void create(){
    StartServer();
}

void StartServer(){
    int sockstat, listsock;

    listsock = socket_create(STREAM,"read_callback","close_callback");
    if(listsock < 0){
        debug("Couldn't create socket. errorcode: "+listsock);
        return;
    }

    sockstat = socket_bind(listsock,port);
    if(sockstat < 0){
        debug("Couldn't bind socket. errorcode: "+sockstat);
        return;
    }

    sockstat = socket_listen(listsock,"listen_callback");
    if(sockstat < 0){
        debug("Couldn't listen on socket. errorcode: "+sockstat);
        return;
    }

}

static void listen_callback(int fd){
    int sockstat = socket_accept(fd,"read_callback","write_callback");

    if(sockstat < 0){
        debug("Couldn't accept on socket. errorcode: "+sockstat);
        return;
    }

    debug("echo server: listening.");
}

static void close_callback(int fd){
    debug("I'm wanting to close fd"+fd+" now.");
}

static mixed read_callback(int fd, mixed data){
    int i;
    string tmp="";
    mixed tmp2;
    debug("fd is: "+fd);

    for(i=0;i<sizeof(data);i++){
        if(data[i] == 13) continue;
        tmp2 = sprintf("%c",data[i]);
        tmp += tmp2;
    }
    tmp2 = truncate(tmp,1);
    if(bufferp(data)) debug("data (buffer): "+identify(read_buffer(data)));
    else debug("data: "+identify(data));
    socket_write(fd, "I read: "+tmp);
    if(tmp2 == "quit"){
        debug("quitting");
        i = socket_close(fd);
        debug("i: "+i);
    }
    return i;
}

Code: [Select]
/*
 * This is a sample uptime server. All it does is tell you
 * how long the mud's been up, then disconnects the telnet
 * session. If your mud game port is 6666, this will be
 * on 6668.
*/

#include <network.h>
int port = query_host_port()+2;

void StartServer();
int SendUptime(int fd);

void create(){
    StartServer();
}

void StartServer(){
    int sockstat, listsock;

    listsock = socket_create(STREAM,"read_callback","close_callback");
    if(listsock < 0){
        debug("Couldn't create socket. errorcode: "+listsock);
        return;
    }

    sockstat = socket_bind(listsock,port);
    if(sockstat < 0){
        debug("Couldn't bind socket. errorcode: "+sockstat);
        return;
    }

    sockstat = socket_listen(listsock,"listen_callback");
    if(sockstat < 0){
        debug("Couldn't listen on socket. errorcode: "+sockstat);
        return;
    }

}

static void listen_callback(int fd){
    int sockstat = socket_accept(fd,"read_callback","write_callback");

    if(sockstat < 0){
        debug("Couldn't accept on socket. errorcode: "+sockstat);
        return;
    }

    debug("uptime server: listening.");
    SendUptime(sockstat);
}

static void close_callback(int fd){
    debug("I'm wanting to close fd"+fd+" now.");
}

static mixed read_callback(int fd, mixed data){
    debug("quitting. fd: "+fd+", "+identify(socket_status(fd)));
    debug(socket_close(fd));
    return 1;
}

int SendUptime(int fd){
    socket_write(fd, "\n"+mud_name()+" has been up "+time_elapsed(uptime())+"\n\n");
    debug("socket_close: "+socket_close(fd));
    return 1;
}

These work fine on ds2.3a10. They'll probably need to be in the
/secure dir hierarchy to work. /secure/lib/net/ is a good place for them.

-Crat