Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - quixadhal

Pages: [1] 2 3 4
1
Code Vault / urlbot extension to chat daemon.
« on: December 27, 2015, 06:28:46 AM »
Hey guys, with the help of Drakkos and Aidil, I finally got around to changing my MUD to use a built-in solution to populate my URL channel, instead of the tinyfugue triggers I'd been using.

This should serve as a handy example of how to use external programs with fluffos.  NOTE:  I don't redirect errors away to NULL or anything... you might want to or everyone will see error messages on your channel. :)

For those who don't know... a while back, I write a small perl script to go get information about URL's that get posted to various intermud channels.  Because I didn't have a way to do the kind of regexp matching on channel input I needed, I programmed some triggers in my client to handle it and splat the result out to a specific channel.

This worked pretty well, but required me to be logged in (not a problem), and would break on occasions when the mud output line wrapped or otherwise disrupted the pattern.  I was thinking of making an NPC to listen to and respond to the I3 traffic, but Dead Souls makes it obnoxiously hard to do this for "security" reasons.

So, the next best thing was to code it inside the chat daemon itself, where all messages have to go anyways.  Dead Souls ALSO tried to stop me here, but a one line fix removed that "security" feature. :)

So, here's the goodies.

Code: (mudos.cfg) [Select]
# The external programs we allow to be run.
external_cmd_1 : /home/bloodlines/bin/untiny.pl

Code: (/daemon/services/channel.c) [Select]
@@ -83,7 +83,7 @@ void eventReceiveChannelMessage(mixed array packet) {
     tn("eventReceiveChannelMessage: "+identify(packet),"green");

     if( file_name(previous_object()) != INTERMUD_D ) return;
-    if( packet[2] == mud_name() ) return;
+    if( packet[2] == mud_name() && packet[3] != "chat_d" ) return;
     if( !packet[2] || packet[2] == "" ) packet[2] = "BustedAssMUD";

     CHAT_D->eventSendChannel(packet[7] + "@" + packet[2], packet[6],

Code: (/secure/daemon/chat.c) [Select]
static private mapping url_callback_buffer = ([]);

void url_read_callback(int fd, mixed msg) {
    if(member_array(fd, keys(url_callback_buffer)) < 0) {
        url_callback_buffer[fd] = "";
    }
    url_callback_buffer[fd] += msg;
}

void url_write_callback(int fd) {
    // This should never happen.
}

void url_close_callback(int fd) {
    // Here, we should send off the result we got back.
    SERVICES_D->eventSendChannel("CHAT_D", "url", url_callback_buffer[fd], 0, "", "");
    map_delete(url_callback_buffer, fd);
}

int check_for_url(string channel, string msg) {
    mixed check_url;
    int fd;
    string check;
    string *patterns = ({
        "(https?://www.youtube.com/watch\?.*?v=[^&\?\.\ ]+)",
        "(https?://tinyurl.com/[^&\?\.\ ]+)",
        "(https?://bit.ly/[^&\?\.\ ]+)",
        "(https?://goo.gl/[^&\?\.\ ]+)",
        "(https?://mcaf.ee/[^&\?\.\ ]+)",
        "(https?://migre.me/[^&\?\.\ ]+)",
        "(https?://durl.me/[^&\?\.\ ]+)",
        "(https?://is.gd/[^&\?\.\ ]+)",
        "(https?://dailym.ai/[^&\?\.\ ]+)",
        "(https?://ebay.to/[^&\?\.\ ]+)",
        "(https?://youtu.be/[^&\?\.\ ]+)",
        "(https?://onforb.es/[^&\?\.\ ]+)",
        "(https?://imgur.com/[^&\>\.\ ]+)",
        "(https?://amzn.to/[^&\?\.\ ]+)",
    });

    if(!channel || channel == "" || channel == "url") {
        // tn("CHAT_D->check_for_url : channel " + channel, "red");
        return 0;
    }

    foreach( check in patterns ) {
        check_url = pcre_extract(msg, check);
        if(check_url && sizeof(check_url) > 0) {
            string command_string = check_url[0] + " " + channel;
            tn("CHAT_D->check_for_url : pattern " + check + " match " + command_string,"green");
            fd = external_start(1, command_string, "url_read_callback", "url_write_callback", "url_close_callback");
            return 1;
        }
    }
    return 0;
}

and your chat daemon likely differs from mine, but somewhere down there you'll see something like:

        eventChannelMsgToListeners(who, ch, msg, emote, target, targmsg);

after that, add:

        if (check_for_url(ch, msg)) {
            // debug stuff
        }

And last but not least, the perl script.

2
Code Vault / /etc/init.d scripts
« on: August 19, 2015, 02:23:20 AM »
Hey guys,

This hasn't been fully tested yet, but I figured I'd share it anyways.  One of the annoying facts of life for any MUD is that the machine it runs on has to reboot every so often.  When it does, it's often when you're not there due to a power outage.

UNIX systems, of course, have ways to automatically start things at boot time.  If you're on an older system that uses /etc/rc and /etc/rc.local, good for you!  You already know how to do stuff, and don't need this.  If you're running linux, almost every distro has switched to SYSV init by now, and a few have some new annoyance that's even worse.

If you have /etc/rc.d directories and /etc/init.d, this is for you.

We have three scripts here.  The main one is called bloodlines, because that's my MUD.  Rename it as you like, and edit a few things like the paths to fit your environment.  The second two are startup scripts for the driver and the addr_server, because I wanted to keep them isolated from each other.  You could probably just merge them into the main script, and I might do so later.

Code: (bloodlines) [Select]
#!/bin/sh
#
### BEGIN INIT INFO
# Provides:          bloodlines
# Required-Start:    $network $local_fs $remote_fs $syslog $named $time
# Required-Stop:     $network $local_fs $remote_fs $syslog $named $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: init-Script for FluffOS MUD driver
### END INIT INFO
#

USERNAME=bloodlines
APORT=4990
MUDDIR=/home/bloodlines
PATH=$MUDDIR/bin:/bin:/usr/bin:/sbin:/usr/sbin
CONFIG=$MUDDIR/bin/mudos.cfg
STARTDIR=$MUDDIR/bin
LOGFILE=`/bin/date "+$MUDDIR/bin/driver_log.%y%m%d-%H%M%S"`

DAEMON=$MUDDIR/bin/driver
PIDFILE=$MUDDIR/bin/driver.pid
SCRIPT=$MUDDIR/bin/start.driver

ADAEMON=$MUDDIR/bin/addr_server
APIDFILE=$MUDDIR/bin/addr_server.pid
ASCRIPT=$MUDDIR/bin/start.addr_server

test -x $DAEMON || exit 0
test -x $ADAEMON || exit 0

case "$1" in
    start)
        echo "Starting MUD Server: Bloodlines"
        /sbin/start-stop-daemon --start --quiet --chuid $USERNAME:users --chdir $STARTDIR --background --pidfile $PIDFILE --exec $ASCRIPT
        # Small delay to ensure it's alive
        sleep 2
        /sbin/start-stop-daemon --start --quiet --chuid $USERNAME:users --chdir $STARTDIR --background --pidfile $PIDFILE --exec $SCRIPT
        ;;
    stop)
        echo -n "Stopping MUD Server: Bloodlines, driver"
        if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name driver --user $USERNAME
        then
            PID=`cat $PIDFILE`
            start-stop-daemon --quiet --stop --signal INT --user $USERNAME --exec $DAEMON --pidfile $PIDFILE --name driver
            # Now we wait for it to die
            while kill -0 $PID 2>/dev/null; do sleep 1; done
            rm -f $PIDFILE
            echo "."
        else
            echo " not running.";
        fi
        echo -n "Stopping MUD Server: Bloodlines, addr_server"
        if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name driver --user $USERNAME
        then
            APID=`cat $APIDFILE`
            start-stop-daemon --quiet --stop --signal INT --user $USERNAME --exec $ADAEMON --pidfile $APIDFILE --name addr_server
            # Now we wait for it to die
            while kill -0 $APID 2>/dev/null; do sleep 1; done
            rm -f $APIDFILE
            echo "."
        else
            echo " not running.";
        fi
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    status)
        if [ ! -f $PIDFILE ]; then
            echo "No PID file, game may be down"
            ps auxww | grep addr_server | grep -v grep
            ps auxww | grep driver | grep -v grep
        else
            ps auxww | grep `cat $APIDFILE` | grep -v grep
            ps auxww | grep `cat $PIDFILE` | grep -v grep
        fi
        ;;
    *)
        echo "Usage: /etc/init.d/bloodlines {start|stop|restart|status}"
        exit 1
esac

exit 0

Code: (start.addr_server) [Select]
#!/bin/bash

USERNAME=bloodlines
APORT=4990
MUDDIR=/home/bloodlines
PATH=$MUDDIR/bin:/bin:/usr/bin:/sbin:/usr/sbin
CONFIG=$MUDDIR/bin/mudos.cfg
STARTDIR=$MUDDIR/bin
LOGFILE=`/bin/date "+$MUDDIR/bin/driver_log.%y%m%d-%H%M%S"`

DAEMON=$MUDDIR/bin/driver
PIDFILE=$MUDDIR/bin/driver.pid
SCRIPT=$MUDDIR/bin/start_driver

ADAEMON=$MUDDIR/bin/addr_server
APIDFILE=$MUDDIR/bin/addr_server.pid
ASCRIPT=$MUDDIR/bin/start_addr_server

test -x $DAEMON || exit 0
test -x $ADAEMON || exit 0

echo -n "    Starting addr_server..."
if start-stop-daemon --quiet --stop --signal 0 --pidfile $APIDFILE --name addr_server --user $username
then
    echo " already running!"
    exit 0
else
    /home/bloodlines/bin/addr_server $APORT >/dev/null 2>&1 &
    ASTAT=$?
    echo $! >/home/bloodlines/bin/addr_server.pid
    echo " done."
    exit $ASTAT
fi

Code: (start.driver) [Select]
#!/bin/bash

USERNAME=bloodlines
APORT=4990
MUDDIR=/home/bloodlines
PATH=$MUDDIR/bin:/bin:/usr/bin:/sbin:/usr/sbin
CONFIG=$MUDDIR/bin/mudos.cfg
STARTDIR=$MUDDIR/bin
LOGFILE=`/bin/date "+$MUDDIR/bin/driver_log.%y%m%d-%H%M%S"`

DAEMON=$MUDDIR/bin/driver
PIDFILE=$MUDDIR/bin/driver.pid
SCRIPT=$MUDDIR/bin/start_driver

ADAEMON=$MUDDIR/bin/addr_server
APIDFILE=$MUDDIR/bin/addr_server.pid
ASCRIPT=$MUDDIR/bin/start_addr_server

test -x $DAEMON || exit 0
test -x $ADAEMON || exit 0

echo -n "    Starting driver..."
if start-stop-daemon --quiet --stop --signal 0 --pidfile $APIDFILE --name addr_server --user $username
then
    if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name driver --user $username
    then
        echo " already running!"
        exit 0
    else
        /home/bloodlines/bin/driver $CONFIG >$LOGFILE 2>&1 &
        DSTAT=$?
        echo $! >/home/bloodlines/bin/driver.pid
        echo " done."
        exit $DSTAT
    fi
else
    echo " addr_server not running!"
    exit 0
fi

3
Code Vault / Repository fetch script
« on: November 25, 2014, 11:22:37 AM »
This is a nice little perl script that goes out and fetches a bunch of different MUD-related code repositories.
Feel free to add your own data, and if you let me know, I'll add it to my version too. :)

Code: [Select]
#!/usr/bin/perl -w

use strict;

my $repositories = {
    'dgd'       => {
        'dgd'                   => { 'type' => 'git', 'url' => 'git@github.com:dworkin/dgd' },
        'lpc-doc'               => { 'type' => 'git', 'url' => 'git@github.com:dworkin/lpc-doc.git' },
        'lpc-ext'               => { 'type' => 'git', 'url' => 'git@github.com:dworkin/lpc-ext' },
        'kernellib'             => { 'type' => 'git', 'url' => 'git@github.com:dworkin/kernellib.git' },
        'dgd-httpd'             => { 'type' => 'git', 'url' => 'git@github.com:dworkin/jorinde.git' },
        'gurbalib'              => { 'type' => 'git', 'url' => 'git@github.com:dworkin/gurbalib' },
        'kernellib-shentino'    => { 'type' => 'git', 'url' => 'git@github.com:shentino/kernellib.git' },
        'gurbalib-sirdude'      => { 'type' => 'git', 'url' => 'git@github.com:sirdude/gurbalib.git' },
        'cloud'                 => { 'type' => 'git', 'url' => 'git@github.com:dworkin/cloud-server.git' },
    },
    'fluffos'   => {
        'quix_fluffos'          => { 'type' => 'git', 'url' => 'git@github.com:quixadhal/fluffos.git' },
        'sunyc_fluffos'         => { 'type' => 'git', 'url' => 'git@github.com:fluffos/fluffos.git' },
        'ds'                    => { 'type' => 'git', 'url' => 'git@github.com:quixadhal/deadsouls.git' },
        'lima'                  => { 'type' => 'git', 'url' => 'git@github.com:quixadhal/lima.git' },
        'diku2ds'               => { 'type' => 'git', 'url' => 'git@github.com:LashMUD/DikuMud-to-Dead-Souls-Port.git' },
    },
    'ldmud'     => {
#        'ldmud-3.3'             => { 'type' => 'svn', 'url' => 'svn://svn.bearnip.com/ldmud/3.3/trunk' },
        'ldmud'                 => { 'type' => 'git', 'url' => 'git@github.com:ldmud/ldmud.git' },
        'ldlib'                 => { 'type' => 'git', 'url' => 'git@github.com:ldmud/ldlib.git' },
        'ldmud-extensions'      => { 'type' => 'git', 'url' => 'git@github.com:ldmud/ldmud-extensions.git' },
        'proftpd-mod_mud'       => { 'type' => 'git', 'url' => 'git@github.com:ldmud/proftpd-mod_mud.git' },
#        'proftpd-cvs'           => { 'type' => 'cvs', 'url' => ':pserver:anonymous@proftp.cvs.sourceforge.net:2401/cvsroot/proftp', 'co' => 'proftpd' },
#        'proftpd-userguide-cvs' => { 'type' => 'cvs', 'url' => ':pserver:anonymous@proftp.cvs.sourceforge.net:2401/cvsroot/proftp', 'co' => 'Userguide' },
    },
    'diku'      => {
        'quix_smaug'            => { 'type' => 'git', 'url' => 'git@github.com:quixadhal/SmaugFUSS.git' },
        'smaug'                 => { 'type' => 'git', 'url' => 'git@github.com:InfiniteAxis/SmaugFUSS.git' },
        'samson_smaug'          => { 'type' => 'git', 'url' => 'git@github.com:Arthmoor/SmaugFUSS.git' },
        'ackfuss'               => { 'type' => 'git', 'url' => 'git@github.com:Kline-/ackfuss.git' },
#        'roh'                   => { 'type' => 'svn', 'url' => 'http://svn.rohonline.net/roh' },
        'brokendreams'          => { 'type' => 'git', 'url' => 'git@github.com:syn2083/BrokenDreams-RoT-2014.git' },
        'wileymud'              => { 'type' => 'git', 'url' => 'git@github.com:quixadhal/WileyMUD.git' },
        'afkmud'                => { 'type' => 'git', 'url' => 'git@github.com:Arthmoor/AFKMud.git' },
    },
    'other'      => {
        'plaintext'             => { 'type' => 'git', 'url' => 'git@github.com:arendjr/PlainText.git' },
        'mudcore'               => { 'type' => 'git', 'url' => 'git@github.com:endgame/MudCore.git' },
        'pyom'                  => { 'type' => 'git', 'url' => 'git@bitbucket.org:mudbytes/pyom.git' },
        'miniboa'               => { 'type' => 'git', 'url' => 'git@github.com:marlboromoo/miniboa.git' },
        'havoc'                 => { 'type' => 'git', 'url' => 'git@github.com:plamzi/Havoc.git' },
    },
    'clients'      => {
        'lyntin'                => { 'type' => 'cvs', 'url' => ':pserver:anonymous@lyntin.cvs.sourceforge.net:/cvsroot/lyntin', 'co' => 'lyntin' },
        'tf-utf8'               => { 'type' => 'git', 'url' => 'git@github.com:kruton/tinyfugue.git' },
        'putty-tray'            => { 'type' => 'git', 'url' => 'git@github.com:FauxFaux/PuTTYTray.git' },
    },
};

sub fetch_repository {
    my $style = shift or return 0;
    my $repo = shift or return 0;
    my $data = shift or return 0;
    my $type = $data->{'type'} or return 0;
    my $url = $data->{'url'} or return 0;

    mkdir $style if ! -d $style;
    chdir $style;
    if( $type eq 'git' ) {
        if( -d $repo ) {
            chdir $repo;
            print "==> Updating $style/$repo from $url\n";
            system("git pull");
            chdir '..';
        } else {
            print "==> Fetching $style/$repo from $url\n";
            system("git clone $url $repo");
        }
    } elsif( $type eq 'svn' ) {
        if( -d $repo ) {
            chdir $repo;
            print "==> Updating $style/$repo from $url\n";
            system("svn update");
            chdir '..';
        } else {
            print "==> Fetching $style/$repo from $url\n";
            system("svn checkout $url $repo");
        }
    } elsif( $type eq 'cvs' ) {
        if( -d $repo ) {
            chdir $repo;
            print "==> Updating $style/$repo from $url\n";
            system("cvs update");
            chdir '..';
        } else {
            my $co = $data->{'co'};
            print "==> Fetching $style/$repo from $url\n";
            system("cvs -d $url -z3 co $co");
            rename $co, $repo;
        }
    }
    chdir '..';
    print "\n";
    return 1;
}

foreach my $style (sort keys %$repositories) {
    foreach my $repo (sort keys %{ $repositories->{$style} }) {
        fetch_repository($style, $repo, $repositories->{$style}->{$repo});
    }
}

4
Dead Souls Support / No New Players
« on: September 26, 2014, 11:33:49 AM »
This prevents the creation of new characters.

Code: [Select]
diff --git a/lib/secure/lib/connect.c b/lib/secure/lib/connect.c
index 9983c30..a3fde2c 100644
--- a/lib/secure/lib/connect.c
+++ b/lib/secure/lib/connect.c
@@ -219,6 +219,12 @@ static void InputName(string namen, string kill_me) {
         }
     }
     if( !user_exists(Name) ) {
+        if ( !ALLOW_NEW_PLAYERS ) {
+            receive("\nSorry, new players are not allowed at this time.\n");
+            flush_messages();
+            Destruct();
+            return;
+        }
         eventCreatePlayer(name);
         return;
     }

Code: [Select]
diff --git a/lib/secure/include/config.h b/lib/secure/include/config.h
index b5fca26..674faa9 100644
--- a/lib/secure/include/config.h
+++ b/lib/secure/include/config.h
@@ -8,7 +8,7 @@
 #define LOCAL_NEWS_PREFIX        "nm"
 #define MUD_IS_LOCKED            0
 #define AUTO_WIZ                 0
-#define RESTRICTED_INTERMUD      0
+#define RESTRICTED_INTERMUD      1
 #define DISABLE_INTERMUD         0
 #define DISABLE_IMC2             1
 #define MINUTES_REBOOT_WARNING   20
@@ -92,6 +92,7 @@
 #define MINIMAP                  1
 #define WIZMAP                   1
 #define GRID                     1
+#define ALLOW_NEW_PLAYERS        0
 #define ENABLE_INSTANCES         0
 #define CED_DISABLED             1
 #define CHANNEL_PIPES            1

Code: [Select]
diff --git a/lib/secure/cmds/admins/mudconfig.c b/lib/secure/cmds/admins/mudconfig.c
index 3a59d09..81b43da 100755
--- a/lib/secure/cmds/admins/mudconfig.c
+++ b/lib/secure/cmds/admins/mudconfig.c
@@ -27,7 +27,7 @@ string array modals = antimodals + ({ "channelpipes", "fastcombat",
         "compat", "exitsbare", "nmexits", "grid", "minimap", "wizmap",
         "cgi", "dirlist", "creweb", "selectclass", "severable",
         "retain", "defaultparse", "disablereboot", "loglocal", "logremote",
-        "questrequired", "autoadvance" });
+        "questrequired", "autoadvance", "newplayers" });
 string array inet_services = ({ "oob", "hftp", "ftp", "http", "rcp", "inet" });

 static int NotImplemented(string which);
@@ -480,7 +480,11 @@ static int ProcessOther(string which, string arg){
                 return 1;
         }
     if(which == "PING_INTERVAL") reload (PING_D,1,1);
-        return 1;
+    if(which == "ALLOW_NEW_PLAYERS") {
+        reload ("/secure/cmds/admins/mudconfig.c",1,1);
+        reload ("/secure/lib/connect.c",1,1);
+    }
+    return 1;
 }

 static int ProcessString(string which, string arg){
@@ -574,6 +578,7 @@ static int ProcessModal(string which, string arg){
                 case "minimap" : which = "MINIMAP";break;
                 case "wizmap" : which = "WIZMAP";break;
                 case "grid" : which = "GRID";break;
+                case "newplayers" : which = "ALLOW_NEW_PLAYERS";break;
             default : break;
         }
     foreach(string element in config){
@@ -1000,6 +1005,7 @@ string MyGetHelp(){
             "\nmudconfig minimap         [" + ( MINIMAP == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( MINIMAP == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]  (Whether players get a minimap
             "\nmudconfig wizmap          [" + ( WIZMAP == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( WIZMAP == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]  (Whether cres get an area map.)"
             "\nmudconfig grid            [" + ( GRID == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( GRID == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]  (Enable or disable the room grid sys
+            "\nmudconfig newplayers      [" + ( ALLOW_NEW_PLAYERS == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( ALLOW_NEW_PLAYERS == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]  (Enable or
             "\nmudconfig compat          [" + ( COMPAT_MODE == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( COMPAT_MODE == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]"
             "\nmudconfig retain          [" + ( RETAIN_ON_QUIT == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( RETAIN_ON_QUIT == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]  (Whether items a
             "\nmudconfig defaultparse    [" + ( DEFAULT_PARSING == 1 ? "%^B_GREEN%^" : "" ) + " yes %^RESET%^|" + ( DEFAULT_PARSING == 0 ? "%^B_RED%^" : "" ) + " no %^RESET%^]"
@@ -1118,6 +1124,7 @@ string GetHelp(){
         output += ({ sprintf( "  %-=15s %-=*s %=36s", "localtime",      width-2-15-1+(LOCAL_TIME ? ena_width : dis_width)-1-36-2,         (LOCAL_TIME ? enabled : disabled),         "use local

         output += ({ sprintf( "%%^BOLD%%^%%^CYAN%%^%|*'='s%%^RESET%%^", width, "[ CHARACTER OPTIONS ]") });
+        output += ({ sprintf( "  %-=15s %-=*s %=36s", "newplayers",     width-2-15-1+(ALLOW_NEW_PLAYERS ? ena_width : dis_width)-1-36-2,  (ALLOW_NEW_PLAYERS ? enabled : disabled),  "allow new
         output += ({ sprintf( "  %-=15s %-=*s %=36s", "autowiz",        width-2-15-1+(AUTO_WIZ ? ena_width : dis_width)-1-36-2,           (AUTO_WIZ ? enabled : disabled),           "all users
         output += ({ sprintf( "  %-=15s %-=*s %=36s", "justhumans",     width-2-15-1+(HUMANS_ONLY ? ena_width : dis_width)-1-36-2,        (HUMANS_ONLY ? enabled : disabled),        "restrict
         output += ({ sprintf( "  %-=15s %-=*s %=36s", "justenglish",    width-2-15-1+(ENGLISH_ONLY ? ena_width : dis_width)-1-36-2,       (ENGLISH_ONLY ? enabled : disabled),       "restrict

5
Dead Souls Support / I3/IMC tell loophole fix.
« on: September 19, 2014, 09:02:23 PM »
So, here's a small fix to make I3 tells (and IMC2 tells) use the existing intermud restriction settings.  If you have your mud set to restircted, you have to explicitly add characters to the list of people allowed to use I3 channels, which for most cases is a small subset of immortals and trusted players.

/daemon/services/tell.c
Code: [Select]
void eventSendTell(string who, string where, string msg) {
    string pl, plc, ret;

    pl = this_player(1)->GetName();
    plc = this_player(1)->GetCapName();
    where = INTERMUD_D->GetMudName(where);

    if(RESTRICTED_INTERMUD) {
        if(!imud_privp(lower_case(pl))) {
            this_player(1)->eventPrint("You lack the power to send tells to other worlds.", MSG_CONV);
            return;
        }
    }

    INTERMUD_D->eventWrite(({ "tell", 5, mud_name(), pl, where,
                convert_name(who), plc, msg }));
    ret = "%^BOLD%^RED%^You tell " + capitalize(who) +
        "@" +  where + ":%^RESET%^ " + msg;
    this_player(1)->eventPrint(ret, MSG_CONV);
    this_player(1)->eventTellHist(ret);
    tn("eventSendTell: "+identify( ({ "tell", 5, mud_name(), pl, where, convert_name(who), plc, msg }) ), "yellow");
}

and for imc2:

/secure/daemon/imc2.c
Code: [Select]
    varargs static void tell_out(object from, string targname, string targmud, string msg, int reply, int emote){
        string ret = "%^BOLD%^RED%^You tell " + capitalize(targname) +
          "@" + targmud + ":%^RESET%^ " + msg;
        // Send outgoing tell.
        if(RESTRICTED_INTERMUD) {
            if(!imud_privp(lower_case(from->GetKeyName()))) {
                this_player(1)->eventPrint("You lack the power to send tells to other worlds.", MSG_CONV);
                return;
            }
        }

        if(!reply) reply=0;
        send_packet(capitalize(from->GetKeyName()),"tell",targname,targmud,
          "text="+escape(msg));
        from->eventPrint(ret, MSG_CONV);
        from->eventTellHist(ret);
    }

The same code that's been added to eventSendTell() should also be added to eventSendEmote() in /daemon/services/emote.c.

6
Discworld Discussion / Distlib, distlib, wherefore art thou distlib?
« on: December 28, 2013, 05:10:46 AM »
As the days of 2013 slowly lie down and fall asleep, beside the cozy fire of New Year's Eve, and the leftover aromas of the Christmas feast, all is quiet.  Yet one tiny brow remains furrowed, as something seems amiss.  The tree twinkles, the snow glitters, and the logs crackle.  But a chill draft slithers along the floor, swirling around the edges of the soft warm rug, stirring a few motes of dust.

The long awaited Discworld distribution lib is missing!!!

How could we have forgotten such an important guest?  I'm sure we even left a place setting for him, yet... nobody remembers seeing him.  In fact, he hasn't been seen for many years now.  I'm sure we sent out the invitations, and I'm pretty sure we heard rumor of him being on the way, yet his chair sits empty.  The dog, curled up at the foot stool, awaiting its master's return, and blinking sadly into the fire.

Has anyone seen the Discworld distlib?  Please help!  It's cold out there, and if he's run off the trail, he could be lost forever!

7
Code Vault / base64
« on: November 10, 2013, 10:53:21 PM »
Cheesy base64 command...

Code: [Select]
#include <lib.h>
#include <daemons.h>

inherit LIB_DAEMON;

mixed cmd(string s) {
    string b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    string array b;

    if (sizeof(s) < 1 )
        return "You must supply SOMETHING to encode!";

    b = rexplode( s, " " );

    if (sizeof(b) < 1)
        return "You must supply SOMETHING to encode!";

    if (b[0] == "-d") {
        // decode base64

        string f = "";
        int i;
        int c;
        int n;
        int plen = 0;
        string r = "";

        s = implode( b[1 ..], " " );
        b = rexplode( b64chars, "" );

        for (i = 0; i < sizeof(s); i++) {
            c = strsrch(b64chars, s[i]);
            if (c == -1) {
                // not found
                if (s[i] == 61) {
                    // We found an "=", meaning we hit the padding.
                    // For decoding purposes, "A" is a zero pad value here.
                    f += "A";
                    plen++;
                    continue;
                } else if(s[i] == 32 || s[i] == 10 || s[i] == 9 || s[i] = 13) {
                    // We found whitespace, skip it
                    continue;
                } else {
                    // invalid character
                    return "Invalid input.";
                }
            } else {
                f += b[c];
            }
        }

        if (sizeof(f) % 4)
            return "Invalid input.";

        for (i = 0; i < sizeof(f); i += 4) {
            c = strsrch(b64chars, f[i]);
            n = c << 18;
            c = strsrch(b64chars, f[i+1]);
            n += c << 12;
            c = strsrch(b64chars, f[i+2]);
            n += c << 6;
            c = strsrch(b64chars, f[i+3]);
            n += c;

            r += "" + sprintf("%c%c%c", ((n >> 16) & 0xFF), ((n >> 8) & 0xFF), (n & 0xFF));
        }

        return r;
    } else {
        // encode base64
        string r = "";
        string p = "";
        int i;
        int n;
        int n1, n2, n3, n4;
        int rlen, slen, plen;

        slen = sizeof(s);
        plen = slen % 3;
        b = rexplode(b64chars, "");

        for (i = 0; i < slen; i += 3) {
            n = s[i] << 16;

            if ((i+1) < slen)
                n += s[i+1] << 8;

            if ((i+2) < slen)
                n += s[i+2];

            n1 = (n >> 18) & 63;
            n2 = (n >> 12) & 63;
            n3 = (n >> 6) & 63;
            n4 = n & 63;

            r += "" + b[n1] + b[n2];

            if ((i+1) < slen)
                r += "" + b[n3];

            if ((i+2) < slen)
                r += "" + b[n4];
        }

        if (plen > 0)
            for (; plen < 3; plen++)
                r += "=";

        return r;
    }

    return 0;
}

8
Drivers / memory and cpu use over time
« on: October 20, 2013, 08:21:52 AM »
A general caution that might be worth trying to test more rigerously....

I noticed this morning that my idle MUD was using up 30% of my CPU and about 120M of RAM.  The RAM is irrelevant (I have 16G), but the CPU was worrying.  This is after about a week's worth of uptime, and no real changes on my part.  This was FluffOS 3.07, latest from the git repository.

For comparison, I've reloaded FluffOS 2.27 and restarted the MUD.  At a fresh boot, it is using 40M of RAM and about 1% of the CPU, local_options being as similar as I could make them.

We'll see if this also grows after a week.

My experience has been that the memory use may grow slowly over time, but I've never had the CPU start being consumed like that, unless there was legitimate activity going on.

I'll keep you posted, but if you have any way to stress test things and leave it running somewhere for a long time, it might be worth doing.

9
Design Lab / libtelnet
« on: October 11, 2013, 12:54:07 AM »
So, out of curiosity, has anyone ever considered trying to hook Elanthis' libtelnet into FluffOS?

It seems like it would be a nice thing, since it can handle the heavy-lifting stuff like MCCP, while allowing callbacks into LPC code for other events, so the mudlib can process special things without having to look at EVERYTHING in raw mode.

10
Intermud / buggys?
« on: August 13, 2013, 10:03:27 PM »
So, trying to debug my channel sending thing to log disconnects (or really, reconnects), and standing in the network room trying to see if my attempt to send automated messages is even partially working, I got this:

Code: [Select]
DISCONNECTED

IMC2: created Tue Aug 13 23:00:21 2013
IMC2: setup Tue Aug 13 23:00:22 2013
Creating IMC2 object at Tue Aug 13 23:00:22 2013.

Creating IMC2 object at Tue Aug 13 23:00:22 2013.

socket_create: Created Socket 1

socket_connect: connected socket 1 to 50.116.16.90 9000

Write_Callback.

CLIENT: "PW Bloodlines cdebaejjgm version=2 autosetup eibahbkhfd(LF)(CR)"

BAD SOCKET ALERT. fd 1:  ({ 11, "DATA_XFER", "STREAM", "", "50.116.16.90.9000", UNDEFINED })
INTERMUD_D mudlist received.
Processing mud: "Avadev", lib: Avalon ONLINE
INTERMUD_D mudlist received.
Processing mud: "Avadev", lib: Avalon offline

Is that normal?

seeing something like "BAD SOCKET ALERT" in red makes me thing not so much...

11
Design Lab / Virtual Wilderness (again)
« on: August 05, 2013, 06:14:46 PM »
This is an old topic, but I'm pondering the idea of trying to actually make something useful from it.

Those of us who aren't buried in text MUD's only might have noticed a trend in graphical games of late.  The rise of the procedurally generated sandbox game.  Minecraft was the first super-popular example, and now Everquest Next appears to be using a hybrid approach with parts of the world being hand designed, while other parts are generated on the fly.

We've had tinker-toy virtual rooms in LPC mudlibs since 1995 or so, so it's not new... but nobody (to my knowledge) has really made use of them yet.

So, here's an idea for you guys to ponder and help me with.  Let's see if this idea makes any sense, and is doable.

Virtual rooms are essentially a fallback for an object not existing yet.  When your LPMUD tries to load "/d/foo/grassland12.c", if the file exists, it loads and you're done... end of story.  If it does NOT exist, the virtual system attempts to provide an object to associate with that path.  In my understanding, you can do whatever you want, but it makes sense to impose some structure on the path names so the virtual system can hand back the right kind of object.

So, let's say you want your entire world to be data-driven.  You have some method to generate a height map for your terrain, and some method to describe what kind of climate/vegetation/etc would be at various points.  The game tries to load "/d/wilderness/rooms/12,387,-9.c" and that gets passed to the virtual system.  It picks it apart and sees that you want a room and the coordinates are 12,387,-9 (x,y,z).

You look up the height map and find that it intersects at -9 (height) for coordinates 12,387 (x,y), so you are indeed on the surface.  You go lookup terrain, vegetation, climate, etc and see you're in a swamp.  Now, you have to look at some number of coordinates around you (on the height map) and see what other values are nearby, and feed that block of data off to your virtual description engine.

"You're in a murky swamp that stretches south and seems deeper to the west.  A few low hills struggle out of the muck to the north, and some possibly dry scrub brush lies to the east."

You fill in whatever other details you need and create the room.  Now, in addition to handing back the object, you might want to save the room as a permenant file so the next time you walk here, it doesn' t have to regenerate it.  That depends on how much you want to use CPU vs. disk space.  Disk space is cheap.

If your CPU is fast enough, maybe you want to also generate a few other surface rooms around this new room, on the principle that whomever caused it to load will probably walk soon, and so pre-generating a small number might reduce lag and CPU use... YMMV as to the right radius to use for this.

Now, let's say you chose a coordinate that was UNDER the height map?  Your room generator now has to decide... are you underground, or underwater?  If you're underground, we can play minecraft and make tunnels!  If you're underwater, do we make water rooms in a column, up to the surface and down to the floor?

Same goes for above the height map.. you make an air room.  If you're not able to fly, it might be pointless to generate a whole set of air rooms, since you're just going to fall and splat.  Even if you are... do you really want 200 rooms of empty air?  Perhaps making a few layers is enough... from 1-10 above the surface is "air", 10-100 is "high up", and 100+ is "very high up", giving you 3 different "rooms" with descriptions appropriate to the general height.

Perhaps underwater should also work that way.  Nobody wants to type "/repeat 300 up" to get to the surface.  No mud admin really wants a billion seldom visited air or water rooms cluttering up the disk.

In light of that, maybe the actual disk naming should be "/d/wilderness/rooms/12,387,surface.c" where the virtual system would take the original pathname and check the height map, and then recurse itself with the chunked filename.

Thoughts?

12
Drivers / Long standing bug in FluffOS
« on: July 27, 2013, 10:07:06 AM »
So, since lots of changes and work are going into FluffOS now, I figured I'd see if I could get someone to take a look at a long-standing bug that still bites people in the arse.

LPC has data types.  Not very many, and a bit strange since the type clings to the value, not the variable... but still, it has types.

In any sane language, when you declare a variable of a specific type, it is initialized to an appropriate value of that same type.  FluffOS's version of LPC does not do this.

If you declare an array or mapping, they are initialized to the value 0, which is an integer.  The runtime error this commonly causes is when you declare a variable and then try to use it the way you'd expect it to work, such as:

Code: [Select]
mapping foo;

foo["hello"] = "blah";

That fails with an illegal index error, because you can't index the value 0, which is what foo is initialized to.  You have to always remember to declare everything and specifically assign it the right value.  Not a big deal if you're working on your MUD consistently, but a royal pain when you just want to code something quickly every now and then, or if you've been using a different driver that does things as you'd expect.

13
Code Vault / DS mudlist CGI page
« on: July 27, 2013, 02:19:47 AM »
Here's a working mudlist command, which can be placed in the cgi directory of DS's internal web server.
Why?  Because it makes it easy to add I3's muds to my mudlist, since my TMC script already handles web pages.

Code: (lpc) [Select]
#include <lib.h>
#include <privs.h>
#include <daemons.h>

inherit LIB_DAEMON;

varargs string gateway(int strip_html) {
    string output = "";
    mapping mudlist = ([]);
    string mud = "";
    mixed *info = ({});
    string *list = ({});
    string *bg = ({ "#FFFFFF", "#DFFFDF" });
    int bgcolor = 0;
    string *keylist = ({});
    int i = 0;

    foreach( mud, info in INTERMUD_D->GetMudList() ) {
        if(info[0] == -1) {
            mudlist[mud] = info;
        }
    }

    keylist = sort_array(keys(mudlist), 1);

    for(i = 0; i < sizeof(keylist); i++) {
        mud = keylist[i];
        info = mudlist[mud];
        bgcolor = !bgcolor;
        list += ({ sprintf(
                    "<td bgcolor=\"%s\">%s</td>" +
                    "<td bgcolor=\"%s\">%s</td>" +
                    "<td bgcolor=\"%s\">%s</td>" +
                    "<td bgcolor=\"%s\">%s</td>" +
                    "<td bgcolor=\"%s\">%s</td>" +
                    "<td align=\"right\" bgcolor=\"%s\">%d</td>",
                    bg[bgcolor], replace_string(strip_colors(mud), " ", "&nbsp;"),
                    bg[bgcolor], replace_string(info[8], " ", "&nbsp;"),
                    bg[bgcolor], replace_string(info[7], " ", "&nbsp;"),
                    bg[bgcolor], replace_string(info[5], " ", "&nbsp;"),
                    bg[bgcolor], info[1],
                    bg[bgcolor], info[2]) });
    }
    output  = "<div align=\"center\"><table width=\"90%\" border=\"1\" cellspacing=\"0\" padding=\"0\">\n";
    output += "<tr class=\"header\"><td align=\"center\" colspan=\"6\">" + mud_name() + " recognizes " + consolidate(sizeof(mudlist), "a mud")+ ":</td></tr>\n";
    output += "<tr class=\"entry\">" + implode(list, "</tr>\n<tr class=\"entry\">") + "</tr>\n";
    output += "</table></div>\n";
    return output;
}

14
Drivers / async IO database example?
« on: May 05, 2013, 02:10:34 PM »
So, in my continuing to slowly poke things into my documentation wiki, I was reminded of something that needs a small quick example, somewhere.

Wodan has stated that Discworld no longer uses the python database helper script, and now uses package_async.  Is there any chance a very small example could be posted in here?

Basically just connect, do a select, do a couple of insert/updates in a transaction block, and disconnect.

At least that way new users wouldn't have to paw through the source code just to figure out how to do basic DB operations. :)

15
Drivers / Documentation Wiki, part 1.
« on: April 14, 2013, 07:08:52 PM »
Hey guys,

Just to get some feedback, here's the documentation wiki I've been working on.  There's still more to go, but after finishing the gigantic sockets document, I figured perhaps I should let other people see and comment on it.

I started doing it by hand, then wrong a script to try and auto-tag many keywords, and am now cleaning that up by hand, as making a script to do everything right is more work than doing it by hand entirely. :)

So, if you think I should add more whitespace, or not highlight every occurance of words, or whatever, do comment.  Eventually, I'll either open it up to editing and/or figure out how to make the stuff that works in mediawiki work in github's wiki.

http://www.shadowlord.org/~quixadhal/wiki/index.php/FluffOS_documentation


Pages: [1] 2 3 4