TSA layout engine: Refactor the final TextOut call into its own function.
Cleanup.
patch_update(): Return prematurely if a patch contains no "servers" object.

Avoids the misleading log message that was previously printed in that case.
Rename the "inet" functions and variables to "http".

Yup, we'd like to go multi-protocol.
ServerDownloadFile: Refactor the HTTP-specific code into its own function.
ServerDownloadFile: Fix potential memory leaks.
thcrap_update: Ensure graceful termination while an update is in progress.
Fix a potential buffer overflow when determining the .msg.jdiff slot key.

One of the few last fixed char arrays, and it was susceptible to a buffer overflow. Hooray.

... yes, I would redesign that format if I had the chance.
MSG patching: Advance the line counter in any case.

What a fucking mess this is.
MSG patching: Don't patch in invalid TSA ruby syntax due to utter plebbery.

Well, of COURSE we can't expect ZUN to apply BASIC PROGRAMMING PRINCIPLES to check the return values of that fucking strchr() calls he uses to get to his cute little absolute ruby positioning parameters. So we just got to do that for him! Or would we *really* want to binary hack that into every game anew? I certainly don't.

And don't tell me "well OK, the almighty ZUN got everything under his drunken control, and if it crashes, he knows where". This is a MINOR TEXT PARSER SYNTAX ISSUE, and if YOU tell ME that this should IN ANY WAY be a reason for a FATAL PROGRAM TERMINATION (especially in a fucking shmup where that kind of thing plays a rather minor role anyway), I just cannot take you seriously.

I can already imagine a future Touhou game where dialog is triggered by some rare condition, ZUN derps around and forgets that fucking comma, doesn't manage to fix the bug due to HURR DURR COMIKET DEADLINE AND ALREADY REACHED TIME QUOTA OF STAGE X, and then this issue stays unpatched until ZUN cured his fucking hangover from the fucking Comiket after-party.

Or in other words: Let someone audit your code, ZUN. Please.
MSG patching: Make the 'lines' key optional.

Time to get rid of this ancient wart.
MSG patching: Add a helper function to get the next instruction.
Tell the user to download KB2533623 if DLL injection failed.

Another cause for DLL injection failure, and hopefully the last one. The LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR flag of LoadLibraryEx is unsupported on Windows XP, but the function works just fine otherwise. However, on Windows Vista and 7 installations *without* KB2533623 installed, the function just outright fails entirely if that flag is given. As a result, f4b1db75e905a443b814b5dddd1e28f49233f6c9 broke thcrap for pretty much everyone who hasn't updated their Windows Vista or 7 since KB2533623 was published in 2011.

Working around this issue is both painful and counter-productive (keep your systems updated, will you!). Thus, we just tell people to get that specific system update instead.

Of course we could have only mentioned that update if the user actually *is* running Vista or 7. However, with Windows 8.1, GetVersionInfoEx() was deprecated and replaced by the new Version Helper APIs (http://msdn.microsoft.com/en-us/library/windows/desktop/dn424972%28v=vs.85%29.aspx). These are, of course, exclusively available in the Windows 8.1 SDK, which I have been failing to integrate into my build environment.
MSG patching: Fix a memory corruption bug introduced by the last cleanup commit.

I should keep a tally of the instances where pointer arithmetic has actually made the code clearer, and where it just made matters worse.
Prepare and keep breakpoint data in a local structure.

This gets rid of all the JSON dictionary lookups in breakpoint_process(), and makes everything a whole lot cleaner.

... It also trades O(1) performance for O(N) performance, but it shouldn't really matter in the current use cases - and once it does, we'll think of a better solution than Jansson.
binhacks_apply(): Fix a logic flaw in the log counting.
Add functions to access flexible JSON arrays.

Suddenly, even my most hated function in this code is looking so clean!
Count the number of binary hack instances in advance.

And yes, we're going to use this for multi-address breakpoints, too.

"Hackpoints". What a brilliant name.
Music Room patching: Don't print "@" for untranslated music titles.
Cleanup.