• November 2017
    M T W T F S S
    « Feb    
     12345
    6789101112
    13141516171819
    20212223242526
    27282930  

A Tale in the Desert: A Geek’s Paradise

A Tale in the Desert is indeed a geek’s paradise. It’s an MMORPG that is different than most. MMO players might refer to it as “that crafting game”, but it really is a lot more than just that. Although I have played the game from its inception nearly 8 years ago, when asked what the game is about I still have a difficult time explaining it. ATITD is indeed a crafting game; there is no maiming and killing. It also has a lot of puzzles, and some extremely complicated game systems. The creator of the game, Andrew Tepper, is a mathematician. Part of the challenge of the game is to actually figure out how it works.

That description still doesn’t capture the true nature of the game, and why some people love it. In the following post I will attempt to capture just one of the major aspects of the game that attracts me: the ability to create third party macros to assist with the grinding aspects of the game. Yes, macroing is allowed in ATITD. However, unattended macroing is strictly forbidden, and getting caught will definitely result in a banned account. Also worth mentioning is that one of the most successful players in the game that I know of doesn’t macro at all; players can still be very competitive and not need to use macros in ATITD.

I’ve recently been preparing for the new “shard”, or server that is coming out this month. Unlike other MMO’s, A Tale in the Desert has a beginning, a middle, and an end. ATITD is on its 4th “telling”. A new idea however was introduced by an ATITD game master: sharding. The beginning of a Tale is often more fun for players, and players who start playing the game at the beginning of a tale are more likely to stay throughout its course. So, the idea of creating a second shard of Tale 4 has come into the works, and I intend to play on it.

I started going through my macros as preparation for the new shard, and realized that there were a few I was missing that I wanted to have at my disposal. I decided to start with a Barrel Vise macro. Barrel Vises are used to make barrels, which are used to store wine and beer, which if you drink enough of give your avatar permanent increases in the Perception stat. The most effective way of gaming this is to create lots of barrels so that you can fill them with lots of different kinds of wines. The process of making a barrel on a Barrel Vise is one of the many mini-games within ATITD. I’m not very good at it.

The “official” documentation from the player-maintained wiki is here, but I will quickly explain how this mini-game works. The Barrel Vise interface has four bars: Fuel, Flame, Heat, and Progress. The idea is to add wood as Fuel, which increases the Flame. If the Flame is higher than the Heat, the Heat will grow. If the Heat is above 50%, Progress will be made on the making of the barrel. Finally, if the Flame reaches max, the barrel incinerates, and all materials are lost. Here is a pic of my avatar after a few rounds of building the flame up.

Once the Heat gets up to 50%, it turns red, and Progress begins! It then becomes a game of adding more wood to keep the Flame and Heat high, without letting the Flame get maxed out.

Now for the fun part, the macro. The macro program that I use, and is very popular in the ATITD community is AuotHotKey. AHK also comes with AutoIt’s Window Spy, which is useful for getting screen coordinates for mouse clicks and colors.

I started by getting the blue color of the status bars. Window Spy made that part easy. Next, I found the coordinates of the Fuel bar. The Fuel bar should have two “ticks” or levels of wood if the Flame can jump another tick itself, and one wood if the Flame is already too high and you don’t want it to jump. I simply took an X coordinate reading of the Fuel bar when I added one wood, then again when I added two wood. The next part was the tricky part, measuring how far I wanted the Flame to go before adding two pieces of wood to the Fuel. I took a conservative eyeball measurement after going through a few runs and incinerating a few barrels. The point is almost all the way to the right side of the Flame bar (near where the Flame bar ends in the second screenshot above), but still leaves room for random spikes (Flame increases are a random measurement within a certain unknown range). I then added some code to see if the barrel is done by updating the UI for the Barrel Vise. For humans, determining if a barrel is done is easy; the Progress bar will go all the way to the right and the mini-game will stop. This was hard to measure by reading colors on the bars within AHK. So instead I wrote a couple of lines that look for the “Take” option which also appears when a Barrel Vise has successfully made a barrel. The macro then takes the completed barrel off of the Barrel Vise and into the avatar’s inventory, and starts making another barrel (remember, I want lots and lots!).

Here is the resulting AHK code:

; Barrel Vise macro by Daniels 02/01/2010
; Using 1280, 1024 game res

; The following should stop runaway macros
; ctrl-alt-p and ctrl-alt-r
^!p::Pause
^!r::Reload

; Barrel Vise - Pin window in upper left of screen.  Coordinates are for Guilded barrel vice.  Pin when it is completely empty.
; alt-shift-b to start the macro
!+b::
IfWinExist eGenesis Client
{
	WinActivate
	SetDefaultMouseSpeed, 0

;;;;;;;;;;;;;;;;;;;;;; COORD VARIABLES ;;;;;;;;;;;;;;;;;;;;;;
	
	winX := 95 			; Top of window X/Y Coords, used to select and update the pinned window
	winY := 50
	makeX := 95 		;Make button and also Take X/Y Coords
	makeY := 90
	takeAllX := makeX + 20 
	takeAllY := makeY + 5
	stokeX := 170		; Stoke Button X/Y Coords
	stokeY := 230

	barHighX := 194 ; right most edge of the bars
	
	barMaxFlameX := 175 ; Max Flame wanted, do not have 2 wood in Fuel passed this point.  May need to adjust.
	bar1WoodX := 78 	; Coord for determining if at least 1 wood is in Fuel
	bar2WoodX := 85 	; Coord for determining if at least 2 wood is in Fuel
	
	fuelBarY := 170  	; Y Coord for Fuel bar
	flameBarY := 185 	; Y Coord for Flame bar
	heatBarY := 200		; Y Coord for Heat bar
	progressBarY := 218 ; Y Coord for Progress bar
	
;;;;;;;;;;;;;;;;;;;;;; MAIN PROGRAM ;;;;;;;;;;;;;;;;;;;;;;

	Loop, 100 ; number of barrels to make
	{
		; Click "Make a barrel"
		MouseClickCoords(winX, winY)
		MouseClickCoords(makeX, makeY)
		
		Loop, 10000 ; Maintain Heat
		{		
			curFuel1 := FindBlue(bar1WoodX, fuelBarY)
			curFuel2 := FindBlue(bar2WoodX, fuelBarY)
			curFlame := FindBlue(barMaxFlameX, flameBarY)

			if (curFlame > 0)
			{					
				if (curFuel1 > 0) ; Add 2 wood
				{
					MouseClickCoords(stokeX, stokeY)							
					MouseClickCoords(stokeX, stokeY)
				}
				else if (curFuel2 > 0) ; Add 1 wood
				{
					MouseClickCoords(stokeX, stokeY)
				}				
			}

			MouseClickCoords(winX, winY)
			ImageSearch, OutputX, OutputY, 15, 80, 60, 105, *50 Take.PNG
			if (ErrorLevel < 1)
			{
				break
			}
		}
		; Unload barrel
		MouseClickCoords(winX, winY)
		sleep 500
		MouseClickCoords(makeX, makeY)
		sleep 500
		MouseClickCoords(takeAllX, takeAllY)
		sleep 500
	}
}

MouseClickCoords(X, Y)
{
	MouseMove, X, Y
	sleep 100
	MouseClick
	sleep 100
}

FindBlue(TX, TY)
{	
	PixelSearch, PX, PY, TX, TY, TX+1, TY+1, 0xFD0606, 55, Fast
	return ErrorLevel
}

I was very happy when this macro made 16 barrels in a row without incinerating even one of them! Now, I will definitely be prepared for mass production of barrels for lots of wine and beer on the new shard. Now if only I could macro making glass, growing vegetables, and probably a slew of other tedious tasks that I am forgetting about. I can now sit back and enjoy the parts of the game that I like without worrying about the prerequisite grinding!

As I mentioned before, one does not need to macro in ATITD in order to be competitive. In fact, one of the most productive and advanced players in the game (the only Sage, I believe, or someone who has passed a certain amount of hard-to-obtain Tests) plays on a Mac and doesn’t macro at all (hi Rob!). For those who would like to use this macro though, see the wiki page where it is hosted for the full macro and documentation on how to use it here. Note that you may have to alter the X and Y coordinates of the macro to suit your operating system and screen resolution.

Advertisements

Blocking Flash Cookies (and Improved Security with Gnash)

A couple of months ago, I wrote about some simple tests that showed the lack of privacy in Chrome’s Incognito mode, and Firefox’s Private Browsing. Both browsers boast a privacy setting that will not save any of your surfing activity on your computer. That is, any activity that doesn’t produce a flash cookie. Most flash websites that I’ve been to save cookies on your computer, regardless of the browser’s privacy options.

A recent episode of FLOSS featured Rob Savoye talking about his Open Source port of Flash, Gnash. On Rob’s Blog, I found an excellent post on how to block Flash cookies on your computer. Here are the steps to block Flash cookies:

1. Browse to Adobe Flash Player Settings Manager.
2. Click on “Global Storage Settings Panel” in the left navigation menu.
3. Uncheck “Allow Third Party Flash Content to store data on your computer”.

According to Rob’s post, you shouldn’t mess with the other Privacy options in here.

An interesting side note to this blog is Gnash itself. Gnash is a completely Open Source and free project aimed at being a replacement for Adobe’s proprietary Flash player. Gnash can run stand alone Flash files, as well as be a browser plugin. Perhaps the most attractive reason to maybe switch to Gnash is that Gnash rarely suffers from the same security holes as Adobe’s Flash, as these holes tend to be due to the implementation of Flash, and not the format, according to Rob. Gnash works on almost all platforms, including Windows, Mac, and Linux, as well as plenty of other more obscure architectures. Gnash also has a significantly larger performance improvement over Adobe’s Flash in terms of CPU processing. There even exists a port of Gnash for Android!

Firefox and Chrome Private Browsing Not So Private

Recently, Chad Tilbury posted a blog article on Flash Cookie Forensics. If you didn’t already know, Adobe Flash stores cookies (actually called LSO’s) on your computer that act more or less like regular HTTP cookies, except they never expire. This got me thinking about the built-in private browsing settings found in the current versions of Firefox (3.5.2) and Chrome (2.0). Both of these browsers have an easy to use private browsing setting that block histories, HTTP cookies, form data, etc. In Firefox, private browsing is called “Private Browsing”, and Chrome has “Incognito” mode. After reading this article, I began wondering just how private Firefox’s and Chrome’s privacy settings were when it comes to Flash cookies. A couple of simple tests showed me that there isn’t much privacy at all.

The tests were simple: locate the storage of Flash cookies (as demonstrated in Chad Tilbury’s article), and see if cookies are being saved while browsing in Firefox’s Private Browsing mode, and in Google Chrome’s Incognito mode. Here is a screenshot of the Flash cookies stored on my computer before I began internet surfing in Firefox:

Firefox Private Browsing Before Surfing the Net

Firefox Private Browsing Before Surfing the Net

And here is a screenshot of the stored Flash cookies after I surfed to hulu.com in Firefox Private Browsing mode:

Firefox Private Browsing after Surfing to Hulu

Firefox Private Browsing after Surfing to Hulu

As you can see, even when using Firefox Private Browsing, Flash cookies are saved to the computer. Let’s see how well Google Chrome’s Incognito mode does. Here is a before screenshot, with Chrome cracked open in Incognito mode and ready to surf:

Google Chrome in Incognito Before Surfing

Google Chrome in Incognito Before Surfing

After surfing to hulu.com in Chrome Incognito, the Flash cookie was clearly stored on my computer:

Google Chrome Incognito after Surfing to Hulu

Google Chrome Incognito after Surfing to Hulu

The problem really shouldn’t be a surprise based on how Flash cookies work, and I am not reporting any thing new. It might not really be the browsers’ fault. Flash cookies aren’t handled by Chrome or Firefox, and thus the browser has no way to block them (as far as I understand it). Still, the private browsing features in Chrome and Firefox are a complete false sense of privacy and security. One might make the argument that both browsers should be able to build in protection against Flash cookies. As Chad mentions in his article, Firefox has an add-on called BetterPrivacy that can manage Flash cookies, and No Script blocks Flash completely, so if an add-on can do it, why can’t it be built into the browser? By the way, as far as I can tell, there isn’t a similar add-on for Chrome.

(This article is dedicated to my friend, John.)

Update: For a follow up on how to block Flash Cookies, and a better implementation of Flash called Gnash, see my article Blocking Flash Cookies (and Improved Security with Gnash.

How to Install and Fix Stumbler Plus Crashes on an iPhone (Jailbroken)

Google seems to have a lot of older forum discussions about how to get Stumbler Plus to work on the iPhone. Most of these discussions revolve around an old upgrade that resulted in a crashing state for this app. However, I have found that new installations of Stumbler Plus from Cydia also crash, and the fixes described in a lot of the Google results don’t solve the problem.

Before you can do this, your phone must be jailbroken, and you need to have OpenSSH up and running. If you are using Windows, you will need a command line SSH client like Putty and pscp.exe. Remember to turn off OpenSSH on your iPhone after this is done (there is no need to leave the service running. Anyone can scan your phone and find the service running on your phone).

To install Stumbler Plus on a jailbroken iPhone, first install it from Cydia. The app will crash as soon as it is launched. Follow these instructions to get it working properly. If you are using Windows and have downloaded pscp.exe, use pscp.exe where these instructions say to use “scp” to copy the Stumbler package to your phone. Use putty to ssh into your phone to complete the rest of the steps from the Stumbler website. If you are not comfortable using putty, you can also use the MobileTerminal application from Cydia directly on your phone.

My Twitter

Follow me on Twitter: http://twitter.com/Dantheman_13

Naming Computers in LANDesk Upgrade

Late last year I wrote an article on how to rename computers before an image is applied during LANDesk’s OSD process (read this article first if you haven’t already). Here at CSN, we PXE boot our faculty/staff computers into LANDesk’s specially configured WinPE, which launches a GUI menu of OSD tasks. These OSD tasks can be anything really, but that is a story for another article. My previous article about injecting the computer name into the Sysprep.inf file used a VBScript. I have since then upgraded to an AutoIt script that gives us more options.

PC Rename

First, let me give a brief explanation of our environment. We have a parent domain, and a child domain for students. We have four LANDesk agent configurations: one for labs and classrooms, one for office computers, one for laptops, and one for computers that don’t reside on our network. The LANDesk agent gets installed during the GUIRunOnce section of Sysprep. So, I upgraded our OSD task to prompt the technician to select which domain to join (or none), and which LANDesk agent to install. Here is the script. I won’t go through line by line like I did for the VBScript; you’ll just have to visit the AutoIt documentation website to look up some of the functions. Re-read my previous article on how I did the VBScript. The AutoIt script follows the exact same logic, but expands the idea to add more options.

#include <GUIConstantsEx.au3>

GUICreate("PC Rename", 250, 310) ; Create the GUI Window
GUICtrlCreateLabel("Enter the computer name:", 30, 10) ; Create a label
$computername = GUICtrlCreateInput("", 30, 30, 190, 20) ; Create the textbox
GUICtrlSetLimit(-1, 15) ; Limit the computer name to 15 characters
GUICtrlCreateGroup("Domain to join", 30, 60, 190, 90) ; Create the join domain "group" that surrounds the radio buttons
$optCSN = GUICtrlCreateRadio("CSN", 40, 80, 100, 20) ; Create the radio button to join the CSN domain
GUICtrlSetState(-1, $GUI_CHECKED) ; Set the CSN radio button as checked by default
$optSTUDENT = GUICtrlCreateRadio("STUDENT", 40, 100, 100, 20) ; Create the radio button to join the STUDENT domain
$optNONE = GUICtrlCreateRadio("Do not join a domain", 40, 120, 150, 20); Create the radio button to not join a domain
GUICtrlCreateGroup("", -99, -99, 1, 1)  ;close group

GUICtrlCreateGroup("LANDesk Agent", 30, 150, 190, 110) ; Create the agent "group" that surrounds the radio buttons
$optStaff = GUICtrlCreateRadio("Standard Staff/Faculty", 40, 170, 150, 20) ; Create the radio button to install the Faculty Staff agent
GUICtrlSetState(-1, $GUI_CHECKED) ; Set the Faculty Staff agent radio button as checked by default
$optDeepfreeze = GUICtrlCreateRadio("Deep Freeze Required", 40, 190, 170, 20) ; Create the radio button to install the Lab Classroom agent
$optLaptop = GUICtrlCreateRadio("Laptop/Roaming", 40, 210, 150, 20); Create the radio button to install the Roaming Laptop agent
$optRural = GUICtrlCreateRadio("Rural Site", 40, 230, 150, 20); Create the radio button to install the Rural Site agent
GUICtrlCreateGroup("", -99, -99, 1, 1)  ;close group

$okbutton = GUICtrlCreateButton("OK", 100, 270, 60)	; Create the OK button
GUISetState(@SW_SHOW) ; Show the GUI

$f = FileOpen("x:\LDClient\insertname.bat", 2) ; Create the insertname.bat file

While 1 ; infinite loop that waits for the GUI to receive a message
  $msg = GUIGetMsg() ; get any user input
  
  Select
    Case $msg = $okbutton ; if the Ok button is pressed, check the options that the user selected
		If GUICtrlRead($computername) = "" Then ; if blank computer name, use the LANDesk inventory computer name for the name.
			FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf COMPUTERNAME=%Computer - Device Name%")
		Else ; else use the user input for the computer name
			FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf COMPUTERNAME=" & GUICtrlRead($computername))
		EndIf
		Select ; Chose the domain to join or not join a domain
			Case GUICtrlRead($optCSN) = $GUI_CHECKED ; Join CSN domain
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf DOMAIN=CSN")
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf NOWG=")
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf WG=;")
			Case GUICtrlRead($optSTUDENT) = $GUI_CHECKED ; Join STUDENT domain
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf DOMAIN=STUDENT")
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf NOWG=")
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf WG=;")
			Case GUICtrlRead($optNONE) = $GUI_CHECKED ; Join WORKGROUP and no domain
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf NOWG=;")
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf WG=")
		EndSelect
		Select ; Chose the Agent to isntall
			Case GUICtrlRead($optStaff) = $GUI_CHECKED ; Install the Staff faculty agent
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf AGENT=instfacst.bat")
			Case GUICtrlRead($optDeepfreeze) = $GUI_CHECKED ; Install the Lab Classroom agent
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf AGENT=instlabcl.bat")
				MsgBox(64, "Deep Freeze Reminder", "1.  Remember to run a scheduled Deep Freeze task for this computer in LANDesk Console after imaging is complete." & @CRLF & "2.  Set the System BIOS to auto power on every day at 11:00 pm.")
			Case GUICtrlRead($optLaptop) = $GUI_CHECKED ; Install the Laptop Roaming agent
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf AGENT=instlaptop.bat")
			Case GUICtrlRead($optRural) = $GUI_CHECKED ; Install the Rural agent
				FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf AGENT=instrural.bat")
		EndSelect
		ExitLoop
	Case $msg = $GUI_EVENT_CLOSE ; if the GUI is closed, the default is to name the computer using the LANDesk inventory, and not join a domain.
		FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf COMPUTERNAME=%Computer - Device Name%")
		FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf NONE=;")
		FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf WG=")
		FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf AGENT=instfacst.bat")
		ExitLoop
  EndSelect
WEnd 

AutoIt scripts can easily be converted into an executable using AutoIt’s “Compile Script to .exe” tool.

I guess I also owe an explanation on how tokreplw.exe works. You can probably get this file by downloading the trial version of LANDesk Management Suite. This command takes two inputs: a file and a pair of tokens. The file is obvious, this is the target file to look at for token replacement. The token syntax is VARIABLE=VALUE, where VARIABLE appears in your target file as %VARIABLE%, and the value is whatever you decide. For example let’s examine one line in the prename.au3 script, line 35:

FileWriteLine($f, "tokreplw c:\sysprep\sysprep.inf DOMAIN=CSN")

To help not confuse the Autoit portion of the code, we’ll break this down to the tokreplw command:

tokreplw c:\sysprep\sysprep.inf DOMAIN=CSN

So, the “c:\sysprep\sysprep.inf” file is targeted. Within this file, an occurrence of the variable %DOMAIN% will be replaced with the value of CSN, which is the name of our parent domain. If we crack open our sysprep.inf file (do an Advanced Edit in LANDesk Console), we have this:

[Identification]
%NOWG%JoinDomain=%DOMAIN%
DomainAdmin=csn\BadBoy
DomainAdminPassword=LeeroyJenkins
%WG%JoinWorkgroup=WORKGROUP

You can see the %DOMAIN% variable here. You will also notice several other variables as well. I use tokreplw to manipulate the sysprep.inf file dynamically, depending on what the technician chooses. If the tech selects to join a domain then %NOWG% becomes blank, and %DOMAIN% becomes the name of one of our two domains. The %WG% variable becomes a semicolon, which comments out the JoinWorkgroup line. If the tech does not select to join a domain, then %NOWG% becomes a semicolon, which comments out the JoinDomain line, and %WG% becomes blank. This configures the sysprep.inf file to join the computer to a workgroup instead.

Feel free to ask any questions about the script, and I will do my best to answer them.

Google Voice on the iPhone

You can currently get an invite for Google Voice. The invitation came right away for me. The only problem is Apple rejected the Google Voice app for iPhones. Of course, this isn’t a big deal for people who have jailbroken phones. With Cydia installed, you can download GV Mobile, and make phone calls through your Google Voice account.

So what is Google Voice, and why would you want one? Let me tell you right now that this thing is cool once you grasp how it works and see it in real time! GV works like this: Google gives you an account and a phone number. In your Google Voice account, you enter your cell phone number, home number, and/or work number. When someone calls your Google voice number, it forwards the phone call to all of your listed phone numbers! You can even specify which numbers ring based on who the caller is. If you have more than one phone, this really allows you to consolidate your phone numbers into one number. I am sure that if you spend any time thinking about the possibilities for this application, you can realize that the uses for this could be huge! For example, you can give your home or cell number to agencies or businesses, while keeping your Google Voice phone number private for friends and family. The main concept to remember here is that your Google Voice number isn’t tied to a phone or device, it is tied to you.

GV also has a lot of neat features, particularly related to voicemail. You can have different greetings for different callers or groups of callers based on your Google Contacts. You can listen to voicemail on the Google Voice webpage. Voicemail is transcribed into text, both when you receive it on your phone (at least for the iPhone), and when you check it on the web. You can forward voicemail recordings to email, or even embed them on websites. GV can record phone call conversations, and listen to a voicemail message as it is being recorded. If you decide to take the call, you can do that too (provided the caller doesn’t hang up of course). Here is the list of things GV can do with links to short videos on how they work.

The one last thing that impressed me, and really sold me on Google Voice, is the international rates. This alone is a good reason to have Google Voice. I occasionally have the need to call Australia, which is only $0.03 a minute. Compare that to my cell phone provider’s international rate, which is $3.50 per minute for the same phone call. I just couldn’t pass that up.

Unfortunately, Google Voice is only available in the USA. There are plans to add it in other countries though. I highly advise folks to go to the GV website and apply for an invitation. If you have a Google or Gmail account, use that if you can. I don’t know if it makes a difference, but I signed up using my Gmail account which I have had for a few years now, and got my invitation instantly. Good luck!