<?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>Kung Foo Code</title>
	<atom:link href="http://www.kungfoocode.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kungfoocode.org</link>
	<description>Home of Anton Fagerberg</description>
	<lastBuildDate>Thu, 13 Oct 2011 22:56:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Ruby sudoku solver</title>
		<link>http://www.kungfoocode.org/projects/ruby-sudoku-solver/</link>
		<comments>http://www.kungfoocode.org/projects/ruby-sudoku-solver/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 22:56:02 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=337</guid>
		<description><![CDATA[I have written a new sudoku solver in Ruby. Just a simple command line tool as a proof on concept to teach myself Ruby and improve the back-tracking code a bit (the code is a bit better written than my Java version). The code and more info is on my Github page: github.com/KungFooAnton/Sudoku-Solver-Ruby class SudokuSolver [...]]]></description>
			<content:encoded><![CDATA[<p>I have written a new sudoku solver in Ruby. Just a simple command line tool as a proof on concept to teach myself Ruby and improve the back-tracking code a bit (the code is a bit better written than my Java version).</p>
<p>The code and more info is on my Github page:<br />
<a title="github.com/KungFooAnton/Sudoku-Solver-Ruby" href="https://github.com/KungFooAnton/Sudoku-Solver-Ruby"> github.com/KungFooAnton/Sudoku-Solver-Ruby</a></p>
<pre class="brush: ruby; title: ;">
class SudokuSolver
	# Transforms each cell (0-80) to the corresponding top-left (0,3, ... ,57,60) of each 3x3 square.
	def fix_pos(cell)
		return 27*(cell/9/3)+3*(cell/3%3)
	end

	def get_valid(cell, matrix)
		valid = [1,2,3,4,5,6,7,8,9]

		# Look for duplicates in row / column.
		0.upto(8) do |n|
			row_element = matrix[cell%9+n*9]
			col_element = matrix[cell/9*9+n]

			valid[row_element-1] = 0 if row_element != 0
			valid[col_element-1] = 0 if col_element != 0
		end

		# Look for duplicates in &quot;square&quot;.
		0.upto(2) do |n|
			[0,9,18].each do |m|
				value = matrix[fix_pos(cell) + n + m]
				valid[value-1] = 0 if value != 0
			end
		end

		return valid.delete_if { |x| x == 0 }
	end

	def solve(i = 0, matrix)
		return true if i == 81
		return solve(i + 1, matrix) if matrix[i] != 0 

		get_valid(i, matrix).each do |n|
			matrix[i] = n
			return true if solve(i+1, matrix)
			matrix[i] = 0
		end

		return false
	end

	# Very simple user-input mode.
	def new
		matrix = Array.new(81).fill(0)

		0.upto(80) do |n|
			matrix[n] = &quot;*&quot;
			puts ascii(matrix) + &quot;\nPick a number 0-9 (Enter or 0 is blank):&quot;
			matrix[n] = 0

			input = gets.chomp.to_i
			puts &quot;\n\n\n==========================================\n\n\n&quot;

			if !get_valid(n, matrix).push(0).include?(input)
				puts &quot;* * * * * * * * * * * * *\n Warning: invalid choice! \n* * * * * * * * * * * * *&quot;
				redo
			end

			matrix[n] = input
		end

		return matrix
	end

	# ASCII-representation of the Sudoku puzzle.
	def ascii(matrix)
		ascii = String.new

		0.upto(80) do |n|
			ascii = ascii + &quot;\n+-------+-------+-------+&quot; if n % 27 == 0
			ascii = ascii + &quot;\n&quot; if n % 9  == 0
			ascii = ascii + &quot;| &quot; if n % 3 == 0
			ascii = ascii + (matrix[n] != 0 ? matrix[n].to_s : &quot;_&quot;) + &quot; &quot;
			ascii = ascii + &quot;|&quot; if n % 9 == 8
		end

		return ascii + &quot;\n+-------+-------+-------+&quot;
	end
end

# Short example of how to use it.
# User have to input the sudoku puzzle from commandline.
s = SudokuSolver::new
start_time = Time.now
s.solve(matrix = s.new)
puts &quot;* * * * * * * * * * * * * *\nSolved it in #{Time.now - start_time}s!\n* * * * * * * * * * * * * * #{s.ascii(matrix)}&quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/projects/ruby-sudoku-solver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brute force Sudoku solver in Java</title>
		<link>http://www.kungfoocode.org/projects/brute-force-sudoku-solver-in-java/</link>
		<comments>http://www.kungfoocode.org/projects/brute-force-sudoku-solver-in-java/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 20:37:16 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Brute force]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Sudoku]]></category>
		<category><![CDATA[Sudoku solver]]></category>
		<category><![CDATA[Swing]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=325</guid>
		<description><![CDATA[I did this Sudoku solver for a school project and I&#8217;ve now decided to release it as a proof-of-concept project. It&#8217;s nothing fancy. It contains a class used to brute force Sudoku puzzles, you can read more about the algorithm on Wikipedia, and a little Swing GUI. I&#8217;ve never used Swing before doing this project [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.kungfoocode.org/wp-content/uploads/sudoku.png" rel="lightbox[325]"><img class="aligncenter size-large wp-image-319" title="Sudoku Solver" src="http://www.kungfoocode.org/wp-content/uploads/sudoku-576x548.png" alt="" width="576" height="548" /></a></p>
<p>I did this Sudoku solver for a school project and I&#8217;ve now decided to release it as a proof-of-concept project. It&#8217;s nothing fancy. It contains a class used to brute force Sudoku puzzles, you can read more about <a href="http://en.wikipedia.org/wiki/Algorithmics_of_sudoku#Solving_Sudokus_by_a_brute-force_algorithm">the algorithm on Wikipedia</a>, and a little Swing GUI. I&#8217;ve never used Swing before doing this project so don&#8217;t expect anything amazing. The code is released under GPL v2 and I hope it might be useful to someone out there. There is a generated Javadoc so check it out for more detailed info about the classes.</p>
<p><a href="http://code.kungfoocode.org/Sudoku/">Check out the code in my public Mercurial repository.</a></p>
<p><a href="http://files.kungfoocode.org/SudokuSolver.jar">Download executable JAR-file.</a></p>
<p>And heres a overview of the brute force class (got to the Mercurial repository to get the GUI source):</p>
<pre class="brush: java; title: ;">
/**
 * Sudoku Solver Proof-of-concept.
 * Copyright (C) 2011 Anton Fagerberg (Kung Foo Code).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
 */
package sudoku;

public class Sudoku {

	private int[][] matrix = new int[9][9];
	private int[][] inputMatrix = new int[9][9];

	/**
	 * Remove all the numbers from the sudoku-matrixes.
	 */
	public void resetMatrix() {
		matrix = new int[9][9];
		inputMatrix = new int[9][9];
	}

	/**
	 * Set value of the X- &amp; Y-coordinate in the matrix.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @param value Number, 1,9.
	 */
	private void fill(int x, int y, int value) {

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		matrix[x][y] = value;
	}

	/**
	 * Save value from user input to the matrix which handles user input.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @param value Number, 1,9.
	 */
	public void set(int x, int y, int value) {

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		inputMatrix[x][y] = value;
	}

	/**
	 * Copy the values of the matrix containing the user input to the matrix used when trying to solve the puzzle.
	 */
	private void copyMatrix() {
		for (int x = 0; x != 9; x++)
			for (int y = 0; y != 9; y++)
				matrix[x][y] = inputMatrix[x][y];
	}

	/**
	 * Try to solve the sudoku-puzzle.
	 * @return True or false based on if the puzzle was solved or not.
	 */
	public boolean solve() {
		copyMatrix();
		return solve(0);
	}

	/**
	 * Get the value from the specified X- &amp; Y-coordinate in the matrix used to solve the sudoku-puzzles.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @return The value, 0-9. (0 is regarded as not defined).
	 */
	public int getValue(int x, int y) {

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		return matrix[x][y];
	}

	/**
	 * Get the value from the specified X- &amp; Y-coordinate from the matrix which contain the user inputs.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @return The value, 0-9. (0 is regarded as not defined).
	 */
	public int getValueOriginal(int x, int y) {

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		return inputMatrix[x][y];
	}

	/**
	 * Recursive function which fills a valid number to the X- &amp; Y-coordinate based on the sudoku-rules.
	 * The function will call itself with the next X- &amp; Y-coordinate if it finds a valid number to insert or if the number is already set by the user input.
	 * If x &gt; 8 the y-value will automatically increase.
	 * @param x X-coordinate.
	 * @return True or false if a valid number can be inserted or not.
	 */
	private boolean solve(int x) {

		if (x == 81)
			return true;

		if (getValue(x, 0) != 0 &amp;&amp; getValue(x, 0) == getValueOriginal(x, 0)) {
			return solve(x+1);
		}
		else {
			for (int i : getValidNumbers(x, 0)) {
				if (i != 0) {
					fill(x, 0, i);

					if (!solve(x+1))
						fill(x,0,0);
					else
						return true;
				}
			}
		}
		return false;
	}

	/**
	 * Validate if a specified number is valid at the X- &amp; Y-coordinate based on the sudoku-rules.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @param number Number (Only 1-9 can be valid).
	 * @return True or false based on if the number is valid according to the sudoku-rules.
	 */
	public boolean validNumberOriginal (int x, int y, int number) {

		if (number &lt; 1 || number &gt; 9)
			return false;

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		int[] validNumbers = {1,2,3,4,5,6,7,8,9};

		// Check vertical and horizontal
		for (int i = 0; i != 9; i++) {
			if (inputMatrix[i][y] != 0)
				validNumbers[inputMatrix[i][y]-1] = 0;
			if (inputMatrix[x][i] != 0)
				validNumbers[inputMatrix[x][i]-1] = 0;
		}

		// Check the &quot;squares&quot;
		int squareX, squareY;

		if (x &lt; 3)
			squareX = 0;
		else if (x &lt; 6)
			squareX = 3;
		else
			squareX = 6;

		if (y &lt; 3)
			squareY = 0;
		else if (y &lt; 6)
			squareY = 3;
		else
			squareY = 6;

		for (int i = 0; i != 3; i++) {
			for (int j = 0; j != 3; j++) {
				if (inputMatrix[i+squareX][j+squareY] != 0) {
					validNumbers[inputMatrix[i+squareX][j+squareY]-1] = 0;
				}
			}
		}

		return (validNumbers[number-1] == 0) ? false : true;
	}

	/**
	 * Returns an array of the valid numbers at the X- &amp; Y-coordinate according to the sudoku-rules.
	 * If the number n is valid the array will have array[n-1] = n. If n is invalid array[n-1] = 0.
	 * If x &gt; 8 the y-value will automatically increase. set(0, 1, 1) is the same as set(9, 0, 1).
	 * @param x X-coordinate, 0-80.
	 * @param y Y-coordinate, 0-8.
	 * @return Array of valid numbers (size 9).
	 */
	private int[] getValidNumbers(int x, int y) {

		while (x &lt; 0) {
			x += 9;
			y--;
		}

		while(x &gt; 8) {
			x -= 9;
			y++;
		}

		int[] validNumbers = {1,2,3,4,5,6,7,8,9};

		// Check vertical and horizontal
		for (int i = 0; i != 9; i++) {
			if (matrix[i][y] != 0) {
				validNumbers[matrix[i][y]-1] = 0;
			}
			if (matrix[x][i] != 0) {
				validNumbers[matrix[x][i]-1] = 0;
			}
		}

		// Check the &quot;squares&quot;
		int squareX, squareY;

		if (x &lt; 3)
			squareX = 0;
		else if (x &lt; 6)
			squareX = 3;
		else
			squareX = 6;

		if (y &lt; 3)
			squareY = 0;
		else if (y &lt; 6)
			squareY = 3;
		else
			squareY = 6;

		for (int i = 0; i != 3; i++) {
			for (int j = 0; j != 3; j++) {
				if (matrix[i+squareX][j+squareY] != 0) {
					validNumbers[matrix[i+squareX][j+squareY]-1] = 0;
				}
			}
		}

		return validNumbers;
	}

	/**
	 * Print a ascii-version of the sudoku-puzzle to the console.
	 */
	public void printTable() {
		System.out.print(&quot;\n&quot;);
		for (int x = 0; x != 9; x++) {
			for (int y = 0; y != 9; y++) {
				System.out.print(&quot; &quot; + inputMatrix[x][y] + &quot; &quot;);
				if (y == 2 || y == 5)
					System.out.print(&quot;|&quot;);
			}
			if (x == 2 || x == 5)
				System.out.print(&quot;\n---------+---------+--------&quot;);
			System.out.print(&quot;\n&quot;);
		}
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/projects/brute-force-sudoku-solver-in-java/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mechanical Keyboards</title>
		<link>http://www.kungfoocode.org/articles/mechanical-keyboards/</link>
		<comments>http://www.kungfoocode.org/articles/mechanical-keyboards/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 22:43:27 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Coding Horror]]></category>
		<category><![CDATA[Das Keyboard]]></category>
		<category><![CDATA[Mechanical keyboards]]></category>
		<category><![CDATA[Microsoft Natural Keyboard 4000]]></category>
		<category><![CDATA[Truly Ergonomic]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=304</guid>
		<description><![CDATA[Or why I bought a $135 keyboard. Not that this post is not to encourage you to buy the Das Keyboard but mechanical keyboards in general. There are a lot of awesome mechanical keyboards so check them all out before making up your mind! So my 25th birthday was coming up and all of my [...]]]></description>
			<content:encoded><![CDATA[<p>Or why I bought a $135 keyboard. Not that this post is not to encourage you to buy the Das Keyboard but mechanical keyboards in general. There are a lot of awesome mechanical keyboards so check them all out before making up your mind!</p>
<p>So my 25th birthday was coming up and all of my friends thought that I should treat myself and get something really. I didn&#8217;t really think much about it but the following weekend I remember reading on <a href="http://www.codinghorror.com/blog/">coding horror</a> about keyboards and I decided to look it up again. You can <a href="http://www.codinghorror.com/blog/2010/10/the-keyboard-cult.html">read the article here</a> and the funny thing about it is that the author uses the same keyboard as I did, the Microsoft Natural Keyboard 4000.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/microsoft_4000.jpg" rel="lightbox[304]"><img class="aligncenter size-large wp-image-305" title="microsoft_4000" src="http://www.kungfoocode.org/wp-content/uploads/microsoft_4000-576x352.jpg" alt="" width="576" height="352" /></a>Let me get one thing clear. I have loved this keyboard since the day I bought it. I love ergonomic keyboards, I love the design and the keyboard is almost perfect. It wasn&#8217;t until I lived with my laptop for a couple of month and returning to this keyboard I started to realize that it was a bit tough to write on. Thinking about that made me remember the coding horror article. After reading a lot of forum posts and other links I decided that there was no way my life would be complete without a mechanical keyboard.</p>
<p>There are a lot of <a href="http://www.overclock.net/keyboards/491752-mechanical-keyboard-guide.html">good articles</a> which can describe this much better than me so I will only summarize my thoughts and let you read the rest on other sites and make your own conclusions. First of all there is a problem for me who is from Sweden. We have different keyboard-layouts. Since we have some additional characters so the first problem was to find a keyboard with the correct layout. I found some mechanical keyboards with Swedish layout like the SteelSeries, Razor, Filco and some others but none of them felt quite right.</p>
<p>At first I was really stubborn about having a ergonomic keyboard like my old but I gave that up after looking for a decent one for hours. The Swedish layout was a big problem and some of the ergonomic keyboards are just to weird, the <a href="http://www.trulyergonomic.com/">Truly Ergonomic</a> was on the right track tough. So I gave up the idea of an ergonomic keyboard (my brain would explode if I could have the Microsoft Natural 4000 with mechanical switches).</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/Cherry-MX-Brown-Animated.gif" rel="lightbox[304]"><img class="aligncenter size-full wp-image-306" title="Cherry MX Brown Animated" src="http://www.kungfoocode.org/wp-content/uploads/Cherry-MX-Brown-Animated.gif" alt="" width="200" height="200" /></a></p>
<p>The next decision was which switch to use. After a lot of research (but unfortunately no hands on experience) I felt like the Cherry MX Brown was the right choice for me. So after a lot of searching it came down to the Das Keyboard Ultimate Silent. I ordered that bad boy from a store in Germany and it worked as a Swedish since I could use the Ultimate EU version with blank keys. After just a couple of minutes to realize how amazing mechanical keyboards are. You know when you&#8217;ve got a really bad fever dream and you run in slow motion like you where running in jelly, that is how it&#8217;s like to returning to a regular keyboard when you&#8217;re used to a mechanical one.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/dasKeyboardUltimateEU.jpg" rel="lightbox[304]"><img class="aligncenter size-large wp-image-307" title="dasKeyboardUltimateEU" src="http://www.kungfoocode.org/wp-content/uploads/dasKeyboardUltimateEU-576x238.jpg" alt="" width="576" height="238" /></a>Some final words about this. Mechanical keyboards are really awesome and the Das Keyboard is truly wonderful. I dig the sleek look of all blank keys (and the fact that my girlfriend can&#8217;t use it) but there is a version with laser etched chars on the keyboards for those who need it. The keyboard is heavy and the feeling is nothing but quality. But note that I bought the Silent version of Das Keyboard and it still makes much much more sound than my old keyboard. Lesson: mechanical keyboards make <em>a lot</em> of sounds. Check YouTube to find out how much sound the keyboard you plan to buy makes if you can&#8217;t try it before you buy it.</p>
<p>And after living with keyboards with Windows-keys all of my life while running Linux I finally had my revenge. I bought additional Tux-keys and placed them on the supposed-to-be-Windows-keys so now I have a completely blank keyboard &#8211; except with Tux-logos! Compensation complete.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/linuxkeyboard.jpg" rel="lightbox[304]"><img class="aligncenter size-large wp-image-308" title="linuxkeyboard" src="http://www.kungfoocode.org/wp-content/uploads/linuxkeyboard-576x344.jpg" alt="" width="576" height="344" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/articles/mechanical-keyboards/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mandelbrot Fractals Generator</title>
		<link>http://www.kungfoocode.org/projects/mandelbrot-fractals-generator/</link>
		<comments>http://www.kungfoocode.org/projects/mandelbrot-fractals-generator/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 17:49:11 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=254</guid>
		<description><![CDATA[I was given an assignment to create a Mandelbrot Fractals Generator at my University &#8211; and this is basically what I did. A short user manual: Chose resolution and Color or Black / White and press render to generate the image. The field labeled &#8220;extra&#8221; is the number of iterations. More iterations = more accurate [...]]]></description>
			<content:encoded><![CDATA[<p>I was given an assignment to create a Mandelbrot Fractals Generator at my University &#8211; and this is basically what I did.</p>
<p>A short user manual:</p>
<ul>
<li>Chose resolution and Color or Black / White and press render to generate the image.</li>
<li>The field labeled &#8220;extra&#8221; is the number of iterations. More iterations = more accurate picture (and slowed load of course).</li>
<li>Press mouse and drag to zoom in. The more you zoom in, the more iterations you&#8217;ll need.</li>
<li>You can save images from the File-menu, the will however be of crappy quality. (Note: I did <span style="text-decoration: underline;">not</span> design the GUI, it was given to me as part of the assignment).</li>
</ul>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot.png" rel="lightbox[254]"><img class="aligncenter size-large wp-image-257" title="Fractal 1" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-576x499.png" alt="" width="576" height="499" /></a><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-1.png" rel="lightbox[254]"><img class="aligncenter size-large wp-image-258" title="Fractal 2" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-1-576x503.png" alt="" width="576" height="503" /></a><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-3.png" rel="lightbox[254]"><img class="aligncenter size-large wp-image-259" title="Fractal 3" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-3-576x504.png" alt="" width="576" height="504" /></a><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-5.png" rel="lightbox[254]"><img class="aligncenter size-large wp-image-260" title="Fractal 4" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-5-576x502.png" alt="" width="576" height="502" /></a></p>
<ul>
<li><a href="http://code.kungfoocode.org/mandelbrot/">Get all of the code from my repository.</a></li>
<li><a href="http://code.kungfoocode.org/mandelbrot/raw-file/03790d38b116/MandelBrot.jar">Download JAR-file.</a></li>
</ul>
<p><b>Example:</b></p>
<pre class="brush: java; title: ;">
import java.awt.Color;

public class Generator {

	private int pixelResolution = 1;
	private int iterations;
	private Color[] colorLevels = new Color[255];;

	public Generator() {
		for (int i = 0; i &lt; 255; i++) {
			colorLevels[i] = new Color(i, 0, i); // From black to pink.
		}
	}

	public void render(MandelbrotGUI mGui) {

		switch (mGui.getResolution()) {
			case MandelbrotGUI.RESOLUTION_VERY_HIGH:
				pixelResolution = 1;
				break;
			case MandelbrotGUI.RESOLUTION_HIGH:
				pixelResolution = 3;
				break;
			case MandelbrotGUI.RESOLUTION_MEDIUM:
				pixelResolution = 5;
				break;
			case MandelbrotGUI.RESOLUTION_LOW:
				pixelResolution = 7;
				break;
			case MandelbrotGUI.RESOLUTION_VERY_LOW:
				pixelResolution = 9;
				break;
		}

		try {
			iterations = Integer.parseInt(mGui.getExtraText());
		} catch (NumberFormatException e) {
			if (mGui.getMode() == MandelbrotGUI.MODE_COLOR) {
				iterations = 50;
			} else {
				iterations = 200;
			}
		}

		Color[][] picture = new Color[mGui.getHeight() / pixelResolution][mGui.getWidth() / pixelResolution];
		Complex[][] c = mesh(mGui.getMinimumReal(), mGui.getMaximumReal(), mGui.getMinimumImag(), mGui.getMaximumImag(), mGui.getWidth(), mGui.getHeight());

		for (int x = 0; x &lt; mGui.getHeight() / pixelResolution; x++) {
			for (int y = 0; y &lt; mGui.getWidth() / pixelResolution; y++) {

				int i = 0;

				Complex almonds = new Complex(0.0, 0.0);

				while (almonds.getAbs2() &lt;= 4 &amp;&amp; i &lt; iterations) {
					almonds.mul(almonds);
					almonds.add(c[x][y]);
					i++;
				}

				if (almonds.getAbs2() &lt;= 4) {
					if (mGui.getMode() == MandelbrotGUI.MODE_BW) {
						picture[x][y] = Color.BLACK;
					} else {
						picture[x][y] = new Color(20, 20, 20);
					}
				} else {
					if (mGui.getMode() == MandelbrotGUI.MODE_BW) {
						picture[x][y] = Color.WHITE;
					} else {
						picture[x][y] = colorLevels[(int) Math.ceil((254 / (double) iterations) * i)];
					}
				}
			}
		}

		mGui.putData(picture, pixelResolution, pixelResolution);
	}

	private Complex[][] mesh(double minRe, double maxRe, double minIm, double maxIm, int width, int height) {

		double positionIm = (maxIm - minIm) / height;
		double positionRe = (maxRe - minRe) / width;

		Complex[][] c = new Complex[height / pixelResolution][width / pixelResolution];

		double alignIm = 0.5 * positionIm * (pixelResolution + 1) - maxIm;
		double alignRe = 0.5 * positionRe * (pixelResolution + 1) + minRe;
		double posResIm = positionIm * pixelResolution;
		double posResRe = positionRe * pixelResolution;

		double[] complexX = new double[(width / pixelResolution)];

		for (int y = 0; y &lt; width / pixelResolution; y++) {
			complexX[y] = posResRe * y + alignRe;
		}

		for (int a = 0; a &lt; height / pixelResolution; a++) {
			double complexY =  posResIm * a  + alignIm;
			for (int b = 0; b &lt; width / pixelResolution; b++) {
				c[a][b] = new Complex(complexX[b], complexY);
			}
		}

		return c;
	}
}
</pre>
<ul>
<li><a href="http://code.kungfoocode.org/mandelbrot/">Get all of the code from my repository.</a></li>
<li><a href="http://code.kungfoocode.org/mandelbrot/raw-file/03790d38b116/MandelBrot.jar">Download JAR-file.</a></li>
</ul>
<p><b><i>Note that I did not write the GUI!</i></b></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/projects/mandelbrot-fractals-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Palindrome finder in Java (+ Ruby)</title>
		<link>http://www.kungfoocode.org/code-snippets/palindrome-finder-in-java/</link>
		<comments>http://www.kungfoocode.org/code-snippets/palindrome-finder-in-java/#comments</comments>
		<pubDate>Sun, 10 Oct 2010 13:37:35 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Code Snippets]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Greplin programming challenge]]></category>
		<category><![CDATA[Hack news]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=227</guid>
		<description><![CDATA[I was doing the first of three steps in the Greplin programming challenge the other night in PHP before I went to sleep, just for the fun of it. I found the link via Hacker News (love that site) and there are a lot of really neat solutions if you read the comments. Much much [...]]]></description>
			<content:encoded><![CDATA[<p>I was doing the first of three steps in the <a href="http://challenge.greplin.com/">Greplin programming challenge</a> the other night in PHP before I went to sleep, just for the fun of it. I found the link via <a href="http://news.ycombinator.com/item?id=1772650">Hacker News</a> (love that site) and there are a lot of really neat solutions if you read the comments. Much much better ones than mine.</p>
<p>The challenge was basically to find the longest <a href="http://en.wikipedia.org/wiki/Palindrome">palindrome</a> (a word, phrase, number or other sequence of units that can be read the same way in either direction) in a given string. I re-wrote the thing the day after in Java (I thought it was a good exercise for me since I&#8217;m taking a Java course in school at the moment) and here&#8217;s how it turned out:</p>
<pre class="brush: java; title: ;">
import java.util.ArrayList;

public class PalindromeFinder {

    public static void main(String[] args) {

        String text = &quot;FhourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth&quot;;
        ArrayList results = new ArrayList();

        for (int blockSize = text.length(); blockSize != 1; blockSize--)
        {
            for (int x = 0; x != text.length() - blockSize; x++) {

                String stringPiece = text.substring(x, x + blockSize);

                if (stringPiece.equals(new StringBuilder(stringPiece).reverse().toString())) {
                    results.add(stringPiece);
                    // Break here if you only want to find largest palindrome.
                }
            }
        }

        System.out.println(results.get(0));
    }
}
</pre>
<p>I did the same thing in Ruby today. Just thought it would be fun learning it.</p>
<pre class="brush: ruby; title: ;">
string = &quot;FhourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth&quot;
results = Array.new

for i in 2 .. string.size
	for j in 0 .. string.size - i
		piece = string[j,i]
		if piece == piece.reverse
			results &lt;&lt; piece
		end
	end
end

puts results[-1]
</pre>
<p><i>Note: It should be &#8220;results < < piece" without a blank space between the < but something gets screwed with the markup.</i></i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/code-snippets/palindrome-finder-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Checkpoint</title>
		<link>http://www.kungfoocode.org/portfolio/checkpoint/</link>
		<comments>http://www.kungfoocode.org/portfolio/checkpoint/#comments</comments>
		<pubDate>Wed, 12 May 2010 15:20:49 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Work Portfolio]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=172</guid>
		<description><![CDATA[Checkpoint is a traffic and gate management system designed for logistic companies. It is used to schedule and control incoming line haul traffic, display gate statuses among other things. The software is designed to run on a variety of devices such as truck-mounted touchscreen PCs. In addition to this, Checkpoint is also communicating and providing [...]]]></description>
			<content:encoded><![CDATA[<p>Checkpoint is a traffic and gate management system designed for logistic companies. It is used to schedule and control incoming line haul traffic, display gate statuses among other things. The software is designed to run on a variety of devices such as truck-mounted touchscreen PCs.</p>
<p>In addition to this, Checkpoint is also communicating and providing information with two internal systems such as a Windows Mobile PDA interface.</p>
<h4>Technical specifications:</h4>
<ul>
<li>PHP 5</li>
<li>MySQL 5.1 (code is database independent)</li>
<li>JavaScript</li>
<li>Runs on Apache 2 &amp; IIS</li>
<li>~7.000 lines of code</li>
<li>Truck-mounted PC interface</li>
</ul>
<h4>Gallery</h4>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Checkpoint-Charlie-0.9.5-Mozilla-Firefox.png" rel="lightbox[172]"><img class="alignnone size-large wp-image-173" title="Screenshot-Checkpoint Charlie 0.9.5 - Mozilla Firefox" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Checkpoint-Charlie-0.9.5-Mozilla-Firefox-576x451.png" alt="" width="576" height="451" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/portfolio/checkpoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Return:Customer</title>
		<link>http://www.kungfoocode.org/portfolio/returncustomer/</link>
		<comments>http://www.kungfoocode.org/portfolio/returncustomer/#comments</comments>
		<pubDate>Wed, 12 May 2010 14:47:39 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Work Portfolio]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=164</guid>
		<description><![CDATA[Return:Customer is a light-weight unified parcel tracker currently used at 11 different locations across Scandinavia. It provides a variety of functionality such as parcel scanning, track &#38; trace, customizable statistics, e-mail reporting and financial data. It&#8217;s currently tracking roughly 500.000 parcels with 15.000 new entries added monthly. Technical specifications: PHP 5 + GD MySQL 5.1 [...]]]></description>
			<content:encoded><![CDATA[<p>Return:Customer is a light-weight unified parcel tracker currently used at 11 different locations across Scandinavia. It provides a variety of functionality such as parcel scanning, track &amp; trace, customizable statistics, e-mail reporting and financial data.</p>
<p>It&#8217;s currently tracking roughly 500.000 parcels with 15.000 new entries added monthly.</p>
<h4>Technical specifications:</h4>
<ul>
<li>PHP 5 + GD</li>
<li>MySQL 5.1 (code is database independent)</li>
<li>JavaScript</li>
<li>Runs on Apache 2 and IIS</li>
<li>~ 5.000 lines of code</li>
<li>~ 100 users</li>
<li>Compatible with IE6+, FF2+, Opera &amp; Chrome.</li>
</ul>
<h4>Gallery</h4>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Rancor-PHP-Parcel-Tracker-Mozilla-Firefox-12.png" rel="lightbox[164]"><img class="alignnone size-large wp-image-157" title="Return:Customer 1" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Rancor-PHP-Parcel-Tracker-Mozilla-Firefox-12-576x325.png" alt="" width="576" height="325" /></a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Rancor-PHP-Parcel-Tracker-Mozilla-Firefox-2.png" rel="lightbox[164]"><img class="alignnone size-large wp-image-158" title="Return:Customer 2" src="http://www.kungfoocode.org/wp-content/uploads/Screenshot-Rancor-PHP-Parcel-Tracker-Mozilla-Firefox-2-576x453.png" alt="" width="576" height="453" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/portfolio/returncustomer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My perfect Irssi setup</title>
		<link>http://www.kungfoocode.org/how-to/my-perfect-irssi-setup/</link>
		<comments>http://www.kungfoocode.org/how-to/my-perfect-irssi-setup/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:21:55 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[How to]]></category>
		<category><![CDATA[bitlbee]]></category>
		<category><![CDATA[fnotify]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[How-to]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[irssi]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[otr]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=72</guid>
		<description><![CDATA[Here it is! The new and updated version of my perfect Irssi setup! The way I like to customize Irssi to make it perfect for me. You probably have different taste so you can either use everything as it is or just some of it as inspiration. If you have any suggestions, please drop a [...]]]></description>
			<content:encoded><![CDATA[<p>Here it is! The new and updated version of my perfect Irssi setup! The way I like to customize Irssi to make it perfect <em>for me</em>. You probably have different taste so you can either use everything as it is or just some of it as inspiration. If you have any suggestions, please drop a comment below.</p>
<p>This updated guide uses new and cool functionality from BitlBee 3. Some of the Irssi scripts are replaced with better versions and I have made the guide a bit more user friendly by including more detailed support on how to use Irssi, BitlBee, the scripts and installing everything in Ubuntu. I&#8217;ve also tried to link to other guides of the more complicated parts.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/irssi1.png" rel="lightbox[72]"></a><a href="http://www.kungfoocode.org/wp-content/uploads/irssi3.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-280" title="irssi" src="http://www.kungfoocode.org/wp-content/uploads/irssi3.png" alt="" width="576" height="392" /></a></p>
<h2>Overview</h2>
<ul>
<li>Installation</li>
<li>Basic Irssi usage</li>
<li>Scripts</li>
<li>Themes</li>
<li>BitlBee</li>
<li>Setting up BitlBee with Twitter and Google Talk</li>
<li>Nicklist</li>
<li>Xchat nick color</li>
<li>Hilight window</li>
<li>Advanced Window List</li>
<li>Auto Away</li>
<li>Autoreply (BitlBee)</li>
<li>Status notice (BitlBee)</li>
<li>OTR encryption for Irssi and BitlBee</li>
<li>Notifications</li>
<li>Last.FM</li>
</ul>
<h2>Installation</h2>
<p>This guide focuses on Ubuntu since it is one of the most common platforms. Everything else in the guide is however the same everywhere.</p>
<p>I have created a shell script which download everything in this tutorial. Use it only if you want to use <strong>everything and autoload all scripts</strong>. It will ask you if you want to install the Ubuntu packages (use <strong>only</strong> if you have Ubuntu Lucid or greater with Backports enabled) which requires root password. If you run any other distro or older version of Ubuntu, press &#8220;n&#8221; (no), an install the manually. The scripts will be downloaded anyway.</p>
<p>To run it:</p>
<pre class="brush: bash; title: ;">
wget http://files.kungfoocode.org/kungfooirssi.sh
chmod +x kungfooirssi.sh
sh kungfooirssi.sh
</pre>
<p>I Will presume that you have not executed the script and through the guide provide necessary setups to install everything &#8220;manually&#8221;.</p>
<p>To install everything we need (in Ubuntu Lucid or greater, enable Backports), type:</p>
<pre class="brush: bash; title: ;">
sudo apt-get install irssi bitlbee screen bitlbee-plugin-otr libtime-duration-perl libnotify-bin irssi-plugin-otr
</pre>
<p>This will install the latest (currently) version of Irssi, BitlBee 3 and Screen. It is important that you have Backports or you will not get Bitlbee 3. You need screen for the nicklist-script and it is totally awesome on its own so you should learn to use it anyway.</p>
<p>Learn more about Irssi and Screen: <a href="http://quadpoint.org/articles/irssi">http://quadpoint.org/articles/irssi</a></p>
<p>Now type irssi in your terminal to get going!</p>
<h2>Basic Irssi usage</h2>
<p>All Irssi-commands starts with a forward slash /. You can use the tab-key to auto-complete commands and you can browse through all commands by pressing tab several times.</p>
<p>First of all you should set your nickname:</p>
<pre class="brush: bash; title: ;">
/nick my-cool-nickname
</pre>
<p>If you want to connect to a IRC-server you can use either /server or /connect. Using /server will kill the old connection (if you have one) but using /connect will establish a new parallel connection so that you can have several active connection.</p>
<p>If you want to auto connect and join channels on start up you can use:</p>
<pre class="brush: bash; title: ;">
/server ADD -auto -network NetworkName irc.host.com 6667
/channel ADD -auto #channel NetworkName password
</pre>
<p>To switch between servers press CTRL + X. To switch between windows / channels press ALT + number or use:</p>
<pre class="brush: bash; title: ;">
/window number
</pre>
<p>To use the ALT-combination on numbers higher than 10 (which uses key 0) you can use the letters below the numbers on a qwerty-keyboard. ALT+Q = 11, ALT+W = 12 and so forth.</p>
<p>To close a window use:</p>
<pre class="brush: bash; title: ;">
/wc
</pre>
<p>When you have customized Irssi as you wanted it, execute:</p>
<pre class="brush: bash; title: ;">
/save
</pre>
<p>This will save all your settings and apply the current theme.</p>
<p>Consult the official manual to get more information about commands and features.<br />
<a href="http://irssi.org/documentation/manual"> http://irssi.org/documentation/manual</a></p>
<h3>Scripts</h3>
<p>The really great thing about Irssi is that there are thousands of scripts and customizations. I will walk you through my favorite scripts further down.</p>
<p>Irssi scripts are written i Perl and are usually located in ~/.irssi/scripts/. To load a script you can use the /script command:</p>
<pre class="brush: bash; title: ;">
/script load mycoolscript.pl
</pre>
<p>Or you can auto-load the scripts so you don&#8217;t have to use the script command every time you start Irssi. You can do this by putting the .pl-file in a folder called autorun in the scripts folder ~/.irssi/scripts/autorun/.</p>
<p>You can find a lot of scripts on Irssi&#8217;s official script site.<br />
<a href="http://scripts.irssi.org/"> http://scripts.irssi.org/</a></p>
<h3>Themes</h3>
<p>There are tons of themes. I use a theme called xchat which you will see in this guide. You can find a lot of themes if you Google for it or visit the official Irssi Theme page:<br />
<a href="http://irssi.org/themes"> http://irssi.org/themes</a></p>
<p>The xchat theme is located at <a href="http://irssi.org/themefiles/xchat.theme">http://irssi.org/themefiles/xchat.theme</a></p>
<p>To load a theme (located in ~/.irssi/):</p>
<pre class="brush: bash; title: ;">
/set theme xchat
</pre>
<p>Replace xchat with the name of your theme of choice.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/irssi2.png" rel="lightbox[72]"></a><a href="http://www.kungfoocode.org/wp-content/uploads/irssi4.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-281" title="irssi" src="http://www.kungfoocode.org/wp-content/uploads/irssi4.png" alt="" width="576" height="392" /></a></p>
<p>Note that I use a special script with this theme. You can read about it further down.</p>
<h2>Bitlbee</h2>
<p>BitlBee is an &#8220;IRC to other networks gateway&#8221;. This means that you can use the protocols XMPP/Jabber (used by Google Talk and Facebook chat), MSN Messenger, Yahoo! Messenger, AIM and ICQ from inside and IRC-client like Irssi. You can connect to a public server but there is no hassle setting up your own which means that your information (like passwords and chat records) isn&#8217;t transmitted to any unknown servers.</p>
<p>This guide uses BitlBee 3.0.1 which you can install in Ubuntu Maverick Lucrid or gerater (enable Backports) by executing:</p>
<pre class="brush: bash; title: ;">
sudo apt-get install bitlbee
</pre>
<p>You can control the BitlBee service from your terminal:</p>
<pre class="brush: bash; title: ;">
sudo service bitlbee {start|stop|restart|force-reload}
</pre>
<p>The config file is located at /etc/bitlbee/bitlbee.conf . Look it up and customize it for your own needs. You need to restart the service if you make any changes to the configuration file.</p>
<p>When you are ready to connect to your BitlBee server (and if you haven&#8217;t changed any configurations) execute the following in Irssi:</p>
<pre class="brush: bash; title: ;">
/connect localhost
</pre>
<p>Once you are connected you should get a channel called BitlBee. This is where your contacts will be located and where you execute all your BitlBee commands. The first thing you should do is to go to the channel and register a new account.</p>
<p>Do this by typing this in the BitlBee channel:</p>
<pre class="brush: bash; title: ;">
register (password)
</pre>
<p>Make sure that you have the nickname which you want to use and note that we want to send command to the Bitlbee-channel and not to Irssi so make sure you don&#8217;t have a / in front of any commands to Bitlbee.</p>
<p>The next time you return to Bitlbee you&#8217;ll use:</p>
<pre class="brush: bash; title: ;">
identify (password)
</pre>
<p>To load all of your accounts.</p>
<p>What we need to do now is to add one of your IM-accounts to Bitlbee. The syntax for this is:</p>
<pre class="brush: bash; title: ;">
account add (protocol) (username)
/OPER
</pre>
<p>Note that we used the Irssi command /OPER to hide the password instead of typing it directly to BitlBee.</p>
<p>To list all of your accounts:</p>
<pre class="brush: bash; title: ;">
account list
</pre>
<p>All accounts are numbered and these numbers are used when modifying and connecting etc.</p>
<p>To bring an account online use.</p>
<pre class="brush: bash; title: ;">
account (number) on
</pre>
<p>If you do not provide any account number all of your accounts will be connected.</p>
<p>There is a help command which you can use if you want to know about the syntax of any of the commands. Usually you&#8217;ll do it in several steps:</p>
<pre class="brush: bash; title: ;">
help account
help account add
help account add msn
</pre>
<p>You might want want to stript out html-tags from the incoming messages since our client is text based. Do this with the following Bitlbee-command:</p>
<pre class="brush: bash; title: ;">
set strip_html true
</pre>
<p>I will guide you how to use Twitter and Google Talk in Bitlbee. You should have no problem adding other accounts the same way.</p>
<h3>Google Talk</h3>
<pre class="brush: bash; title: ;">
account add jabber (email)
/OPER
account (number) set server talk.google.com:5223:ssl
</pre>
<p>The account is now ready to be brought online!</p>
<h3>Twitter</h3>
<p>This setup is a bit different since Twitter use OAuth.</p>
<p>Firstly do as normal:</p>
<pre class="brush: bash; title: ;">
account add twitter (username)
/OPER
</pre>
<p>The new &#8220;twitter user&#8221; will send ju a PM. With a link for the OAuth authentication. Open the link in your browser, sign in and press Allow. Get the numeric code and send it back to the twitter user in the same window.</p>
<p>You should now be signed in to your twitter account. If you like you can rename this or any other user:</p>
<pre class="brush: bash; title: ;">
rename twitter_username twitter
</pre>
<p>Once signed in a new channel will be open which displays all tweets from your contacts.  Send a message in this channel to post a status update to Twitter.</p>
<h2>Nicklist</h2>
<p>This script places all nicknames in a channel in a bar at the side of the window like many other IRC-channels. You can use it in two ways. None of them is perfect but I prefer using it together with Screen.</p>
<p>You have to start Irssi inside a Gnu Screen session for it to work. You can do this directly from the console by typing:</p>
<pre class="brush: bash; title: ;">
screen irssi
</pre>
<p>You must specify the script to use Screen from inside Irssi:</p>
<pre class="brush: bash; title: ;">
/nicklist screen
</pre>
<p>Download: <a href="http://scripts.irssi.org/scripts/nicklist.pl">http://scripts.irssi.org/scripts/nicklist.pl</a><br />
Learn more about Irssi and Screen: <a href="http://quadpoint.org/articles/irssi">http://quadpoint.org/articles/irssi</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/nicklist2.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-288" title="nicklist" src="http://www.kungfoocode.org/wp-content/uploads/nicklist2.png" alt="" width="576" height="392" /></a></p>
<h2>Xchat nick color</h2>
<p>This script works together with the xchat-theme (as you can find if you scroll up a bit) and does two very important things. First of all, it aligns all nicknames to the right in the chat area which creates a vertical line with the chat messages. This makes it a lot easier to read. And secondly, it will give all nicknames a unique color so it is easier to see who sends what.</p>
<p>Download: <a href="http://dave.waxman.org/irssi/xchatnickcolor.pl">http://dave.waxman.org/irssi/xchatnickcolor.pl</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/irssi_nickcolor1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-286" title="irssi_nickcolor" src="http://www.kungfoocode.org/wp-content/uploads/irssi_nickcolor1.png" alt="" width="576" height="92" /></a></p>
<h2>Hilight window</h2>
<p>Every time you get hilighted (someone types your nickname or any other higlighted word or sends you a private message) a copy of that message will be sent to a separate window.</p>
<p>A great option is to display that window on the top of the terminal at all time. That way you&#8217;ll never miss a message.</p>
<pre class="brush: bash; title: ;">
/window new split
/window name hilight
/window size 4
</pre>
<p>Download: <a href="http://scripts.irssi.org/scripts/hilightwin.pl">http://scripts.irssi.org/scripts/hilightwin.pl</a><br />
More info: <a href="http://quadpoint.org/articles/irssi#hilight_window">http://quadpoint.org/articles/irssi#hilight_window</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/nicklist1.png" rel="lightbox[72]"></a><a href="http://www.kungfoocode.org/wp-content/uploads/hilight1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-291" title="hilight" src="http://www.kungfoocode.org/wp-content/uploads/hilight1.png" alt="" width="576" height="392" /></a></p>
<h2>Advanced Window List</h2>
<p>AWL customizes the list at the bottom which displays the window list with channels etc.</p>
<p>This is my configuration which I&#8217;ve stoled from the link below:</p>
<pre class="brush: bash; title: ;">
/set awl_display_key $Q%K|%n$H$C$S
</pre>
<p>Download: <a href="http://anti.teamidiot.de/static/nei/*/Code/Irssi/adv_windowlist.pl">http://anti.teamidiot.de/static/nei/*/Code/Irssi/adv_windowlist.pl</a><br />
More info: <a href="http://quadpoint.org/articles/irssi#channel_statusbar_using_advanced_windowlist">http://quadpoint.org/articles/irssi#channel_statusbar_using_advanced_windowlist</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/awl.png" rel="lightbox[72]"><br />
</a><a href="http://www.kungfoocode.org/wp-content/uploads/awl1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-284" title="awl" src="http://www.kungfoocode.org/wp-content/uploads/awl1.png" alt="" width="576" height="363" /></a></p>
<h2>Auto away</h2>
<p>Another script to use together with Screen. It marks you as away when Screen detects that you are not active in the session.</p>
<pre class="brush: bash; title: ;">
/set screen_away_active ON
/set screen_away_message
/set screen_away_nick
</pre>
<p>Download:<a href="http://scripts.irssi.org/scripts/screen_away.pl"> http://scripts.irssi.org/scripts/screen_away.pl</a></p>
<h2>Auto-reply Bitlbee</h2>
<p>This will reply to all incoming conversation within BitlBee with a custom message when you are away. This of it as an answering machine.</p>
<p>You will need the Perl library time-duration. Ubuntu users can use:</p>
<pre class="brush: bash; title: ;">
sudo apt-get install libtime-duration-perl
</pre>
<p>And to activate it in Irssi:</p>
<pre class="brush: bash; title: ;">
/set bitlbee_autoreply_duration ON
</pre>
<p>Download: <a href="https://github.com/msparks/irssiscripts/raw/master/bitlbee_autoreply.pl">https://github.com/msparks/irssiscripts/raw/master/bitlbee_autoreply.pl</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/irssi_autoreply1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-287" title="irssi_autoreply" src="http://www.kungfoocode.org/wp-content/uploads/irssi_autoreply1.png" alt="" width="576" height="33" /></a></p>
<h2>Status notice (BitlBee)</h2>
<p>Displays additional information when a users change status such as how long the user was marked as away / offline.</p>
<p>Download: <a href="http://github.com/msparks/irssiscripts/raw/master/bitlbee_status_notice.pl">http://github.com/msparks/irssiscripts/raw/master/bitlbee_status_notice.pl</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/irssi_status_notice1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-289" title="irssi_status_notice" src="http://www.kungfoocode.org/wp-content/uploads/irssi_status_notice1.png" alt="" width="576" height="61" /></a></p>
<h2>OTR encryption for Irssi &amp; BitlBee</h2>
<p>Installation for Ubuntu users:</p>
<pre class="brush: bash; title: ;">
sudo apt-get install bitlbee-plugin-otr irssi-plugin-otr
</pre>
<p>You need to load the OTR module inside Irssi:</p>
<pre class="brush: bash; title: ;">
/LOAD otr
</pre>
<p>If you wish to do it automatically add this to or create the file ~/.irssi/startup:</p>
<pre class="brush: bash; title: ;">
LOAD otr
</pre>
<p>Note that we do not use forward-slash in this file.</p>
<p>Irssi OTR settings:</p>
<pre class="brush: bash; title: ;">
Commands:

/otr genkey nick@irc.server.com
	Manually generate a key for the given account(also done on demand)
/otr auth [&lt;nick&gt;@&lt;server&gt;] &lt;secret&gt;
	Initiate or respond to an authentication challenge
/otr authabort [&lt;nick&gt;@&lt;server&gt;]
	Abort any ongoing authentication
/otr trust [&lt;nick&gt;@&lt;server&gt;]
	Trust the fingerprint of the user in the current window.
	You should only do this after comparing fingerprints over a secure line
/otr debug
	Switch debug mode on/off
/otr contexts
	List all OTR contexts along with their fingerprints and status
/otr finish [&lt;nick&gt;@&lt;server&gt;]
	Finish an OTR conversation
/otr version
	Display irc-otr version. Might be a git commit

Settings:

otr_policy
	Comma-separated list of &quot;&lt;nick&gt;@&lt;server&gt; &lt;policy&gt;&quot; pairs. See comments
	above.
otr_policy_known
	Same syntax as otr_policy. Only applied where a fingerprint is
	available.
otr_ignore
	Conversations with nicks that match this regular expression completely
	bypass libotr. It is very unlikely that you need to touch this setting,
	just use the OTR policy never to prevent OTR sessions with some nicks.
otr_finishonunload
	If true running OTR sessions are finished on /unload and /quit.
otr_createqueries
	If true queries are automatically created for OTR log messages.
</pre>
<p>OTR for BitlBee is loaded automatically when installing the Ubuntu package. Use the help command in BitlBee to get information about how to use it:</p>
<pre class="brush: bash; title: ;">
help otr
</pre>
<h2>Notifications</h2>
<p>This script provides notifications when you get hilighted via libnotify. In Ubuntu you need to install libnotify-bin:</p>
<pre class="brush: bash; title: ;">
sudo apt-get install libnotify-bin
</pre>
<p>It works with SSH and GNU Screen but remember to forward X when using SSH with the -X switch.</p>
<p>Download: <a href="http://irssi-libnotify.googlecode.com/svn/trunk/notify.pl">http://irssi-libnotify.googlecode.com/svn/trunk/notify.pl</a><br />
More info: <a href="http://code.google.com/p/irssi-libnotify/">http://code.google.com/p/irssi-libnotify/</a></p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/notification.png" rel="lightbox[72]"></a><a href="http://www.kungfoocode.org/wp-content/uploads/notification1.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-285" title="notification" src="http://www.kungfoocode.org/wp-content/uploads/notification1.png" alt="" width="576" height="192" /></a></p>
<h2>Last.FM</h2>
<p>I use this to show my friends what I&#8217;m listening to. It prints out the last played song from Last.FM.</p>
<p>Set your username:</p>
<pre class="brush: bash; title: ;">
/set lastfm_user
</pre>
<p>And show what&#8217;s playing:</p>
<pre class="brush: bash; title: ;">
/np
</pre>
<p>Download: <a href="http://scripts.irssi.org/scripts/lastfm.pl">http://scripts.irssi.org/scripts/lastfm.pl</a></p>
<h2>Official sites</h2>
<p><a href="http://irssi.org/">http://irssi.org/</a><br />
<a href="http://bitlbee.org/">http://bitlbee.org/</a><br />
<a href="http://irssi-otr.tuxfamily.org/">http://irssi-otr.tuxfamily.org/</a></p>
<h2>More help</h2>
<p>Official Irssi documentation:</p>
<p><a href="http://irssi.org/documentation">http://irssi.org/documentation</a></p>
<p>Official BitlBee wiki:<br />
<a href="http://wiki.bitlbee.org/"> http://wiki.bitlbee.org/</a></p>
<p>Quadpoint &#8211; the best known Irssi guides:<br />
<a href="http://quadpoint.org/articles/irssi">http://quadpoint.org/articles/irssi</a></p>
<p style="text-align: center;"><a href="http://www.kungfoocode.org/wp-content/uploads/comic_3.01.png" rel="lightbox[72]"><img class="aligncenter size-full wp-image-290" title="comic_3.0" src="http://www.kungfoocode.org/wp-content/uploads/comic_3.01.png" alt="" width="238" height="453" /></a>Comic from <a href="http://xkcd.com/">XKCD</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/how-to/my-perfect-irssi-setup/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Building a portable server</title>
		<link>http://www.kungfoocode.org/build-logs/building-a-portable-server/</link>
		<comments>http://www.kungfoocode.org/build-logs/building-a-portable-server/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 13:09:39 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[Build-logs]]></category>
		<category><![CDATA[Alix]]></category>
		<category><![CDATA[Alix 3C3]]></category>
		<category><![CDATA[Geode]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/?p=64</guid>
		<description><![CDATA[I decided, on a boring day in May of 2008, that I would try to do something I hadn’t done before. So I decided to &#8220;build&#8221; a tiny computer that would function as my private home server. My motto was &#8220;as tiny as possible but still usable&#8221;. I had seen this other guy build his [...]]]></description>
			<content:encoded><![CDATA[<p>I decided, on a boring day in May of 2008, that I would try to do something I hadn’t done before. So I decided to &#8220;build&#8221; a tiny computer that would function as my private home server. My motto was &#8220;as tiny as possible but still usable&#8221;. I had seen this other guy build his own server using m0n0wall and a Alix motherboard; so I ordered my own Alix board but instead of going the same road as he did; I picked a ever smaller version with some features that suited me better &#8211; the Alix 3C3.</p>
<h2>Specifications</h2>
<p><strong>CPU:</strong> 500 MHz AMD Geode LX800<br />
<strong>DRAM:</strong> 256 MB DDR DRAM on board<br />
<strong>Storage:</strong> CompactFlash socket<br />
<strong>Power:</strong> DC jack or passive POE, min. 7V to max. 20V<br />
<strong>Expansion:</strong> 2 miniPCI slots, LPC bus<br />
<strong>Connectivity:</strong> 1 Ethernet channel (Via VT6105M 10/100)<br />
<strong>I/O:</strong> DB9 serial port, dual USB, VGA, audio headphone out / microphone in RTC battery<br />
<strong>Board size:</strong> 100 x 160mm Firmware: tinyBIOS<br />
<strong>Other:</strong> Three LEDs</p>
<h2>Build Log</h2>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/16797-full.jpg" rel="lightbox[64]"><img class="alignnone size-large wp-image-65" title="16797-full" src="http://www.kungfoocode.org/wp-content/uploads/16797-full-576x432.jpg" alt="" width="576" height="432" /></a></p>
<p>So this is everything you need to build a system like my PoSer.</p>
<p>In order left to right, up to down:<br />
* 12 V power supply.<br />
* CF-card reader.<br />
* Chassi<br />
* Alix 3C3 motherboard (or other model of choice)<br />
* CF-card (I used 4GB which turned out to be a bit overkill so far)</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/16798-full.jpg" rel="lightbox[64]"><img class="alignnone size-large wp-image-66" title="16798-full" src="http://www.kungfoocode.org/wp-content/uploads/16798-full-576x432.jpg" alt="" width="576" height="432" /></a></p>
<p>I was surprised to see how tiny this motherboard really is even though I had read about the exact measurements before. It feels way smaller when you hold it in your hand. This is a comparison to my cellphone and a creditcard (actually two credit card cut in half and taped together).</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/16802-full.jpg" rel="lightbox[64]"><img class="alignnone size-large wp-image-67" title="16802-full" src="http://www.kungfoocode.org/wp-content/uploads/16802-full-576x432.jpg" alt="" width="576" height="432" /></a></p>
<p>Getting the system to boot really was piece of cake. At first I tried using standard Ubuntu just to check what would happened. It installed OK but failed booting since the CPU wasn’t supported.  I found this wonderful Linux distribution called Voyage Linux. It’s derived from Debian and especially designed to run on embedded platforms as the Alix etc.  The installation was very simple and not much of experience is needed. I took the CF-card and plugged it in to my multi-card reader. I created a Ext3 partition and ran the Voyage Linux installation in a terminal from my workstation.</p>
<p>All you really need to do is specify where the CF-card is mounted and it’s pretty much done deal.  Just two small pieces of advice besides following the readme: 1. Unpack the compressed file as root to preserve privileges and 2. Specify if you want an serial terminal or not.</p>
<p>When the installation is completed, pop the CF-card to the slot on the Alix card, plug some electricity and your ready to rock! Either connect a monitor to the VGA-port or connect a Ethernet cable and manage everything using SSH.  Voyage Linux promotes the “remountrw” and “remountro” commands since the CF-cards has limited amounts of read and write cycles.</p>
<p>This will mount your filsystem as read only to save the life time of your CF-card. When you need to install or change anything just type “remountrw” and your good to go.</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/16804-full.jpg" rel="lightbox[64]"><img class="alignnone size-large wp-image-68" title="16804-full" src="http://www.kungfoocode.org/wp-content/uploads/16804-full-576x432.jpg" alt="" width="576" height="432" /></a></p>
<p>This is the beauty in action. I haven’t painted or branded it yet but I will do it soon. I’m still waiting on one of the side plates to arrive from the shop I bought it at.  I use this bad boy as a file server running Screen and rTorrent. I have also plugged in a external HDD that is powered by two of the USB-ports on the PoSer to get some more storage without having to use the CF-card.</p>
<h2>Recommended areas of using devices like this</h2>
<p>Well, there are endless possibilities but this is some potential fun project you can use this hardware or similar Alix boards to do:</p>
<p>» File server<br />
» Tiny web server<br />
» Seedbox for torrents<br />
» Wardriving<br />
» Car PC<br />
» GPS (you need a GPS card or something for this, probably a bigger project)<br />
» Hidden webcam for home surveliance<br />
» Thin client<br />
» Router (there is alot of good Alix-cards for routers)<br />
» Networked music streamer<br />
» Media player (havn’t tried if it’s possible yet though)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/build-logs/building-a-portable-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fix the invalid CD key bug in Warhammer 40.000</title>
		<link>http://www.kungfoocode.org/how-to/fix-the-invalid-cd-key-bug-in-warhammer-40000-dawn-of-war/</link>
		<comments>http://www.kungfoocode.org/how-to/fix-the-invalid-cd-key-bug-in-warhammer-40000-dawn-of-war/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 16:00:58 +0000</pubDate>
		<dc:creator>Anton Fagerberg</dc:creator>
				<category><![CDATA[How to]]></category>

		<guid isPermaLink="false">http://www.kungfoocode.org/fix-the-invalid-cd-key-bug-in-warhammer-40-000-dawn-of-war/</guid>
		<description><![CDATA[Warhammer 40.000 is a great RTS series for the PC. What’s good for us Linux people is that it works excellent under Wine. I bought the “Warhammer 40K &#8211; Dawn of War Anthology”, I believe it’s called Dawn of War Platinum Edition on Steam. It really is an awesome game and it should be able [...]]]></description>
			<content:encoded><![CDATA[<p>Warhammer 40.000 is a great RTS series for the PC. What’s good for us Linux people is that it works excellent under Wine. I bought the “Warhammer 40K &#8211; Dawn of War Anthology”, I believe it’s called Dawn of War Platinum Edition on Steam. It really is an awesome game and it should be able to find it fairly cheap (I bought it at a “local” online retailer for about $20 &#8211; however the USD is really low compared to the SEK right now so it might sound cheeper to me then it does to you). There is a new expansion out called Soul Storm but I havn’t bought it yet. Dawn of War 2 is under development as well.</p>
<p>The anthology edition contains Warhammer 40K &#8211; Dawn of War and Winter Assault and Dark Crusade. Installing Dawn of War and Winter Assault went just fine but I ran into some trouble with Dark Crusade. Dark Crusade is a expansion but they’ve made it into a stand alone game so you can play it without having Dawn of War or Winter Assault installed (or owned). However, if you wish to play the races from Dawn of War and Winter Assault you have to enter the CD-keys from those games.</p>
<p>When I tried to enter these CD-keys I got the error message saying “Your CD-key seems to be invalid. Please try again.” even though I have bought the games and the keys are valid. I Googled it and found a lot of people had the same problem (on the Windows side as well) but the only solution they had was to re-install it. I did not feel like re-installing it because it’s a pain in the ass and you have to switch between 6 CDs.</p>
<p>I felt that there could be something messy in the Windows Registry Editor (open it with wine using “wine regedit”) since they recomended a re-install so I started searching through it and found the strings which caused this problem. It seems as the Winter Assault and Dawn of War keys for Dark Crusade is located in “HKEY_LOCAL_MACHINE/Software/THQ/Dawn of War &#8211; Dark Crusade”. However, the same strings can also be found in “HKEY_LOCAL_MACHINE/Software/THQ/Dawn of War” and it looks like the game checks these strings as well.</p>
<p>For some reason these strings just contained zeros so what you have to do is to change these strings to your CD-keys in the “Dawn Of War”-folder (not “Dawn of War &#8211; Dark Crusade”!). The CD-key string for Dawn of War is named CDKEY (16 chars) and the Winter Assault is named CDKEY_WXP (20 chars). I have also read that some recieved a 16 chars long CD-key for Winter Assault. This seems to be a printing error and cant be fixed this way.</p>
<p>Registry Editor in Wine:</p>
<p><a href="http://www.kungfoocode.org/wp-content/uploads/warhammer_regedit.png" rel="lightbox[4]"><img class="alignnone size-large wp-image-49" title="warhammer_regedit" src="http://www.kungfoocode.org/wp-content/uploads/warhammer_regedit-576x427.png" alt="" width="576" height="427" /></a></p>
<p>Start the game again after you’ve entered your CD-keys (with the “-” between them ofcourse). You will be prompted for you CD-keys in the game once more but they should report as valid. You can enter them directly in to you “Dawn of War &#8211; Dark Crusade” registry folder as well. The Dawn of War string is named W40KCDKEY and the Winter Assault is named WXPCDKEY (and the CDKEY-string in this folder is for the Dark Crusade game itself). I have heard that the Soul Storm has a similair problem but since I havn’t bought it yet I cant tell you how to fix it. My guess is that it is pretty much the same deal.</p>
<p><strong>Update:</strong> Some users have reported a slightly different problem on Windows Vista. Mic-B has made a comment about how to fix it.</p>
<p>Banjo has an additional comment about Windows 7 64-bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kungfoocode.org/how-to/fix-the-invalid-cd-key-bug-in-warhammer-40000-dawn-of-war/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

