/*=================================================================
	File created by Yohann NICOLAS.
	Add support 1.13d by L'Autour.
	Add support 1.14d by haxifix.

	Updating server.

=================================================================*/

#include "updateServer.h"
#include "updateClient.h"
#include "infinityStash.h"
#include "newInterfaces.h"
#include "newInterface_CubeListing.h"
#include "extraOptions.h"
#include "windowed.h"
#include "common.h"
#include "savePlayerData.h"
#include <stdio.h>

bool active_Commands=true;

bool active_listAllCubeFormula=true;
bool active_savegame=false;

#define MAX_CMD_SIZE 200

const char * CMD_PLAYERS="players set to";

const char * CMD_SAVE="/save";
const char * CMD_SELECTPAGE="/page";

const char * CMD_LOCK_MOUSE = "/lockmouse";
const char * CMD_LOCK_MOUSE2 = "/lock";
const char * CMD_UNLOCK_MOUSE = "/unlockmouse";
const char * CMD_UNLOCK_MOUSE2 = "/unlock";

const char * CMD_RENAME_CHAR="/renamechar";

const char * CMD_RENAME_PAGE = "/renamepage";
const char * CMD_SHORT_RENAME_PAGE = "/rp";
const char * CMD_SET_INDEX = "/setindex";
const char * CMD_SET_MAIN_INDEX = "/setmainindex";
const char * CMD_RESET_INDEX = "/resetindex";
const char * CMD_INSERT_PAGE = "/insertpage";
const char * CMD_SHORT_INSERT_PAGE = "/ip";
const char * CMD_DELETE_PAGE = "/deletepage";
const char * CMD_SHORT_DELETE_PAGE = "/dp";
const char * CMD_SWAP_PAGE = "/swappage";
const char * CMD_SHORT_SWAP_PAGE = "/sp";
const char * CMD_TOGGLE_PAGE = "/togglepage";
const char * CMD_SHORT_TOGGLE_PAGE = "/tp";

const char * CMD_DISPLAY_MANA_LIFE = "/dml";
const char * CMD_DISPLAY_LIFE_MANA = "/dlm";
const char * CMD_DISPLAY_LIFE = "/dl";
const char * CMD_DISPLAY_MANA = "/dm";

const char * CMD_LISTCUBEFORMULA="/listcube";
//const char * CMD_RELOAD="/reload";
//const char * CMD_MAXGOLD="/maxgold";


/*
$+21C8   02020648   |. 6A 01          PUSH 1
$+21CA   0202064A   |. 52             PUSH EDX
$+21CB   0202064B   |. 57             PUSH EDI
$+21CC   0202064C   |. 55             PUSH EBP
$+21CD   0202064D   |. 8BC3           MOV EAX,EBX
$+21CF   0202064F   |. E8 2CDEFFFF    CALL D2Game.0201E480
*/

/*
struct D2NPCRecordStrc
{
	DWORD	value;
};
struct D2NPCDataStrc
{
	DWORD	value;
};
D2NPCRecordStrc* __fastcall STORES_GetRecord(Game* pGame, int nNPC, int* pIndex)
{
	if (pGame == NULL)
		return NULL;

	if (pIndex != NULL)
		*pIndex = 0;

	D2NPCDataStrc* pControl = pGame->pVendorControl;
	if (pControl == NULL)
		return NULL;

	D2NPCRecordStrc* pList = pControl->pVendors;
	if (pList == NULL)
		return NULL;

	const int nCount = INLINE_GetCustomTXT()->nNPCCount;
	for (int i = 0; i < nCount; i++)
	{
		if (pList->nNPC == nNPC)
		{
			if (pIndex != NULL)
				*pIndex = i;

			return pList;
		}

		pList++;
	}

	return NULL;
}

Inventory* __fastcall STORES_GetGambleInventory(Game* pGame, Unit* pPlayer, Unit* pNPC)
{
	if (pGame == NULL || pPlayer == NULL || pNPC == NULL)
		return NULL;

	D2NPCRecordStrc* pRecord = STORES_GetRecord(pGame, pNPC->nUnitIndex, NULL);
	if (pRecord == NULL || !pRecord->bGambleInit)
		return NULL;

	D2NPCGambleStrc* pGamble = pRecord->pGamble;
	int nGUID = pPlayer->dwGUID;
	while (pGamble != NULL)
	{
		if (pGamble->dwGUID == nGUID)
			return pGamble->pInventory;

		pGamble = pGamble->pNext;
	}

	return NULL;
}

void __fastcall STORES_UpdateInventoryItems(D2UnitStrc* pNPC, D2InventoryStrc* pInventory, BOOL bPlayDropSounds = FALSE)
{

	D2UnitStrc* pItem = pInventory->pFirstItem;
	while (pItem != NULL)
	{
		if (pItem->nUnitType == UNIT_ITEM)
		{
			pItem->fUnitFlagsEx |= UNITFLAG_SHOPITEM;
			if (ITEMS_CheckSocketable(pItem))
				ITEMS_SetFlag(pItem, ITEMFLAG_NEWITEM, TRUE);

			ITEMS_UpdateTrade(pNPC->pInventory, pItem); //D2Common.#10283
			if (bPlayDropSounds)
			{
				FileItemTable* pRecord = INLINE_GetItemRecord(pItem->nUnitIndex);
				if (pRecord != NULL)
					D2PlaySound(pRecord->nDropSound, pInventory->pOwner, 0, 0, 0);
			}
		}

		pItem = pItem->pItemData->pNext;
	}
}

void gambleReload(Unit* ptChar)
{
	D2UnitStrc* pNPC = UNITS_GetServer(pGame, UNIT_MONSTER, pPacket->dwInteractGUID);
	if (pNPC != NULL)
	{
		if (pNPC->dwGUID == pPlayer->dwInteractGUID)
		{
			D2NPCRecord* pNPCRecord = NPC_GetRecord(pGame, pNPC->nUnitIndex);
			if (pNPCRecord->bGambleInit)
			{
				D2FillTradeOrGamble(pGame, pNPC, pPlayer, TRUE); //D2Game.0x6FCCAE20
				D2InventoryStrc* pInv = STORES_GetGambleInventory(pGame, pPlayer, pNPC);
				STORES_UpdateInventoryItems(pNPC, pInv, TRUE);
				D2RefreshUnitInventory(pNPC, TRUE); //D2Common.#10357
			}
		}
	}
}
*/


/*void gambleReload(Unit* ptChar)
{
	Unit* ptNPC = D2GetCurrentNPC();
	if (ptNPC)
	{
		D2TogglePage(0xC,1,0);
		//Game* ptGame = ptChar->ptGame;
		//DWORD caller = offset_D2Game + 0x74900;
		//__asm {
		//	PUSH 0
		//	PUSH 6
		//	PUSH 2
		//	PUSH ptGame
		//	MOV ECX, ptChar
		//	CALL caller
		//}
		//0330CD70   . 837C24 08 0D   CMP DWORD PTR SS:[ESP+8],0D
		D2OpenNPCMenu(ptNPC);
		D2ReloadGambleScreen();
	}
}
//6FACFFD4  |. E8 77F90000    CALL D2Client.6FADF950
*/

void savePlayers(Unit* ptChar)
{
	if (active_savegame)
		D2SaveGame(PCGame);
}

void maxGold(Unit* ptChar)
{
	log_msg("maxGold\n");

	DWORD maxGold = D2GetMaxGold(ptChar);
	DWORD maxGoldBank = D2GetMaxGoldBank(ptChar);
	DWORD playerGold = D2GetPlayerStat(ptChar, STATS_GOLD, 0);
	DWORD playerGoldBank = D2GetPlayerStat(ptChar, STATS_GOLDBANK, 0);
	if ( (playerGold < maxGold) || (playerGoldBank < maxGoldBank) ) {
		D2AddPlayerStat( ptChar, STATS_GOLD, maxGold-playerGold, 0 );
		D2AddPlayerStat( ptChar, STATS_GOLDBANK, maxGoldBank-playerGoldBank, 0 );
	} else {
		D2AddPlayerStat( ptChar, STATS_GOLD, 100000, 0 );
	}
	if (active_sharedGold)
	{
		PCPY->sharedGold = 0xFFFFFFFF;
		updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0);
	}
}

void putGold(Unit* ptChar, DWORD amount)
{
	if (!active_sharedGold) return;
	log_msg("putGold : %d\n", amount);

	DWORD playerGold = D2GetPlayerStat(ptChar, STATS_GOLD, 0);
	DWORD toAdd = 0xFFFFFFFF - PCPY->sharedGold;
	if (playerGold < toAdd)
		toAdd = playerGold;
	if (amount && (toAdd > amount))
		toAdd = amount;
	D2AddPlayerStat(ptChar, STATS_GOLD, 0-toAdd, 0);
	PCPY->sharedGold += toAdd;
	updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0);
}

void takeGold(Unit* ptChar, DWORD amount)
{
	if (!active_sharedGold) return;
	log_msg("takeGold : %d\n", amount);

	DWORD maxGold =     D2GetMaxGold(ptChar) - D2GetPlayerStat(ptChar, STATS_GOLD, 0);
//	DWORD maxGoldBank = D2GetMaxGoldBank(ptChar) - D2GetPlayerStat(ptChar, STATS_GOLDBANK, 0);
	DWORD toAdd = maxGold < PCPY->sharedGold ? maxGold : PCPY->sharedGold;
	if (amount && (toAdd > amount))
		toAdd = amount;
	D2AddPlayerStat( ptChar, STATS_GOLD, toAdd, 0 );
	PCPY->sharedGold -= toAdd;
	updateClient(ptChar, UC_SHARED_GOLD, PCPY->sharedGold, 0, 0);
}


void updateSharedGold(DWORD goldAmount)
{
	Unit* ptChar = D2GetClientPlayer();
	log_msg("SharedGold = %d\n",goldAmount);
	PCPY->sharedGold = goldAmount;
}

bool renamePage(Unit* ptChar, char* newName)
{
	Stash* ptStash = PCPY->currentStash;
	if (!ptStash)
		return 0;

	log_msg("Rename current page on Client : '%s' -> '%s'\n", ptStash->name, newName);
	int len = strlen(newName);
	// trim text
	while (newName[0] == ' ')
	{
		newName++;
		len--;
	}
	while (len > 0 && newName[len-1] == ' ')
	{
		newName[len-1] = NULL;
		len--;
	}
	// Fix max length
	if (len > 20)
	{
		newName[20] = NULL;
		len = 20;
	}

	// Check if new name is default name
	char defautText[50];
	wcstombs(defautText, getDefaultStashName(ptChar), 50);
	if (!strcmp(newName, defautText))
	{
		newName[0] = NULL;
		len = 0;
	}

	// Check if the name change
	if (newName[0] == NULL && (ptStash->name == NULL || ptStash->name[0] == NULL))
		return 0;

	if (ptStash->name && !strcmp(newName, ptStash->name))
		return 0;

	// Rename the page
	log_msg("Rename current page valid : '%s' (%s)\n", newName, defautText);
	renameCurrentStash(ptChar, newName);
	for (int i = 0; i <= len; i++)
		updateServer(US_PAGENAME + (newName[i] << 8));
	return 0;
}

bool renameCharacter(Unit* ptChar, char* newName)
{
	int len = strlen(newName);
	if (len < 2 || len > 15)
		return 0;
	for (int i = 0; i < len; i++)
	{
		char c = newName[i];
		if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_')))
			return 1;
	}
	log_msg("Rename Character : %s -> %s\n", PCPlayerData->name, newName);

	// Move current save file
	backupSaveFiles(PCPlayerData->name, -1);
	{
		char szCurrentFile[MAX_PATH];
		char szNewFile[MAX_PATH];

		//Get temporary savefile name.
		D2FogGetSavePath(szCurrentFile, MAX_PATH);
		D2FogGetSavePath(szNewFile, MAX_PATH);
		strcat(szCurrentFile, PCPlayerData->name);
		strcat(szNewFile, newName);
		strcat(szCurrentFile, ".");
		strcat(szNewFile, ".");
		int curLen = strlen(szCurrentFile);
		int newLen = strlen(szNewFile);
		strcpy(&szCurrentFile[curLen], "d2s");
		strcpy(&szNewFile[newLen], "d2s");
		if (!MoveFile(szCurrentFile, szNewFile))
			return 0;
		strcpy(&szCurrentFile[curLen], "d2x");
		strcpy(&szNewFile[newLen], "d2x");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "key");
		strcpy(&szNewFile[newLen], "key");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "ma0");
		strcpy(&szNewFile[newLen], "ma0");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "ma1");
		strcpy(&szNewFile[newLen], "ma1");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "ma2");
		strcpy(&szNewFile[newLen], "ma2");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "ma3");
		strcpy(&szNewFile[newLen], "ma3");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "ma4");
		strcpy(&szNewFile[newLen], "ma4");
		MoveFile(szCurrentFile, szNewFile);
		strcpy(&szCurrentFile[curLen], "map");
		strcpy(&szNewFile[newLen], "map");
		MoveFile(szCurrentFile, szNewFile);
	}

	// Update server
	for (int i = 0; i <= len; i++)
		updateServer(US_RENAME + (newName[i] << 8));

	// Update client
	log_msg("Rename on Client : %s -> %s\n", PCPlayerData->name, newName);
	strcpy(PCPlayerData->name, newName);

	updateServer(US_SAVE);
	return 0;
}

/****************************************************************************************************/

int STDCALL commands (char* ptText)
{
	log_msg("Command : %s\n", ptText);
	Unit* ptChar = D2GetClientPlayer();

	char command[MAX_CMD_SIZE];
	ZeroMemory(command,MAX_CMD_SIZE);
	strncpy(command,ptText,MAX_CMD_SIZE-1);
	_strlwr(command);

	if (!strncmp(command, CMD_PLAYERS, strlen(CMD_PLAYERS)))
	{
		int nb = atoi(&command[strlen(CMD_PLAYERS)]);
		if (nb > 0 && nb <= 64)
			nbPlayersCommand = nb;
		return 1;
	}

	if (!strcmp(command, CMD_SAVE))
	{
		if (onRealm) return 1;
		updateServer(US_SAVE);
		return 0;
	}

	if (!strncmp(command, CMD_SELECTPAGE, strlen(CMD_SELECTPAGE)))
	{
		if (!active_newInterfaces) return 1;
		GoStatPage(atoi(&command[strlen(CMD_SELECTPAGE)]) - 1);
		return 0;
	}

	if (!strcmp(command, CMD_LOCK_MOUSE) || !strcmp(command, CMD_LOCK_MOUSE2))
	{
		if (onRealm) return 1;
		lockMouseCursor();
		return 0;
	}

	if (!strcmp(command, CMD_UNLOCK_MOUSE) || !strcmp(command, CMD_UNLOCK_MOUSE2))
	{
		if (onRealm) return 1;
		unlockMouseCursor();
		return 0;
	}

	if (!strncmp(command, CMD_RENAME_CHAR, strlen(CMD_RENAME_CHAR)))
	{
		char* param = &ptText[strlen(CMD_RENAME_CHAR)];
		if (param[0] != ' ')
			return 1;
		param++;
		return renameCharacter(ptChar, param);
	}

	if (!strncmp(command, CMD_RENAME_PAGE, strlen(CMD_RENAME_PAGE)))
	{
		if (!active_multiPageStash) return 1;
		char* param = &ptText[strlen(CMD_RENAME_PAGE)];
		return renamePage(ptChar, param);
	}

	if (!strncmp(command, CMD_SHORT_RENAME_PAGE, strlen(CMD_SHORT_RENAME_PAGE)))
	{
		if (!active_multiPageStash) return 1;
		char* param = &ptText[strlen(CMD_SHORT_RENAME_PAGE)];
		return renamePage(ptChar, param);
	}

	if (!strcmp(command, CMD_SET_INDEX))
	{
		if (!active_multiPageStash) return 1;
		updateServer(US_SET_INDEX);
		return 0;
	}

	if (!strcmp(command, CMD_SET_MAIN_INDEX))
	{
		if (!active_multiPageStash) return 1;
		updateServer(US_SET_MAIN_INDEX);
		return 0;
	}

	if (!strcmp(command, CMD_RESET_INDEX))
	{
		if (!active_multiPageStash) return 1;
		updateServer(US_RESET_INDEX);
		return 0;
	}

	if (!strcmp(command, CMD_INSERT_PAGE))
	{
		if (!active_multiPageStash) return 1;
		insertStash(ptChar);
		updateServer(US_INSERT_PAGE);
		return 0;
	}

	if (!strcmp(command, CMD_SHORT_INSERT_PAGE))
	{
		if (!active_multiPageStash) return 1;
		insertStash(ptChar);
		updateServer(US_INSERT_PAGE);
		return 0;
	}

	if (!strcmp(command, CMD_DELETE_PAGE))
	{
		if (!active_multiPageStash) return 1;
		if (deleteStash(ptChar, true))
			updateServer(US_DELETE_PAGE);
		return 0;
	}

	if (!strcmp(command, CMD_SHORT_DELETE_PAGE))
	{
		if (!active_multiPageStash) return 1;
		if (deleteStash(ptChar, true))
			updateServer(US_DELETE_PAGE);
		return 0;
	}

	if (!strncmp(command, CMD_SWAP_PAGE, strlen(CMD_SWAP_PAGE)))
	{
		if (!active_multiPageStash) return 1;
		int page = atoi(&command[strlen(CMD_SWAP_PAGE)]) - 1;
		if (page < 0 && PCPY->currentStash->nextStash)
			page = PCPY->currentStash->nextStash->id;
		if (page < 0)
			return 1;
		updateServer(US_SWAP3 + ((page & 0xFF000000) >> 16));
		updateServer(US_SWAP2 + ((page & 0xFF0000) >> 8));
		updateServer(US_SWAP1 + (page & 0xFF00));
		updateServer(US_SWAP0 + ((page & 0xFF) << 8));
		return 0;
	}

	if (!strncmp(command, CMD_SHORT_SWAP_PAGE, strlen(CMD_SHORT_SWAP_PAGE)))
	{
		if (!active_multiPageStash) return 1;
		int page = atoi(&command[strlen(CMD_SHORT_SWAP_PAGE)]) - 1;
		if (page < 0 && PCPY->currentStash->nextStash)
			page = PCPY->currentStash->nextStash->id;
		if (page < 0)
			return 1;
		updateServer(US_SWAP3 + ((page & 0xFF000000) >> 16));
		updateServer(US_SWAP2 + ((page & 0xFF0000) >> 8));
		updateServer(US_SWAP1 + (page & 0xFF00));
		updateServer(US_SWAP0 + ((page & 0xFF) << 8));
		return 0;
	}

	if (!strncmp(command, CMD_TOGGLE_PAGE, strlen(CMD_TOGGLE_PAGE)))
	{
		if (!active_sharedStash) return 1;
		int page = atoi(&command[strlen(CMD_TOGGLE_PAGE)]) - 1;
		if (page < 0)
			return 1;
		updateServer(US_SWAP3 + ((page & 0xFF000000) >> 16));
		updateServer(US_SWAP2 + ((page & 0xFF0000) >> 8));
		updateServer(US_SWAP1 + (page & 0xFF00));
		updateServer(US_SWAP0_TOGGLE + ((page & 0xFF) << 8));
		return 0;
	}

	if (!strncmp(command, CMD_SHORT_TOGGLE_PAGE, strlen(CMD_SHORT_TOGGLE_PAGE)))
	{
		if (!active_sharedStash) return 1;
		int page = atoi(&command[strlen(CMD_SHORT_TOGGLE_PAGE)]) - 1;
		if (page < 0)
			return 1;
		updateServer(US_SWAP3 + ((page & 0xFF000000) >> 16));
		updateServer(US_SWAP2 + ((page & 0xFF0000) >> 8));
		updateServer(US_SWAP1 + (page & 0xFF00));
		updateServer(US_SWAP0_TOGGLE + ((page & 0xFF) << 8));
		return 0;
	}

	if (!strcmp(command,CMD_DISPLAY_LIFE))
	{
		active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana;
		return 0;
	}

	if (!strcmp(command,CMD_DISPLAY_MANA))
	{
		active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana;
		return 0;
	}

	if (!strcmp(command,CMD_DISPLAY_LIFE_MANA) || !strcmp(command,CMD_DISPLAY_MANA_LIFE))
	{
		active_AlwaysDisplayLifeMana = !active_AlwaysDisplayLifeMana;
		return 0;
	}

	if (!strcmp(command, CMD_LISTCUBEFORMULA))
	{
		if (!active_listAllCubeFormula) return 1;
		listAllCubeFormula();
		return 0;
	}

	//if (!strcmp(command,CMD_RELOAD))
	//{
	//	if (onRealm) return 1;
	//	gambleReload(ptChar);
	//	return 0;
	//}

	//if (!strcmp(command,CMD_MAXGOLD))
	//{
	//	if (onRealm) return 1;
	//	updateServer(US_MAXGOLD);
	//	return 0;
	//}

	//if (!strcmp(command,"t"))
	//{
	//	//test();
	//	FILE* file = fopen("D:\\tmp.txt", "wb+");
	//	for (int i = 0; i<= 0xFFFF; i++)
	//	{
	//		fwprintf( file, L"== %04X ===================================\n%s\n", i, D2GetStringFromIndex(i) );
	//	}
	//	fclose(file);
	//	return 0;
	//}

	if (!strcmp(command,"aa"))
	{
		#pragma pack(1)
		struct {
			BYTE displayType;//0x15 main msg;  0x14: char popup
			BYTE un;
			BYTE zero;
			char string[0xFF];
			char null;
			char u1[0x100];
			char u2[0x100];
			char u3[0x100];
		} data;
		#pragma pack()

		//D2SetNbPlayers(nbPlayersCommand);

		memset(&data,0,sizeof(data));
		data.displayType=0x15;
		data.un=1;
		data.zero=0;//*(BYTE*)(offset_D2Client+0x112CFC); in 1.10
		data.null=NULL;
		sprintf(data.string, "players %u", nbPlayersCommand);
		D2SendMsgToAll((BYTE*)&data);
		return 0;
	}

	return 1;
}

FCT_ASM ( caller_Commands )
	TEST EAX,EAX
	JE MANAGESOUNDCHAOSDEBUG
	PUSH DWORD PTR SS:[ESP+0x1C]
	CALL commands
	TEST EAX,EAX
	JNZ MANAGESOUNDCHAOSDEBUG
	ADD DWORD PTR SS:[ESP],7
MANAGESOUNDCHAOSDEBUG:
	RETN 8
}}

FCT_ASM ( caller_Commands_111 )
	TEST EAX,EAX
	JE MANAGESOUNDCHAOSDEBUG
	PUSH ESI
	CALL commands
	TEST EAX,EAX
	JNZ MANAGESOUNDCHAOSDEBUG
	ADD DWORD PTR SS:[ESP],7
MANAGESOUNDCHAOSDEBUG:
	RETN 8
}}

FCT_ASM ( caller_Commands_113d )
	TEST EAX,EAX
	JE MANAGESOUNDCHAOSDEBUG
	PUSH EDI
	CALL commands
	TEST EAX,EAX
	JNZ MANAGESOUNDCHAOSDEBUG
	ADD DWORD PTR SS:[ESP],7
MANAGESOUNDCHAOSDEBUG:
	RETN 8
}}


void Install_Commands()
{
	static int isInstalled = false;
	if (isInstalled) return;

	Install_UpdateServer();

	log_msg("Patch D2Client for install commands. (Commands)\n");

	active_listAllCubeFormula = version_D2Common >= V110;
	active_savegame = version_D2Common >= V111;

	// Run custom commmand
	mem_seek R8(D2Client, 2C120, 2C110, 32BDD, C1EE6, 91C16, 86926, 70AE6, B1FD6, 7C548);
	memt_byte( 0x83, 0xE8 );	// CALL
	MEMT_REF4( 0xC08508C4 , version_D2Client >= V113d ? caller_Commands_113d : version_D2Client >= V111 ? caller_Commands_111 : caller_Commands);
	//6FB71EE6   . 83C4 08        ADD ESP,8
	//6FB71EE7   . 85C0           TEST EAX,EAX
	//6FB41C16  |. 83C4 08        ADD ESP,8
	//6FB41C19  |. 85C0           TEST EAX,EAX
	//6FB36926  |. 83C4 08        ADD ESP,8
	//6FB36929  |. 85C0           TEST EAX,EAX
	//6FB20AE6  |. 83C4 08        ADD ESP,8
	//6FB20AE9  |. 85C0           TEST EAX,EAX
	//6FB20AE6  |. 83C4 08        ADD ESP,8
	//6FB20AE9  |. 85C0           TEST EAX,EAX
	//6FB61FD6  |. 83C4 08        ADD ESP,8
	//6FB61FD9  |. 85C0           TEST EAX,EAX
	//0047C548  |. 83C4 08        ADD ESP,8
	//0047C54B  |. 85C0           TEST EAX,EAX

	log_msg("\n");

	isInstalled = true;
}

/*================================= END OF FILE =================================*/