source: Daodan/src/Daodan.c @ 465

Last change on this file since 465 was 465, checked in by rossy, 13 years ago
File size: 16.8 KB
Line 
1#include <string.h>
2
3#include "Daodan.h"
4#include "Daodan_Patch.h"
5#include "Daodan_Utility.h"
6#include "Daodan_Win32.h"
7#include "Daodan_Cheater.h"
8#include "Daodan_Persistence.h"
9#include "Daodan_BSL.h"
10
11#include "Daodan_WindowHack.h"
12
13#include "Oni.h"
14#include "Oni_Persistence.h"
15
16#include "BFW_Utility.h"
17
18#include "oni_gl.h"
19#include "daodan_gl.h"
20
21#include "inifile.h"
22
23HMODULE DDrDLLModule;
24HMODULE DDrONiModule;
25
26bool patch_fonttexturecache = true;
27bool patch_largetextures = true;
28bool patch_levelplugins = true;
29bool patch_pathfinding = true;
30bool patch_projaware = true;
31bool patch_directinput = true;
32bool patch_wpfadetime = true;
33bool patch_kickguns = false;
34bool patch_cooldowntimer = true;
35bool patch_throwtest = false;
36bool patch_alttab = true;
37bool patch_particledisablebit = false;
38bool patch_multibyte = false;
39bool patch_cheattable = true;
40bool patch_argb8888 = true;
41bool patch_killvtune = true;
42
43bool patch_safeprintf = true;
44bool patch_daodandisplayenum = true;
45bool patch_usegettickcount = true;
46bool patch_cheatsenabled = true;
47bool patch_usedaodangl = false;
48bool patch_windowhack = true;
49bool patch_daodaninit = true;
50bool patch_bsl = true;
51bool patch_cheater = true;
52
53bool opt_usedaodanbsl = true;
54
55bool DDrPatch_Init()
56{
57        DDrStartupMessage("patching engine");
58       
59        // Font texture cache doubled
60        if (patch_fonttexturecache)
61        {
62                DDrPatch_Byte  (OniExe + 0x00020ea7, 0x20);
63                DDrPatch_Byte  (OniExe + 0x00020f4a, 0x40);
64        }
65       
66        // Now supports textures up to 512x512
67        if (patch_largetextures)
68                DDrPatch_Byte  (OniExe + 0x00005251, 0x10);
69       
70        // Non-"_Final" levels are now valid
71        if (patch_levelplugins)
72                DDrPatch_Byte  (OniExe + 0x000206a8, 0x01);
73       
74        // Pathfinding grid cache size x8
75        if (patch_pathfinding)
76        {
77                DDrPatch_Byte  (OniExe + 0x0010b03b, 0x20);
78                DDrPatch_Byte  (OniExe + 0x0010b04c, 0x20);
79        }
80       
81        // Projectile awareness fixed
82        if (patch_projaware)
83        {
84                DDrPatch_Byte  (OniExe + 0x0009c07c, 0x6c);
85                DDrPatch_Byte  (OniExe + 0x0009c080, 0x70);
86                DDrPatch_Byte  (OniExe + 0x0009c084, 0x74);
87                DDrPatch_Byte  (OniExe + 0x0009c110, 0x6c);
88        }
89       
90        // Forced DirectInput (for Windows NT)
91        if (patch_directinput)
92                DDrPatch_Byte  (OniExe + 0x00002e6d, 0xeb);
93       
94        if (patch_wpfadetime)
95        {
96                // Makes wp_fadetime actually have a function
97                const char fadetime_patch[] = { 0x66, 0x8B, 0x1D, 0xC4, 0x7D, 0x62, 0x00, 0x66, 0x89, 0x5E, 0x46, 0x5B, 0x5E, 0x83, 0xC4, 0x14, 0xC3 };
98                DDrPatch_Const (OniExe + 0x0011a889, fadetime_patch);
99                DDrPatch_Byte  (OniExe + 0x0011a560, 0x31);
100               
101                // Sets the fadetime to 4800 by default
102                DDrPatch_Int16 (OniExe + 0x0011ab0e, 0x12c0);
103        }
104       
105       
106        // Hackish fix for Konoko not kicking guns
107        if (patch_kickguns)
108        {
109                const char kickgun_patch[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0xC7, 0x05, 0x1C, 0xC9, 0x5E, 0x00, 0x70, 0xB8, 0x43, 0x00, 0xC7, 0x05, 0x20, 0xC9, 0x5E, 0x00, 0x20, 0xBE, 0x43 };
110                DDrPatch_Const (OniExe + 0x000dc420, kickgun_patch);
111        }
112       
113        // Cooldown timer exploit fix ^_^
114        if (patch_cooldowntimer)
115        {
116                const char cooldown_patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
117                DDrPatch_Const (OniExe + 0x0011a825, cooldown_patch);
118        }
119       
120        if (patch_throwtest)
121        {
122                const char throwtest_patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
123                DDrPatch_Const(OniExe + 0x000dc190, throwtest_patch);
124        }
125       
126        // Disable UUrPlatform_Initalize/Terminate, this enables the Alt-Tab and the Windows key but has the possible side effect of allowing the screensaver to enable itself in-game.
127        if (patch_alttab)
128        {
129                DDrPatch_Byte  ((void*)UUrPlatform_Initialize, 0xC3);
130                DDrPatch_Byte  ((void*)UUrPlatform_Terminate, 0xC3);
131        }
132       
133        // Unlocks particle action disabling/enabling bits for all events. (Will be controlled by a command line switch when I figure out how to do that without Win32 hacks.)
134        if (patch_particledisablebit)
135                DDrPatch_Int16 (OniExe + 0x001b184, 0x9090);
136       
137        // Multi-byte patch (multiple language support)
138        if (!patch_multibyte)
139        {
140                DDrPatch_Byte  (OniExe + 0x0002d8f8, 0xeb);
141                DDrPatch_Byte  (OniExe + 0x0002d9ad, 0xeb);
142                DDrPatch_Byte  (OniExe + 0x0002dbe2, 0xeb);
143                DDrPatch_Byte  (OniExe + 0x0002dec3, 0xeb);
144                DDrPatch_Byte  (OniExe + 0x0002e2ab, 0xeb);
145                DDrPatch_Byte  (OniExe + 0x0002e2c4, 0xeb);
146                DDrPatch_Byte  (OniExe + 0x0002e379, 0xeb);
147                DDrPatch_Byte  (OniExe + 0x0002e48c, 0xeb);
148                DDrPatch_Byte  (OniExe + 0x0002e4d0, 0xeb);
149                DDrPatch_Byte  (OniExe + 0x0002e4f4, 0xeb);
150                DDrPatch_Byte  (OniExe + 0x0002e646, 0xeb);
151                DDrPatch_Byte  (OniExe + 0x0002e695, 0xeb);
152                DDrPatch_Byte  (OniExe + 0x0002e944, 0xeb);
153                DDrPatch_Byte  (OniExe + 0x0002e95d, 0xeb);
154                DDrPatch_Byte  (OniExe + 0x0002e98e, 0xeb);
155                DDrPatch_Byte  (OniExe + 0x0002e9dc, 0xeb);
156        }
157       
158        // Cheat table patch
159        if (patch_cheattable)
160        {
161                DDrPatch_Int32 (OniExe + 0x000f616b, (int)&DDr_CheatTable[0].name);
162                DDrPatch_Int32 (OniExe + 0x000f617a, (int)&DDr_CheatTable[0].message_on);
163        }
164       
165        // ARGB8888 textures
166        if (patch_argb8888)
167        {
168                DDrPatch_Byte  (OniExe + 0x00135af0, 0x07);
169                DDrPatch_Byte  (OniExe + 0x00135af4, 0x0B);
170        }
171       
172        // Disable loading the vtuneapi.dll
173        if (patch_killvtune)
174                DDrPatch_Byte  (OniExe + 0x00026340, 0xC3);
175       
176        return true;
177}
178
179enum {s_unknown, s_options, s_patch, s_bsl, s_language} ini_section;
180
181bool DDrIniCallback(char* section, bool newsection, char* name, char* value)
182{
183        if (newsection)
184        {
185                if (!stricmp(section, "options"))
186                        ini_section = s_options;
187                else if (!stricmp(section, "patch"))
188                        ini_section = s_patch;
189                else if (!stricmp(section, "bsl"))
190                        ini_section = s_bsl;
191                else if (!stricmp(section, "language"))
192                        ini_section = s_language;
193                else
194                {
195                        ini_section = s_unknown;
196                        DDrStartupMessage("unrecognised ini section \"%s\"", section);
197                }
198        }
199       
200        switch (ini_section)
201        {
202                case s_options:
203                        if (!stricmp(name, "usedaodanbsl"))
204                                opt_usedaodanbsl = !stricmp(inifile_cleanstr(value), "true");
205                        break;
206                case s_patch:
207                        if (!stricmp(name, "fonttexturecache"))
208                                patch_fonttexturecache = !stricmp(inifile_cleanstr(value), "true");
209                        else if (!stricmp(name, "largetextures"))
210                                patch_largetextures = !stricmp(inifile_cleanstr(value), "true");
211                        else if (!stricmp(name, "levelplugins"))
212                                patch_levelplugins = !stricmp(inifile_cleanstr(value), "true");
213                        else if (!stricmp(name, "pathfinding"))
214                                patch_pathfinding = !stricmp(inifile_cleanstr(value), "true");
215                        else if (!stricmp(name, "projaware"))
216                                patch_projaware = !stricmp(inifile_cleanstr(value), "true");
217                        else if (!stricmp(name, "directinput"))
218                                patch_directinput = !stricmp(inifile_cleanstr(value), "true");
219                        else if (!stricmp(name, "wpfadetime"))
220                                patch_wpfadetime = !stricmp(inifile_cleanstr(value), "true");
221                        else if (!stricmp(name, "kickguns"))
222                                patch_kickguns = !stricmp(inifile_cleanstr(value), "true");
223                        else if (!stricmp(name, "cooldowntimer"))
224                                patch_cooldowntimer = !stricmp(inifile_cleanstr(value), "true");
225                        else if (!stricmp(name, "throwtest"))
226                                patch_throwtest = !stricmp(inifile_cleanstr(value), "true");
227                        else if (!stricmp(name, "alttab"))
228                                patch_alttab = !stricmp(inifile_cleanstr(value), "true");
229                        else if (!stricmp(name, "particledisablebit"))
230                                patch_particledisablebit = !stricmp(inifile_cleanstr(value), "true");
231                        else if (!stricmp(name, "multibyte"))
232                                patch_multibyte = !stricmp(inifile_cleanstr(value), "true");
233                        else if (!stricmp(name, "cheattable"))
234                                patch_cheattable = !stricmp(inifile_cleanstr(value), "true");
235                        else if (!stricmp(name, "argb8888"))
236                                patch_argb8888 = !stricmp(inifile_cleanstr(value), "true");
237                        else if (!stricmp(name, "killvtune"))
238                                patch_killvtune = !stricmp(inifile_cleanstr(value), "true");
239                        else if (!stricmp(name, "safeprintf"))
240                                patch_safeprintf = !stricmp(inifile_cleanstr(value), "true");
241                        else if (!stricmp(name, "daodandisplayenum"))
242                                patch_daodandisplayenum = !stricmp(inifile_cleanstr(value), "true");
243                        else if (!stricmp(name, "usegettickcount"))
244                                patch_usegettickcount = !stricmp(inifile_cleanstr(value), "true");
245                        else if (!stricmp(name, "cheatsenabled"))
246                                patch_cheatsenabled = !stricmp(inifile_cleanstr(value), "true");
247                        else if (!stricmp(name, "usedaodangl"))
248                                patch_usedaodangl = !stricmp(inifile_cleanstr(value), "true");
249                        else if (!stricmp(name, "windowhack"))
250                                patch_windowhack = !stricmp(inifile_cleanstr(value), "true");
251                        else if (!stricmp(name, "daodaninit"))
252                                patch_daodaninit = !stricmp(inifile_cleanstr(value), "true");
253                        else if (!stricmp(name, "bsl"))
254                                patch_bsl = !stricmp(inifile_cleanstr(value), "true");
255                        else if (!stricmp(name, "cheater"))
256                                patch_cheater = !stricmp(inifile_cleanstr(value), "true");
257                        else
258                                DDrStartupMessage("unrecognised patch \"%s\"", name);
259                        break;
260                case s_language:
261                        if (!stricmp(name, "savepoint"))
262                        {
263                                char* str = strdup(value);
264                                DDrPatch_Int32(OniExe + 0x000fd730, (int)str);
265                                DDrPatch_Int32(OniExe + 0x000fd738, (int)str);
266                        }
267                        else if (!stricmp(name, "syndicatewarehouse"))
268                        {
269                                char* str = strdup(value);
270                                DDrPatch_Int32(OniExe + 0x000fd71a, (int)str);
271                                DDrPatch_Int32(OniExe + 0x0010ef75, (int)str);
272                        }
273                        else if (!stricmp(name, "damn"))
274                                DDrPatch_StrDup(OniExe + 0x0010fb6e, value);
275                        else if (!stricmp(name, "blam"))
276                                DDrPatch_StrDup(OniExe + 0x0010fb73, value);
277                        else if (!stricmp(name, "shapeshifter_on"))
278                                DDr_CheatTable[0].message_on = strdup(value);
279                        else if (!stricmp(name, "shapeshifter_off"))
280                                DDr_CheatTable[0].message_off = strdup(value);
281                        else if (!stricmp(name, "liveforever_on"))
282                                DDr_CheatTable[1].message_on = strdup(value);
283                        else if (!stricmp(name, "liveforever_off"))
284                                DDr_CheatTable[1].message_off = strdup(value);
285                        else if (!stricmp(name, "touchofdeath_on"))
286                                DDr_CheatTable[2].message_on = strdup(value);
287                        else if (!stricmp(name, "touchofdeath_off"))
288                                DDr_CheatTable[2].message_off = strdup(value);
289                        else if (!stricmp(name, "canttouchthis_on"))
290                                DDr_CheatTable[3].message_on = strdup(value);
291                        else if (!stricmp(name, "canttouchthis_off"))
292                                DDr_CheatTable[3].message_off = strdup(value);
293                        else if (!stricmp(name, "fatloot_on"))
294                                DDr_CheatTable[4].message_on = strdup(value);
295                        else if (!stricmp(name, "glassworld_on"))
296                                DDr_CheatTable[5].message_on = strdup(value);
297                        else if (!stricmp(name, "glassworld_off"))
298                                DDr_CheatTable[5].message_off = strdup(value);
299                        else if (!stricmp(name, "winlevel_on"))
300                                DDr_CheatTable[6].message_on = strdup(value);
301                        else if (!stricmp(name, "loselevel_on"))
302                                DDr_CheatTable[7].message_on = strdup(value);
303                        else if (!stricmp(name, "bighead_on"))
304                                DDr_CheatTable[8].message_on = strdup(value);
305                        else if (!stricmp(name, "bighead_off"))
306                                DDr_CheatTable[8].message_off = strdup(value);
307                        else if (!stricmp(name, "minime_on"))
308                                DDr_CheatTable[9].message_on = strdup(value);
309                        else if (!stricmp(name, "minime_off"))
310                                DDr_CheatTable[9].message_off = strdup(value);
311                        else if (!stricmp(name, "superammo_on"))
312                                DDr_CheatTable[10].message_on = strdup(value);
313                        else if (!stricmp(name, "superammo_off"))
314                                DDr_CheatTable[10].message_off = strdup(value);
315                        else if (!stricmp(name, "devmode_on"))
316                        {
317                                char* str = strdup(value);
318                                DDr_CheatTable[11].message_on = str;
319                                DDr_CheatTable[cheat_x].message_on = str;
320                        }
321                        else if (!stricmp(name, "devmode_off"))
322                        {
323                                char* str = strdup(value);
324                                DDr_CheatTable[11].message_off = str;
325                                DDr_CheatTable[cheat_x].message_off = str;
326                        }
327                        else if (!stricmp(name, "reservoirdogs_on"))
328                                DDr_CheatTable[12].message_on = strdup(value);
329                        else if (!stricmp(name, "reservoirdogs_off"))
330                                DDr_CheatTable[12].message_off = strdup(value);
331                        else if (!stricmp(name, "roughjustice_on"))
332                                DDr_CheatTable[13].message_on = strdup(value);
333                        else if (!stricmp(name, "roughjustice_off"))
334                                DDr_CheatTable[13].message_off = strdup(value);
335                        else if (!stricmp(name, "chenille_on"))
336                                DDr_CheatTable[14].message_on = strdup(value);
337                        else if (!stricmp(name, "chenille_off"))
338                                DDr_CheatTable[14].message_off = strdup(value);
339                        else if (!stricmp(name, "behemoth_on"))
340                                DDr_CheatTable[15].message_on = strdup(value);
341                        else if (!stricmp(name, "behemoth_off"))
342                                DDr_CheatTable[15].message_off = strdup(value);
343                        else if (!stricmp(name, "elderrune_on"))
344                                DDr_CheatTable[16].message_on = strdup(value);
345                        else if (!stricmp(name, "elderrune_off"))
346                                DDr_CheatTable[16].message_off = strdup(value);
347                        else if (!stricmp(name, "moonshadow_on"))
348                                DDr_CheatTable[17].message_on = strdup(value);
349                        else if (!stricmp(name, "moonshadow_off"))
350                                DDr_CheatTable[17].message_off = strdup(value);
351                        else if (!stricmp(name, "munitionfrenzy_on"))
352                                DDr_CheatTable[18].message_on = strdup(value);
353                        else if (!stricmp(name, "fistsoflegend_on"))
354                                DDr_CheatTable[19].message_on = strdup(value);
355                        else if (!stricmp(name, "fistsoflegend_off"))
356                                DDr_CheatTable[19].message_off = strdup(value);
357                        else if (!stricmp(name, "killmequick_on"))
358                                DDr_CheatTable[20].message_on = strdup(value);
359                        else if (!stricmp(name, "killmequick_off"))
360                                DDr_CheatTable[20].message_off = strdup(value);
361                        else if (!stricmp(name, "carousel_on"))
362                                DDr_CheatTable[21].message_on = strdup(value);
363                        else if (!stricmp(name, "carousel_off"))
364                                DDr_CheatTable[21].message_off = strdup(value);
365                        else
366                                DDrStartupMessage("unrecognised language item \"%s\"", name);
367                        break;
368                case s_bsl:
369                default:
370                        break;
371        }
372       
373        return true;
374}
375
376void DDrConfig()
377{
378        if (GetFileAttributes("daodan.ini") == INVALID_FILE_ATTRIBUTES)
379        {
380                DDrStartupMessage("daodan.ini doesn't exist, creating");
381                FILE* fp = fopen("daodan.ini", "w");
382                if (fp)
383                {
384                        fputs("[Options]\n", fp);
385                        fclose(fp);
386                }
387        }
388       
389        DDrStartupMessage("parsing daodan.ini...");
390        if (!inifile_read("daodan.ini", DDrIniCallback))
391                DDrStartupMessage("error reading daodan.ini, check your syntax!");
392        DDrStartupMessage("finished parsing");
393}
394
395void ONICALL DDrGame_Init()
396{
397        if (opt_usedaodanbsl)
398                SLrDaodan_Initalize();
399}
400
401void __cdecl DDrMain(int argc, char* argv[])
402{
403        DDrStartupMessage("daodan attached!");
404        DDrConfig();
405        DDrPatch_Init();
406       
407        // Safe startup message printer
408        if (patch_safeprintf)
409                DDrPatch_MakeJump(UUrStartupMessage, DDrStartupMessage);
410       
411        // Daodan device mode enumeration function
412        if (patch_daodandisplayenum)
413                DDrPatch_MakeJump(gl_enumerate_valid_display_modes, daodan_enumerate_valid_display_modes);
414       
415        // Performance patch
416        if (patch_usegettickcount)
417        {
418                DDrPatch_MakeJump(UUrMachineTime_High, DDrMachineTime_High);
419                DDrPatch_MakeJump(UUrMachineTime_High_Frequency, DDrMachineTime_High_Frequency);
420                DDrPatch_MakeJump(UUrMachineTime_Sixtieths, DDrMachineTime_Sixtieths);
421        }
422       
423        // Cheats always enabled
424        if (patch_cheatsenabled)
425                DDrPatch_MakeJump(ONrPersist_GetWonGame, DDrPersist_GetWonGame);
426       
427        // Windowed mode
428        if (patch_usedaodangl)
429        {
430                DDrPatch_MakeJump(ONrPlatform_Initialize, DDrPlatform_Initialize);
431                DDrPatch_MakeJump(gl_platform_initialize, daodangl_platform_initialize);
432        }
433       
434        // Hacked windowed mode (for when daodangl isn't working properly)
435        if (patch_windowhack)
436                DDrWindowHack_Install();
437       
438        if (patch_daodaninit)
439                DDrPatch_MakeCall(OniExe + 0x000d345a, DDrGame_Init);
440       
441        // Patches for existing BSL functions
442        if (patch_bsl)
443                SLrDaodan_Patch();
444       
445        if (patch_cheater)
446        {
447                DDrPatch_MakeCall(OniExe + 0x000f618f, DDrCheater);
448                DDrPatch_Int16(OniExe + 0x000deb45, 0x5590);
449                DDrPatch_MakeCall(OniExe + 0x000deb47, FallingFrames);
450                DDrPatch_MakeJump(OniExe + 0x0010f021, DDrCheater_LevelLoad);
451        }
452       
453        init_daodan_gl();
454       
455        ONiMain(argc, argv);
456}
457/*
458void DDrWrongExe()
459{
460        switch (MessageBox(NULL, "This version of the Daodan DLL is incompatible with your Oni.exe.\n"
461                "Click OK for more information. To continue using Oni without the patch, replace the downloaded binkw32.dll with the original.", "Daodan", MB_OKCANCEL | MB_ICONERROR))
462        {
463                case IDOK:
464                        {
465                                STARTUPINFO si;
466                                PROCESS_INFORMATION pi;
467                                FillMemory(&si, 0, sizeof(si));
468                                FillMemory(&pi, 0, sizeof(pi));
469                                si.cb = sizeof(si);
470                                if (!CreateProcess(NULL, "cmd /c \"start http://wiki.oni2.net/Daodan_DLL\"", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
471                                        MessageBox(NULL, "", "", 0);
472                                CloseHandle(pi.hProcess);
473                                CloseHandle(pi.hThread);
474                        }
475                default:
476                        ExitProcess(0);
477        }
478}
479*/
480BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
481{
482        switch (fdwReason)
483        {
484                case DLL_PROCESS_ATTACH:
485                        DDrDLLModule = hinstDLL;
486                        DDrONiModule = GetModuleHandle(NULL);
487                       
488                        if (*(uint32_t*)((void*)OniExe + 0x0011acd0) == 0x09d36852)
489                                DDrPatch_MakeCall(OniExe + 0x0010fb49, DDrMain);
490                        else
491                                ExitProcess(0);
492                        break;
493        }
494        return TRUE;
495}
Note: See TracBrowser for help on using the repository browser.