source: Daodan/src/Daodan.c@ 466

Last change on this file since 466 was 466, checked in by rossy, 15 years ago

command line arguments (btw Oni's AUrBuildArgumentList doesn't follow C standards, this confused me for ages)

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