Archive for March, 2006
Humanizing Ziggy
For those that are not familiar with Ziggy, he is a character based on a DnD character from a few years back and has taken on a life of his own. He’s made an appearance in my Willis module for Neverwinter Nights (based off the same campaign), a book that I’m writing, several sketches as to what he looks like, and an IRC bot written in perl.
The IRC bot is what has really shaped his personality, and he’s become pretty much another member of the group. The first iteration of ziggy had noticable issues- mainly the instantaneous full sentence reponses.
Fortunately, the initial workaround for this problem was easy- Ziggy is based off the PoCo-IRC module, and there’s an ability to delay() calls to session hooks. This has made ziggy much more realistic and given me the ability to make him… bizarre.
As I’ve added more and more functionality to Ziggy, I’ve had successes and failures. The current code rewrite I’m working on is massive, but well worth the effort. One of the big pushes I’m working on is modularizing his code; that in combination with the personality xml file would allow others to easily create bots and pick and choose features to add. This would also allow me to create an API for modules and let others develop for ziggy.
The problem I’m running into is the code I wrote in the previous version of ziggy is dependent on features available in the PoCo-IRC scripts, but not the plugin class. Lets look at a sample case:
Bar_brawl.pm
Bar_brawl is triggered when someone performs a ctcp action that involves punching ziggy.
* morgajel punches ziggy in the liver
1-3 second delay
[ziggy] BAR BRAAAWL!!!!!
1-5 second delay
*ziggy hits morgajel with a chair
repeat the last two sets 4-8 times, changing the delay, the target, and it’s an action or a battle cry.
In the original version, I created a bar_brawl handler which recursively called itself and decremented a variable. Each round of bar brawl randomly selected a “brawl_option” from the personality xml file, immedately performed a post(‘privmsg’) or action to the channel, then performed a delay() on itself for a random 1-5 seconds.
The result was exactly what I was looking for, except that it was a big mass of ugly code in the middle of the program. This, if anything, should be moved to a module. The problem then became, “how do I declare the delays?”
BinGOs, the guy who maintains PoCo-IRC is working on a delay for plugins, which will almost fix my problem- he says that it’ll only work for main session hooks like privmsg, kick, etc- which means no plugin-level delay on a plugin-level bar_brawl hook.
So where should I go from here?
UPDATE
So it looks like the fix was using an internal function in $irc called _send_events
with this I could send a ‘say’ event, and had say recursively call itself if an extra parameter was given to it (a delay in seconds). on top of this, delay_add fixed the disappearing delays issue. Moral of the story: it’s all working now.
Useful Utility: sed
Sed is a powerful utility for going regexes on the fly. Regular Expressions (regex) are beyond the scope of this artcle, but I’ll try to write one later. As I go, I’ll explain the regexes I use, but you really should learn about them because they’re handy as hell in many different utilities.
First up, we’ll use a simple example of a regular expression. Suppose for some reason, you want a list of the Input Device names used by Xorg, and plan on piping it into another script later on. We can look at the Xorg log and find a lot of data, but locating the Input Devices is like searching for a needle in a haystack.
Our first step is to cat the file, then grep for the phrase “Input Device”. This provides us with
morgajel@FCOH1W-8TJRW31 ~/docs $ cat /var/log/Xorg.0.log \ | grep "Input Device" (**) |-->Input Device "Mouse1" (**) |-->Input Device "Keyboard1"
Which tells us what we need to know, but your script is more picky about the format. This is where sed comes in to play. we can tell sed to throw away everything before and including Input Device
morgajel@FCOH1W-8TJRW31 ~/docs $ cat /var/log/Xorg.0.log \ | grep "Input Device"|sed -e "s/.*Input Device //" "Mouse1" "Keyboard1"
Lets break this down. Sed can accept regular expressions one of two ways, either through the -e flag, as shown above or through a file using the -f flag. The advantage of using the -e flag is it’s quick and simple, whereas the advantage of using the -f flag is you can build compound regular expressions executing again one at a time, in order.
Now, what’s the regex doing? it’s saying switch(s) the first parameter(/.*Input Device /) with the second parameter (//, or nothing) the first time you see it in every line. the “.*” means “match every character” before “Input Device”. Note that we’re replacing “every character before Input Device” AND “Input Device” and the space after “Input Device”, and replacing it with nothing.
The good news is we’ve gotten it down to the base information we need- the bad news is it’s still surrounded by double quotes, which your script doesn’t want. How can we fix this? by using another sed to remove the quotes!
morgajel@FCOH1W-8TJRW31 ~/docs $ cat /var/log/Xorg.0.log \ | grep "Input Device" | sed -e "s/.*Input Device //" | sed -e "s/\"//g" Mouse1 Keyboard1
Lets bread this one down. There are two important things to learn here- ” is a special character and needs to be escaped since we’re writing this on the command line, so it has a “\” in front of it so the regex isn’t closed prematurely. one of the drawbacks of using the -e flag is properly escaping characters not only for regex, but for bash as well. The next thing to note is the trailing “g” at the end of the regex. the g stands for global, and says to replace all instances of the match with the replacement term (which is again, nothing).
Alright, that was the simple example, ready for the more difficult ones? Too bad, I’m tired of explaining regex. Instead I’ll focus back on what sed can do. If this is a command we’re going to be running often, it might benefit us to move the regexes to a file- I’ll call mine “myscript”, because I’m original like that:
morgajel@FCOH1W-8TJRW31 ~ $ cat myscript s/.*Input Device // s/"//g
Note that the double quote is not escaped. Our command to use this file goes like this:
cat /var/log/Xorg.0.log|grep "Input Device"|sed -f myscript
Much cleaner, if you ask me- but then again, you need to create a file to do so, so it’s a trade off.
Here’s an ugly ugly regex, but it has some useful things in it. Suppose we wanted a list of shells and the users who used those shells, in alphabetical order. One way to do that (although there are much better tools for this sorta thing,) is with sed.
cat /etc/passwd|sed -e "s/^\([^:]*\).*:\([^:]*\)$/\2\t\t\1/"|sort [edited for length and security] /bin/false squid /bin/false sshd /bin/false uucp /bin/false vpopmail /bin/false xfs /bin/sync sync /sbin/halt halt /sbin/shutdown shutdown
There are some more important things in this one as well- this is a good lesson in building expressions.
- “^” tells sed that it must start at the beginning of the line.
- “\(” and “\)” are bash-escaped parenthesis that tells sed “save this bit for later
- “[” to “]” represents a range- normally, you would see it in the context of “[a-z]” or “[13579]” matching a single lowercase a-z and/or a single odd digit, respectively.
- “^:” the carrot has a different function when it a range- it negates it, basically saying “any character but what follows”, in this case, a colon( : )
- “^\([^:]*\)” put together means “match zero or more characters starting at the beginning of the line until you reach a colon- oh, and save that glob for later.”
- “$” is similar to the first use of “^”- it matches the end of the line.
- “\2” represents a glob that we set aside with the parenthesis- notice they start counting in order: “\1” picks up the first glob (username) and \2 picks up the second glob (shell name). Notice that most of the line was ignored- “.*:” hiding in the center of the regex matches everything else, but since it wasn’t surrounded by parenthesis, it doesn’t get saved.
- “\t” is last, but not least- it places a tab character between \2 and \1, spacing them out a bit. I put 2 in there to make it easier to read.
Argh, I said I wasn’t going to explain any more regex! Oh well, screw it. I’d also suggest checking out the info page for sed as well as the man page- running “info sed” will also give you a lot of information on sed’s regex.
instablity
I don’t know if BSD can smell the gnu in my blood or what, but it is seriously putting up a fight. As I mentioned in the previous post’s followups, I got kde working finally- however every time I pop open Konqueror and hit slashdot, the entire machine locks solid. Not just konqueror, not just X; the whole machine.
Now, I know slashdot has a troll meme about BSD dying, but this is ridiculous. I had kde up and running for a good 24 hours before I popped open konqueror the first time, so it’s not like an instant hardware failure or something. I’ve been able to do everything fine in Linux for years on this hardware- Still works after this experience, as well. Konqueror, although not my first choice browser, has never had this issue before, either.
So what I’m really wondering is, where does the fault lie? Even if it is kde/konqueror based, why is a user-level application locking the entire system? Is it the fault of X, which probably falls in the top 20 most useful unix programs? Is it BSD itself? Perhaps K_F was right, maybe it is a library issue.
I know one thing for sure; VP was right when he said FreeBSD was not a workstation OS. I can’t cope with that kind of instability- I have no choice but to go back to Linux. I need to get shit done. I’ll convert my Ridllr sideproject box to BSD and see what I can do there. I hope it makes a MUCH better server than it does a workstation…
What’s Missing?
So, I’m compiling a list of what’s missing from my BSD install from the get go.
- tab-complete – stupid default shell is csh, which means no tab complete. Come on guys, jump on up to 1999.
- alt key – This is probably a keymap issue, but the alt and delete keys do not work. Alt acts like it does nothing, and delete behaves like a tilde. This means no alt tab. The question becomes, “if USA ISO is not the proper keymap, what is?” I’d like the one that windows and linux use as default if anyone knows offhand.
- Where’s my X – installed as a “user + X” setup, but X does not start on boot. I can figure out how to get it to start, but still a pain in the ass.
- searching in sysinstall – again a comparison to make menuconfig- searching in the package list with / would be really handy.
- Scroll Wheel – stupid scroll wheel doesn’t work by default
- cvsup not installed – I’m lead to believe that cvsup is responsible for the same effect as apt-get update or emerge sync in the linux world- i.e. major importance for package management. Then why isn’t it installed by default?
- vim is not vi – Perhaps this is another keymap related issue, but vim seems to think it’s vi- i.e. simple things like backspace and delete do not work properly in insert mode. I don’t know what’s going on, but I had to install nano to make even simple changes, and I’ve been using vi for years.
- Updatedb – There’s a locate, but no updatedb. Upon further research, I found a /usr/libexec/locate.updatedb. why it’s here, who knows, but it’s a pain in the ass- especially if you install a new system and you don’t want to wait a week for it to rebuild it’s database. Just one more thing to track down.
I know a lot of these arguments are of the vein “But that’s now how linux does it!”
Yes, I know, BSD isn’t linux, and yeah you could probably argue it’s apples to oranges or that BSD is more secure. But these are simple things. And to those who argue that BSD has better documentation than Linux, I suggest you check out the gentoo project’s documentation- it somehow manages to cover exactly what you need and does it in an efficient manner.
For cryin out loud guys, being “a real unix” doesn’t mean you have to stagnate.
Need an Update
Anyone know where I can find an update for Lynx?
I got this message while trying to test my printer to see if it was still connected via wire or if wireless had decided to work. Nothing suprising really, just amusing.
First Impressions
Holy crap, welcome to 1980. The FreeBSD install is going to take a little bit longer than I thought. I booted off the Install CD and the first thing I noticed was the lack of color. Not shiny pretty GUI color, but angry fruit salad color. As pages of white text on black blackground whizzed past my screen, nothing stuck out as important; I noticed no dividers between sections. This is a very small, trivial thing, but it is nice. Compare and contrast with say a gentoo liveCD- I’m not even talking about the background images and framebuffered text; I just mean colored headers.
Never underestimate the power of syntax coloring.
Next up, HD partitioning- the tool they’re using is sorta like cfdisk, but ugly. I panicked at this point because I wasn’t sure where I wanted to install fbsd, and I was having second thoughts about completely wiping draccus. None of the partitions were labeled in silly ways like “hda1”, just (IIRC) ranges of blocks. Solution? Jumped back to linux, found a 15 gig partition that I had forgotten about, moved the stuff to the 150 gig linux partition, then booted off an unbuntu LiveCD I picked up at the FOSE Convention, and am currently resizing the 150 gig, deleting the 15 gig, and merging the free space so I can dedicate aroung 70 gigs to FreeBSD.
Unfortunately I’ve run out of time this morning to actually install FBSD, but I’ll get to it tonight. GParted is a very nice tool, BTW. Hopefully it’ll be done running e2fsck on the HD by the time I get home 🙂
Going FreeBSD
Well, the new job is gonna have a bucket full of FreeBSD servers. It’s been a while since I tinkered with FBSD, so it’ll be a challenge. To prepare for that challenge, I’ve decided to convert Draccus (my workstation) to BSD. The following is a list of hurdles I’ll need to surpass before I start in April:
- get draccus up and running
- get KDE up and running
- get Gimp working
- get my Wacom Graphire 3 tablet working
- get my Logitech Quickcam working
- get my m-audio keyboard working
- get rosegarden recording again
- burn a cd-rw
- burn a dvd+rw
I’m presuming I’ll have no problems with my Nvidia 6600 GT, Audigy 4 soundcard, or other common hardware. With the problems I’ve been having with linux as of late (specifically draccus) there is a moderate chance I might fully convert from Linux to BSD. If I can accomplish the above list, I will continue using FBSD for one year. The disc is burning now.
Going Home
For the few people who haven’t heard yet, Jackie and I will be returning to Grand Rapids. I was offered a position at a local GR company as a Network Administrator. The company seems really nice from what I saw last friday.
I can’t describe how much I really hate the DC area. It’s just too crowded for me. Among the many benefits of this move, Jackie and I will:
- be able to be with our friends and family again
- take up physical training with yojimbo again
- home cooked meals
- not live trapped in a box
- have a 20 minute commute to work instead of an hour
- be able to go outside and not see a single person.
I’m by no means a farm boy, but DC is just way too big for me. On the positive side, DC has done me some good.
- I can now stand in a crowd of 30 people without having a panic attack
- I have a new car
- paid the bills when Michigan was in a huge recession
- met some decent people
- learned to value silence
- Learned there’s more to do than play with a computer all day
So there you have it. Jackie and I have also picked out an apartment- we finally managed to get into ramblewood after a 3rd or 4th time of fate stepping in. Nice backwoods section near kent trails. I can’t wait to get back- my last day at my current company is April 7th, and I will be in town on the 14th of April. Don’t get me wrong, I like my current coworkers, I just don’t like the area (Sorry Tony, it’s just too crowded).
So it looks like Operation BTFO was a success.
Useful Utility: whereis
Whereis is an older utility- it’s functionality shows us of a time when a program not only had a man page, but also stored the source on the machine in question. That’s becoming more rare as programs like firefox come into play- firefox, for example, has no man page and doesn’t install the source (due to size issues).
Whereis locates the binary, man page and source of a given command on the current machine.
$ whereis ls ls: /bin/ls /usr/bin/ls /usr/X11R6/bin/ls /usr/bin/X11/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz $ ls -l /bin/ls /usr/bin/ls \ /usr/X11R6/bin/ls /usr/bin/X11/ls /usr/share/man/man1/ls.1.gz \ /usr/share/man/man1p/ls.1p.gz -rwxr-xr-x 1 root root 70708 Jan 24 15:53 /bin/ls lrwxrwxrwx 1 root root 7 Jan 24 15:53 /usr/X11R6/bin/ls -> /bin/ls lrwxrwxrwx 1 root root 7 Jan 24 15:53 /usr/bin/X11/ls -> /bin/ls lrwxrwxrwx 1 root root 7 Jan 24 15:53 /usr/bin/ls -> /bin/ls -rw-r--r-- 1 root root 6403 Mar 6 10:52 /usr/share/man/man1/ls.1.gz -rw-r--r-- 1 root root 8070 Mar 6 10:52 /usr/share/man/man1p/ls.1p.gz
The flags are a little boring- you can limit your searches to binaries (-b), source (-s) or manuals (-m).
Something I found interesting is the capitalized versions of those flags states to only check the directories immediately listed after, but only when the last directory is followed by a -f flag.
$ whereis -m -M /usr/share/man/man1/ -f ls ls: /usr/share/man/man1//ls.1.gz
I’ve never seen anything like this before- a space-delimited option with a flag terminator. I’m sure other examples exist, I just can’t think of any. Normally you’d just use commas as seperators and follow it with a whitespace to terminate. The man page also states that due to an specific function it uses(chdir), make sure you use full, not relative paths.
Honestly I was hoping whereis would have a little more meat to it. This is probably one of the more useless programs I’ve written about.
This Year’s Lesson
I’ve spent entirely too long trying to figure out what skill I wanted to focus on this year- what to “get another skill point in” as it were.
I really wanted to try electronics, but I think I’m going to put that off just a little bit longer. Instead I’m going to focus on learning to play the keyboard. Well, not actually how to play, but learn enough to teach myself Chord Theory. I’ve found a great site that shows the proper fingerings for piano chords which will be a great help.
I’ve also been reading a “songwriters guide” book that teach about the fundamentals of music theory. The author is pretentious, snoppy and hates anything written after the 1950’s, but he knows his stuff. If you can get past the fact that he’d be sneering at your musical taste, you can learn quite a bit.
My end goal is to eventually produce a CD so I list that as an accomplishment on my resume (for shits and giggles): “composed, arranged performed and produced ________.” It’s all about being well rounded 🙂
So here I am, the year 2006, and my Year Lesson will be Keyboard/Chord Theory.
Wish me luck.