So… I just finished the first half of my CCNA today.
I never really cared about networking much beyond that needed to make sure clients on a lan can talk to their dns server… but we’ve been growing enough here at work that the needs quickly outpaced my prior skillset. And since I was the closest thing we had to a network admin, I got signed up for classes
It’s been fun and profoundly enlightening. I didn’t expect to have my way of thinking so radically altered, but I’m hardly complaining.
I’ll be starting up the second class in a week or two. This’ll include such topics as VLANs, IPv6, and fancy routing protocols. I’m stoked.
It’s funny. I never finished college (though I took classes for roughly 10 years), so this is actually the first certificate of education I’ve received since highschool.
The comment was made at work that I’d dinged as a sysadmin. I haven’t. I’m just cherry picking my next few levels in netadmin 
Posted by Ammon as play at 2:25 PM EDT
No Comments »
One of the more annoying things about svn is that (to my knowledge), there exists no single simple command to retrieve the revision number from a shell.
What I want:
ammon@hermes:~/repo$ svn info --get-revision .
1234
But of course, nothing like this exists.
Thankfully, svn info's output IS easy enough to parse. You just have to do it your self.
ammon@hermes:~/repo$ svn info | grep Revision | awk -- '{print $2}'
1234
Will give you the revision of your current checkout without the network hit of a call to svn log.
To get the current version of the repo itself (hits the network), add "-r HEAD" to the svn info call:
ammon@hermes:~/repo$ svn info -r HEAD | grep Revision | awk -- '{print $2}'
1280
Of course, svn info also supports outputting info as xml, so you could use that to parse things in a more advanced environment but one where you're still not using the svn api bindings.
Posted by Ammon as play at 12:57 PM EDT
No Comments »
I have a php script that frequently needs to email me the last few lines of a log file. I can't afford to exec() a binary tail process, so the solution has to be in pure php.
Originally, the files in question never exceeded more than a few thousand lines. Unfortunately, I am encountering cases now where the files are now occasionally 50,000 lines or longer. This causes PHP's memory consumption to explode.
Note: Code snippets provided here are not fully functional standalone shell scripts. The scripts I ran to benchmark the algorithms contain some rudimentary setup logic that is not important here, so has not been included.
My original method:
// tail-file.php
$arr = @
file( $fname, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
$arr =
array_slice($arr, -
$lines);
$buf =
implode("\n",
$arr);
This is easy to understand and is pretty fast, all things considered. Unfortunately, the memory footprint for loading a file into an array is obscene. Loading a 4400 line log file with this method could consume more than 17mb of ram. 50,000 line files easily stressed the 256mb limit I am able to provide the process.
So, the obvious solution to the memory consumption is to avoid loading the entire file at once. What if we kept a rotating list of lines in the file?
This method works by keeping the $lines-many most recent lines of the file in an array. Memory consumption remains sane, but the performance hit for performing so many array pushes and shifts is bad. Really bad. With small files, I can't notice any difference between this method and the file() method... but with longer files, it adds up quickly.
Given a 51 line, 4kb file, an average execution ($lines = 20) might look like this:
ammon@zap:~$ time ./tail-file.
php a.
log>/dev/null
real 0m0.015s
user 0m0.009s
sys 0m0.007s
ammon@zap:~$ time ./tail-array.php a.log>/dev/null
real 0m0.016s
user 0m0.010s
sys 0m0.006s
Comparable enough. But given a 50,004 line (3.3mb) log file:
ammon@zap:~$ time ./tail-file.php b.log >/dev/null
real 0m0.079s
user 0m0.058s
sys 0m0.021s
ammon@zap:~$ time ./tail-array.php b.log >/dev/null
real 0m0.119s
user 0m0.112s
sys 0m0.007s
The difference becomes quite clear. However... what if my log file grows obscenely large? I've got a 9 million line log file (1.6gb) lying around to test with...
ammon@zap:~$ time ./tail-file.php c.log >/dev/null
real 0m0.015s
user 0m0.008s
sys 0m0.008s
ammon@zap:~$ time ./tail-array.php c.log >/dev/null
real 0m19.351s
user 0m18.545s
sys 0m0.803s
The file() method crashes because it can't allocate enough ram to hold a 9 million element array and the array method takes almost 20 seconds to execute. It's slow... but at least it works.
Of course, there are other methods. The one I finally settled on is this:
// tail-seek.php
$fp =
fopen($fname,
"r");
$lines_read =
0;
if( $fp !==
FALSE ) {
fseek( $fp,
0, SEEK_END
);
$pos =
$eof =
ftell($fp);
do {
--
$pos;
fseek($fp,
$pos);
$c =
fgetc($fp);
if( $c ==
"\n" )
$lines_read++;
} while( $pos>
0 &&
$lines_read <=
$lines );
$buf =
fread($fp,
$eof-
$pos);
}
fclose($fp);
This method doesn't waste time reading the bulk of the file. It jumps to the end and scans backward until enough newlines have been located. The only problem here is that your average filesystem isn't optimized for reading backwards... but since we're not really reading very much data, it doesn't much matter.
ammon@zap:~$ time ./tail-seek.php a.log >/dev/null
real 0m0.017s
user 0m0.009s
sys 0m0.008s
ammon@zap:~$ time ./tail-seek.php b.log >/dev/null
real 0m0.017s
user 0m0.008s
sys 0m0.010s
ammon@zap:~$ time ./tail-seek.php c.log >/dev/null
real 0m0.023s
user 0m0.015s
sys 0m0.008s
Performance is a trifle slower on small files, but it's astronomically better on long ones. This is similar to the method used by most unix 'tail' commands, and is the clear winner for actual use in my application.
Of course, it needs a bit of cleanup from the state I've provided it in, and isn't appropriate for all environments... but it's a trifle better than requiring 20 seconds and 20gb of ram to execute 
Posted by Ammon as play at 12:08 PM EDT
No Comments »
I just spent 30 minutes trying to come up with a suitable opening for this post and have decided that it's simply not going to happen. A friend of mine sent me a copy of Byousoku Go Senchimetoru a few weeks ago. I couldn't sleep last night, so I watched it. I'm a fan of the director's previous work, Hoshi no Koe, so I thought I knew what to expect.
But just because I was expecting it doesn't mean I was in any way prepared. I was floored.
The story is beautiful and sad and the visuals are simply astounding. I give the movie a ten and I'm going to shut up now and just share some screen caps.













Posted by Ammon as anime at 4:55 AM EDT
2 Comments »
Wow, 5 technical posts in a row. I must be doing something right/wrong. Well, I'm certainly doing something, I'm just not entirely sure what that something is... but now it's time for something completely different.
Recently, I've been playing a good bit of Dream of Mirror Online (DOMO - not to be confused with Domo-kun), and I think it's safe to say that I'm hooked for now.
Earlier this month, Massively posted an article on five games they thought were better than WoW in one category or another. (It's not really that hard to beat WoW in one thing, their secret sauce is in the combination...). I agreed with the first four games on the list, but had never even heard of the fifth game - DOMO, which they claimed had a way better casual experience. Scouring their site, it turns out they've shown the game nothing but love, and a lot of it. So I suffered through the enormous download and slightly creepy registration process (they provided me with a gmail link to check my registration email when I was done...).
DOMO is what I've always referred to as a Korean style MMORPG (except that in this case it is actually by a Taiwanese game studio, for what it's worth). Normally, the genre is typified by soul crushingly repetitive grinding of mobs for the sole reason of becoming capable of grinding a different colour of mob. There is no plot, there is very little skill or thought involved. You buy health potions in batches of 1000 and drink 50 of them every kill - I've actually had other players recommend I wedge a penny in my keyboard to hold down the potion spam button...
These games can be fun... for a few hours, sometimes even days. But in all of my sampling of the genre (why I keep coming back, I'll never know), I've only really encountered 3 games I liked enough to spend more than a week on. DOMO makes four.
I like them because they appear to have learned from the mistakes of others, they actually address most of my standard gripes about the genre. For starters, they don't install a rootkit on your system and you can auto-reject duel requests...
For a free-to-play game (entirely optional micropayments), they offer one thing I'd never really really seen before. Content. For any given level of character in the stereotypical KMMO, there is precisely one optimal grinding spot that all players compete over. When you ding, you progress to the next spot and compete with those players. Maybe the mobs you compete for change models.
For a level 10-11 character in DOMO, I can think of four different places to hunt/quest. They actually have quests. And they're not all just the "kill 300 foozles and I will give you money" type quests (though there are admittedly a lot of those). So far, I have done quests that involved:
- Talking to all of the important NPC's in town so I know my way around.
- Bribing and bamboozling members of the thieves' guild in order to gain admission.
- Manufacturing a sturdy rope so I could gain access to a new dungeon.
- Slaying zombies to collect information and try to figure out why they're rising.
- Walking across a few maps while blind.
At around level 15, characters can learn to fly by surfing on their sword (the game is wuxia themed, after all). The quest to gain this ability involves defeating the Flying Frog King with a large party and getting some magical frog powder from him... (Which always reminds me of kind of the opposite of Discworld's dried frog pills, which were actually used to keep the Bursar from hallucinating that he could fly).
DOMO has a sense of humor. The art is cell shaded and cartoony (which I personally appreciate). The monsters are just a bit goofy. While the translation isn't 100% (when is it ever?), it's worth paying attention to quest dialog. During the introductory quests, you pose for pictures with one of the game universe's gods, etc... (and a little frog pops up to tell you how to take screenshots).
DOMO also has a refreshingly interesting pick-and-choose sort of class system. It's not really that innovative, other games have done it before... but I don't think any other multi-player game has done it as well. It reminds me of a cross between FFXI and FFT. Every character can advance levels separately in different classes (I am currently a lvl 17 thief, 15 fencer, 12 musician, and 11 doctor between the two characters I've been playing). You can then equip abilities that you learned on other classes - even if they do perform at slightly lowered efficiency. At higher levels, you can learn to equip gear from other classes as well - so you could play a wizard wearing mercenary heavy armour if desired.
Unlike FFXI, where you start every class at level 1... DOMO has a "Commoner" class that everyone starts with. You level commoner to 10 and then start questing to learn other classes. Every other job in the game starts at level 10. So far, I've found almost every class to be completely viable for solo play at 10 (Wizard is difficult because their spells cost components that are very expensive at low level).
One of the most interesting things about DOMO's class system is that they've made completely viable support roles available - no potion spamming here. And sure, while anybody can equip first aid as a secondary ability... many of a class's best abilities require you to equip that class's equipment as well. The doctor and musician classes are in high demand. If you're going to go fight anthropomorphic casks of wine in the basement, who wouldn't want to bring along a doctor who's going to suck the toxic booze out of your system with a 3 foot long syringe?
The game's crafting system starts off as pretty typical of the genre. You are encouraged to AFK while collecting resources by using consumable gathering tools in designated areas. Items gathered in this way are combined with normal mob drops to both create and upgrade equipment. Where DOMO improves on the old system is by actually making crafted equipment preferable to vendor equipment. Recipes must be gathered in a variety of ways, and the ability to actually use the recipes is purchased with your Commoner class's skill points.
The game has a cash shop, but very few of the items for sale there really affect gameplay. In fact, every one of them is entirely optional. Most are cosmetic in nature or offer temporary buffs of one sort or another. The only things from the item shop that really matter are pet tokens - can't get summons without either buying them from the cash shop or by buying them from another player in game. But there seems to be no shortage of players willing to sell you a starter pet for 10-20k game currency.
Of course, nobody's perfect. The two places where DOMO falls down in my eyes are in the documentation and in the archaic user interface.
The official US web page is almost devoid of useful information. You're much better off looking for an answer in the forums or one of several 3rd-party wikis. Because the translation isn't perfect, skill/quest descriptions may be misleading or confusing.
The UI suffers from similar problems. The game launcher hangs around after you've launched the game (but you can close it manually). All music is turned off by default. In order to toggle on the ability to see what other users are wearing you actually deselect the "Show equipment" option. And I don't even know what "Turn off player'" even means
NPC dialog takes over all other mouse input, so if you start a conversation with a quest giver and his chat bubbles start popping up behind your inventory window... well, tough. You'll just have to click through and hope you didn't care what he said, because you can't close the window (clicks anywhere are interpreted as instructions to progress the dialog). HUD notification text (such as from earning xp for a quest turnin or exchanging items with an NPC, etc...) take a LONG time to fade away, and since they often pop up during NPC interaction, they frequently obscure these chat bubbles as well.
They give players the option of WASD for movement (click-to-move is still the default), but don't give keyboard commands for target selection. So you still have to click on your enemies to start attacking them.
Most of the game's keybindings are just bizarre and can't be changed. Ctrl-X brings up your skill list, Ctrl-D for inventory, Ctrl-C for quest journal, etc...
Oh, and in order to cast a targeted spell on yourself, you have to actually click on your avatar (or on your character portrait in the UI). There's no way to automatically target self when casting heals while soloing, etc...
But I can live with all of that. Xfire seems to think that I've played a total of 26 hours since I installed the game 3 weeks ago (several of those hours were spent afking overnight while working in the glass mines).
Overall, I give the game an 8 out of 10. The UI gets a 3 and the fun factor gets a 9 - it is probably the best casual MMORPG I've seen since Puzzle Pirates. While certainly not a game for everyone, it is absolutely worth the cost if you're looking for something casual and silly with a good degree of replayability.
Thank you, DOMO. Thank you for giving me something to do in stead of my Sunwell dailies while waiting for WoW's next expansion. Thank you for renewing my faith in the free-to-play MMORPG industry.
p.s. Please forgive me my awful puns...
Posted by Ammon as play at 3:42 AM EDT
No Comments »