Piracy and Copy Protection

There’s been a lot of hooting and hollering in the media about copy protection and piracy.  DRM seems to be a rallying cry for the younger generation.  Which makes sense.  I figured I’d throw my own $.02 out there to the wind (for all the good its worth) But I’d first like to say that (as is true with all generalizations) this doesnt apply to all people all the time.

You really have 3 classes of people who might buy a game.  You have the people with enough disposable income not to care, they just buy their game, and use it as directed.  (please not I’m not discussing the as directed part, simply the who’s yelling part. I fully agree that as directed should come outside the bos — or be returnable — and should also be reduced to lay speak since most of us dont speak asshole lawyer.)  Those people really arent who’se yelling about DRM.

You have the gaming middle class who, more or less, wants to go straight.  They buy what they can when they can, but at $60 a pop they cant afford *everything* they want.  To varying degrees they have a couple of options.  They can pick what they *think* they’ll like best, and abstain from everything they cant afford, or they can “test-run” the game and see whether they like it first.  As someone who has bought a car before I know which one of those options makes the most sense to me… This stage is definitely not a plateau, though, it slopes down from the previous upper class to the next… lower class.

Finally there’s the poor people.  They have a computer.. maybe handed down.. maybe cannibalized…  Maybe they’re preteen to mid/late twenties.  Maybe they’ve got a job, maybe they dont. Maybe they’re in school, maybe not.  But the common denominator here is that you arent going to see a red penny from these people no matter what you do.  One does not squeeze blood from a stone.  These people have WAY more time than they have money, and so spending 2 days downloading, and 2 days searching for an install key, then a crack, is NOT a problem for them… It’s cheaper than buying the thing.  What, I think, game companies are missing is that a good number of these people WANT to be in the middle and upper gamer class, and when they get there they *will* spend money, because they’ll have more of that then time.

What I think *IS* interesting is the time to money ratio.  You develop a game that might take 10-30 hours to beat (in the case of non mmorpgs) or last forever (in the case of mmorpgs.)  Essentially you’re making something that appeals TO the people who have more time than money… Much like payday loans your target audience is pretty dangerous in general, fiscally.  And as people progress to upper gamer class you have way more money than time.  And you wonder why people are willing to fork over $30 to get a bunch of WoW gold so they can kill something besides “soft fluffy bunnies, which pose no threat to humanity” without having to neglect their wife and kids for 400 straight hours.

Crucify the young for being young, crucify the old for being old.  It makes you wonder… in the minds eye of the video gaming industry… does their ideal customer base actually exist?  I bet it lies dangerously, and precariously, in the same kind of balance that the tobacco industry lies: hook em while they’re young and bleed em dry as they age.  Except the tobacco company does it better, they dont actively vilify their young “patrons” they simply wait.

Writing your own shell in php

I’ve always wanted to write my own simple shell in php.  Call me a glutin for punishment, but it seems like something that a lot of people could use to be able to do… If your web app had a command line interface for various things… like looking up stats, or users, or suspending naughty accounts, or whatever…. wouldnt that be cool and useful?  Talk about geek porn.  Anyways this this morning I got around to tinkering with the idea, and here is what i came up with… It’s rough, and empty, but its REALLY easy to extend and plug into any php application.

apokalyptik:~/phpshell$ ./shell.php

/home/apokalyptik/phpshell > hello

hi there

/home/apokalyptik/phpshell > hello world

hi there world

/home/apokalyptik/phpshell > cd ..

/home/apokalyptik/ > cd phpshell

/home/apokalyptik/phpshell > ls

shell.php

/home/apokalyptik//phpshell > exit

apokalyptik:~/phpshell$ ./shell.php

See the source here: shell.phps

Internally Caching Longer Than Externally Caching

We use varnish for a lot of our file caching needs, and recently we figured out how to do something rather important through a combination of technologies. Imagine you have backend servers generating dynamic content based on user input. So your users do something that fits the following categories:

  • is expensive to generate dynamically, and should be served from cache
  • many requests come in for the same objects, bandwidth should be conserved
  • doesnt change very often
  • once changed needs to take effect quickly

Now wish varnish we’ve been using the Expires header for a long time with great success, but for this we were having no luck. If we set the expires header to 3 weeks, then clients also cache the content for 3 weeks (violating requirement #3.) We can kill the Expires header in varnish at vcl_deliver, but then clients don’t cache at all (#2.) We can add Content-Control, overwrite the Age (otherwise reported Age: will be greater than max-age), and kill the Expires headers in the same place, but this isn’t pretty, and seems like a cheap hack. Ideally we could rewrite the Expires header in varnish, but that doesn’t seem doable.

So what we ended up doing, was header rewriting at the load balancer (nginx.) inside our location tag we added the following:

proxy_hide_header Age;
proxy_hide_header Expires;
proxy_hide_header Cache-Control;
add_header Source-Age $upstream_http_Age;
expires  300s;

Now nginx setsa proper Cache-Control: and Expires: headers for us, disregarding what varnish serves out. Web clients dont check back for 5 minutes (reusing the old object) and varnish can cache until judgment dat because we get wild card invalidation

Isn’t technology fun?!

Simple TCP Daemon Example

Using some stuff I’ve covered in the past on my blog here’s a simple way to put up a daytime server (well to put any service onto a tcp port. I haven’t looked into its bi-directional capabilities yet, this was just sort of a proof-of-concept…

$ apt-get install ipsvd
$ wget http://blog.apokalyptik.com/files/daemonize/daemonize.c
$ cc daemonize.c -o daemonize
$ ./daemonize /var/run/daytime.pid /var/log/daytime.log 'tcpsvd 0 13 date'

start/stop and/or monit script are an extremely short jump from there… And kind of trivial/menial… so I leave that as an exercise to you… if you care 🙂

Is it simple enough?

One question I sometimes forget to ask myself, when I’m coming up with solutions to problems is this: “Is it simple enough?”  Even though I try and make a habit of asking myself that often I, sometimes, don’t ask often enough.    The lesson of the importance of simplicity in both software development and systems management is one of those lessons that you really only ever “learn” after you’re war scarred and battle weary.  One day it clicks, and you realize “hey… this should be easier.”

The interesting thing about the problems that we (as a community of tech minded developer types, and systems people) is that the majority of our solutions can be done easily.  Sure there’s always something… at the deep dark core of a really difficult problem… that will always be that arcane black magic voodoo bit of code.  But by and large everything else can (and should) be simple.

I wonder what stories you, my 2.5 readers, may have to share on the subject.  When was it that you became totally fed up with writing complex solutions?  Or have you some other opinion on the matter?

AIM Spam

has any body else noticed a huge increase in AIM spam lately?

I’m just waiting for the akismet-style service/plugin combo to come along for the IM space… It’s probably long overdue.

Autumn Leaves Leaf (Irc Bot) — Chanlogger

Simple, straight forward. Logs channel messages.

class Chanlogger < AutumnLeaf
 def did_receive_channel_message(sender, channel, msg)
  log_base = File::dirname(File::dirname(__FILE__)) + "/data/logs"
   subdir = log_base + "/" + Date::today.to_s[0..6]
  Dir::mkdir(subdir) if false == File::directory?(subdir)
  logfile = subdir + "/" + channel.to_s.sub('#','') + "@" + Date::today.to_s
  f = File::open(logfile, 'a')
  f.puts(Time::now.to_s + "\t" + sender.to_s + "\t" + msg.to_s)
  f.close()
 end
end

Just a friendly new years eve reminder!

Keep your WP installs up to date!  You never know who might b using the holidays (and their general hustle and bustle) to cloak their activities. Often times you’ll find that bad things happen while you we’re off doing other things for a while. This is usually no coincidence 🙂

So upgrade those WP’s kiddies!