mirror of
https://gitlab.com/hashborgir/plugy.git
synced 2024-10-05 17:16:03 +00:00
964 lines
30 KiB
C++
964 lines
30 KiB
C++
/*=================================================================
|
|
File created by Yohann NICOLAS.
|
|
Add support 1.13d by L'Autour.
|
|
Add support 1.14d and DoNotCloseNihlathakPortal by haxifix.
|
|
|
|
More little options.
|
|
|
|
=================================================================*/
|
|
|
|
#include "common.h"
|
|
#include "infinityStash.h"
|
|
#include <stdio.h>
|
|
|
|
bool active_DisplayItemLevel = false;
|
|
DWORD nbPlayersCommandByDefault = 0;
|
|
DWORD nbPlayersCommand = 0;
|
|
bool active_alwaysRegenMapInSP = false;
|
|
bool active_RunLODs = false;
|
|
int active_AlwaysDisplayLifeMana = 0;
|
|
bool active_EnabledTXTFilesWithMSExcel = false;
|
|
bool active_DisplayBaseStatsValue = false;
|
|
bool active_LadderRunewords = false;
|
|
bool active_EnabledCowPortalWhenCowKingWasKill = false;
|
|
bool active_DoNotCloseNihlathakPortal = false;
|
|
bool active_MoveCainNearHarrogathWaypoint = false;
|
|
bool active_RemoveExperienceDiminushingReturn = false;
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void STDCALL displayItemlevel(LPWSTR popup, Unit* ptItem)
|
|
{
|
|
if (onRealm && (selectModParam==MOD_NO)) return;
|
|
WCHAR text[0x50];
|
|
_snwprintf(text, 50, L"%s: %u\n", getLocalString(STR_ITEM_LEVEL), D2GetItemLevel(ptItem));
|
|
D2SetColorPopup(text,WHITE);
|
|
wcscat(popup,text);
|
|
}
|
|
|
|
FCT_ASM ( caller_displayItemlevel_114 )
|
|
PUSH ECX
|
|
PUSH EAX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[EBP-0x2434]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EAX
|
|
POP ECX
|
|
POP EDX
|
|
PUSH 0x100
|
|
JMP EDX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevel_113 )
|
|
PUSH ECX
|
|
PUSH EAX
|
|
PUSH EAX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x1E70]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EAX
|
|
POP ECX
|
|
POP EDX
|
|
PUSH 0x100
|
|
JMP EDX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevel_111 )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x1E74]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevelSet_114 )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[EBP-0x2138]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
FCT_ASM ( caller_displayItemlevelSet_111 )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x1958]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
|
|
FCT_ASM ( caller_displayItemlevel )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x5018]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevelSet )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x1220]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevel_9 )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x501C]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
FCT_ASM ( caller_displayItemlevelSet_9 )
|
|
PUSH ECX
|
|
PUSH EDX
|
|
PUSH ECX
|
|
LEA EAX,DWORD PTR SS:[ESP+0x1224]
|
|
PUSH EAX
|
|
CALL displayItemlevel
|
|
POP EDX
|
|
POP ECX
|
|
POP EAX
|
|
PUSH 0x100
|
|
JMP EAX
|
|
}}
|
|
|
|
|
|
void Install_DisplayItemLevel()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client to display item popup. (DisplayPopup)\n");
|
|
|
|
// print the text in the final buffer
|
|
mem_seek R8(D2Client, 3D47C, 3D47C, 438A1, ADD0A, 789DA, AE0AA, 941C0, 98590, 8E983);
|
|
memt_byte( 0x68 , 0xE8);
|
|
MEMT_REF4( 0x100, version_D2Client >= V114d ? caller_displayItemlevel_114 : version_D2Client >= V113c ? caller_displayItemlevel_113 : version_D2Client >= V111 ? caller_displayItemlevel_111 : version_D2Client == V110 ? caller_displayItemlevel : caller_displayItemlevel_9);
|
|
//6FAE38A1 . 68 00010000 PUSH 100
|
|
//6FB5DD0A |. 68 00010000 PUSH 100
|
|
//6FB289DA |. 68 00010000 PUSH 100
|
|
//6FB5E0AA |. 68 00010000 PUSH 100
|
|
//6FB441C0 |. 68 00010000 PUSH 100
|
|
//6FB48590 |. 68 00010000 PUSH 100
|
|
//0048E983 |. 68 00010000 PUSH 100 ; /Arg1 = 00000100
|
|
|
|
// print the text in the final buffer (for set items)
|
|
mem_seek R8(D2Client, 3C452, 3C452, 427BE, AC773, 77773, ACEB3, 92FE3, 973B3, 8D774);
|
|
memt_byte( 0x68 , 0xE8);
|
|
MEMT_REF4( 0x100, version_D2Client >= V114d ? caller_displayItemlevelSet_114 : version_D2Client >= V111 ? caller_displayItemlevelSet_111 : version_D2Client == V110 ? caller_displayItemlevelSet : caller_displayItemlevelSet_9);
|
|
//6FAE27BE . 68 00010000 PUSH 100
|
|
//6FB5C773 |. 68 00010000 PUSH 100
|
|
//6FB27773 |. 68 00010000 PUSH 100
|
|
//6FB5CEB3 |. 68 00010000 PUSH 100
|
|
//6FB42FE3 |. 68 00010000 PUSH 100
|
|
//6FB473B3 |. 68 00010000 PUSH 100
|
|
//0048D774 |. 68 00010000 PUSH 100 ; /Arg1 = 00000100
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
char* msgNBPlayersString = "players %u";
|
|
DWORD* infoEnabledSendPlayersCommand;
|
|
void SendPlayersCommand()
|
|
{
|
|
if (!needToInit || onRealm) return;
|
|
needToInit = false;
|
|
|
|
#pragma pack(1)
|
|
struct {
|
|
BYTE displayType;//0x15 main msg; 0x14: char popup
|
|
BYTE un;
|
|
BYTE zero;
|
|
char string[0xFF];
|
|
char null;
|
|
char targetName[0x10];
|
|
char null2;
|
|
} data;
|
|
#pragma pack()
|
|
|
|
DWORD info = *infoEnabledSendPlayersCommand;
|
|
if ((info != 0) && (info != 1) && (info != 6) && (info != 8)) return;
|
|
|
|
if (!active_multiPageStash)
|
|
nbPlayersCommand = nbPlayersCommandByDefault;
|
|
|
|
//if (nbPlayersCommand < 2)
|
|
// return;
|
|
|
|
log_msg("SendPlayersCommand %u\n", nbPlayersCommand);
|
|
|
|
D2SetNbPlayers(nbPlayersCommand);
|
|
|
|
memset(&data,0,sizeof(data));
|
|
data.displayType=0x15;
|
|
data.un=1;
|
|
data.zero=0;//*(BYTE*)(offset_D2Client+0x112CFC); in 1.10
|
|
sprintf(data.string, msgNBPlayersString, nbPlayersCommand);
|
|
data.null=NULL;
|
|
D2SendMsgToAll((BYTE*)&data);
|
|
}
|
|
|
|
//FCT_ASM ( caller_SendPlayersCommand_old )
|
|
// CALL SendPlayersCommand
|
|
// JMP D2GetResolution
|
|
//}}
|
|
|
|
FCT_ASM ( caller_SendPlayersCommand )
|
|
PUSH ECX
|
|
CALL SendPlayersCommand
|
|
POP ECX
|
|
JMP D2PrintInterface
|
|
}}
|
|
|
|
void Install_SendPlayersCommand()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client for init default nb /players. (SendPlayersCommand)\n");
|
|
|
|
infoEnabledSendPlayersCommand = (DWORD*)R8(D2Client, 111D60, 110BC0, 107960, 11BFBC, 11C2AC, 11BFF8, 11C394, 11D1DC, 3A0610);
|
|
if ( version_D2Client >= V110 )
|
|
msgNBPlayersString = (char*)R8(D2Client, 0000, 0000, D8448, D06A8, D4748, D4680, D4E00, D470C, 2D7374);
|
|
|
|
// Set nb Player to default
|
|
// mem_seek R8(D2Client, 8723B, 865BB, 81B8B, A3602, 66A02, 90162, C39F2, 1D3F2, 56EF9);//6FB1C7B7-6FAA0000
|
|
// MEMJ_REF4( D2GetResolution, caller_SendPlayersCommand_old);
|
|
//6FB2723A |. E8 7D8E0300 CALL <JMP.&D2gfx.#10005>
|
|
//6FB265BA |. E8 7D8E0300 CALL <JMP.&D2gfx.#10005>
|
|
//6FB21B8A . E8 4F9C0400 CALL <JMP.&D2gfx.#10005>
|
|
//6FB53601 |. E8 E099F6FF CALL <JMP.&D2gfx.#10000>
|
|
//6FB16A01 |. E8 AA65FAFF CALL <JMP.&D2gfx.#10063>
|
|
//6FB40161 |. E8 1ECFF7FF CALL <JMP.&D2gfx.#10043>
|
|
//6FB739F1 |. E8 B896F4FF CALL <JMP.&D2gfx.#10031>
|
|
//6FACD3F1 |. E8 EAFBFEFF CALL <JMP.&D2gfx.#10012>
|
|
//00456EF8 |. E8 63E20900 CALL Game.004F5160
|
|
|
|
// Set nb Player to default
|
|
mem_seek R8(D2Client, 90BA, 90AA, 97DA, 88E4C, 32C8C, 7CB5C, 4437C, 453CC, 4CB04);//6FB1C7B7-6FAA0000
|
|
MEMC_REF4( D2PrintInterface, caller_SendPlayersCommand);
|
|
//6FAA90B9 . E8 62E10700 CALL D2Client.6FB27220
|
|
//6FAA90A9 . E8 F2D40700 CALL D2Client.6FB265A0
|
|
//6FAA97D9 . E8 92830700 CALL D2Client.6FB21B70
|
|
//6FB38E4B . E8 A0A70100 CALL D2Client.6FB535F0
|
|
//6FAE2C8B . E8 603D0300 CALL D2Client.6FB169F0
|
|
//6FB2CB5B . E8 F0350100 CALL D2Client.6FB40150
|
|
//6FAF437B . E8 60F60700 CALL D2Client.6FB739E0
|
|
//6FAF53CB . E8 1080FDFF CALL D2Client.6FACD3E0
|
|
//0044CB03 |. E8 D8A30000 CALL Game.00456EE0
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
|
|
void Install_AlwaysRegenMapInSP()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Game for always regenerate maps in Single player. (AlwaysRegenMapInSP)\n");
|
|
|
|
// Always regenerate maps in Single player
|
|
mem_seek R8(D2Game, 517ED, 51BFA, 5DE88, 6235D, 2966D, 1E1FE, ED3BE, 26D7E, 16A20F);
|
|
memt_byte( 0x74 , 0xEB); // JMP SHORT D2Game.01FE2368
|
|
//6FC8DE88 |. 74 09 JE SHORT D2Game.6FC8DE93
|
|
//01FE235D |. 74 09 JE SHORT D2Game.01FE2368
|
|
//01F9966D |. 74 09 JE SHORT D2Game.01F99678
|
|
//6FC3E1FE |. 74 09 JE SHORT D2Game.6FC3E209
|
|
//6FD0D3BE |. 74 09 JE SHORT D2Game.6FD0D3C9
|
|
//6FC46D7E |. 74 09 JE SHORT D2Game.6FC46D89
|
|
//0056A20F |. 74 09 JE SHORT Game.0056A21A
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void Install_RunLODs()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2gfx for launch any number of Diablo II game in the same computer. (RunLODs)\n");
|
|
|
|
// execute if it's our packet else continue
|
|
mem_seek R8(D2gfx, 447C, 447C, 446A, 84CF, 84AF, 894F, 85BF, B6B0, F562B);
|
|
memt_byte( 0x74, 0xEB ); // JMP SHORT D2gfx.6FA884F6
|
|
//6FA884AF |. 74 45 JE SHORT D2gfx.6FA884F6
|
|
//6FA8894F |. 74 45 JE SHORT D2gfx.6FA88996
|
|
//6FA885BF |. 74 45 JE SHORT D2gfx.6FA88606
|
|
//6FA8B6B0 |. 74 45 JE SHORT D2gfx.6FA8B6F7
|
|
//004F562B |. 74 45 JE SHORT Game.004F5672
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
FCT_ASM (caller_AlwaysDisplayLife_114)
|
|
JNZ displayLife
|
|
CMP onRealm,0
|
|
JNZ normalDisplayLife
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayLife
|
|
displayLife:
|
|
POP EAX
|
|
ADD EAX,0x24
|
|
JMP EAX
|
|
normalDisplayLife:
|
|
LEA EAX,DWORD PTR DS:[ESI-0x1E]
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayLife_113)
|
|
POP EAX
|
|
CMP onRealm,0
|
|
JNZ normalDisplayLife
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayLife
|
|
ADD EAX,0x28
|
|
JMP EAX
|
|
normalDisplayLife:
|
|
CMP EDX,0x1E
|
|
JGE cont
|
|
ADD EAX,0xBC
|
|
cont:
|
|
JMP EAX
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayLife_111)
|
|
CMP onRealm,0
|
|
JNZ normalDisplayLife
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayLife
|
|
POP EAX
|
|
ADD EAX,0x25
|
|
JMP EAX
|
|
normalDisplayLife:
|
|
MOV EAX,ptResolutionY
|
|
MOV EAX,DWORD PTR DS:[EAX]
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayLife)
|
|
CMP onRealm,0
|
|
JNZ normalDisplayLife
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayLife
|
|
POP EAX
|
|
ADD EAX,0x28
|
|
JMP EAX
|
|
normalDisplayLife:
|
|
MOV EAX,ptResolutionY
|
|
MOV EAX,DWORD PTR DS:[EAX]
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayMana_114)
|
|
CMP onRealm,0
|
|
JNZ normalDisplayMana
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayMana
|
|
POP EAX
|
|
ADD EAX,0x23
|
|
JMP EAX
|
|
normalDisplayMana:
|
|
LEA EDI,DWORD PTR DS:[ECX-0x6F]
|
|
CMP ESI,EDI
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayMana_113)
|
|
MOV EAX,DWORD PTR DS:[ptResolutionY]
|
|
MOV EAX,DWORD PTR DS:[EAX]
|
|
CMP onRealm,0
|
|
JNZ normalDisplayMana
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayMana
|
|
POP EAX
|
|
ADD EAX,0x3C
|
|
JMP EAX
|
|
normalDisplayMana:
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayMana)
|
|
CMP onRealm,0
|
|
JNZ normalDisplayMana
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayMana
|
|
POP EAX
|
|
MOV WORD PTR SS:[ESP+0x14],0
|
|
ADD EAX,0x38
|
|
JMP EAX
|
|
normalDisplayMana:
|
|
POP EAX
|
|
POP EDI
|
|
POP ESI
|
|
POP EBP
|
|
POP EBX
|
|
ADD ESP,0x25C
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM (caller_AlwaysDisplayMana_9)
|
|
CMP onRealm,0
|
|
JNZ normalDisplayMana
|
|
CMP active_AlwaysDisplayLifeMana,0
|
|
JE normalDisplayMana
|
|
ADD DWORD PTR SS:[ESP],0x32
|
|
LEA ECX,DWORD PTR SS:[ESP+0x24]
|
|
PUSH DWORD PTR SS:[ESP+0xC]
|
|
PUSH DWORD PTR SS:[ESP+0xC]
|
|
PUSH DWORD PTR SS:[ESP+0xC]
|
|
CALL D2PrintString
|
|
MOV WORD PTR SS:[ESP+0x24],0
|
|
RETN 0xC
|
|
normalDisplayMana:
|
|
POP EAX
|
|
ADD EAX,0xC2
|
|
JMP EAX
|
|
}}
|
|
|
|
void Install_AlwaysDisplayLifeMana()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client for always display life and mana. (ALwaysPrintLifeMana)\n");
|
|
|
|
if ( version_D2Client >= V113c )
|
|
{
|
|
mem_seek R8(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 2764A, 6D6FA, 98183);
|
|
if (version_D2Client < V114d) memt_byte( 0x0F , 0x90);
|
|
memt_byte( version_D2Client >= V114d ? 0x75 : 0x8C , 0xE8);
|
|
MEMT_REF4( version_D2Client >= V114d ? 0xE2468D27 : 0x000000BC, version_D2Client >= V114d ? caller_AlwaysDisplayLife_114 : caller_AlwaysDisplayLife_113);
|
|
//6FAD764A |. 0F8C BC000000 JL D2Client.6FAD770C
|
|
//6FAD7650 |. 83FA 6E CMP EDX,6E
|
|
//6FAD7653 |. 0F8F B3000000 JG D2Client.6FAD770C
|
|
//6FAD7659 |. A1 4CBCB86F MOV EAX,DWORD PTR DS:[6FB8BC4C]
|
|
|
|
//6FAD7667 |. 0F8C A4000000 JL D2Client.6FAD7711
|
|
//6FB1D717 |. 0F8C A4000000 JL D2Client.6FB1D7C1
|
|
//6FB1D6FA |. 0F8C BC000000 JL D2Client.6FB1D7BC
|
|
//00498183 |. 75 27 JNZ SHORT Game.004981AC
|
|
//00498185 |. 8D46 E2 LEA EAX,DWORD PTR DS:[ESI-1E]
|
|
} else {
|
|
// Always display life.
|
|
mem_seek R8(D2Client, 58B32, 58B32, 5F102, 2D713, B5DF3, 81733, 0000, 0000, 0000);
|
|
memt_byte( 0xA1 , 0xE8);
|
|
MEMT_REF4( ptResolutionY , version_D2Client >= V111 ? caller_AlwaysDisplayLife_111 : caller_AlwaysDisplayLife);
|
|
//6FADD713 |. A1 605CBA6F MOV EAX,DWORD PTR DS:[6FBA5C60]
|
|
//6FB65DF3 |. A1 C84FBA6F MOV EAX,DWORD PTR DS:[6FBA4FC8]
|
|
//6FB31733 |. A1 E4C6B86F MOV EAX,DWORD PTR DS:[6FB8C6E4]
|
|
}
|
|
|
|
|
|
// Always display mana.
|
|
if ( version_D2Client >= V113c )
|
|
{
|
|
//mem_seek R7(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 27711);
|
|
//memt_byte( 0x8B , 0x90);
|
|
//memt_byte( 0x0D , 0xE8);
|
|
//MEMT_REF4( offset_D2Client + 0x11C4B4 , caller_AlwaysDisplayMana_113);
|
|
mem_seek R8(D2Client, 0000, 0000, 0000, 0000, 0000, 0000, 2770C, 6D7BC, 9825D);
|
|
memt_byte( version_D2Client >= V114d ? 0x8D : 0xA1 , 0xE8);
|
|
MEMT_REF4( version_D2Client >= V114d ? 0xF73B9179 : (DWORD)ptResolutionY , version_D2Client >= V114d ? caller_AlwaysDisplayMana_114 : caller_AlwaysDisplayMana_113);
|
|
//6FAD770C |> A1 4CBCB86F MOV EAX,DWORD PTR DS:[6FB8BC4C]
|
|
//6FAD7711 |> 8B0D B4C4BC6F MOV ECX,DWORD PTR DS:[6FBCC4B4]
|
|
|
|
//6FAD7708 |. 8B5424 10 MOV EDX,DWORD PTR SS:[ESP+10]
|
|
|
|
//6FAD77C7 |> 5F POP EDI
|
|
//6FAD77C8 |. 5E POP ESI
|
|
//6FAD77C9 |. 5D POP EBP
|
|
//6FAD77CA |. 5B POP EBX
|
|
//6FAD77CB |. 81C4 28030000 ADD ESP,328
|
|
//6FAD77D1 \. C3 RETN
|
|
//6FB1D7BC |> A1 3870BA6F MOV EAX,DWORD PTR DS:[6FB8BC4C]
|
|
//0049825D |. 8D79 91 LEA EDI,DWORD PTR DS:[ECX-6F]
|
|
//00498260 |. 3BF7 CMP ESI,EDI
|
|
}
|
|
else if ( version_D2Client >= V110 )
|
|
{
|
|
mem_seek R8(D2Client, 0000, 0000, 5F1E6, 2D7FB, B5EDB, 8181B, 0000, 0000, 0000);
|
|
memt_byte( 0x5F , 0xE8);
|
|
MEMT_REF4( 0x815B5D5E , caller_AlwaysDisplayMana);
|
|
memt_byte( 0xC4 , 0x90); // NOP
|
|
memt_byte( 0x5C , 0x90); // NOP
|
|
memt_byte( 0x02 , 0x90); // NOP
|
|
memt_byte( 0x00 , 0x90); // NOP
|
|
memt_byte( 0x00 , 0x90); // NOP
|
|
//6FADD7FB |. 5F POP EDI
|
|
//6FADD7FC |. 5E POP ESI
|
|
//6FADD7FD |. 5D POP EBP
|
|
//6FADD7FE |. 5B POP EBX
|
|
//6FADD7FF |. 81C4 5C020000 ADD ESP,25C
|
|
//6FB65EDB |. 5F POP EDI
|
|
//6FB65EDC |. 5E POP ESI
|
|
//6FB65EDD |. 5D POP EBP
|
|
//6FB65EDE |. 5B POP EBX
|
|
//6FB65EDF |. 81C4 5C020000 ADD ESP,25C
|
|
//6FB3181B |. 5F POP EDI
|
|
//6FB3181C |. 5E POP ESI
|
|
//6FB3181D |. 5D POP EBP
|
|
//6FB3181E |. 5B POP EBX
|
|
//6FB3181F |. 81C4 5C020000 ADD ESP,25C
|
|
//6FB31825 |. C3 RETN
|
|
} else {
|
|
mem_seek R8(D2Client, 58C09, 58C09, 0000, 0000, 0000, 0000, 0000, 0000, 0000);
|
|
memt_byte( 0xE9 , 0xE8);
|
|
MEMT_REF4( 0x000000C2 , caller_AlwaysDisplayMana_9);
|
|
//6FAF8C09 . E9 C2000000 JMP D2Client.6FAF8CD0
|
|
}
|
|
|
|
if (active_AlwaysDisplayLifeMana==2)
|
|
active_AlwaysDisplayLifeMana=0;
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void Install_EnabledTXTFilesWithMSExcel()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client for enabled the opening of files already opened by MS Excel. (EnabledTXTFilesWithMSExcel)\n");
|
|
|
|
mem_seek( (DWORD)D2StormMPQOpenFile + (version_Storm >= V114d ? 0xB4 : version_Storm >= V111 ? 0x12A : 0xFF) );
|
|
memt_byte( 0x01 , 0x03); //; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
|
|
//6FC1C969 |. 6A 01 PUSH 1 ; |ShareMode = FILE_SHARE_READ
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void STDCALL printDisplayBaseStatsValue(WORD statID, sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6)
|
|
{
|
|
if ( onRealm || !D2isLODGame())
|
|
{
|
|
D2PrintImage(data,x,y,p4,p5,p6);
|
|
return;
|
|
}
|
|
Unit* ptChar = D2GetClientPlayer();
|
|
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
int minValue=1;
|
|
switch (statID)
|
|
{
|
|
case STATS_STRENGTH: minValue = charStats->baseSTR; break;
|
|
case STATS_DEXTERITY: minValue = charStats->baseDEX; break;
|
|
case STATS_VITALITY: minValue = charStats->baseVIT; break;
|
|
case STATS_ENERGY: minValue = charStats->baseENE; break;
|
|
}
|
|
int statValue = D2GetPlayerBaseStat(ptChar, statID, 0);
|
|
|
|
if (isOnRect(D2GetMouseX(),D2GetMouseY(),x+5,y+5,32,32))
|
|
{
|
|
WCHAR text[100];
|
|
_snwprintf(text, 100, getLocalString(STR_STATS_BASE_MIN), statValue, minValue);
|
|
D2SetFont(1);
|
|
D2PrintPopup(text, x+18, y-32, WHITE, 1);
|
|
}
|
|
|
|
if ( D2GetPlayerBaseStat(ptChar, 4, 0) <= 0)
|
|
setFrame(data, 2);
|
|
D2PrintImage(data,x,y,p4,p5,p6);
|
|
}
|
|
|
|
FCT_ASM ( caller_displayBaseStatsValue )
|
|
POP EAX
|
|
XOR ECX,ECX
|
|
MOV CX,WORD PTR DS:[ESI+8]
|
|
PUSH ECX
|
|
PUSH EAX
|
|
JMP printDisplayBaseStatsValue
|
|
}}
|
|
|
|
void Install_DisplayBaseStatsValue()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client for display base stats value. (DisplayBaseStatsValue)\n");
|
|
|
|
// Always print stat button images.
|
|
mem_seek R8(D2Client, 29B12, 29B02, 30073, 82BBA, 8963A, 6B59A, BD1B5, BF955, A7FFB);
|
|
memt_byte( 0x8B, 0xEB ); // JMP SHORT D2Client.6FAD0088
|
|
memt_byte( version_D2Client == V114d ? 0x4D : 0x4C, V8(D2Client, 12, 12, 13, 13, 13, 13, 13, 13, 12) );
|
|
memt_byte( version_D2Client == V114d ? 0xF8 : 0x24, 0x90 ); // NOP
|
|
if (version_D2Client < V114d) memt_byte( V8(D2Client, 20, 20, 14, 1C, 1C, 1C, 1C, 1C, 53), 0x90 ); // NOP (V109d:0x20 , V110:0x14
|
|
//6FAD0073 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14]
|
|
//6FB32BBA > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB3963A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB1B59A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB6D1B5 |> 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB6F955 |> 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//004A7FFB > 8B4D F8 MOV ECX,DWORD PTR SS:[EBP-8]
|
|
//004A7FFE . 53 PUSH EBX ; /Arg3
|
|
|
|
mem_seek R8(D2Client, 29B9D, 29B8D, 300FD, 82C54, 896D4, 6B637, BD23E, BF9DE, A808C);
|
|
MEMJ_REF4( D2PrintImage, caller_displayBaseStatsValue);
|
|
//6FB32C53 . E8 82A3F8FF CALL <JMP.&D2gfx.#10047>
|
|
//6FB396D3 . E8 D238F8FF CALL <JMP.&D2gfx.#10044>
|
|
//6FB1B636 . E8 431AFAFF CALL <JMP.&D2gfx.#10024>
|
|
//6FB6D23D |. E8 54FEF4FF |CALL <JMP.&D2gfx.#10041>
|
|
//6FB6F9DD |. E8 54FEF4FF |CALL <JMP.&D2gfx.#10042>
|
|
//004A808B . E8 F0E30400 CALL Game.004F6480 ; \Game.004F6480
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
|
|
/****************************************************************************************************/
|
|
|
|
RunesBIN* STDCALL compileRunesTxt(DWORD unused, const char* filename, BINField* ptFields, DWORD* ptRecordCount, DWORD recordLength)
|
|
{
|
|
RunesBIN* ptRunesBin = (RunesBIN*)D2CompileTxtFile(unused, filename, ptFields, ptRecordCount, recordLength);
|
|
for (DWORD i=0; i < *ptRecordCount; i++)
|
|
ptRunesBin[i].Server=0;
|
|
return ptRunesBin;
|
|
}
|
|
|
|
void Install_LadderRunewords()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
if ( version_D2Common < V110 )
|
|
return;
|
|
|
|
log_msg("Patch D2Common for enabled the ladder only runewords. (LadderRunewords)\n");
|
|
|
|
mem_seek R8(D2Common, 0000, 0000, 1E965, 61762, 43A72, 5D492, 724B2, 63782, 239C40);
|
|
MEMC_REF4( D2CompileTxtFile, compileRunesTxt);
|
|
//01B6E964 |. E8 0714FFFF CALL D2Common.#10578 ; \#10578
|
|
//6FDB1761 |. E8 FAA8FCFF CALL D2Common.#10653 ; \#10653
|
|
//6FD93A71 |. E8 EAADFCFF CALL D2Common.#10496 ; \#10496
|
|
//6FDAD491 |. E8 BA49FEFF CALL D2Common.#10244 ; \#10244
|
|
//6FDC24B1 |. E8 8ACAFEFF CALL D2Common.#10849 ; \#10849
|
|
//6FDB3781 |. E8 5A93FAFF CALL D2Common.#10037 ; \#10037
|
|
//00639C3F |. E8 AC86FDFF CALL Game.006122F0 ; \Game.006122F0
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void Install_EnabledCowPortalWhenCowKingWasKill()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Game for enabled the opening of Cow Portal when player have already kill the cow king in that difficulty. (EnabledCowPortalWhenCowKingWasKill)\n");
|
|
|
|
mem_seek R8(D2Game, 5DFF7, 5E457, 6C5E7 , B1278, 5DB68, 75C68, 67508, EBE8, 194179);
|
|
memt_byte( 0x85 , 0x33); // XOR EAX,EAX
|
|
//6FC8DFF7 . 85C0 TEST EAX,EAX
|
|
//6FC8E457 . 85C0 TEST EAX,EAX
|
|
//6FC9C5E7 . 85C0 TEST EAX,EAX
|
|
//02061278 |. 85C0 TEST EAX,EAX
|
|
//01FEDB68 |. 85C0 TEST EAX,EAX
|
|
//6FC95C68 |. 85C0 TEST EAX,EAX
|
|
//6FC87508 |. 85C0 TEST EAX,EAX
|
|
//6FC2EBE8 |. 85C0 TEST EAX,EAX
|
|
//00594179 |. 85C0 TEST EAX,EAX
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void Install_DoNotCloseNihlathakPortal()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Game to not close Nihlathak's portal. (DoNotCloseNihlathakPortal)\n");
|
|
|
|
mem_seek R8(D2Game, 76B19, 77019, 86679 , 107C7, 51987, 26B67, 5AE67, 1FF27, 18B9D7);
|
|
memt_byte(0x0F, 0x90);
|
|
memt_byte(0x85, 0x90);
|
|
memt_dword( version_D2Game >= V114d ? 0x000000C5 : version_D2Game >= V111 ? 0x000000BF : 0x000000C1, 0x90909090);
|
|
//6FCA6B19 . 0F85 C1000000 JNZ D2Game.6FCA6BE0
|
|
//6FCA7019 . 0F85 C1000000 JNZ D2Game.6FCA70E0
|
|
//6FCB6679 . 0F85 C1000000 JNZ D2Game.6FCB6740
|
|
//6FC307C7 . 0F85 BF000000 JNZ D2Game.6FC3088C
|
|
//6FC71987 . 0F85 BF000000 JNZ D2Game.6FC71A4C
|
|
//6FC46B67 . 0F85 BF000000 JNZ D2Game.6FC46C2C
|
|
//6FC7AE67 . 0F85 BF000000 JNZ D2Game.6FC7AF2C
|
|
//6FC3FF27 . 0F85 BF000000 JNZ D2Game.6FC3FFEC
|
|
//0058B9D7 |. 0F85 C5000000 JNZ Game.0058BAA2
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/****************************************************************************************************/
|
|
/* townWest.ds1:
|
|
129A6 : 4D->76
|
|
129AA : 56->3A
|
|
12ACA : 05->04
|
|
+4 : 4D->76
|
|
+4 : 56->3A
|
|
+4 : 4E->76
|
|
+4 : 58->3A
|
|
+4 : 01->01
|
|
+4 : 4C->7B
|
|
+4 : 57->50
|
|
+4 : 02->02
|
|
+4 : 4D->7B
|
|
+4 : 5D->41
|
|
+4 : 01->01
|
|
+4 : 49->7D
|
|
+4 : 5C->3E
|
|
+4 : 02->02
|
|
+4 : 4F->
|
|
+4 : 5B->
|
|
+4 : 02->
|
|
*/
|
|
|
|
/*char* FASTCALL usePlugYTownWest(char* filename)
|
|
{
|
|
if (onRealm)
|
|
return filename;
|
|
|
|
if (!strcmp(filename, "DATA\\GLOBAL\\TILES\\Expansion\\Town\\townWest.ds1"))
|
|
return "PlugY\\townWest.ds1";
|
|
|
|
return filename;
|
|
}
|
|
|
|
FCT_ASM ( caller_usePlugYTownWest )
|
|
LEA EAX,DWORD PTR SS:[EBP-0x40]
|
|
MOV ECX,EAX
|
|
CALL usePlugYTownWest
|
|
MOV ECX,EAX
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM ( caller_usePlugYTownWest_113d )
|
|
LEA EAX,DWORD PTR SS:[ESP+0x14]
|
|
MOV ECX,EAX
|
|
CALL usePlugYTownWest
|
|
MOV EDX,ESI
|
|
RETN
|
|
}}*/
|
|
|
|
/****************************************************************************************************/
|
|
|
|
void* FASTCALL updateHarrogath(DWORD unused, char* filename, DWORD* size, const char* __CallFile, DWORD __CallLine)
|
|
{
|
|
if (onRealm)
|
|
return D2ReadFile(unused, filename, size, __CallFile, __CallLine);
|
|
|
|
if (strcmp(filename, "DATA\\GLOBAL\\TILES\\Expansion\\Town\\townWest.ds1"))
|
|
return D2ReadFile(unused, filename, size, __CallFile, __CallLine);
|
|
|
|
DWORD fileSize = 0;
|
|
if (size == NULL)
|
|
size = &fileSize;
|
|
char* data = (char*)D2ReadFile(unused, filename, size, __FILE__, __LINE__);
|
|
if (*size > 400 &&
|
|
*(DWORD*)(data + *size - 0x16C) == 0x0000004D &&
|
|
*(DWORD*)(data + *size - 0x168) == 0x00000056 &&
|
|
*(DWORD*)(data + *size - 0x48) == 0x00000005 &&
|
|
*(DWORD*)(data + *size - 0x44) == 0x0000004D &&
|
|
*(DWORD*)(data + *size - 0x40) == 0x00000056 &&
|
|
*(DWORD*)(data + *size - 0x3C) == 0x0000004E &&
|
|
*(DWORD*)(data + *size - 0x38) == 0x00000058 &&
|
|
*(DWORD*)(data + *size - 0x34) == 0x00000001 &&
|
|
*(DWORD*)(data + *size - 0x30) == 0x0000004C &&
|
|
*(DWORD*)(data + *size - 0x2C) == 0x00000057 &&
|
|
*(DWORD*)(data + *size - 0x28) == 0x00000002 &&
|
|
*(DWORD*)(data + *size - 0x24) == 0x0000004D &&
|
|
*(DWORD*)(data + *size - 0x20) == 0x0000005D &&
|
|
*(DWORD*)(data + *size - 0x1C) == 0x00000001 &&
|
|
*(DWORD*)(data + *size - 0x18) == 0x00000049 &&
|
|
*(DWORD*)(data + *size - 0x14) == 0x0000005C &&
|
|
*(DWORD*)(data + *size - 0x10) == 0x00000002 &&
|
|
*(DWORD*)(data + *size - 0x0C) == 0x0000004F &&
|
|
*(DWORD*)(data + *size - 0x08) == 0x0000005B &&
|
|
*(DWORD*)(data + *size - 0x04) == 0x00000002)
|
|
{
|
|
log_msg("update TownWest to Move Cain near Harrogath waypoint\n");
|
|
*(DWORD*)(data + *size - 0x16C) = 0x00000076;
|
|
*(DWORD*)(data + *size - 0x168) = 0x0000003A;
|
|
*(DWORD*)(data + *size - 0x48) = 0x00000004;
|
|
*(DWORD*)(data + *size - 0x44) = 0x00000076;
|
|
*(DWORD*)(data + *size - 0x40) = 0x0000003A;
|
|
*(DWORD*)(data + *size - 0x3C) = 0x00000076;
|
|
*(DWORD*)(data + *size - 0x38) = 0x0000003A;
|
|
*(DWORD*)(data + *size - 0x34) = 0x00000001;
|
|
*(DWORD*)(data + *size - 0x30) = 0x0000007B;
|
|
*(DWORD*)(data + *size - 0x2C) = 0x00000050;
|
|
*(DWORD*)(data + *size - 0x28) = 0x00000002;
|
|
*(DWORD*)(data + *size - 0x24) = 0x0000007B;
|
|
*(DWORD*)(data + *size - 0x20) = 0x00000041;
|
|
*(DWORD*)(data + *size - 0x1C) = 0x00000001;
|
|
*(DWORD*)(data + *size - 0x18) = 0x0000007D;
|
|
*(DWORD*)(data + *size - 0x14) = 0x0000003E;
|
|
*(DWORD*)(data + *size - 0x10) = 0x00000002;
|
|
*(DWORD*)(data + *size - 0x0C) = 0x00000000;
|
|
*(DWORD*)(data + *size - 0x08) = 0x00000000;
|
|
*(DWORD*)(data + *size - 0x04) = 0x00000000;
|
|
}
|
|
else
|
|
log_msg("ERROR : Failed to update TownWest to Move Cain near Harrogath waypoint\n");
|
|
return data;
|
|
}
|
|
|
|
FCT_ASM ( caller_updateHarrogath )
|
|
MOV ECX,DWORD PTR SS:[ESP+4]
|
|
PUSH 0
|
|
PUSH 0
|
|
PUSH DWORD PTR SS:[ESP+0x10]
|
|
MOV EDX,EAX
|
|
CALL updateHarrogath
|
|
RETN 8
|
|
}}
|
|
|
|
void Install_MoveCainNearHarrogathWaypoint()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Common to move Deckard Cain near Waypoint in Harrogath. (MoveCainNearHarrogathWaypoint)\n");
|
|
mem_seek R8(D2Common, 3653E, 3654E, 45A2E , 82233, 39593, 222A3, B573, 54033, 265972);
|
|
MEMC_REF4( V2ReadFile, version_D2Common >= V111 && version_D2Common <= V113d? (TD2ReadFile)caller_updateHarrogath : updateHarrogath);
|
|
//6FD7653D |. E8 62D30300 CALL D2Common.6FDB38A4
|
|
//6FD7654D |. E8 62D40300 CALL D2Common.6FDB39B4
|
|
//6FD85A2D |. E8 36E80300 CALL D2Common.6FDC4268
|
|
//6FDD2232 . E8 A974F8FF CALL D2Common.6FD596E0
|
|
//6FD89592 . E8 3903FDFF CALL D2Common.6FD598D0
|
|
//6FD722A2 . E8 5976FEFF CALL D2Common.6FD59900
|
|
//6FD5B572 . E8 89E3FFFF CALL D2Common.6FD59900
|
|
//6FDA4032 . E8 A975FBFF CALL D2Common.6FD5B5E0
|
|
//00665971 |. E8 0317EBFF CALL Game.00517079
|
|
|
|
/*
|
|
mem_seek R8(D2Common, 0000, 0000, 0000 , 0000, 0000, 734AA, 6C75A, 308FA, 21E4F7);
|
|
memt_byte( 0x8D, 0xE8);
|
|
MEMT_REF4( version_D2Common >= V114d ? 0xC88BC045 : 0x8B102444, version_D2Common >= V114d ? caller_usePlugYTownWest : caller_usePlugYTownWest_113d);
|
|
if (version_D2Common < V114d) memt_byte( 0xD6, 0x90);
|
|
//6FDC34AA |. 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
|
|
//6FDC34AE |. 8BD6 MOV EDX,ESI
|
|
//6FDBC75A |. 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
|
|
//6FDBC75E |. 8BD6 MOV EDX,ESI
|
|
//6FD808FA |. 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
|
|
//6FD808FE |. 8BD6 MOV EDX,ESI
|
|
//0061E4F7 |. 8D45 C0 LEA EAX,DWORD PTR SS:[EBP-40]
|
|
//0061E4FA |. 8BC8 MOV ECX,EAX
|
|
*/
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
|
|
ExperienceBIN* STDCALL modifExperienceBin(ExperienceBIN* ptExperienceBIN)
|
|
{
|
|
for (int i=71; i<101; i++)
|
|
ptExperienceBIN[i].ExpRatio = 1024;
|
|
return ptExperienceBIN;
|
|
}
|
|
|
|
FCT_ASM ( caller_modifExperienceBin )
|
|
PUSH DWORD PTR SS:[ESP+0x14]
|
|
PUSH DWORD PTR SS:[ESP+0x14]
|
|
PUSH DWORD PTR SS:[ESP+0x14]
|
|
PUSH DWORD PTR SS:[ESP+0x14]
|
|
PUSH DWORD PTR SS:[ESP+0x14]
|
|
CALL D2CompileTxtFile
|
|
PUSH EAX
|
|
CALL modifExperienceBin
|
|
RETN 0x14
|
|
}}
|
|
|
|
void Install_RemoveExperienceDiminushingReturn()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Common to remove experience diminushing return. (RemoveExperienceDiminushingReturn)\n");
|
|
|
|
// modification of experienceBIN
|
|
mem_seek R8(D2Common, 00000, 00000, 00000, 00000, 00000, 00000, 00000, 00000, 213E42);
|
|
MEMC_REF4( D2CompileTxtFile, caller_modifExperienceBin);
|
|
//00613E41 |. E8 AAE4FFFF CALL Game.006122F0 ; \Game.006122F0
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/*================================= END OF FILE =================================*/ |