<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Building Browsergames &#187; perl</title>
	<atom:link href="http://buildingbrowsergames.com/category/code/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://buildingbrowsergames.com</link>
	<description>Ever wanted to build a browsergame?</description>
	<lastBuildDate>Mon, 29 Mar 2010 14:00:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building Browsergames: Buying Armor (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/09/25/buying-armor-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/09/25/buying-armor-perl/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 14:00:08 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=418</guid>
		<description><![CDATA[For all that we&#8217;ve built weapons into our game, we&#8217;re still missing armor! Today we will be starting on the code for our armor system.
To start off, check out a copy of the source code for our tutorial:

svn checkout http://building-browsergames-tutorial.googlecode.com/svn/trunk/perl/pbbg tutorial -r 30

With that finished, we&#8217;re ready to start writing some code.
Based on our poll [...]]]></description>
			<content:encoded><![CDATA[<p>For all that we&#8217;ve built weapons into our game, we&#8217;re still missing armor! Today we will be starting on the code for our armor system.</p>
<p>To start off, check out a copy of the source code for our tutorial:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">svn checkout http://building-browsergames-tutorial.googlecode.com/svn/trunk/perl/pbbg tutorial -r 30</pre></div></div>

<p>With that finished, we&#8217;re ready to start writing some code.</p>
<p>Based on our poll from earlier, there are going to be 5 armor slots &#8211; head, torso, legs, right arm, and left arm. That&#8217;s a lot of stats &#8211; but not altogether difficult to add to our <em>stats</em> table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span>short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Armor - Head'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'ahead'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Armor - Torso'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'atorso'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Armor - Legs'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'alegs'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Armor - Right Arm'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'aright'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Armor - Left Arm'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'aleft'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Item Armor Slot'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>If you&#8217;ve been paying attention at all, you&#8217;ll have noticed that there are actually <strong>six</strong> stats being inserted above &#8211; the sixth one being <strong>Item Armor Slot</strong>. This stat was added so that we can keep track of which armor slot an item should end up in &#8211; we will take advantage of it later.</p>
<p>In order to display things, we&#8217;re going to need a template. With that in mind, we&#8217;ll create <strong>armor-shop.tmpl</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;The Armor Shop&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;p&gt;Welcome to the Armor Shop.&lt;/p&gt;
	&lt;p&gt;&lt;a href='index.cgi'&gt;Back to main&lt;/a&gt;&lt;/p&gt;
	&lt;h3&gt;Current Armor:&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;
			Head:
			&lt;tmpl_if name='ahead'&gt;
				&lt;!-- tmpl_var name='ahead'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='ahead' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Torso:
			&lt;tmpl_if name='atorso'&gt;
				&lt;!-- tmpl_var name='atorso'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='atorso' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Legs:
			&lt;tmpl_if name='alegs'&gt;
				&lt;!-- tmpl_var name='alegs'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='alegs' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Right Arm:
			&lt;tmpl_if name='aright'&gt;
				&lt;!-- tmpl_var name='aright'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='aright' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Left Arm:
			&lt;tmpl_if name='aleft'&gt;
				&lt;!-- tmpl_var name='aleft'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='aleft' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;You may purchase any of the armor listed below.&lt;/p&gt;
	&lt;tmpl_if name='error'&gt;
		&lt;p style='color:red'&gt;&lt;!--tmpl_var name='error'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;tmpl_if name='message'&gt;
		&lt;p style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;ul&gt;
		&lt;tmpl_loop name='armor'&gt;
			&lt;li&gt;
				&lt;strong&gt;&lt;!--tmpl_var name='name'--&gt;&lt;/strong&gt; - &lt;em&gt;&lt;!--tmpl_var name='price'--&gt; gold coins&lt;/em&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='armor-id' value='&lt;!--tmpl_var name=&quot;id&quot;--&gt;' /&gt;
					&lt;input type='submit' value='Buy' /&gt;
				&lt;/form&gt;
			&lt;/li&gt;
		&lt;/tmpl_loop&gt;
	&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>If that code looks at all similar to you, that&#8217;s because it is &#8211; it&#8217;s almost entirely copied from the weapon shop template code. While I prefer to write templates for each individual piece of functionality/view, no matter how similar they are, it&#8217;s entirely up to you &#8211; and you could probably refactor the two templates into one &#8211; although I&#8217;ll leave that as an exercise for the reader.</p>
<p>Seeing as there will probably be a lot more armor in our game compared to weapons(5 slots to fill instead of just 1 or 2), we&#8217;ll display a little bit more armor &#8211; and retrieve 10 different pieces using this query:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">,</span> price <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> type <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Armor'</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> RAND<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">10</span>;</pre></div></div>

<p>We&#8217;ve figured out how to display our armor shop, and how to retrieve the items that will be for sale inside of it &#8211; but we still haven&#8217;t written the page that will actually handle all of our functionality. It&#8217;s time to build <strong>armor-shop.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT DISTINCT(id), name, price FROM items WHERE type = 'Armor' ORDER BY RAND() LIMIT 10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@armor</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$row</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_hashref</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">push</span> <span style="color: #0000ff;">@armor</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$row</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>armor<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">\@armor</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@stats</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>atorso ahead alegs aright aleft<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@stats</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$id</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$key</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'armor-shop.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This code is extremely similar to the weapons shop, too &#8211; because at the core of it, all we&#8217;re doing for weapons or armor or any other type of item is shuffling items around. However, you may notice one fairly large difference between this and weapon shop code: there doesn&#8217;t seem to be any code to display the user&#8217;s current armor!</p>
<p>However, this isn&#8217;t actually true &#8211; all we&#8217;ve done is convert our retrieval logic to something that&#8217;s a little more generic when it retrieves things. Lines 34-45 contain all of the code we need to display as many stats we want &#8211; although we&#8217;re currently only displaying the current armor for the user.</p>
<p>It&#8217;s a fairly simple piece of code, really. We begin by defining the keys within our stats system for the different stats, and then looping through those keys. At that point, our code is the same as it&#8217;s always been &#8211; we just retrieve the name of our item, and then store it into our template. It&#8217;s pretty simple, and pretty handy &#8211; instead of writing 50+ lines of code(10 lines per armor slot), we&#8217;ve written just 10 that will handle it all for us. We can get away with doing this because of the way that we&#8217;ve set up the keys in both our stats system and our template &#8211; because they&#8217;re the same, we can retrieve from the database and store the data back into the template using the same key.</p>
<p>As cool as that is, though, we haven&#8217;t gotten to the actual <strong>point</strong> of our armor shop &#8211; buying armor! Therefore, we now need to build that logic. But before we can build that, we need to create <strong>armorstats.pm</strong>, so that we can retrieve stats for individual pieces of armor:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> armorstats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getArmorStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'Item'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>With that finished, we can now write our code to purchase armor:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">use</span> armorstats<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$armorID</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'armor-id'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$slot</span> <span style="color: #339933;">=</span> armorstats<span style="color: #339933;">::</span><span style="color: #006600;">getArmorStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'aslot'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$equipped</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$slot</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$equipped</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$slot</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'message'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You purchased and equipped the new armor.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;"># they already have something equipped - display an error message</span>
			<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'error'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You are already wearing a piece of that kind of armor! You will need to sell your current armor before you can buy new armor.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'error'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You cannot afford that piece of armor.'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And with that added, users can purchase armor to wear. As you can see, we are using our <em>aslot</em> stat to keep track of which armor slot a specific piece of armor goes in &#8211; that way, we can reduce the amount of code that we have to write to handle more than one different armor slot.</p>
<p>So now players can buy armor &#8211; but they can&#8217;t quite sell it yet. We&#8217;ll add in the code to handle what happens when a user clicks the &#8217;sell&#8217; button next to a piece of armor they&#8217;re wearing:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;">	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$armorID</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$price</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">$price</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #ff0000;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></pre></td></tr></table></div>

<p>And with that, users can now buy <strong>and</strong> sell armor. The last change we need to make is to <strong>index.tmpl</strong>, where we&#8217;ll add the &#8216;Armor Shop&#8217; link:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>19
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">	&lt;p&gt;&lt;a href='armor-shop.cgi'&gt;The Armor Shop&lt;/a&gt;&lt;/p&gt;</pre></td></tr></table></div>

<p>And that&#8217;s all there is to it! Here&#8217;s the code for <strong>armor-shop.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">use</span> armorstats<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$armorID</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$price</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$price</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">$price</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #ff0000;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$armorID</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'armor-id'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$slot</span> <span style="color: #339933;">=</span> armorstats<span style="color: #339933;">::</span><span style="color: #006600;">getArmorStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'aslot'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$equipped</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$slot</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$equipped</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$slot</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$armorID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'message'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You purchased and equipped the new armor.'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;"># they already have something equipped - display an error message</span>
				<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'error'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You are already wearing a piece of that kind of armor! You will need to sell your current armor before you can buy new armor.'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'error'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You cannot afford that piece of armor.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT DISTINCT(id), name, price FROM items WHERE type = 'Armor' ORDER BY RAND() LIMIT 10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@armor</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$row</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_hashref</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">push</span> <span style="color: #0000ff;">@armor</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$row</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>armor<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">\@armor</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@stats</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>atorso ahead alegs aright aleft<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@stats</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$id</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$key</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$name</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'armor-shop.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And here&#8217;s our template file(<strong>armor-shop.tmpl</strong>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;The Armor Shop&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;p&gt;Welcome to the Armor Shop.&lt;/p&gt;
	&lt;p&gt;&lt;a href='index.cgi'&gt;Back to main&lt;/a&gt;&lt;/p&gt;
	&lt;h3&gt;Current Armor:&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;
			Head:
			&lt;tmpl_if name='ahead'&gt;
				&lt;!-- tmpl_var name='ahead'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='ahead' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Torso:
			&lt;tmpl_if name='atorso'&gt;
				&lt;!-- tmpl_var name='atorso'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='atorso' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Legs:
			&lt;tmpl_if name='alegs'&gt;
				&lt;!-- tmpl_var name='alegs'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='alegs' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Right Arm:
			&lt;tmpl_if name='aright'&gt;
				&lt;!-- tmpl_var name='aright'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='aright' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Left Arm:
			&lt;tmpl_if name='aleft'&gt;
				&lt;!-- tmpl_var name='aleft'--&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='aleft' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;You may purchase any of the armor listed below.&lt;/p&gt;
	&lt;tmpl_if name='error'&gt;
		&lt;p style='color:red'&gt;&lt;!--tmpl_var name='error'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;tmpl_if name='message'&gt;
		&lt;p style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;ul&gt;
		&lt;tmpl_loop name='armor'&gt;
			&lt;li&gt;
				&lt;strong&gt;&lt;!--tmpl_var name='name'--&gt;&lt;/strong&gt; - &lt;em&gt;&lt;!--tmpl_var name='price'--&gt; gold coins&lt;/em&gt;
				&lt;form action='armor-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='armor-id' value='&lt;!--tmpl_var name=&quot;id&quot;--&gt;' /&gt;
					&lt;input type='submit' value='Buy' /&gt;
				&lt;/form&gt;
			&lt;/li&gt;
		&lt;/tmpl_loop&gt;
	&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>If you&#8217;re having issues getting some armor into your shop to play with, here&#8217;s a quick SQL query you can run to insert some sample armors:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">,</span>price<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Sample Helmet'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Sample Helmet'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'ahead'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">,</span>price<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Sample Torso'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Sample Torso'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'atorso'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">,</span>price<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Sample Legs'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Sample Legs'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'alegs'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">,</span>price<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Sample Right Arm'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Sample Right Arm'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'aright'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">,</span>price<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Sample Left Arm'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Armor'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>;
	<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'aslot'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'Sample Left Arm'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'aleft'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<h2>Extra Credit</h2>
<ol>
<li>Refactor the weapon shop code to use the same code as the armor shop for displaying current equipment.</li>
<li>Refactor the weapon/armor shop templates so that both pages can use the same template.</li>
<li>Refactor both pieces of code, so that there is only one template and one code file for weapons <strong>and</strong> armor.</li>
</ol>
<p class='blurb'>There was a small bug found in the weapon stat&#8217;s retrieval code during the writing of this entry &#8211; make sure to update your checked out version!</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/09/25/buying-armor-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Integrating weapons into our combat system (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/09/15/integrating-weapons-into-our-combat-system-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/09/15/integrating-weapons-into-our-combat-system-perl/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 14:00:29 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=358</guid>
		<description><![CDATA[Even though we&#8217;ve built a combat system and a weapons system, we haven&#8217;t done anything yet to make them work together. Today, we&#8217;re going to be modifying our combat system so that it takes into account the &#8216;attack&#8217; attribute of the user&#8217;s current primary weapon.
This is a quick, easy change &#8211; all we have to [...]]]></description>
			<content:encoded><![CDATA[<p>Even though we&#8217;ve built a <a href='http://buildingbrowsergames.com/2008/06/12/building-browsergames-a-simple-combat-system-perl/'>combat system</a> and a <a href='http://buildingbrowsergames.com/2008/08/20/swapping-weapons-perl/'>weapons system</a>, we haven&#8217;t done anything yet to make them work together. Today, we&#8217;re going to be modifying our combat system so that it takes into account the &#8216;attack&#8217; attribute of the user&#8217;s current primary weapon.</p>
<p>This is a quick, easy change &#8211; all we have to do is retrieve the &#8216;attack&#8217; stat for the user&#8217;s primary weapon, and then add it onto their attack stat for our combat calculations. Here&#8217;s the code that retrieves a players stats, from <strong>forest.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>28
29
30
31
32
33
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%player</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>
	name		<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$username</span><span style="color: #339933;">,</span>
	attack		<span style="color: #339933;">=&gt;</span>	stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'atk'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	defence		<span style="color: #339933;">=&gt;</span>	stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'def'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	curhp		<span style="color: #339933;">=&gt;</span>	stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'curhp'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If you&#8217;ve been following along with all of the tutorials so far, you might have noticed a slight problem: <strong>we can&#8217;t retrieve weapon stats yet</strong>. Thanks to our DRY changes from earlier, it&#8217;s easy to write that code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> weaponstats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getWeaponStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'Weapon'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>It&#8217;s even easier because we aren&#8217;t going to be allowing users to change the stats &#8211; which means we only need to write the code to retrieve them(and not update them).</p>
<p>With that finished, we&#8217;re going to make sure that <strong>forest.cgi</strong> includes the new code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>8
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> weaponstats<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Because our combat formula is as simple as it is(<em>attack</em> &#8211; <em>defence</em>), all we need to do is modify the &#8216;attack&#8217; value that we stored in the <em>%player</em> hash with the attack for their primary weapon:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$player</span><span style="color: #009900;">&#123;</span>attack<span style="color: #009900;">&#125;</span> <span style="color: #339933;">+=</span> weaponstats<span style="color: #339933;">::</span><span style="color: #006600;">getWeaponStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'atk'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And with that small piece of code added, we&#8217;re done! If the weapon has an attack value, it will be added to the player&#8217;s attack when they fight the monster &#8211; even if it&#8217;s negative.</p>
<h2>Extra Credit</h2>
<ul>
<li>Make it so that only positive attack values are added to the player&#8217;s attack.</li>
</ul>
<p class='blurb'>There was a small bug with the stats retrieval code found in this version of the tutorial &#8211; it has been fixed in the latest revision of the <a href='http://code.google.com/p/building-browsergames-tutorial'>Google Code Repository</a>. Make sure to update if you&#8217;ve been using it!</p></p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/09/15/integrating-weapons-into-our-combat-system-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: now on Google Code!</title>
		<link>http://buildingbrowsergames.com/2008/08/28/building-browsergames-now-on-google-code/</link>
		<comments>http://buildingbrowsergames.com/2008/08/28/building-browsergames-now-on-google-code/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 14:00:43 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gettingstarted]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=274</guid>
		<description><![CDATA[If you&#8217;ve been following along with our tutorial at all, you may have noticed that our code files tend to&#8230;evolve over time. Templates go from being simple list-of-links affairs to being filled with loops and conditionals and all kinds of other goodies.
Today, I have news for you that will make it much easier to follow [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been following along with our tutorial at all, you may have noticed that our code files tend to&#8230;<em>evolve</em> over time. Templates go from being simple list-of-links affairs to being filled with loops and conditionals and all kinds of other goodies.</p>
<p>Today, I have news for you that will make it much easier to follow the different versions that our tutorial goes through &#8211; it&#8217;s now under source control! With the help of <a href='http://www.johnmunsch.com'>John Munsch</a>, the Building Browsergames tutorial is now on Google Code. You can take a look at the project by visiting <a href='http://code.google.com/p/building-browsergames-tutorial/'>http://code.google.com/p/building-browsergames-tutorial/</a>. You can check out the latest version of the entire tutorial&#8217;s codebase by issuing this command:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">svn checkout http://building-browsergames-tutorial.googlecode.com/svn/trunk building-browsergames-tutorial-read-only</pre></div></div>

<p>Which will retrieve the latest version(in all languages) and store it into a directory called <em>building-browsergames-tutorial-read-only</em>. If you&#8217;d like to check out the latest version of the code for a specific language, you can use this command:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">svn checkout http://building-browsergames-tutorial.googlecode.com/svn/trunk/language/pbbg buildingbrowsergames-tutorial-read-only</pre></div></div>

<p>..Where &#8216;language&#8217; is one of the languages that the tutorial has been implemented in(currently, &#8216;perl&#8217;, &#8216;php&#8217;, and &#8216;rubyonrails&#8217; are available).</p>
<p>You can also update the code if you retrieved the latest copy and then new changes are committed by running the <em>svn update</em> command:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">svn update</pre></div></div>

<p>Don&#8217;t know what Subversion is, or how to use it on your system? Take a look at this <a href='http://blog.clickablebliss.com/2006/04/26/introduction-to-subversion-screencast/'>introduction to Subversion screencast</a> to learn more.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/08/28/building-browsergames-now-on-google-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Swapping Weapons (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/08/20/swapping-weapons-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/08/20/swapping-weapons-perl/#comments</comments>
		<pubDate>Wed, 20 Aug 2008 14:00:13 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=236</guid>
		<description><![CDATA[The results of our poll from earlier have been decided, and the option &#8216;Toggle active weapons&#8217; won by a slim margin. So, that&#8217;s what we&#8217;ll be building today!
The &#8217;swap weapon&#8217; page is a simple one &#8211; we&#8217;ve already written most of the code when we wrote the purchasing logic in our weapon shop from earlier. [...]]]></description>
			<content:encoded><![CDATA[<p>The results of our <a href='http://buildingbrowsergames.com/2008/08/05/implementing-ranged-weapons/'>poll from earlier</a> have been decided, and the option &#8216;Toggle active weapons&#8217; won by a slim margin. So, that&#8217;s what we&#8217;ll be building today!</p>
<p>The &#8217;swap weapon&#8217; page is a simple one &#8211; we&#8217;ve already written most of the code when we wrote the purchasing logic in our <a href='http://buildingbrowsergames.com/2008/08/12/building-browsergames-buying-weapons-perl/'>weapon shop</a> from earlier. To start off with, we&#8217;ll need a template(named <strong>equipment.tmpl</strong>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Equipment Management&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h3&gt;Current Equipment:&lt;/h3&gt;
	&lt;p&gt;&lt;a href='index.cgi'&gt;Back to main&lt;/a&gt;&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;
			Primary Hand:
			&lt;tmpl_if name='phand'&gt;
				&lt;!--tmpl_var name='phand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='phand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Secondary Hand:
			&lt;tmpl_if name='shand'&gt;
				&lt;!--tmpl_var name='shand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='shand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		&lt;form action='equipment.cgi' method='post'&gt;
			&lt;input type='submit' value='Swap' name='swap' /&gt;
		&lt;/form&gt;
	&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>This is a simple template, and is actually a duplication of our weapon shop&#8217;s template &#8211; right down to the &#8216;Sell&#8217; button. By leaving the &#8216;Sell&#8217; button on this page, users can sell their weapons from the equipment management screen if they so choose(also, because of this duplication we can trim this down to a common template &#8211; but that will come later). We have to make sure that the &#8217;swap&#8217; button has a &#8216;name&#8217; attribute, so that we can make sure our page was POSTed to and swap the player&#8217;s weapons.</p>
<p>Next, we&#8217;ll build <strong>equipment.cgi</strong>, which is the page responsible for retrieiving the weapons a user is user, and displaying our template:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$phand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand_name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>phand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># $sth is already prepared, so all we do is re-execute</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$shand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>shand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand_name</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'equipment.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>We don&#8217;t need to add much to implement weapon swapping; just a simple swap when users click on the &#8217;swap&#8217; button. We do this by checking to see if the page has been POSTed to &#8211; if it has, we perform the swap:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$temp</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$temp</span><span style="color: #339933;">;</span>	
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>With that done, we&#8217;re finished! Users can now swap the weapons in their primary and secondary hands quickly and easily from the equipment management page. All we have left to do is add a link to the equipment management page to our index template:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>19
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">	&lt;p&gt;&lt;a href='equipment.cgi'&gt;Equipment Management&lt;/a&gt;&lt;/p&gt;</pre></td></tr></table></div>

<p>And we&#8217;re done! Here&#8217;s our template:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Equipment Management&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h3&gt;Current Equipment:&lt;/h3&gt;
	&lt;p&gt;&lt;a href='index.cgi'&gt;Back to main&lt;/a&gt;&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;
			Primary Hand:
			&lt;tmpl_if name='phand'&gt;
				&lt;!--tmpl_var name='phand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='phand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Secondary Hand:
			&lt;tmpl_if name='shand'&gt;
				&lt;!--tmpl_var name='shand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='shand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;
		&lt;form action='equipment.cgi' method='post'&gt;
			&lt;input type='submit' value='Swap' name='swap' /&gt;
		&lt;/form&gt;
	&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>And here&#8217;s the code responsible for displaying it and handling the swap:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$temp</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$temp</span><span style="color: #339933;">;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$phand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand_name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>phand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># $sth is already prepared, so all we do is re-execute</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$shand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>shand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand_name</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'equipment.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/08/20/swapping-weapons-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Buying Weapons (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/08/12/building-browsergames-buying-weapons-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/08/12/building-browsergames-buying-weapons-perl/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 14:00:21 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=155</guid>
		<description><![CDATA[The winner in our poll from earlier in regards to weapons was that players should be able to carry two weapons(of any type they want), with a primary and a secondary hand that can both have weapons in them.
Our stats system is the perfect way to implement this &#8211; we just add two more stats, [...]]]></description>
			<content:encoded><![CDATA[<p>The winner in <a href='http://buildingbrowsergames.com/2008/07/21/important-design-choices/'>our poll from earlier</a> in regards to weapons was that players should be able to carry two weapons(of any type they want), with a primary and a secondary hand that can both have weapons in them.</p>
<p>Our stats system is the perfect way to implement this &#8211; we just add two more stats, so that we can keep track of which weapon is in the player&#8217;s primary hand, and which is in their secondary hand.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> stats<span style="color: #66cc66;">&#40;</span>display_name<span style="color: #66cc66;">,</span> short_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Primary Hand Weapon'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'phand'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Secondary Hand Weapon'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'shand'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>With our new stats inserted, we can write code to take advantage of them. But how will users get weapons to populate those stats with?</p>
<p>For now at least, players will buy weapons at the Weapon Shop &#8211; which is what we will build today. The weapon shop will display a list of weapons that are available for players to purchase, and automatically put the weapon purchased into a player&#8217;s primary or secondary hand for the player8.</p>
<p>In order to make our items work in a shop setting, however, we need to add something that we&#8217;re currently missing &#8211; prices! We&#8217;ll add a column to our <em>items</em> table called &#8216;price&#8217;, because every item should have a price. We&#8217;ll also set it to a default of 10(so prices are defaulted to 10 gold coins):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span>  <span style="color: #ff0000;">'items'</span> <span style="color: #993333; font-weight: bold;">ADD</span>  <span style="color: #ff0000;">'price'</span> INT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span>  <span style="color: #ff0000;">'10'</span>;</pre></div></div>

<p>With that change made, we can start building the template for our Weapon Shop. To start off, we&#8217;ll build a template and save it as <strong>weapon-shop.tmpl</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;The Weapon Shop&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;p&gt;Welcome to the Weapon Shop.&lt;/p&gt;
	&lt;h3&gt;Current Equipment:&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Primary Hand: &lt;tmpl_if name='phand'&gt;&lt;!--tmpl_var name='phand'--&gt;&lt;tmpl_else&gt;None&lt;/tmpl_if&gt;&lt;/li&gt;
		&lt;li&gt;Secondary Hand: &lt;tmpl_if name='shand'&gt;&lt;!--tmpl_var name='shand'--&gt;&lt;tmpl_else&gt;None&lt;/tmpl_if&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Below are the weapons currently available for purchase.&lt;/p&gt;
	&lt;ul&gt;
		&lt;tmpl_loop name='weapons'&gt;
			&lt;li&gt;
				&lt;strong&gt;&lt;!--tmpl_var name='name'--&gt;&lt;/strong&gt; - &lt;em&gt;&lt;!--tmpl_var name='price'--&gt; gold coins&lt;/em&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='weapon-id' value='&lt;!--tmpl_var name=&quot;id&quot;--&gt;' /&gt;
					&lt;input type='submit' value='Buy' /&gt;
				&lt;/form&gt;
			&lt;/li&gt;
		&lt;/tmpl_loop&gt;
	&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>As you can see in our template, we&#8217;ll be using a <em>tmpl_loop</em> to list off all of the weapons that are available for users to purchase. We&#8217;re going to use a fairly simple SQL query to retrieve 5 weapons(If you&#8217;d like to see the SQL query to retrieve a random list of items, take a look at yesterday&#8217;s post on <a href='http://buildingbrowsergames.com/2008/08/11/building-browsergames-buying-weapons-php/'>Building the Weapon Shop in PHP</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> name<span style="color: #66cc66;">,</span> price <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> type <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Weapon'</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">5</span>;</pre></div></div>

<p>Now that we have written the SQL query we&#8217;ll be using to retrieve our wepaons for sale, we need to quickly write the Perl to handle the information returned by that query, inside <strong>weapon-shop.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT DISTINCT(id), name, price FROM items WHERE type = 'Weapon' LIMIT 5&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@weapons</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$row</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_hashref</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">push</span> <span style="color: #0000ff;">@weapons</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$row</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>weapons<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">\@weapons</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$phand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand_name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>phand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;"># $sth is already prepared, so all we do is re-execute</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$shand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>shand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand_name</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'weapon-shop.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>We loop through all of the data that our SQL query returns, and add the information to an array &#8211; using that array, we display information on each weapon that is available within our weapon shop. We display each weapon&#8217;s name, price, and a &#8216;Buy&#8217; button that users can use to purchase the weapon in question. Now all we need to do is make it possible for users to actually buy the weapons.</p>
<p>As you saw in our template, there is a form inside each of our weapon entries, with a &#8216;Buy&#8217; button and a hidden input that stores the ID of the weapon users might choose to buy. We will modify <strong>weapon-shop.cgi</strong> so that when users click on the &#8216;Buy&#8217; button, we purchase the weapon in question for them &#8211; or display a helpful message if they can&#8217;t afford it. First off, we&#8217;ll modify our template so that it can display the messages for us:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>13
14
15
16
17
18
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;tmpl_if name='error'&gt;
	&lt;p style='color:red'&gt;&lt;!--tmpl_var name='error'--&gt;&lt;/p&gt;
&lt;/tmpl_if&gt;
&lt;tmpl_if name='message'&gt;
	&lt;p style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/p&gt;
&lt;/tmpl_if&gt;</pre></td></tr></table></div>

<p>With that quick modification made, we can add to our code so that we can handle users clicking on the &#8216;Buy&#8217; button for specific weapons:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$weaponID</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'weapon-id'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$weaponID</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You equipped the weapon in your primary hand.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$weaponID</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You equipped the weapon in your secondary hand.'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You already have two weapons! You must sell one before equipping another.'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You cannot afford that weapon!'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>We have written some simple logic to swap the weapons for our player in this situation &#8211; if their primary hand is empty, that is where the weapon goes. If their secondary hand is empty, it goes there &#8211; and if both hands are full, a message is displayed telling the user to sell one of their weapons.</p>
<p>At the moment, there isn&#8217;t a way for users to sell their weapons if they want to purchase a new one &#8211; but not for long! Open up <strong>weapon-shop.tmpl</strong> again, and edit these lines:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;li&gt;
	Primary Hand:
	&lt;tmpl_if name='phand'&gt;
		&lt;!--tmpl_var name='phand'--&gt;
		&lt;form action='weapon-shop.cgi' method='post'&gt;
			&lt;input type='hidden' name='sell' value='phand' /&gt;
			&lt;input type='submit' value='Sell' /&gt;
		&lt;/form&gt;
	&lt;tmpl_else&gt;
		None
	&lt;/tmpl_if&gt;
&lt;/li&gt;
&lt;li&gt;
	Secondary Hand:
	&lt;tmpl_if name='shand'&gt;
		&lt;!--tmpl_var name='shand'--&gt;
		&lt;form action='weapon-shop.cgi' method='post'&gt;
			&lt;input type='hidden' name='sell' value='shand' /&gt;
			&lt;input type='submit' value='Sell' /&gt;
		&lt;/form&gt;
	&lt;tmpl_else&gt;
		None
	&lt;/tmpl_if&gt;
&lt;/li&gt;</pre></td></tr></table></div>

<p>With our template modified, we&#8217;ll switch back to editing <strong>weapon-shop.cgi</strong>, and make a small change so that we can work off of the new arguments sent to us:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;">	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$weaponID</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #ff0000;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></pre></td></tr></table></div>

<p>And with that done, users are able to buy and sell weapons at the weapon shop. There is only one change left to make &#8211; adding a link to the weapon shop in our main template:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>18
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">	&lt;p&gt;&lt;a href='weapon-shop.cgi'&gt;The Weapon Shop&lt;/a&gt;&lt;/p&gt;</pre></td></tr></table></div>

<p>And that&#8217;s that! We&#8217;ve built a fully working weapon shop, that allows users to buy and sell weapons at will. Here&#8217;s the code from <strong>weapon-shop.cgi</strong> in it&#8217;s entirety:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> stats<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$weaponID</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>sell<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #ff0000;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$weaponID</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'weapon-id'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT price FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cost</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$cost</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$gold</span> <span style="color: #339933;">=</span> stats<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'phand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$phand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$weaponID</span><span style="color: #339933;">;</span>
				<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You equipped the weapon in your primary hand.'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'shand'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$weaponID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					stats<span style="color: #339933;">::</span><span style="color: #006600;">setStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'gc'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$gold</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$cost</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #0000ff;">$shand</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$weaponID</span><span style="color: #339933;">;</span>
					<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You equipped the weapon in your secondary hand.'</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You already have two weapons! You must sell one before equipping another.'</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'You cannot afford that weapon!'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT DISTINCT(id), name, price FROM items WHERE type = 'Weapon' LIMIT 5&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@weapons</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$row</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_hashref</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">push</span> <span style="color: #0000ff;">@weapons</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$row</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>weapons<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">\@weapons</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$phand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$phand_name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>phand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$phand_name</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># $sth is already prepared, so all we do is re-execute</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$shand</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$shand_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>shand<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$shand_name</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$shand_name</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'weapon-shop.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And here&#8217;s our template file(<strong>weapon-shop.tmpl</strong>):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;The Weapon Shop&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;p&gt;Welcome to the Weapon Shop.&lt;/p&gt;
	&lt;h3&gt;Current Equipment:&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;
			Primary Hand:
			&lt;tmpl_if name='phand'&gt;
				&lt;!--tmpl_var name='phand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='phand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
		&lt;li&gt;
			Secondary Hand:
			&lt;tmpl_if name='shand'&gt;
				&lt;!--tmpl_var name='shand'--&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='sell' value='shand' /&gt;
					&lt;input type='submit' value='Sell' /&gt;
				&lt;/form&gt;
			&lt;tmpl_else&gt;
				None
			&lt;/tmpl_if&gt;
		&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Below are the weapons currently available for purchase.&lt;/p&gt;
	&lt;tmpl_if name='error'&gt;
		&lt;p style='color:red'&gt;&lt;!--tmpl_var name='error'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;tmpl_if name='message'&gt;
		&lt;p style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/p&gt;
	&lt;/tmpl_if&gt;
	&lt;ul&gt;
		&lt;tmpl_loop name='weapons'&gt;
			&lt;li&gt;
				&lt;strong&gt;&lt;!--tmpl_var name='name'--&gt;&lt;/strong&gt; - &lt;em&gt;&lt;!--tmpl_var name='price'--&gt; gold coins&lt;/em&gt;
				&lt;form action='weapon-shop.cgi' method='post'&gt;
					&lt;input type='hidden' name='weapon-id' value='&lt;!--tmpl_var name=&quot;id&quot;--&gt;' /&gt;
					&lt;input type='submit' value='Buy' /&gt;
				&lt;/form&gt;
			&lt;/li&gt;
		&lt;/tmpl_loop&gt;
	&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<h2>Extra Credit</h2>
<ol>
<li>Make the shop display how much gold a user has remaining after they purchase a weapon.</li>
<li>Make the shop display only weapons that the player can afford.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/08/12/building-browsergames-buying-weapons-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Securing our hashes (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 14:00:59 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=85</guid>
		<description><![CDATA[Yesterday, we worked on securing our hashes in PHP &#8211; and today, we&#8217;re going to take a look at our Perl systems.
According to tilly from perlmonks, crypt() is horribly insecure &#8211; which is definitely a big problem. We&#8217;re going to need to update our login and registration system, so that our user&#8217;s passwords are a [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, we worked on <a href='http://buildingbrowsergames.com/2008/07/15/securing-our-hashes-php/'>securing our hashes</a> in PHP &#8211; and today, we&#8217;re going to take a look at our Perl systems.</p>
<p>According to <a href='http://perlmonks.org/?node=tilly'>tilly from perlmonks</a>, crypt() is horribly insecure &#8211; which is definitely a big problem. We&#8217;re going to need to update our login and registration system, so that our user&#8217;s passwords are a little bit more secure if a malicious user ever gained access to our database.</p>
<p>First off, we&#8217;re going to convert our code to use the <a href='http://search.cpan.org/~gaas/Digest-MD5-2.36/MD5.pm'>Digest::MD5</a> module so that we can MD5 our passwords &#8211; in addition to salting them. If you don&#8217;t have it already, you&#8217;ll need to install Digest::MD5. Enter this at your shell(or get your web host to install it for you if they haven&#8217;t already):</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">cpan install Digest::MD5</pre></div></div>

<p>After installing Digest::MD5, we need to change each line that calls <em>crypt()</em> inside register.cgi and login.cgi. Here&#8217;s what the relevant line in register.cgi looks like now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>33
34
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;">			<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And that&#8217;s the only change that you need to make to your register or login code &#8211; just adjusting your execute() statements to md5 the password, and making sure that you
<pre>use Digest::MD5</pre>
<p> in each code file.</p>
<p>However, if you upload your new files and take a look, you&#8217;ll notice something &#8211; you can no longer log in!</p>
<p>Unfortunately, making this change has broken logins for all of our users who signed up before we had to make this change. Now, if your game hasn&#8217;t been released to the public yet or everyone is used to you &#8216;resetting&#8217; the game, this is fine &#8211; but if users are already playing your game, this is a bit of an issue. So we&#8217;re going to modify <strong>login.cgi</strong>, so that it first checks to see whether a user is still using a crypt()&#8217;d password or not &#8211; and if they are, it will redirect them to a page where they can change their password. Here&#8217;s what login.cgi looks like now:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI<span style="color: #339933;">::</span><span style="color: #006600;">Carp</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>fatalsToBrowser warningsToBrowser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>		<span style="color: #666666; font-style: italic;"># this is our database settings</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'login.tmpl'</span><span style="color: #339933;">,</span>
		associate	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$query</span><span style="color: #339933;">,</span>		<span style="color: #666666; font-style: italic;"># for argument memory</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%parameters</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #000066;">crypt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span>
				<span style="color: #339933;">-</span>name	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'username+password'</span><span style="color: #339933;">,</span>
				<span style="color: #339933;">-</span>value	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'+'</span> <span style="color: #339933;">.</span> <span style="color: #000066;">crypt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
				<span style="color: #339933;">-</span>expires	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'+3M'</span><span style="color: #339933;">,</span>
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'changepass.cgi'</span><span style="color: #339933;">;</span>
		<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>cookie<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$cookie</span><span style="color: #339933;">,-</span>location<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT COUNT(id) FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE users SET last_login = NOW() WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT is_admin FROM users WHERE UPPER(username) = UPPER(?) AND password = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$is_admin</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$is_admin</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span>
					<span style="color: #339933;">-</span>name	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'username+password'</span><span style="color: #339933;">,</span>
					<span style="color: #339933;">-</span>value	<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>username<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'+'</span> <span style="color: #339933;">.</span> md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
					<span style="color: #339933;">-</span>expires	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'+3M'</span><span style="color: #339933;">,</span>
				<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'index.cgi'</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$is_admin</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;"># redirect to admin page</span>
				<span style="color: #0000ff;">$uri</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'admin.cgi'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>cookie<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$cookie</span><span style="color: #339933;">,-</span>location<span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">$uri</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$parameters</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'That username and password combination does not match any currently in our database.'</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%parameters</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>It might be hard to tell what&#8217;s different, there &#8211; but take a look at our code to check and see if the user&#8217;s information matched anything in our database. We start off by checking the username and password using crypt() &#8211; and if it matches anything, we redirect them to <strong>changepass.cgi</strong> &#8211; which we&#8217;ll be building shortly. If it doesn&#8217;t match with crypt(), we check to see if it matches with Digest::MD5&#8217;s md5() function &#8211; and if it doesn&#8217;t match either of those, we tell the user that it didn&#8217;t match anything.</p>
<p>If you haven&#8217;t guessed it yet, <strong>changepass.cgi</strong> is going to be the page users use to change their password. Here&#8217;s what the template(<strong>changepass.tmpl</strong>) looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Change Password&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;tmpl_if name='error'&gt;
		&lt;span style='color:red'&gt;Error: &lt;!--tmpl_var name='error'--&gt;&lt;/span&gt;
	&lt;/tmpl_if&gt;
	&lt;tmpl_if name='message'&gt;
		&lt;span style='color:green'&gt;&lt;!--tmpl_var name='message'--&gt;&lt;/span&gt;
	&lt;/tmpl_if&gt;
	&lt;form method='post' action='changepass.cgi'&gt;
		Password: &lt;input type='password' name='password' id='password' /&gt;&lt;br /&gt;
		Confirm Password: &lt;input type='password' name='confirm' /&gt;&lt;br /&gt;
		&lt;input type='submit' value='Change Password' /&gt;
	&lt;/form&gt;
	&lt;script type='text/javascript'&gt;
	document.getElementById('password').focus();
	&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>Here&#8217;s the code for <strong>changepass.cgi</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Digest<span style="color: #339933;">::</span><span style="color: #006600;">MD5</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">require</span> login<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%arguments</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Vars</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%params</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%arguments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">ne</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>confirm<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$params</span><span style="color: #009900;">&#123;</span>error<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'Passwords do not match!'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE users SET password = ? WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span>md5<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'saltgoeshere'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">$arguments</span><span style="color: #009900;">&#123;</span>password<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$params</span><span style="color: #009900;">&#123;</span>message<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;Password updated successfully.&quot;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$template</span> <span style="color: #339933;">=</span> HTML<span style="color: #339933;">::</span><span style="color: #006600;">Template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>
		filename	<span style="color: #339933;">=&gt;</span>	<span style="color: #ff0000;">'changepass.tmpl'</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">param</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">%params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$template</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">output</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And that&#8217;s all there is to it! By making this quick change, we&#8217;ve secured our user passwords a little better against any malicious users &#8211; and as an added bonus, we&#8217;ve created a change password page!</p>
<p><strong style='color:red'>Note</strong>: don&#8217;t forget to change &#8217;saltgoeshere&#8217; to an actually random value, like &#8217;s79dj@#*(hd&#8217; or something &#8211; you won&#8217;t make any security gains if malicious users can easily guess your password salt. If you&#8217;re feeling <strong>really</strong> adventurous, you could(and probably should) turn the salt into a configuration parameter &#8211; but I&#8217;ll leave how to do that up to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/16/securing-our-hashes-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: DRYing out our stats</title>
		<link>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/</link>
		<comments>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 14:00:35 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=82</guid>
		<description><![CDATA[Over the course of developing our game, our database has sort of grown organically. As we added a new feature, we&#8217;d add the tables we needed to accomodate this feature. While this works(and has been working for us just fine), it&#8217;s not neccessarily the best way to design your database &#8211; because as you can [...]]]></description>
			<content:encoded><![CDATA[<p>Over the course of developing our game, our database has sort of grown organically. As we added a new feature, we&#8217;d add the tables we needed to accomodate this feature. While this works(and has been working for us just fine), it&#8217;s not neccessarily the best way to design your database &#8211; because as you can see, we now have 3 stats tables(<em>user_stats</em>,<em>monster_stats</em>, and <em>item_stats</em>) when we only actually need one &#8211; as <a href='http://blog.fetmab.com/'>sepp</a> has once again helpfully pointed out.</p>
<p>With that in mind, we&#8217;re going to create another table, to replace those three. Because lots of different things can have stats, I&#8217;m going to call the table <em>entity_stats</em> &#8211; although if you want to, you can call it whatever you want(but make sure to keep your change in mind when you&#8217;re working through this code). Here&#8217;s what we&#8217;re going to do to create the table:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> entity_stats <span style="color: #66cc66;">&#40;</span>
	id int <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	stat_id int<span style="color: #66cc66;">,</span>
	entity_id int<span style="color: #66cc66;">,</span>
	value text<span style="color: #66cc66;">,</span>
	entity_type ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'User'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Monster'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Item'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Now that we&#8217;ve created this new table, we&#8217;re going to need to customize our SQL queries slightly. Previously, we were only using an object&#8217;s ID value to retrieve the stats for it &#8211; now that we don&#8217;t have that separation, we will need to run the query based on two things &#8211; the object&#8217;s ID, and the object&#8217;s type.</p>
<p>Because we&#8217;ve been doing re-writing to our stats code, we&#8217;re actually in a good position to make this change &#8211; we only need to change the query in one file, instead of 3(or more). Our old SQL looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #ff0000;">&quot;SELECT value FROM table WHERE stat_id = (SELECT id FROM stats WHERE display_name = 'foo' OR short_name = 'bar') AND column = 'baz'&quot;</span></pre></div></div>

<p>The new SQL is going to look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #ff0000;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = 'foo' OR short_name = 'bar') AND entity_id = 'baz' AND type = 'bat'&quot;</span></pre></div></div>

<p>One of the benefits of doing this is that we&#8217;re actually going to be cleaning up our new DRY stats code a little bit more, too &#8211; we get to trim it down to only take a &#8216;type&#8217; argument, instead of the table and column names it needs to retrieve with. Think back to our DRY stats code from earlier:</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #339933;">,</span><span style="color: #000088;">$columnName</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM <span style="color: #009933; font-weight: bold;">%s</span> WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND <span style="color: #009933; font-weight: bold;">%s</span> = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tableName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$columnName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>And here&#8217;s what it looks like with the change made:</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Once we&#8217;ve made those changes, it&#8217;s easy to modify all of our code for the new database structure:</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'database.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>		
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE entity_stats SET value = '<span style="color: #009933; font-weight: bold;">%s</span>' WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type = '<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT count(value) FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>') AND entity_id = '<span style="color: #009933; font-weight: bold;">%s</span>' AND entity_type ='<span style="color: #009933; font-weight: bold;">%s</span>'&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// the stat doesn't exist; insert it into the database</span>
		<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO entity_stats(stat_id,entity_id,value,entity_type) VALUES ((SELECT id FROM stats WHERE display_name = '<span style="color: #009933; font-weight: bold;">%s</span>' OR short_name = '<span style="color: #009933; font-weight: bold;">%s</span>'),'<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>','<span style="color: #009933; font-weight: bold;">%s</span>')&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$trackingID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">mysql_real_escape_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> database<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE entity_stats SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$type</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$trackingID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM entity_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND entity_id = ? AND entity_type = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$trackingID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO entity_stats(stat_id,entity_id,value,entity_type) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And with that done, our change is made! Now it&#8217;s just a matter of modifying the code we created for each stat specifically(only one shown):</p>
<h2>PHP</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'stats-dry.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> getStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> getStatDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> setStat<span style="color: #009900;">&#40;</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	setStatDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #000088;">$statName</span><span style="color: #339933;">,</span><span style="color: #000088;">$userID</span><span style="color: #339933;">,</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h2>Perl</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> stats<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">getStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	statsDRY<span style="color: #339933;">::</span><span style="color: #006600;">setStatDRY</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And once all of the changes are done, you&#8217;re good! Now all of the stat values will be stored in a single table.</p>
<p>But what about users who have already registered for your game, or monsters and items that you&#8217;ve already added?</p>
<p>We definitely don&#8217;t want to have to tell every single person playing our game to re-register &#8211; so we&#8217;re going to write some quick SQL to copy the values over for us, before removing the tables that we no longer need:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>user_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'user'</span> <span style="color: #993333; font-weight: bold;">FROM</span> user_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> user_stats;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>monster_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'monster'</span> <span style="color: #993333; font-weight: bold;">FROM</span> monster_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> monster_stats;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> entity_stats<span style="color: #66cc66;">&#40;</span>stat_id<span style="color: #66cc66;">,</span>entity_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span>entity_type<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> stat_id<span style="color: #66cc66;">,</span>item_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'item'</span> <span style="color: #993333; font-weight: bold;">FROM</span> item_stats<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> item_stats;</pre></div></div>

<p>Once we&#8217;ve run that SQL, we&#8217;ll have deleted our 3 new tables &#8211; but not before we moved the data over from them to our new <em>entity_stats</em> table. Once you make the necessary modifications to your stats code and upload it all, take a look at your game &#8211; it will still work just like it did before!</p>
<p>This might seem like a weird thing to get excited about, but it&#8217;s a pretty big deal &#8211; we just changed a significant portion of our database, and didn&#8217;t break any of our existing code at all. <strong>This</strong> is why the DRY approach is so useful to have, and why you should always strive to use DRY in your designs to begin with &#8211; because making this change with the database logic spread accross dozens of files would drive even the calmest developer batty.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/11/drying-out-our-stats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: DRYing out our database connections (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/07/10/drying-out-our-database-connections-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/07/10/drying-out-our-database-connections-perl/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 14:00:39 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=81</guid>
		<description><![CDATA[One piece of our code that definitely needs a bit of DRYing out is our database connections &#8211; we keep copying and pasting the exact same code anytime we want to connect!
We&#8217;ve been repeatedly writing out the exact same three lines, any time we want to connect to a database &#8211; in some cases, even [...]]]></description>
			<content:encoded><![CDATA[<p>One piece of our code that definitely needs a bit of DRYing out is our database connections &#8211; we keep copying and pasting the exact same code anytime we want to connect!</p>
<p>We&#8217;ve been repeatedly writing out the exact same three lines, any time we want to connect to a database &#8211; in some cases, even multiple times in the same file! This is the offending code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>While this has worked for us so far, it&#8217;s still a bit of a bad idea &#8211; what happens if our game suddenly changes and needs to work off of an Oracle database? You would need to go through and find <strong>every single file where this code occurs</strong>, and manually change it. Not fun.</p>
<p>With that in mind, we&#8217;re going to simplify things a little bit &#8211; by creating a file that exists purely to connect to the database for us. We&#8217;re going to merge our database code with some of our configuration file code, to create a file called <strong>database.pm</strong>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> database<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> Exporter<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
<span style="color: #b1b100;">our</span> <span style="color: #0000ff;">@ISA</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>Exporter<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">our</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">our</span> <span style="color: #0000ff;">@EXPORT</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$dbh</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And now that that&#8217;s done, we&#8217;ll never have to worry about copying and pasting those lines again! In any file that interacts with the database, all we need to do is add this line, right at the top:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> database<span style="color: #339933;">;</span></pre></div></div>

<p>Which means we can modify our DRY stats code from looking like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE $tableName SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$config{dbName}:$config{dbHost}&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbUser<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$config</span><span style="color: #009900;">&#123;</span>dbPass<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO $tableName(stat_id,$columnName,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Into something like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> statsDRY<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> database<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> setStatDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	createIfNotExistsDRY<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE $tableName SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExistsDRY <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$tableName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$columnName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM $tableName WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND $columnName = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO $tableName(stat_id,$columnName,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$userID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Because we used the <em>our</em> keyword to put <em>$dbh</em> into the root scope, we don&#8217;t need to bother re-useing the database code that we&#8217;ve created &#8211; all we do is put a use statement at the start of our code file, and we&#8217;re in business.</p>
<p>There is one slight caveat, however &#8211; you need to be very careful about scope in a situation like this. Because <em>$dbh</em> is now in the root scope, it&#8217;s very easy to accidentally try to use it when another function is trying to as well &#8211; which causes weird bugs. A good way to prevent this is to just clone over <em>$dbh</em> in whatever function needs it:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span></pre></div></div>

<p>At which point you don&#8217;t need to worry about scope conflicts at all.</p>
<p>What have we gained by making this change? Well, we&#8217;ve managed to make it so that we don&#8217;t have to write as much code &#8211; <strong>and</strong>, if the way we connect to our database ever needs to change, we&#8217;ll only need to modify one file, instead of every single file in our codebase. This is one of the big benefits of DRY, and if you ever get into a situation where you need to make a change like this, you&#8217;ll definitely appreciate it!</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/10/drying-out-our-database-connections-perl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: Retrieving Items (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/07/04/retrieving-items-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/07/04/retrieving-items-perl/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 14:00:59 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=77</guid>
		<description><![CDATA[The other day, we set up the initial database structure for our items system &#8211; and today, we&#8217;re going to write the code we use to interact with that system and retrieve item data.
For the most part, you&#8217;ve seen all of this code before &#8211; it&#8217;s a slightly modified version of our stats code, along [...]]]></description>
			<content:encoded><![CDATA[<p>The other day, we set up the initial database structure for our items system &#8211; and today, we&#8217;re going to write the code we use to interact with that system and retrieve item data.</p>
<p>For the most part, you&#8217;ve seen all of this code before &#8211; it&#8217;s a slightly modified version of our stats code, along with one extra function. We don&#8217;t even have to include any functionality for setting up item information &#8211; because our players shouldn&#8217;t ever be able to(although if you want them to in <strong>your</strong> game, you should be able to figure out how to make the change after this). We&#8217;ll start off with our one new function, <em>getItem</em>, which will return a hash with the item&#8217;s attributes inside:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> items<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getItem <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name, type FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%item</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\@item</span><span style="color: #009900;">&#123;</span><span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>name type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>id<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$itemID</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">%item</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>
This is just some simple database querying &#8211; the only thing that&#8217;s fancy is that we used our <em>%item</em> hash as an array slice so that we could bind keys directly to columns returned by our query. I find that it&#8217;s easier to deal with a hash of attributes than a bunch of variables, which is why it&#8217;s being done this way.</p>
<p>Unfortunately, we won&#8217;t be building anything that takes advantage of this code today &#8211; but we can at least build some testing code. To start off, run this SQL to insert a testing item into the database:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> items<span style="color: #66cc66;">&#40;</span>name<span style="color: #66cc66;">,</span>type<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Wooden Sword'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Weapon'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Once that&#8217;s finished, create a file named <strong>test.cgi</strong> with this code inside:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> items<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%item</span> <span style="color: #339933;">=</span> items<span style="color: #339933;">::</span><span style="color: #006600;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #000066;">qq</span> <span style="color: #339933;">~</span>
Name<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>name<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span>
Type<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>type<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span>
ID<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>id<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">~;</span></pre></td></tr></table></div>

<p>Once you&#8217;ve uploaded test.cgi to your server, visit that page &#8211; you should see all the information on the Wooden Sword, which means that our item retrieval code is working properly.</p>
<p>That&#8217;s really the only &#8217;special&#8217; part of our items code &#8211; the rest is just a customization of our stats code, so that we retrieve stats for items:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM item_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE item_stats SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExists <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM item_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO item_stats(stat_id,item_id,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>If we want to test our stats code to make sure that it&#8217;s working, we&#8217;ll first need to add a stat to our wooden sword:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> item_stats<span style="color: #66cc66;">&#40;</span>item_id<span style="color: #66cc66;">,</span>stat_id<span style="color: #66cc66;">,</span>value<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> items <span style="color: #993333; font-weight: bold;">WHERE</span> name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Wooden Sword'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> stats <span style="color: #993333; font-weight: bold;">WHERE</span> short_name <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'atk'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Then, we&#8217;ll modify our testing page so that it retrieves the &#8216;atk&#8217; stat for our sword:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>8
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>atk<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> items<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'atk'</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>15
16
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;">Attack<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>atk<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">~;</span></pre></td></tr></table></div>

<p>And with that, we&#8217;ve written the code to retrieve our item information! Once you run your test page, you&#8217;ll be able to see all of the information for the Wooden Sword. Here&#8217;s all the code inside <strong>items.pm</strong> in one place:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> items<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getItem <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT name, type FROM items WHERE id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%item</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\@item</span><span style="color: #009900;">&#123;</span><span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>name type<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>id<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$itemID</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">%item</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> getStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT value FROM item_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">return</span> <span style="color: #0000ff;">$value</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">sub</span> setStat <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statValue</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	createIfNotExists<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;UPDATE item_stats SET value = ? WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statValue</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> createIfNotExists <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>	
	<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT count(value) FROM item_stats WHERE stat_id = (SELECT id FROM stats WHERE display_name = ? OR short_name = ?) AND item_id = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$count</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$count</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$count</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;"># no entry for that stat/user combination - insert one with a value of 0</span>
		<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;INSERT INTO item_stats(stat_id,item_id,value) VALUES ((SELECT id FROM stats WHERE display_name = ? OR short_name = ?),?,?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$statName</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$itemID</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And here&#8217;s the tester page code, which lets us verify that our items code is working:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl -w</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> items<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%item</span> <span style="color: #339933;">=</span> items<span style="color: #339933;">::</span><span style="color: #006600;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>atk<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> items<span style="color: #339933;">::</span><span style="color: #006600;">getStat</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'atk'</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">header</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #000066;">qq</span> <span style="color: #339933;">~</span>
Name<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>name<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span>
Type<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>type<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span>
ID<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>id<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;</span>br <span style="color: #339933;">/&gt;</span>
Attack<span style="color: #339933;">:</span> <span style="color: #0000ff;">$item</span><span style="color: #009900;">&#123;</span>atk<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">~;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/07/04/retrieving-items-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Browsergames: forcing users to log in (Perl)</title>
		<link>http://buildingbrowsergames.com/2008/06/25/building-browsergames-forcing-users-to-log-in-perl/</link>
		<comments>http://buildingbrowsergames.com/2008/06/25/building-browsergames-forcing-users-to-log-in-perl/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 14:00:51 +0000</pubDate>
		<dc:creator>Luke</dc:creator>
				<category><![CDATA[buildingbrowsergames]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://buildingbrowsergames.com/?p=72</guid>
		<description><![CDATA[While we&#8217;ve been working on building our browsergame, one thing that we haven&#8217;t really touched on is making sure that our users are logged in before they try to do anything. Most of the pages that we&#8217;ve built rely on the user being logged in so that we can retrieve their User ID and use [...]]]></description>
			<content:encoded><![CDATA[<p>While we&#8217;ve been working on building our browsergame, one thing that we haven&#8217;t really touched on is making sure that our users are logged in before they try to do anything. Most of the pages that we&#8217;ve built rely on the user being logged in so that we can retrieve their User ID and use it for whatever the page does &#8211; but none of them force the user to be logged in yet. Today, we&#8217;re going to add that piece of functionality to our game.</p>
<p>We already know how to figure out whether or not a user is logged in &#8211; all we do is use the values from their cookie, and compare them against the database to see if they match &#8211; if they do, we retrieve a User ID. We&#8217;ll know a user is logged in when we retrieve something, and we&#8217;ll know that they aren&#8217;t when we don&#8217;t get anything back.</p>
<p>If this sounds familiar, that&#8217;s because it is &#8211; here&#8217;s the code from our index page that does just that:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><p>All we need to do is add a quick conditional check to our code to see what was returned, and modify our code slightly so that it&#8217;s re-usable in modular format:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> login<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> CGI <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">:</span>cgi<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> config<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CGI<span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$cookie</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cookie</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'username+password'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\+/</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$cookie</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;DBI:mysql:$dbname:$dbhost&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbuser</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$dbpass</span><span style="color: #339933;">,</span><span style="color: #009900;">&#123;</span>RaiseError <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;SELECT id FROM users WHERE UPPER(username) = UPPER(?)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$username</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$userID</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">bind_columns</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">\$userID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetch</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$userID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">print</span> <span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'login.cgi'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>	
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If you save that code as <strong>login.pm</strong>, you&#8217;ll now be able add this line to any file that you want to force users to log in to view:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">require</span> login<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And if a user attempts to access the page without their cookie set properly, they&#8217;ll be automated redirected to the login page. Check out <a href='http://buildingbrowsergames.com/game/cgi/index.cgi'>The index page</a> to see it in action.</p>
]]></content:encoded>
			<wfw:commentRss>http://buildingbrowsergames.com/2008/06/25/building-browsergames-forcing-users-to-log-in-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

