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.


Messages - quixadhal

Pages: 1 2 [3] 4 5 ... 43
31
Drivers / Re: new year resolution
« on: January 10, 2016, 02:53:50 PM »
OK, fine. :)

How about a package that integrates libpng (or similar) to allow for the easy retrieval of blocks of graphical data from files without needing to parse binary stuff in LPC?

IE: if you wanted to use a large high-resolution image for your world map, via virtual rooms, you might want to grab blocks of 3x3 or 5x5 pixels at given coordinates so you can generate dynamic descriptions of the room and its surroundings.  Asking libpng for that is easy.  Parsing a PNG file in LPC... not so much.

32
Intermud / Re: Intermud-3 router status
« on: December 27, 2015, 08:20:29 AM »
Merry Christmas!

2015.12.27 -- *dalet is dead, *i4 is up, but nobody using the stock code will know that, as the intermud code is hard-coded to use router[0][0] in lots of places, rather than walking down the list when one is down. :)

Might be a good time to fix that, or at least hire someone to go physically kick *dalet again.

33
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.

34
Design Lab / Re: Timed events for player characters
« on: December 22, 2015, 03:59:07 PM »
First, I would likely change your AddFaction() function a bit.  Setting both ltime and rtime to the same value seems silly.  I assume "ltime" is the time at which the player last modified the faction by some action on their part?

If so, rtime could just be 30 * DAY_LENGTH * HOUR_LENGTH.

To see how much time has elapsed since then, and how many faction points to deduct,

(SEASONS_D->GetTime() - Factions["poo"]["level_timer"]) % Factions["poo"]["reputation_timer"]

So, you could, on login, deduct that many points from their reputation value and reset ltime so the next calculation is correct.

There's utterly no reason to check every N minutes for something that only happens every 30 days.

However, if you WANTED to for some other purpose....

In heart_beat, you could add a check to ensure the callout you want is there, and if not, make it there.

if( find_call_out("silly_check_function") < 0) {
    call_out( "silly_check_function", 60 * 60 * 30 );
}

You can also use the "handle" that call_out returns, which is more useful if you use the same function for multiple things.

However, heart_beat() runs every 1 or 2 seconds, so it's really a waste to do this for something that doesn't do anything very often.  In the case of your 30 day thing, checking during login is MORE than sufficient.

35
Drivers / Re: WIP: Fluffos 3.0 Alpha 9.0
« on: November 14, 2015, 07:26:55 AM »
I'm not an expert on character set encodings, but my first instinctive thought was... are you using UTF-8 or a similar extended character set, and are there any valid byte sequences that use 255 in them?  TELNET was designed for ASCII transmission, and character 255 was denoted as the special IAC escape code to say "Hey, the next byte is either part of a command sequence, or another 255 escaped"

If libtelnet is scanning data at the byte level for IAC sequences, and one happens to be part of a multi-byte character set in whatever encoding you're using, it's very possible that libtelnet might try to analyze it.  If it happens to be a valid command (but with nonsense data), it might do something unexpected.

That's just a wild guess though.

36
Drivers / Re: WIP: Fluffos 3.0 Alpha 9.0
« on: November 11, 2015, 04:31:12 AM »
It's probably also helpful to compile with the debug flags on, and link against the debug versions of your system libraries.  ./build_FluffOS devel used to do this (or maybe debug).

If you know how to reproduce the crash, or you have beefy enough hardware to not mind the overhead, you can also run the driver in gdb, which would let you poke around in the case of a crash.  If you do that though, I'd recommend using screen, or doing it on a console.... a remote shell without screen may stop the driver if you get disconnected.

37
Drivers / Re: Different CUSTOM_CRYPT
« on: November 11, 2015, 04:27:55 AM »
If you can find an old copy of the "crack" utility, you could harvest the old crypt versions of your players passwords and construct a password file in the old unix style format, which would then let you run crack against it.

Players who have weak passwords would be revealed to you, and you could then generate new ones using the new encryption to put into their player files.

38
Drivers / Re: function pointers and anon funcs
« on: November 01, 2015, 07:12:46 PM »
Thanks Dworkin!

You are correct.  In fluffos, the "update" command just recompiles the new code which may call restore_object(), and if that works... destructs the old version.  Not actually upgrading the in-place object at all, but making a new one.

In that respect, the only place function points can be an issue would be if you tried to optimize lookups like CHAT_D->get_chat_color(), which is a synonym for "/secure/daemons/chat"->get_chat_color(), or call_other("/secure/daemons/chat", "get_chat_color");

If you were to cache those and not properly update the cache, you'd get either an error if the old copy were destructed, or unhappiness if you expected a daemon to be a singleton, but somehow ended up with multiple copies anyways.

39
Drivers / Re: function pointers and anon funcs
« on: October 31, 2015, 04:23:17 PM »
One thing to note here is that (unless I'm remembering wrong) LPC is designed so that when an object is updated, it always gets a new chunk of code attached to it, but retains its old data structures.

IE: If I modify a daemon (such as /secure/daemons/chat.c), and recompile it, the running object will now be using the new code, but still keep its existing data structures (IE: list of people who said something).

So, if you're going to start using raw function pointers in objects, you need to ensure that those pointers are always updated to point to the newest version of the object's code.  Otherwise, you will end up with some objects using the new version, but still having call_out()'s or call_other()'s pointing at older code revisions.

I don't know how FluffOS implements this behavior, so it may be a non-issue... but it's the first thing that came to mind with your suggestion as a potential gotcha.

40
Open Chat / Re: Merry Christmas and a happy New Year!
« on: October 31, 2015, 05:04:33 AM »

41
Drivers / Re: WIP: Fluffos 3.0 Alpha 9.0
« on: October 06, 2015, 11:23:29 PM »
Actually, array makes more sense for LPC than the old C pointer notation.

LPC doesn't allow you to (directly) use pointers as a variable type.  As such, using a cryptic pointer notation to mean an array only makes sense to people who first learned C or C++ programming.  If it weren't for trying to support legacy code, I'd actually get rid of the * notation and force the use of the array keyword as the ONLY way to declare an array.

42
Code Vault / Re: /etc/init.d scripts
« on: August 26, 2015, 01:09:40 PM »
Ironically, we had a power outage for a half hour the other day, so I did get to tweak things a bit. :)

There were a couple of typos from cut/pasting, and as I expected I would, I got rid of the external scripts and just merged their function into the main one.

Enjoy!
Code: (bash) [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

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

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

case "$1" in
    start)
        echo "Starting MUD Server: Bloodlines"
        if start-stop-daemon --quiet --stop --signal 0 --pidfile $APIDFILE --name addr_server --user $USERNAME
        then
            APID=`cat $APIDFILE`
            echo "    addr_server [$APID] running."
        else
            echo -n "    Starting addr_server..."
            $ADAEMON $APORT >/dev/null 2>&1 &
            echo $! >$APIDFILE
            echo " done."
        fi
        #
        if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name driver --user $USERNAME
        then
            PID=`cat $PIDFILE`
            echo "    driver [$PID] running."
        else
            echo -n "    Starting driver..."
            sleep 2
            $DAEMON $CONFIG >$LOGFILE 2>&1 &
            echo $! >$PIDFILE
            echo " done."
        fi
        ;;
    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 $APIDFILE --name addr_server --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

43
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

44
You actually have the clue in the part you pasted.

if(!exec(Player, this_object()) ...

The driver doesn't "run" a player the way a DikuMUD works.  The driver has a handful of applies that get called when network level things happen.  The call the exec() tells the driver that when input arrives at the socket from now on, it should be sent to the Player object instead of this_object().

Player, in this case, is a global variable in connect.c which is set in the InputPassword() method by
Player = master()->player_object(Name);

The last piece of code the driver (via connect) runs is Player->SetTeloptIp(0).  A that point, the player object exists, has been initialized or restored, and exec() has transferred processing to that object.  Text send to that object will be sent to the socket associated with the connection, and input received on that socket will be sent to the receive function of the object for processing.

The "magic" part happens in the master object.  That's where it takes the player name and restores the saved data via a call to load_object(), returning the new object if it worked.

Note that there is security in place to prevent arbitrary code from calling this function, as it would be a nasty security hole if anyone could do this... effectively you could become anyone (including admins) without needing the login with their password.

45
Drivers / Re: Fluffos 3.0-alpha-8.1 Releases
« on: July 01, 2015, 01:57:59 PM »
sorry.
Because of pragma optimize error, i was using fluffos-3.0-alpha8.0 until the last release of 8.1.

The exact code that i said is in add_message (comm.cc):
Code: [Select]
for (cp = trans; cp < end; cp++) {
...
...
...
  if ((*cp == '\n' || *cp == -1){
...
...
      ip->message_buf[ip->message_producer] = (*cp == '\n') ? '\r' : -1;
...
...
    }
   ip->message_buf[ip->message_producer] = *cp;
}

I simulated that in 8.1.
I mean, i insert \r when i found \n, but is a patch for my mud.

I hope you're only doing that for TELNET sockets, and not for normal binary mode sockets.  This would, for example, break the "mudmode" sockets used for intermud connections.

Pages: 1 2 [3] 4 5 ... 43