Decal for AC on Linux - It was wine all along!
Decal, the popular plug-in framework for Asheron's Call, allows people running the game on windows to script certain actions. Asheron's Call, a game that is free to download with a 15 day trial, (hereinafter referred to as AC) relies on Microsoft™ DirectX™d3d functions. Wine has its own facsimile of d3d which does not support the dynamic hooks that decal uses to patch in its own functions. However, these hooks are not needed! If you are a C programmer with somewhat average knowledge of C, wine's d3d (and everything else) is already exposed. Hello. It's open source!
From time to time we have seen requests for a decalesque plug-in framework for AC on Linux. This started out as an attempt at creating such a framework, only we found out the framework is already there. In fact, it is unnecessary to hook into DirectX to do what we need to do. Instead, we have hooked into the wine keyboard driver and we have patched one native dll, MSVCR70.dll, in order to peek inside the game and see spell messages, so we know when our spell was effective. For other games besides AC, we would need to patch other dlls to gather info about the state of the running game. These messages and their associated DLLs can be discovered by searching through the output of various wine debug commands, such as WINEDEBUG="+nls", see Hacking Tips below.
Our patch lives in the wine source folder as hkbuffbot.c and compiles as hkbuffbot.o, a winelib library that is ultimately linked into (becomes part of) winex11.drv.so. Essentially, a winelib library can make calls to both the windows and Linux API, so we have the best of both worlds! The advantage of this is that the same technique can be used with other games. This is not so much a plug-in framework as a demonstration of how wine itself is our AC plug-in framework.
The simplest sort of plug-in is one like ours that merely sends a series of keys (fake keypresses) to AC and waits for either a key press or a certain set of messages from the application to know when to quit. To do this we hook into the wine keyboard driver and we also log some strings from wine's MultiByteToWideChar() to a file to look for messages such as "You cast [something] on [someone]". Then the buffbot can look at the log and know what to do next.
Using the plug-in requires the user to compile their own copy of wine with our patch. Just look at the patch using any text editor. It's not that big already. It will take more time to read what's here, but anyway let's try to clarify some things.
We made two functions to communicate with the keyboard, hkSnoopKeys() and hkKey(). hkKey() is incomplete. It does not work with all keys, but it does what we want. To emulate pressing the number 3, for example, we would use the command, hkKey(VkKeyScanA('3')); but before we send keys to the application we need to create our own thread. Otherwise wine, and everything running under it, would block and the windows would grey out waiting for our routine to finish. This is where hkSnoopKeys() comes in handy. By patching hkSnoopKeys() into X11DRV_KeyEvent we can have it launch a thread when the user presses a key. The details are inside the hkSnoopKeys() function. hkSnoopKeys() waits for the user to press a key and then launches CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) hkBuffThread, NULL, 0, NULL); Just modify or replace hkBuffThread with whatever custom plugins you want. These plug-ins could send keys to the application, read from the keyboard or monitor functions or data inside the running applications.
Take full advantage of wine as a plug-in framework a little bit of C knowledge is necessary. We recommend taking a look at the following links.
Main Page - C
Now look at some other wine patches that are also hacks. This will give us ideas about how to successfully patch a hack into wine and launch it. There are hacks that work off a key press, hacks that work off a registry key entry, hacks that deal with sockets, drawing to the desktop window and more:
Monkey "C", monkey do!
Download the patch and open it in your favorite text editor. After you're satisfied that it will not do anything harmful, you may run it by typing the following commands:
chmod +x acbuff2.sh ./acbuff2.sh
A patch will be created in the current folder and instructions will be displayed on how to apply the patch.
Download license: GPL 2.1+
License details and further instructions are inside the file.
|locale.c|| log casting messages to a file
|Makefile.in|| tell 'make' to compile hkbuffbot.c into winex11.drv.so
|hkbuffbot.c|| main buffing routine, hacks and hkSnoopKeys() launcher
|keyboard.c|| add 1 line to call our hkSnoopKeys() launcher
|| put a forward reference to hkSnoopKeys() in the header file
It should be a trivial task for any intermediate level programmer to convert this to work with other games. So we remove all references to wcslen, msvcr70.dll and associated #includes, the LoadLibrary and swapFunc call or modify the target of these functions to work with whatever DLL and export you want to patch and swap. Everything is exposed and ready to hack, so it should be pretty easy. If you successfully make it work with other games, we would like to know about it!
Windows™ is a trademark of the Microsoft Corporation. Linux™ is a trademark of Linus Torvalds in the U.S. and other countries. We claim not to be affiliated with trademark holders.