<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Untitled</title>
	<atom:link href="http://ammonlauritzen.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://ammonlauritzen.com/blog</link>
	<description>and still for good reason.</description>
	<pubDate>Sat, 16 Aug 2008 13:48:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>wrath of the hunter king</title>
		<link>http://ammonlauritzen.com/blog/2008/08/16/wrath-of-the-hunter-king/</link>
		<comments>http://ammonlauritzen.com/blog/2008/08/16/wrath-of-the-hunter-king/#comments</comments>
		<pubDate>Sat, 16 Aug 2008 13:39:48 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[beta]]></category>

		<category><![CDATA[games]]></category>

		<category><![CDATA[hunters]]></category>

		<category><![CDATA[mmorpg]]></category>

		<category><![CDATA[numberchasing]]></category>

		<category><![CDATA[play]]></category>

		<category><![CDATA[warcraft]]></category>

		<category><![CDATA[wotlk]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=395</guid>
		<description><![CDATA[Well, it&#8217;s about that time again. WoW&#8217;s second expansion is in beta, and will be bringing with it an absolutely staggering number of changes. So far, I am very pleased with the way things are going.
Today, I am going to try to confine my ramblings to the subject of the hunter talent tree upgrades. Pet [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it&#8217;s about that time <a href='http://ammonlauritzen.com/blog/2006/10/09/burning_hunter_crusade/'>again</a>. WoW&#8217;s second expansion is in beta, and will be bringing with it an absolutely staggering number of changes. So far, I am <i>very</i> pleased with the way things are going.</p>
<p>Today, I am going to try to confine my ramblings to the subject of the hunter talent tree upgrades. Pet changes, new spells, and upgrades to old spells will have to wait until a future post or two. And of course, I&#8217;ve also got to write about the priest changes. Hmm&#8230; And I&#8217;m trying to get my warlock to 70 before the expansion as well&#8230; Anyway. Hunters. Talents. Go.</p>
<div style='float: right; padding: 0.25em; margin-left: 0.5em; border: thin dotted black;' id='heavy-beast-spec'>
<b>Beast Mastery Talents -  53 points</b></p>
<ul>
<li>Improved Aspect of the Hawk - rank 5/5</li>
<li>Endurance Training - rank 3/5</li>
<li>Focused Fire - rank 2/2</li>
<li>Aspect Mastery - rank 1/1</li>
<li>Unleashed Fury - rank 5/5</li>
<li>Ferocity - rank 5/5</li>
<li>Spirit Bond - rank 2/2</li>
<li>Intimidation - rank 1/1</li>
<li>Bestial Discipline - rank 2/2</li>
<li>Frenzy - rank 5/5</li>
<li>Ferocious Inspiration - rank 3/3</li>
<li>Bestial Wrath - rank 1/1</li>
<li>Catlike Reflexes - rank 3/3</li>
<li>Invigoration - rank 2/2</li>
<li>Serpent&#8217;s Swiftness - rank 5/5</li>
<li>Longevity - rank 3/3</li>
<li>The Beast Within - rank 1/1</li>
<li>Cobra Strikes - rank 3/3</li>
<li>Beast Mastery - rank 1/1</li>
</ul>
<p><b>Marksmanship Talents -  5 points</b></p>
<ul>
<li>Lethal Shots - rank 5/5</li>
</ul>
<p><b>Survival Talents -  3 points</b></p>
<ul>
<li>Hawk Eye - rank 3/3</li>
</ul>
</div>
<h3>Beastier Mastery</h3>
<p>At present, my hunter is a <a href='http://www.worldofwarcraft.com/info/classes/hunter/talents.html?tal=5320000050521205312510550201000000000000003300000000000000000000'>pretty heavy beast mastery spec</a>. If things remain largely unchanged, he will likely become <a href='http://www.worldofwarcraft.com/info/classes/hunter/talents2.html?tal=532000015052120531325313010050000000000000000000000000300000000000000000000000000'>even heavier beast spec</a> immediately upon getting the expansion. Of course&#8230; there is so much goodness in the pending changes that I might not actually stick with beast spec much past 70, but this is my current plan for day one in Northrend.</p>
<p>First, let&#8217;s discuss what I&#8217;m planning on giving up (initially). In order to get 53 points in beast mastery, I will have to give up 11 points from marksmanship and survival. The talents that are going byebye:</p>
<ul>
<li><b>Humanoid Slaying</b> (3 points, T1 survival) - No real pain here. This reduces my damage &#038; crit damage caused to Humanoids by +3% each. Of course&#8230; this talent is gone in the expansion anyway. It&#8217;s being replaced by the 5 point Improved Tracking ability which gives you +5% base damage to whatever you&#8217;re tracking. It&#8217;s nominally an upgrade, but it&#8217;s not worth the points.</li>
<li><b>Improved Hunter&#8217;s Mark</b> (5 points, T2 marks) - Shrug. This talent causes my mark&#8217;s +AP bonus to apply to melee damage as well (ie, my pet&#8217;s). That means -110 AP that my pet would normally enjoy against a target I&#8217;ve marked. That&#8217;s roughly 8 dps + whatever specials might gain from AP. In the expansion&#8230; the talent gets a major buff. Cost is reduced to 3 points and it also gains +30% to resist dispel. I like the improvement, but it&#8217;s still not earthshaking.</li>
<li><b>Go for the Throat</b> (2 points, T3 marks) - This one makes me cry. Go for the Throat causes my pet to regenerate 50 focus every time I score a ranged critical hit. Getting this talent back will probably be my first major focus - with the planned build, I&#8217;ll be able to get this back at level 77.</li>
<li><b>Aimed Shot</b> (1 point, T3 marks) - This one also makes me cry. I refuse to explain aimed shot. Anyone who&#8217;s read this far knows exactly what it does. I <i>might</i> pick this back up, but it will take some careful juggling.</li>
</ul>
<p>But oh&#8230; oh what am I going to get in exchange <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> It&#8217;s gonna rock.</p>
<p><b>Aspect Mastery</b> is a new T3 beast talent. For <u>one</u> point, it buffs your 3 basic aspects. Viper gets +10% to its mana regen rate. Monkey gets 10% damage reduction - that&#8217;s right, flat out absorption when the dodge fails. This also means monkey now helps when you&#8217;re getting hit by spells. Hawk gets +50% to its AP bonus. At level 70, hawk is worth +155 AP, so this talent is worth +77 AP. At level 80, hawk will be worth +300 AP&#8230; <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>While I&#8217;m going this deep in the tree (and since I don&#8217;t need the point for Aimed Shot any more), I&#8217;ll also be picking up a 3rd point in <b>Catlike Reflexes</b> for an additional +1% to my dodge and +3% to my pet&#8217;s dodge.</p>
<p><b>Invigoration</b> is a new T8 beast talent that for two points causes you to instantly regenerate 2% of your mana every time your pet scores a crit with a special. My pre-existing talents already give my pet +10% crit chance and double focus regen. I&#8217;m losing the focus regen from Go for the Throat but am also picking up both of the new T9 talents&#8230;</p>
<p><b>Longevity</b> costs 3 points at T9 beast and reduces cooldowns on Bestial Wrath, Intimidation, and all pet special abilities by 30%. Intimidate&#8217;s cooldown goes down from 60 seconds to 40; Bestial Wrath is down from 120 seconds to 84. These cooldowns were already short enough that I have macros that ensure I am able to burn them almost every time they&#8217;re up. The buff makes me giddy.</p>
<p>Reducing the cooldown on pet specials by 30% means I don&#8217;t have to rely on my pet&#8217;s focus dump ability any more. 30% more frequent crits from specials means 30% more frequent procs of Invigoration and happy joyful mana regeneration.</p>
<p><b>Cobra Strikes</b> costs 3 points at T9 beast and gives me a 60% chance when I crit with Arcane, Steady, or Kill shot to cause my pet&#8217;s next 3 specials to crit&#8230; In conjunction with Invigoration, this effectively reduces the mana cost for my Steady shots into the realm of the microscopic.</p>
<p>And of course, then there&#8217;s <b>Beast Mastery</b>, the new T11 talent. This will allow me to tame exotic pets (devilsaur, chimera, silithid, etc&#8230;) and effectively gives all of my pets +20 levels worth of talent points.</p>
<p>The only new beast talents that I&#8217;m not actually picking up with this build are:</p>
<ul>
<li>Animal Handler (T6, 2 points), which gives my pet +4% to hit (that&#8217;s never been a problem) and reduces the cooldown on the new Master&#8217;s Call ability by 10 seconds (from 60 to 50). I don&#8217;t think I&#8217;ll be using Master&#8217;s Call much. I&#8217;ve already got 84 second Bestial Wrath.</li>
<li>Separation Anxiety (T10, 5 points), which is quite probably very cool, really. Fully trained, it gives your pet +10% movement speed when <=20 yards from you and then turns the speed bonus into +10% dps once it gets 20 yards away. This makes interception time even faster and generally translates into an almost permanent +10% pet damage (since 20+ yards is a quite normal range for hunters to shoot from).</li>
</ul>
<p>I&#8217;m vaguely torn by Separation Anxiety. <i>Insert pun here</i>. To pick it up immediately upon WotLK launch would mean foregoing +5% crit chance, and my crits already give my pet huge bonuses that I wouldn&#8217;t want to go without.</p>
<p>Of course&#8230; the other two talent trees have gotten an even bigger upgrade. Beast was already terribly overpowered, so it is only fair. If it weren&#8217;t for the lure of exotic pets, I&#8217;d be all over the other trees. As it is, I&#8217;m having a hard time deciding what I want out of their first 3 tiers.</p>
<h3>Marksmanship</h3>
<p>The changes to the marks tree mean major improvements to hunter shots, reliable improvements to baseline DPS, and absolute gobs of bonus mana efficiency.</p>
<p>One of my longstanding gripes has been <b>Improved Concussive Shot</b>. In BC, it was a 5 point talent that gave the dubious benefit of a 20% chance of proccing a 3 second stun in addition to the daze effect. There are numerous problems with this that I really don&#8217;t want to get into since the bad talent is finally going away. In return, we get a sleek new 2 point talent that increases the duration of the daze by 2 seconds. This is pure awesome. If I were leveling a newbie hunter, this would be my first talent, hands down.</p>
<p>T1 marks also gets the 3 point <b>Focused Aim</b> talent, which gives hunters the same sort of 70% interruption resistance (while charging Aimed &#038; Steady) that other mana-using classes have traditionally been able to buy for low tier talents. I find this to be of questionable usefulness, however - especially since it&#8217;s a T1 talent that buffs abilities that aren&#8217;t available at level 10. Aimed shot is a T3 talent, so it is first available at level 20. Steady shot rank 1 is level 62&#8230;</p>
<p>T2 marks gets some amazing changes, I&#8217;ve already mentioned the buff to Improved Mark. </p>
<p><b>Careful Aim</b> makes an appearance at T2. All the way down from T7. Yup. They moved a tier seven talent down to tier two. And then they buffed it 3x. In stead of a puny +45% of your int converted into RAP, it now gives a full +100%. Epic win.</p>
<p>They have also switched the locations of Mortal Shots (+crit damage) and Efficiency (-mana cost). <b>Mortal Shots</b> is now T2 and becomes Aimed Shot&#8217;s pre-req (in stead of the other way around). Efficiency wasn&#8217;t very important at low levels, so moving it up to T4 makes more sense (when it&#8217;s saving you more than 1 or 2 mana per spell).</p>
<p>In stead of Careful Aim at T7, marks hunters now get <b>Piercing Shots</b> for 3 points. This gives Steady and Aimed shots the ability to ignore 6% of target armour. Very unshabby.</p>
<p><b>Rapid Recuperation</b> is a new 3 point T8 ability that helps mana efficiency. While using Rapid Fire, both the hunter&#8217;s and pet&#8217;s abilities are 60% cheaper. This makes for a lot of focus dump happiness for your pet. Additionally, Rapid Killing (which already reduces Rapid Fire&#8217;s cooldown) is improved by giving you a mana regen tick that heals you for 150% of the damage dealt by the +20% damage shot you fire to use the Rapid Killing charge. This is quite probably enough to keep high level hunters at full mana forever, so long as things keep dying.</p>
<p><b>Wild Quiver</b> is a new T9 (3 point) talent that gives you a 10% chance to fire an additional auto shot at 60% damage. Combine this with the fact that heavy marks hunters will likely be using Improved Hawk in stead of Viper (since the marks tree is really taking care of the hunter&#8217;s mana needs without it now)&#8230; and you have a LOT of extra arrows flying.</p>
<p>T9 also gets <b>Improved Steady Shot</b> (3 points). This gives your steady shots 15% chance to increase the damage of your next aimed/arcane/kill shot by 15% while reducing its mana cost by 40%. See? I told you. Mana efficiency.</p>
<p>The new T10 marks talent is <b>Marked for Death</b> (5 points). It gives your already improved hunter&#8217;s mark an additional +10% damage dealt by the hunter &#038; pet and increases your critical strike damage bonus of all shot spells by a further 10%. This really encourages the hunter to mark their targets but I wonder how it plays out with multiple hunters firing on the same target. Do they all get the bonus, or does only the hunter who placed the mark?</p>
<p>And <b>Chimera Shot</b> is the new T11 talent. It&#8217;s a 10 second cooldown shot for 125% damage that refreshes your current sting and procs an additional bonus depending on which sting was active. Serpent deals 40% of the sting&#8217;s normal damage instantly. Viper heals you for 60% of the amount it drains (mana efficiency). Scorpid procs a 10 second disarm attempt that can only occur once a minute. All told, way cool.</p>
<h3>Survival</h3>
<p>The big change at T1 for the survival tree is that the former pair of 3 point talents Monster Slaying and Humanoid Slaying have been replaced with the 5 point <b>Improved Tracking</b>. I&#8217;ve already discussed this above, but just to reiterate:</p>
<ul>
<li>Only costs 5 talent points in stead of 6.</li>
<li>+5% damage in stead of +3% damage and +3% crit damage.</li>
<li>Works on whatever you&#8217;re tracking in stead of just 4 different creature types.</li>
</ul>
<p>T2 gets a new talent called <b>T.N.T.</b>. <i>Hehe.</i> This gives your fire traps 15% chance to deal a 2 second stun when they do damage (I assume this means 15% each time the dot procs&#8230;). It also increases the crit chance of your explosive trap by 15%. And&#8230; the talent also extends these bonuses to your Explosive Shot (which is the new T11 talent that effectively acts as a ranged explosive trap). I could live with this.</p>
<p>Tier 2 also gets <b>Survival Instincts</b>. Yup, another high tier talent moving down into cherry picking range. They didn&#8217;t even nerf it in the process (but they didn&#8217;t buff it like they did Careful Aim). This formerly 5th tier talent gives you a whopping 4% damage reduction and 4% AP for 2 points.</p>
<p>T3 sees an upgraded version of <b>Deflection</b>. This talent previously cost 5 T2 points for +5% parry bonus. Now it costs 3 T4 points for +6% bonus. Deflection also becomes Counterattack&#8217;s new pre-req (since the old pre-req, Deterrence is becoming a baseline ability now). Win.</p>
<p>T3 also gets <b>Trap Mastery</b>, which is currently unimplemented. But I believe it is supposed to be a combination of the previous T3 Clever Traps talent and the previous T4 Trap Mastery talent.</p>
<p>And&#8230; T3 also gets an improved version of the formerly T4 Improved Feign Death. <b>Survival Tactics</b> (2 points) is Improved Feign Death (+4% to difficulty to resist feign) plus a 4 second reduction to Disengage&#8217;s cooldown.</p>
<p>At T4, <B>Surefooted</b> is slightly changed to cut the duration of snares in half. Previously it supposedly gave you a +15% chance to resist them, but I&#8217;m not the only one who&#8217;s noticed that a lot of CC/snare/etc&#8230; type effects are, well, simply irresistible. So this is a nice improvement. They&#8217;re actually doing this sort of thing all across the board (changing chance to resist effects that weren&#8217;t ever actually resistible to a reduction in that effect&#8217;s duration).</p>
<p><b>Lock and Load</b> is a new 3 point T4 survival talent that gives you a crazy weird clearcasting type effect that procs whenever you trap a target or 15% of the time you sting something. The proc is that your next 3 arcane and explosive shots are free to cast and have no cooldown (they normally both have a 6 second cooldown). I really wonder if successive explosive shot dots stack&#8230; because explosive trap + 3x explosive shot = actual big boy aoe dps. This would actually make hunters vaguely useful in situations where previously only mages &#038; warlocks would do.</p>
<p><b>Hunter vs Wild</b> is a new T5 talent for 3 points that increases you and your pet&#8217;s AP by 30% of your total stamina. 5 points in Survivalist are the nominal pre-req, but when considering taking a talent like this, who&#8217;d pass up a +10% stamina bonus anyway?</p>
<p><b>Noxious Stings</b> is new at T8 and has Wyvern as a pre-req and gives your wyvern sting a backlash effect that hits the dispeller for 50% of the remaining sting duration. In addition, it also increases all damage dealt to victims of your serpent sting by 3%. This really improves the usefulness of wyvern in pvp and makes serpent a nice addition to an improved mark in group situations. I don&#8217;t think this should be a T8 talent with a pre-req&#8230; but there really isn&#8217;t room to put it anywhere else <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><b>Point of No Escape</b> is a new T9 survival talent that costs 3 points and increases the crit chance of all attacks on victims of your ice traps (and possibly bear trap, but I think they&#8217;re doing away with that one). This is very nice for frost trap and potentially very very fun with the rumored changes to freeze trap (it won&#8217;t break on any old damage now). This means you might get to cycle off two big crit shots into something when breaking its freeze now.</p>
<p><b>Sniper Training</b> is another new T9 talent (3 points). This increases the damage dealt by steady, aimed, and explosive shots by 6% when you are >30 yards away from the target. It also (possibly more importantly) improves your chance to crit by 15% when executing with Kill Shot. It&#8217;s kind of a shame this is so mutually exclusive with Separation Anxiety (+pet dps at long range).</p>
<p>The new T10 survival talent is <b>Hunting Party</b> (5 points) and serves as an awesome hunter version of Vampiric Touch (shadow priest spell that dots an enemy and turns the damage into mana for the party). Hunting Party has Thrill of the Hunt as a pre-req (regen 40% of shot costs when you crit) and heals your whole party&#8217;s mana/energy/rage/runic power slightly whenever you crit with an arcane/explosive/steady shot. Hehehe. Oh, and remember, TNT gives explosive shots +15% to crit while Lock and Load makes them subject to chain clearcasting <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>And of course then there&#8217;s <b>Explosive Shot</b> at T11. We&#8217;ve already seen numerous other talents that improve it, but what is it? It&#8217;s a ranged explosive trap on a 6 second cooldown. It hits the primary target for a good chunk of fire damage and then splashes everything within 5 yards with a dot for half of the base damage again over 2 seconds.</p>
<p>And so&#8230; with so many wonderful options, I am really starting to wish for the first time that they will let us dual spec somehow. It would mean I can keep my insanely heavy beast spec for soloing and take something from marks and/or survival for groups/pvp. Mmm. Happy ideas.</p>
<p>Anyhow, I&#8217;ve spent entirely too long on this, and now I&#8217;m less sure than ever of what I&#8217;ll be doing with my 10 shiny new lvl 71-80 talent points. Oh well. Respecs aren&#8217;t really <i>that</i> expensive after all.</p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/08/16/wrath-of-the-hunter-king/feed/</wfw:commentRss>
		</item>
		<item>
		<title>burn down the stables (or: the bland pet conundrum)</title>
		<link>http://ammonlauritzen.com/blog/2008/08/02/burn-down-the-stables/</link>
		<comments>http://ammonlauritzen.com/blog/2008/08/02/burn-down-the-stables/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 22:13:54 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[games]]></category>

		<category><![CDATA[hunters]]></category>

		<category><![CDATA[ideas]]></category>

		<category><![CDATA[mmorpg]]></category>

		<category><![CDATA[play]]></category>

		<category><![CDATA[sleep]]></category>

		<category><![CDATA[warcraft]]></category>

		<category><![CDATA[wotlk]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=386</guid>
		<description><![CDATA[Two and a half months ago, I started writing a post on the topic of WoW hunter pets. In their present incarnation, they are boring and unbalanced. They&#8217;re difficult to learn how to use effectively and make tremendous time sinks.
In the time since I started this post WotLK has gone into beta and a lot [...]]]></description>
			<content:encoded><![CDATA[<p><i>Two and a half months ago, I started writing a post on the topic of WoW hunter pets. In their present incarnation, they are boring and unbalanced. They&#8217;re difficult to learn how to use effectively and make tremendous time sinks.</p>
<p>In the time since I started this post WotLK has gone into beta and a lot of things have changed. They seem to be making similar choices to those I was guessing at, only much cooler <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>However, since I hate to waste a good rant, I&#8217;m going to dust this thing off before it goes entirely stale. Let&#8217;s see what I can salvage.<br />
</i></p>
<div style='border: thin dotted #b82619; padding: 0.5em'><b>&lt;original-post&gt;</b><br />
Lately, there seems to have been a lot of discussion on the topic of hunter pets - especially in the wake of recent patches that have broken longstanding aggro mechanics.</p>
<p><a href='http://themystichunter.wordpress.com/2008/04/18/inevitable-normalization/'>Znodis</a> seems to think that sweeping normalization of pets is inevitable - ie, all pets will eventually have identical stats and have access to the exact same set of skills. <a href='http://www.maniasarcania.com/2008/05/01/pet-normalization-the-middle-way-part-ii/'>Mania</a> agrees in part, but is hoping for a middle ground solution - where all pets become viable not by giving all pets access to all abilities, but by guaranteeing that all pets have access to at least one ability of a given variety.</p>
<p>I think that any sort of large scale normalization that negates Blizzard&#8217;s (now long-standing) trend of slowly releasing unique abilities for individual races of pets&#8230; would be a mistake.</p>
<p>The core of the argument seems to be thus:</p>
<ol>
<li>Some pets are useless.</li>
<li>Because of this, people tend to gravitate toward 2 or 3 distinct sets of pets - even though there are some 20+ varieties available.</li>
</ol>
<p>You don&#8217;t see warlocks rioting in the streets because they have <u>never</u> had even the <i>illusion</i> of choice in their pets. Warlocks get a handful of pets, each of which is completely identical to any other comparably leveled and specced warlock&#8217;s version of the pet. They have a few novelty pets that come out for parties&#8230; but they generally stick to 2 or 3 different pets for 99% of all situations.</p>
<p>Hunters at least have a choice. They can use monkeys and flamingos and crabs if they want to. Not that there is any compelling reason to do so, other than the fact that staring at an endless array of cats, bears, pigs, and birds over the course of one&#8217;s entire hunter career gets a bit boring.</p>
<p>This is apparently a bad thing.</p>
<p>I think the only bad thing here is that Blizzard is wasting effort releasing pets that almost nobody uses. Why bother making spore bats tamable in the first place? No hunter big enough to tame one is going to waste his limited pet slots on&#8230; well, a complete waste of a slot. Not when there are pets out there that can hold aggro and eat conveniently available food and maybe do some damage while they&#8217;re at it&#8230;</p>
<p>The proposals I&#8217;ve seen from other hunters:</p>
<ol>
<li>Do away with useless pets forever.</li>
<li>Make all pets the same.</li>
<li>Make all pets mostly the same.</li>
<li>Take the time to balance each pet type and encourage people to use them.</li>
</ol>
<p>Nobody&#8217;ll bite the first option. They&#8217;re in game, it doesn&#8217;t do any real harm to leave them in.</p>
<p>Two and three are really the same thing. Turn pets into pretty skins around an otherwise identical blob of function. We&#8217;re already frighteningly close to this. Different attack speeds were done away with. Different travel speeds were done away with. Large pools of shared trainable abilities were added to allow hunters to respec around a pet&#8217;s natural deficiencies.</p>
<p>And nobody thinks that option 4 will fly either - nobody seems to think that Blizzard cares enough to dedicate the resources. And while I&#8217;m loathe to agree&#8230; I&#8217;d like to think that a compromise will be made. Blizzard clearly wants us to use different pets, they just don&#8217;t want to make them very interesting.</p>
<p>I&#8217;d like to suggest my own wacky solution.</p>
<h3>burn down the stables</h3>
<p>Stables are a pain, and they&#8217;re an unnecessary restriction on the class. Who else has to run back to an inn (or even more inconvenient location in some towns) to change their equipment? I mean, if a feral druid knows they might need to switch into a healing role for part of an instance run, they can always just carry a change of clothes.</p>
<p>This restriction becomes even more arbitrary feeling in the face of Death Knights possibly being able to perform little &#8216;mini-respecs&#8217; in the field. Warlocks can cycle through pets during combat - they can even spec to improve this process, why does a hunter have to run all the way to the back corner of Orgrimmar to trade their bear in for an owl?</p>
<p>But even worse than the arbitrariness of the stable system is the simple fact that it&#8217;s had a glaring bug since beta that nobody&#8217;s bothered fixing. Non-hunters can buy stable slots. They can&#8217;t use them for anything. So unlike a mage portal trainer who refuses to talk to non-mages, the stable master is more than happy to talk to and steal money from non-hunters.</p>
<p>And the stables don&#8217;t even always work. I&#8217;ve had pets get stuck in the stable and require GM assistance to extricate. And then there&#8217;s the elusive virtual pet slot that sometimes exists and sometimes doesn&#8217;t, depending on how you juggle things&#8230;</p>
<p>The system was clearly a rushed job that hasn&#8217;t had an ounce of polish in over three years. I say get rid of it, and replace it with something that works.</p>
<h3>so now what?</h3>
<p>Well, now we let hunters switch pets in the field. Just like mini-pets take up a player&#8217;s inventory, I&#8217;m willing to sacrifice some inventory room for the ability to take 3 or 4 pets adventuring with me.</p>
<p>This could be justified by giving the hunters a number of &#8216;whistles&#8217; that are associated with new pets as they&#8217;re captured. If they abandon a pet, the whistle becomes disassociated.</p>
<p>Allow hunters to capture pets even when they don&#8217;t have a free whistle slot (similar to a warlock&#8217;s enslave). Pets captured in this way do not gain loyalty and cannot be fed, so they&#8217;ll run away after a while. They do not persist through a logout, and they cannot be raised if they die. Since they have no training points and do -25% damage, they&#8217;re not useful as permanent pets - but they are useful to learn abilities and as a means of crowd control.<br />
<b>&lt;/original-post&gt;</b></div>
<p>Well, that wasn&#8217;t terribly outdated after all. Most of the changes (beta changes, so not entirely guaranteed to go live, of course) that obsolete some of my opinions are:</p>
<ol>
<li>Mini-pets are going into your spellbook.</li>
<li>The stable might have been increased in size by 2 slots.</li>
<li>All pet races have a unique ability.</li>
<li>Bite has been nerfed to act as simply another name for claw (a focus dump). Every race gets one or the other.</li>
<li>Pets now magically learn new abilities as they level, thus eliminating the need to go out and tame a lvl 63 ravager to teach your level 64 boar rank 9 gore&#8230;</li>
<li>Pets automatically level up to a minimum of 5 below their owner when tamed.</li>
<li>Loyalty is quite probably going away, so that&#8217;s no longer a concern for the &#8216;enslaved&#8217; pets I was pondering.</li>
<li>Along with loyalty, the often confusing training point system is gone and has been replaced with a much nicer and more familiar talent system. Each pet family falls into one of 3 trees.</li>
</ol>
<p>So what does this all mean? It means that Blizzard is normalizing pets in the best possible way. It means that there will finally be a real reason (other than aesthetics) to choose weird pet races. It means that I&#8217;m absolutely going to maintain a minimum of 3 pets now, and will have an easier time of doing it.</p>
<p>It also means that we have a slim chance that they will actually burn the stables down (by making pets into spells, just like mini-pets and mounts). I&#8217;m guessing that they&#8217;ll try to live with the broken stable system for a bit longer (as evidenced by their expanding it to 5 slots from 3), but I&#8217;m hoping that this is just a temporary mechanism that will be done away with when the expansion goes final (or in the patch immediately following).</p>
<p>I mean&#8230; they&#8217;re already getting rid of the pet trainers&#8230; and they&#8217;ve already written most of the systems we&#8217;d need for it&#8230; so why not get rid of the stables as well? Here&#8217;s to hoping.</p>
<p>&#8230;</p>
<p>Because encouraging us to keep more pets around without similarly increasing our access to said pets is just plain mean <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /></p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/08/02/burn-down-the-stables/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ccent</title>
		<link>http://ammonlauritzen.com/blog/2008/07/02/ccent/</link>
		<comments>http://ammonlauritzen.com/blog/2008/07/02/ccent/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 22:25:20 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[play]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=390</guid>
		<description><![CDATA[So&#8230; 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&#8230; but we&#8217;ve been growing enough here at work that the needs quickly outpaced my prior skillset. And since I was the closest [...]]]></description>
			<content:encoded><![CDATA[<p>So&#8230; I just finished the <a href='http://www.cisco.com/web/learning/le3/current_exams/640-822.html'>first half</a> of my <a href='http://www.cisco.com/web/learning/le3/le2/le0/le9/learning_certification_type_home.html'>CCNA</a> today.</p>
<p>I never really cared about networking much beyond that needed to make sure clients on a lan can talk to their dns server&#8230; but we&#8217;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 <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>It&#8217;s been fun and profoundly enlightening. I didn&#8217;t expect to have my way of thinking so radically altered, but I&#8217;m hardly complaining.</p>
<p>I&#8217;ll be starting up the <a href='http://www.cisco.com/web/learning/le3/current_exams/640-816.html'>second class</a> in a week or two. This&#8217;ll include such topics as VLANs, IPv6, and fancy routing protocols. I&#8217;m stoked.</p>
<p>It&#8217;s funny. I never finished college (though I took classes for roughly 10 years), so this is actually the first certificate of education I&#8217;ve received since highschool.</p>
<p>The comment was made at work that I&#8217;d dinged as a sysadmin. I haven&#8217;t. I&#8217;m just cherry picking my next few levels in netadmin <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/07/02/ccent/feed/</wfw:commentRss>
		</item>
		<item>
		<title>svn get revision</title>
		<link>http://ammonlauritzen.com/blog/2008/05/27/svn-get-revision/</link>
		<comments>http://ammonlauritzen.com/blog/2008/05/27/svn-get-revision/#comments</comments>
		<pubDate>Tue, 27 May 2008 20:57:04 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[play]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=388</guid>
		<description><![CDATA[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$ [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>What I want:</p>
<div class="syntax_hilite">
<div id="code-4">
<div class="code">ammon@hermes:~/repo$ svn info --get-revision .<br />
<span style="color:#800000;">1234</span></div>
</div>
</div>
<p></p>
<p>But of course, nothing like this exists.</p>
<p>Thankfully, svn info's output IS easy enough to parse. You just have to do it your self.</p>
<div class="syntax_hilite">
<div id="code-5">
<div class="code">ammon@hermes:~/repo$ svn info | grep Revision | awk -- <span style="color:#CC0000;">'{print $2}'</span><br />
<span style="color:#800000;">1234</span></div>
</div>
</div>
<p></p>
<p>Will give you the revision of your current checkout without the network hit of a call to svn log.</p>
<p>To get the current version of the repo itself (hits the network), add "-r HEAD" to the svn info call:</p>
<div class="syntax_hilite">
<div id="code-6">
<div class="code">ammon@hermes:~/repo$ svn info -r HEAD | grep Revision | awk -- <span style="color:#CC0000;">'{print $2}'</span><br />
<span style="color:#800000;">1280</span></div>
</div>
</div>
<p></p>
<p>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.</p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/05/27/svn-get-revision/feed/</wfw:commentRss>
		</item>
		<item>
		<title>php tail</title>
		<link>http://ammonlauritzen.com/blog/2008/05/27/php-tail/</link>
		<comments>http://ammonlauritzen.com/blog/2008/05/27/php-tail/#comments</comments>
		<pubDate>Tue, 27 May 2008 20:08:21 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[play]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=389</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>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.</p>
<p><i>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.</i></p>
<p>My original method:</p>
<div class="syntax_hilite">
<div id="php-11">
<div class="php"><span style="color:#FF9933; font-style:italic;">// tail-file.php</span><br />
<span style="color:#0000FF;">$arr</span> = @<a href="http://www.php.net/file"><span style="color:#000066;">file</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$fname</span>, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$arr</span> = <a href="http://www.php.net/array_slice"><span style="color:#000066;">array_slice</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$arr</span>, -<span style="color:#0000FF;">$lines</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$buf</span> = <a href="http://www.php.net/implode"><span style="color:#000066;">implode</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\</span><span style="color:#000099; font-weight:bold;">n</span>"</span>,<span style="color:#0000FF;">$arr</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>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.</p>
<p>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?</p>
<div class="syntax_hilite">
<div id="php-12">
<div class="php"><span style="color:#FF9933; font-style:italic;">// tail-array.php</span><br />
<span style="color:#0000FF;">$arr</span> = <a href="http://www.php.net/array_fill"><span style="color:#000066;">array_fill</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC66CC;">0</span>, <span style="color:#0000FF;">$lines</span>+<span style="color:#CC66CC;">1</span>, <span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\</span><span style="color:#000099; font-weight:bold;">n</span>"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p><span style="color:#0000FF;">$fp</span> = <a href="http://www.php.net/fopen"><span style="color:#000066;">fopen</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fname</span>, <span style="color:#FF0000;">"r"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#616100;">while</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/feof"><span style="color:#000066;">feof</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$line</span> = <a href="http://www.php.net/fgets"><span style="color:#000066;">fgets</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span>, <span style="color:#CC66CC;">4096</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$arr</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$line</span>; <span style="color:#FF9933; font-style:italic;">// faster than array_push()</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/array_shift"><span style="color:#000066;">array_shift</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$arr</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span><br />
<a href="http://www.php.net/fclose"><span style="color:#000066;">fclose</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$buf</span> = <a href="http://www.php.net/implode"><span style="color:#000066;">implode</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">""</span>,<span style="color:#0000FF;">$arr</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>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.</p>
<p>Given a 51 line, 4kb file, an average execution ($lines = 20) might look like this:</p>
<div class="syntax_hilite">
<div id="code-13">
<div class="code">ammon@zap:~$ time ./tail-file.<span style="">php</span> a.<span style="">log</span>&gt;/dev/null</p>
<p>real&nbsp; &nbsp; 0m0.015s<br />
user&nbsp; &nbsp; 0m0.009s<br />
sys&nbsp; &nbsp; &nbsp;0m0.007s</p>
<p>ammon@zap:~$ time ./tail-array.<span style="">php</span> a.<span style="">log</span>&gt;/dev/null</p>
<p>real&nbsp; &nbsp; 0m0.016s<br />
user&nbsp; &nbsp; 0m0.010s<br />
sys&nbsp; &nbsp; &nbsp;0m0.006s</div>
</div>
</div>
<p></p>
<p>Comparable enough. But given a 50,004 line (3.3mb) log file:</p>
<pre>
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
</pre>
<p>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...</p>
<pre>
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
</pre>
<p>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.</p>
<p>Of course, there are other methods. The one I finally settled on is this:</p>
<div class="syntax_hilite">
<div id="php-14">
<div class="php"><span style="color:#FF9933; font-style:italic;">// tail-seek.php</span><br />
<span style="color:#0000FF;">$fp</span> = <a href="http://www.php.net/fopen"><span style="color:#000066;">fopen</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fname</span>, <span style="color:#FF0000;">"r"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$lines_read</span> = <span style="color:#CC66CC;">0</span>;<br />
<span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$fp</span> !== <span style="color:#000000; font-weight:bold;">FALSE</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/fseek"><span style="color:#000066;">fseek</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$fp</span>, <span style="color:#CC66CC;">0</span>, SEEK_END <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$pos</span> = <span style="color:#0000FF;">$eof</span> = <a href="http://www.php.net/ftell"><span style="color:#000066;">ftell</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">do</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; --<span style="color:#0000FF;">$pos</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/fseek"><span style="color:#000066;">fseek</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span>, <span style="color:#0000FF;">$pos</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$c</span> = <a href="http://www.php.net/fgetc"><span style="color:#000066;">fgetc</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$c</span> == <span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\</span><span style="color:#000099; font-weight:bold;">n</span>"</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$lines_read</span>++;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">while</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$pos</span>&gt; <span style="color:#CC66CC;">0</span> &amp;&amp; <span style="color:#0000FF;">$lines_read</span> &lt;= <span style="color:#0000FF;">$lines</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#0000FF;">$buf</span> = <a href="http://www.php.net/fread"><span style="color:#000066;">fread</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span>, <span style="color:#0000FF;">$eof</span>-<span style="color:#0000FF;">$pos</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span><br />
<a href="http://www.php.net/fclose"><span style="color:#000066;">fclose</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fp</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>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.</p>
<pre>
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
</pre>
<p>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.</p>
<p>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 <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/05/27/php-tail/feed/</wfw:commentRss>
		</item>
		<item>
		<title>5cm per second</title>
		<link>http://ammonlauritzen.com/blog/2008/04/27/5cm-per-second/</link>
		<comments>http://ammonlauritzen.com/blog/2008/04/27/5cm-per-second/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 12:55:23 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[anime]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=367</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>But just because I was expecting it doesn't mean I was in any way prepared. I was floored.</p>
<p>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.</p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=369" title="5cm-sec-01"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15868383-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=371" title="5cm-sec-03"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15869754-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=372" title="5cm-sec-04"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15870118-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=373" title="5cm-sec-05"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15870970-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=374" title="5cm-sec-06"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15871947-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=375" title="5cm-sec-07"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15876145-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=376" title="5cm-sec-08"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15876584-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=377" title="5cm-sec-09"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15877884-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=378" title="5cm-sec-10"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15878267-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=379" title="5cm-sec-11"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15878463-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=380" title="5cm-sec-12"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15878596-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=381" title="5cm-sec-13"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15879052-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<p><a href="http://ammonlauritzen.com/blog/?attachment_id=370" title="5cm-sec-02"><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/vlcsnap-15879859-150x150.png" class="attachment-thumbnail" style='float: left; margin: 1em' alt="" height="150" width="150"></a></p>
<div style='clear: left;'></div>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/04/27/5cm-per-second/feed/</wfw:commentRss>
		</item>
		<item>
		<title>DOMO &#12354;&#12426;&#12364;&#12392;&#12358;</title>
		<link>http://ammonlauritzen.com/blog/2008/04/25/domo-arigatou/</link>
		<comments>http://ammonlauritzen.com/blog/2008/04/25/domo-arigatou/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 11:42:13 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[play]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=363</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, 5 technical posts in a row. I must be doing something right/wrong. Well, I'm certainly doing <u>something</u>, I'm just not entirely sure what that something is... but now it's time for something completely different.</p>
<p>Recently, I've been playing a good bit of Dream of Mirror Online (DOMO - not to be confused with <a href='http://youtube.com/results?search_query=domokun'>Domo-kun</a>), and I think it's safe to say that I'm hooked for now.</p>
<p><a href='http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-allaryin-portrait.jpg'><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-allaryin-portrait-216x300.jpg" alt="" title="domo-allaryin-portrait" width="216" height="300" style='float: left; margin-right: 0.5em; margin-bottom: 0.5em;'/></a>Earlier this month, Massively posted <a href='http://www.massively.com/2008/04/01/five-mmos-better-than-world-of-warcraft-part-1/'>an article</a> 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...).</p>
<p>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...</p>
<p>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.</p>
<p>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 <a href='http://en.wikipedia.org/wiki/GameGuard'>rootkit</a> on your system and you can auto-reject duel requests...</p>
<p>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.</p>
<p>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:</p>
<ul>
<li>Talking to all of the important NPC's in town so I know my way around.</li>
<li>Bribing and bamboozling members of the thieves' guild in order to gain admission.</li>
<li>Manufacturing a sturdy rope so I could gain access to a new dungeon.</li>
<li>Slaying zombies to collect information and try to figure out why they're rising.</li>
<li>Walking across a few maps while blind.</li>
</ul>
<p><a href='http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-demonic-zombie.jpg'><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-demonic-zombie-135x300.jpg" alt="" title="domo-demonic-zombie" width="135" height="300" style='float: right; margin-left: 0.5em; margin-bottom: 0.5em;' /></a>At around level 15, characters can learn to fly by surfing on their sword (the game is <a href='http://en.wikipedia.org/wiki/Wuxia'>wuxia</a> 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 <a href='http://wiki.lspace.org/wiki/Dried_frog_pills'>dried frog pills</a>, which were actually used to keep the <a href='http://wiki.lspace.org/wiki/Bursar'>Bursar</a> from hallucinating that he could fly).</p>
<p>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).</p>
<p>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.</p>
<p>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).</p>
<p>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?</p>
<p>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.</p>
<p><a href='http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-leola-portrait.jpg'><img src="http://ammonlauritzen.com/blog/wp-content/uploads/2008/04/domo-leola-portrait-175x300.jpg" alt="" title="domo-leola-portrait" width="175" height="300" style='float: left; margin-right: 0.5em; margin-bottom: 0.5em' /></a>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 <i>really</i> 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.</p>
<p>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.</p>
<p>The <a href='http://domo.aeriagames.com/'>official US web page</a> is almost devoid of useful information. You're much better off looking for an answer in <a href='http://forums.aeriagames.com/index.php?f=4'>the forums</a> or one of several 3rd-party <a href='http://domocamp.com/wiki/'>wikis</a>. Because the translation isn't perfect, skill/quest descriptions may be misleading or confusing.</p>
<p>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 <b>de</b>select the "Show equipment" option. And I don't even know what "Turn off player'" even means <img src='http://ammonlauritzen.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>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.</p>
<p>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.</p>
<p>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...</p>
<p>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...</p>
<p>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).</p>
<p>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.</p>
<p>Thank you, DOMO. Thank you for giving me something to do in stead of my <a href='http://wowwiki.com/Shattered_Sun_Offensive#Quests'>Sunwell dailies</a> while waiting for WoW's next expansion. Thank you for renewing my faith in the free-to-play MMORPG industry.</p>
<p><i>p.s. Please forgive me my awful puns...</i></p>

]]></content:encoded>
			<wfw:commentRss>http://ammonlauritzen.com/blog/2008/04/25/domo-arigatou/feed/</wfw:commentRss>
		</item>
		<item>
		<title>flash policy service daemon</title>
		<link>http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/</link>
		<comments>http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 09:05:10 +0000</pubDate>
		<dc:creator>Ammon</dc:creator>
		
		<category><![CDATA[flash]]></category>

		<category><![CDATA[howto]]></category>

		<category><![CDATA[networking]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[sleep]]></category>

		<category><![CDATA[sysadmin]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://ammonlauritzen.com/blog/?p=362</guid>
		<description><![CDATA[Sorry it took me so long to post this, but Wordpress 2.5 doesn't seem to like me trying to upload gz/zip files, so I had to upload the source manually.
Well, it's been months since I promised to post some usable socket policy service code, so I will.
The script here is meant to serve as a [...]]]></description>
			<content:encoded><![CDATA[<p><i>Sorry it took me so long to post this, but Wordpress 2.5 doesn't seem to like me trying to upload gz/zip files, so I had to upload the source manually.</i></p>
<p>Well, it's been months since <a href='http://ammonlauritzen.com/blog/2007/12/13/new-flash-security-policies/'>I promised</a> to post some usable socket policy service code, so I will.</p>
<p>The script here is meant to serve as a good starting point for people whose servers need to allow flash clients to make socket connections. I have not actually used this exact code in a production environment, but I have been using code that is 99% identical for a while now. I am confident that any blatant flaws are the result of simple copy-paste errors as I compiled the package. Please let me know if you find any.</p>
<p>I <u>have</u> however, stress tested the heck out of this service. One instance successfully served up over 16000 policy file requests fed into it as rapidly as I could send them. The same networking code has also handled requests from at least 100 different hosts at roughly the same time.</p>
<p>Everything has been combined into a single cli php script that requires no special installation. Just plop it down on the server and run it as root. It will take care of the rest. The config defaults should be safe, but you probably want to specify them more clearly - just to be safe.</p>
<p>The daemon is made of three classes:</p>
<ul>
<li><b>Logger</b> - A rudimentary log file management class that I copy from project to project in one form or another. The included version is stripped down from some of the other versions I've written, and I'm planning on releasing a more feature-rich version in the future.</li>
<li><b>Daemon</b> - A simple class for daemonizing a process. Adapted and re-adapted countless times from an original php4 class I found on the net a few years ago by some guy named Seth (whose email domain no longer exists).</li>
<li><b>FlashPolicyService</b> - The meat and potatoes, a child of Daemon. Mostly, this is just the requisite networking code and glue to make everything work together.</li>
</ul>
<p>As with any of my other code, this is licensed under <a href='http://creativecommons.org/licenses/by/3.0/'>CC Attribution 3.0</a>.</p>
<p>Download:</p>
<ul>
<li><a href='http://ammonlauritzen.com/FlashPolicyService-09b.zip'>FlashPolicyService-09b.zip</a> (4.4kb)</li>
</ul>
<p>Source code after the jump.<br />
<span id="more-362"></span></p>
<div class="syntax_hilite">
<div id="php-16">
<div class="php"><span style="color:#008000; font-style:italic;">#!/usr/local/bin/php</span><br />
<span style="color:#000000; font-weight:bold;">&lt;?php</span><br />
<span style="color:#008000;">/**<br />
&nbsp;* Flash Policy Service v0.9.b<br />
&nbsp;*<br />
&nbsp;* This script listens for &lt;policy-file-request/&gt; on port 843 and serves up<br />
&nbsp;* an xml crossdomain policy file. This sort of service is necessary if any<br />
&nbsp;* flash content is going to connect to sockets on the running host.<br />
&nbsp;*<br />
&nbsp;* I have made every effort to package everything you need into a single<br />
&nbsp;* file here, even though it could easily have been split into 3 or more<br />
&nbsp;* scripts.<br />
&nbsp;*<br />
&nbsp;* Requirements:<br />
&nbsp;*&nbsp; - PHP 5 with sockets, pcntl, and posix extensions<br />
&nbsp;*&nbsp; - Root access (to bind to a &lt;1024 port)<br />
&nbsp;*<br />
&nbsp;* Use:<br />
&nbsp;*&nbsp; Simply execute the script from the command line as root:<br />
&nbsp;*&nbsp; &nbsp; # ./FlashPolicyService.php<br />
&nbsp;*&nbsp; You can enable debug mode by invoking the script with '-d' as a parameter:<br />
&nbsp;*&nbsp; &nbsp; # ./FlashPolicyService.php -d<br />
&nbsp;*&nbsp; To stop the daemon, simply send it a SIGTERM and it should attempt to<br />
&nbsp;*&nbsp; exit cleanly.<br />
&nbsp;*<br />
&nbsp;*&nbsp; If you get 'bad interpreter' errors or the like, change the #! line to<br />
&nbsp;*&nbsp; reflect the actual installed location of your php cli.<br />
&nbsp;*<br />
&nbsp;* Configuration:<br />
&nbsp;*&nbsp; At present, there aren't very many config options. Simply edit the<br />
&nbsp;*&nbsp; section immediately following this header. Options are commented.<br />
&nbsp;*<br />
&nbsp;* License:<br />
&nbsp;*&nbsp; This code is made available under a Creative Commons Attribution 3.0<br />
&nbsp;*&nbsp; License. Basically, you can use it however you like, but I would<br />
&nbsp;*&nbsp; appreciate some credit when you do.<br />
&nbsp;*<br />
&nbsp;* Disclaimer:<br />
&nbsp;*&nbsp; I make no guarantees that this code won't make your server explode in a<br />
&nbsp;*&nbsp; shower of blue flames. However, I don't expect that it will. I am actually<br />
&nbsp;*&nbsp; confident that this code will be helpful.<br />
&nbsp;*<br />
&nbsp;*&nbsp; That said, this is still my beta release. If you find any bugs, please<br />
&nbsp;*&nbsp; let me know so I can fix them.<br />
&nbsp;*<br />
&nbsp;* - Ammon Lauritzen [Apr 21, '08]<br />
&nbsp;*&nbsp; &nbsp;http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/<br />
&nbsp;*/</span></p>
<p><span style="color:#008000;">/*** Config ***/</span></p>
<p><span style="color:#FF9933; font-style:italic;">// where should we save the log output?</span><br />
<span style="color:#0000FF;">$log_filename</span> = <span style="color:#FF0000;">"/tmp/flash-policy.log"</span>;</p>
<p><span style="color:#FF9933; font-style:italic;">// uncomment these lines to choose which user to run the daemon as</span><br />
<span style="color:#FF9933; font-style:italic;">// default behavior is to look up and attempt to run as 'nobody'</span><br />
<span style="color:#008000; font-style:italic;"># $daemon_uid = 99;</span><br />
<span style="color:#008000; font-style:italic;"># $daemon_gid = 99;</span></p>
<p><span style="color:#FF9933; font-style:italic;">// set this if you want to use an external file in stead of the default</span><br />
<span style="color:#0000FF;">$xml_filename</span> = <span style="color:#FF0000;">""</span>;<br />
<span style="color:#0000FF;">$default_xml</span> =<br />
&nbsp; &nbsp; <span style="color:#FF0000;">'&lt;'</span>.<span style="color:#FF0000;">'?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?'</span>.<span style="color:#FF0000;">'&gt;'</span>.<br />
&nbsp; &nbsp; <span style="color:#FF0000;">'&lt;cross-domain-policy xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:noNamespaceSchemaLocation=&quot;http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd&quot;&gt;'</span>.<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF0000;">'&lt;allow-access-from domain=&quot;*&quot; to-ports=&quot;*&quot; secure=&quot;false&quot; /&gt;'</span>.<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF0000;">'&lt;site-control permitted-cross-domain-policies=&quot;all&quot; /&gt;'</span>.<br />
&nbsp; &nbsp; <span style="color:#FF0000;">'&lt;/cross-domain-policy&gt;'</span>;</p>
<p><span style="color:#008000;">/*** You shouldn't have to edit anything below here ***/</span></p>
<p><span style="color:#FF9933; font-style:italic;">/////////////////////////////////////////////////////////////////////////////</span><br />
<span style="color:#000000; font-weight:bold;">class</span> Logger <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __construct<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$logfile</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logfile</span> = <span style="color:#0000FF;">$logfile</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">open_log</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: constructor</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __destruct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @<a href="http://www.php.net/fflush"><span style="color:#000066;">fflush</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">fh</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; @<a href="http://www.php.net/fclose"><span style="color:#000066;">fclose</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">fh</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: destructor</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> <a href="http://www.php.net/log"><span style="color:#000066;">log</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// deal with redundant log spam</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span> == <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">last_msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">last_msg_count</span>++;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">last_msg_count</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"Last message repeated "</span>.<span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">last_msg_count</span>.<span style="color:#FF0000;">" times."</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">lasg_msg</span> = <span style="color:#0000FF;">$msg</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">last_msg_count</span> = <span style="color:#CC66CC;">0</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// actually write the log message out</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: log</span></p>
<p>&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> write<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$msg</span> = <a href="http://www.php.net/sprintf"><span style="color:#000066;">sprintf</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"[%s] %s<span style="color:#000099; font-weight:bold;">\</span>n"</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"y-m-d H:i:s"</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<span style="color:#0000FF;">$msg</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$succ</span> = @<a href="http://www.php.net/fwrite"><span style="color:#000066;">fwrite</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">fh</span>, <span style="color:#0000FF;">$msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$succ</span> === <span style="color:#000000; font-weight:bold;">FALSE</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$msg</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: write</span></p>
<p>&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> open_log<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/file_exists"><span style="color:#000066;">file_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logfile</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/touch"><span style="color:#000066;">touch</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logfile</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/chmod"><span style="color:#000066;">chmod</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logfile</span>, <span style="color:#CC66CC;">0664</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">fh</span> = @<a href="http://www.php.net/fopen"><span style="color:#000066;">fopen</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logfile</span>, <span style="color:#FF0000;">"a"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: logger class</span></p>
<p><span style="color:#FF9933; font-style:italic;">/////////////////////////////////////////////////////////////////////////////</span><br />
<span style="color:#000000; font-weight:bold;">class</span> Daemon <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __construct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/error_reporting"><span style="color:#000066;">error_reporting</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/set_time_limit"><span style="color:#000066;">set_time_limit</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/global"><span style="color:#000066;">global</span></a> <span style="color:#0000FF;">$log_filename</span>, <span style="color:#0000FF;">$pid_filename</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logger</span> = <span style="color:#000000; font-weight:bold;">new</span> Logger<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$log_filename</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">pid_filename</span> = <span style="color:#0000FF;">$pid_filename</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log_tag</span> = <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> = <span style="color:#FF0000;">"launcher"</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"constructed"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: constructor</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __destruct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"destructing"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: destructor</span></p>
<p>&nbsp; &nbsp; protected <span style="color:#000000; font-weight:bold;">function</span> <a href="http://www.php.net/log"><span style="color:#000066;">log</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span>, <span style="color:#0000FF;">$tag</span> = <span style="color:#000000; font-weight:bold;">false</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$tag</span> == <span style="color:#000000; font-weight:bold;">false</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$tag</span> = <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log_tag</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">logger</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$tag</span>.<span style="color:#FF0000;">": "</span>.<span style="color:#0000FF;">$msg</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: log</span><br />
&nbsp; &nbsp; protected <span style="color:#000000; font-weight:bold;">function</span> debug<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span>, <span style="color:#0000FF;">$tag</span> = <span style="color:#000000; font-weight:bold;">false</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> DEBUG <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$msg</span>, <span style="color:#0000FF;">$tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: debug</span></p>
<p>&nbsp; &nbsp; protected <span style="color:#000000; font-weight:bold;">function</span> main<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"override main() in daemon subclass"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">stop</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: main</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> start<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"starting daemon"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<span style="color:#0000FF;">$this</span>-&gt;_start<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to start daemon"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// report execution details</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"uid = "</span>.<a href="http://www.php.net/posix_getuid"><span style="color:#000066;">posix_getuid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#FF0000;">", gid = "</span>.<a href="http://www.php.net/posix_getgid"><span style="color:#000066;">posix_getgid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"cwd = "</span>.<a href="http://www.php.net/getcwd"><span style="color:#000066;">getcwd</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// invoke main loop</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">running</span> = <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">while</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">running</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">main</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: start</span><br />
&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> _start<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<span style="color:#0000FF;">$this</span>-&gt;_fork<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: try to fork</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/posix_setsid"><span style="color:#000066;">posix_setsid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to setsid()"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: try to set sid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<span style="color:#0000FF;">$this</span>-&gt;_suid<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: try to set uid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// register signal handler</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; declare<span style="color:#006600; font-weight:bold;">&#40;</span>ticks = <span style="color:#CC66CC;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; pcntl_signal<span style="color:#006600; font-weight:bold;">&#40;</span> SIGTERM, <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>&amp;<span style="color:#0000FF;">$this</span>, <span style="color:#FF0000;">"on_sigterm"</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// chdir somewhere moderately safe by default</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/chdir"><span style="color:#000066;">chdir</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">'/tmp'</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: _start</span><br />
&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> _fork<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"forking..."</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$pid</span> = pcntl_fork<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$pid</span> == -<span style="color:#CC66CC;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// error</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to fork"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$pid</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// parent</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"done with parent"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/exit"><span style="color:#000066;">exit</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC66CC;">0</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// child</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> = <span style="color:#FF0000;">"daemon"</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">child</span> = <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">pid</span> = <a href="http://www.php.net/posix_getpid"><span style="color:#000066;">posix_getpid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"child pid = "</span>.<span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">pid</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: _fork</span><br />
&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> _suid<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/global"><span style="color:#000066;">global</span></a> <span style="color:#0000FF;">$daemon_uid</span>, <span style="color:#0000FF;">$daemon_gid</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$daemon_uid</span><span style="color:#006600; font-weight:bold;">&#41;</span> || !<a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$daemon_gid</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// we didn't get a uid/gid, try to make one up</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"searching for info on 'nobody'"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/posix_getpwnam"><span style="color:#000066;">posix_getpwnam</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"nobody"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$res</span> !== <span style="color:#000000; font-weight:bold;">FALSE</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$uid</span> = <span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'uid'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$gid</span> = <span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'gid'</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// the 'nobody' user doesn't exist on this system, refuse</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// to daemonize as root</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to find info on 'nobody' user"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"got uid/gid of $daemon_uid/$daemon_gid"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$uid</span> = <span style="color:#0000FF;">$daemon_uid</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$gid</span> = <span style="color:#0000FF;">$daemon_gid</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// actually try to switch now</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/posix_setgid"><span style="color:#000066;">posix_setgid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$gid</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to set gid to "</span>.<span style="color:#0000FF;">$gid</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<a href="http://www.php.net/posix_setuid"><span style="color:#000066;">posix_setuid</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">uid</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to set uid to "</span>.<span style="color:#0000FF;">$uid</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: _suid</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> stop<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"stopping daemon"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">running</span> = <span style="color:#000000; font-weight:bold;">false</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: stop</span></p>
<p>&nbsp; &nbsp; protected <span style="color:#000000; font-weight:bold;">function</span> on_sigterm<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$sig</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$sig</span> == SIGTERM <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"got SIGTERM"</span>, <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">daemon_tag</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">stop</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/exit"><span style="color:#000066;">exit</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC66CC;">0</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: on_sigterm</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: daemon class</span></p>
<p><span style="color:#FF9933; font-style:italic;">/////////////////////////////////////////////////////////////////////////////</span><br />
<span style="color:#000000; font-weight:bold;">class</span> FlashPolicyService extends Daemon <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __construct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parent::__construct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log_tag</span> = <span style="color:#FF0000;">"fps"</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"constructing"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">connections</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">request_str</span> = <span style="color:#FF0000;">"&lt;policy-file-request/&gt;"</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">port</span> = <span style="color:#CC66CC;">843</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// get our xml</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/global"><span style="color:#000066;">global</span></a> <span style="color:#0000FF;">$xml_filename</span>, <span style="color:#0000FF;">$default_xml</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <a href="http://www.php.net/strlen"><span style="color:#000066;">strlen</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$xml_filename</span><span style="color:#006600; font-weight:bold;">&#41;</span> || !<a href="http://www.php.net/file_exists"><span style="color:#000066;">file_exists</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$xml_filename</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"unable to read xml from '$xml_filename', using default"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">xml</span> = <span style="color:#0000FF;">$default_xml</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"reading policy xml from $xml_filename"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">xml</span> = <a href="http://www.php.net/file_get_contents"><span style="color:#000066;">file_get_contents</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$xml_filename</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"policy xml: "</span>.<span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">xml</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// make sure we're null terminated</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">xml</span> = <a href="http://www.php.net/trim"><span style="color:#000066;">trim</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">xml</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#FF0000;">"<span style="color:#000099; font-weight:bold;">\</span>n<span style="color:#000099; font-weight:bold;">\</span>0"</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// and get going</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">init</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: constructor</span></p>
<p>&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __destruct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; parent::__destruct<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">sock</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<a href="http://www.php.net/fclose"><span style="color:#000066;">fclose</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">sock</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: destructor</span></p>
<p>&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> init<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"init..."</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">check_socket</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent::<span style="color:#006600;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">log</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"not starting daemon"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: init</span></p>
<p>&nbsp; &nbsp; protected <span style="color:#000000; font-weight:bold;">function</span> main<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">sock</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">while</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#000000; font-weight:bold;">true</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">accept_socket</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#616100;">else</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">trace</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#FF0000;">"server socket is closed?!"</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent::<span style="color:#006600;">stop</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// paranoia to keep from absolutely hosing cpu if something goes wrong</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/usleep"><span style="color:#000066;">usleep</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC66CC;">10000</span> <span style="color:#006600; font-weight:bold;">&#41;</span>;&nbsp; &nbsp; <span style="color:#FF9933; font-style:italic;">// 10ms</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#FF9933; font-style:italic;">// end: main</span></p>
<p>&nbsp; &nbsp; private <span style="color:#000000; font-weight:bold;">function</span> check_socket<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">sock</span> = @<a href="http://www.php.net/socket_create"><span style="color:#000066;">socket_create</span></a><span style="color:#006600; font-weight:bold;">&#40;</span> AF_INET, SOCK_STREAM, SOL_TCP <span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span> !<span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">sock</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &n