[Dev] MuServer 99.6XT(1.0M) main.exe decompilation

^TheLast^

Active Member
Joined
Jan 13, 2010
Messages
332
Reaction score
232

-=BG=-

Здравейте,
тъй като работя по един мой проект, реших да споделя с вас част от работата си, която съм сигурен, че ще бъде от полза на хора, които се занимават с кодване на сървъри.

Главното, което ще правя е да декомпилирам методи от main.exe на посочената версия. Декомпилацията ще бъде до разбирам и работещ C++ код, който ще може да се използва в .dll файлове с къстъм неща в клиента.

Първия метод, който ще получите декомпилиран е този за Chaos Machine, където клиента проверява, дали итемите, които са поставени в машината отговарят на изискванията за комбинация. Тоест, ще може да се добавят custom комбинации в Chaos Machine.

--==EN==--

Hello,
as working on a project of mine, I decided to share with you some of my work, which I'm sure will be useful to people who deal with coding servers.

The main thing to do is to decompile methods in main.exe of that version. Decompilation will be to understandable and running C ++ code, which can be used in .dll files with custom things in the client .

The first method, you will get decompiled is that of Chaos Machine, where the client verifies that the items that are placed in the machine meet the requirements for combination. With this you can add custom combinations in Chaos Machine.

1. Chaos Machine Декомпилация :

1.1. signed int ChaosMachineGetCombinationType(unsigned int item, int argument2, int argument3) //0x005D26B0


Прогрес : 100%
Progress : 100%


Оптимизация : 75%
Optimisation : 75%


Code:
struct Item // Recovering Item struct
{
	short itemType; //0x0
	int itemLevel; //0x4
	int itemTypeTemp; //??
	 
	BYTE itemDurability; //0x1A
	int ItemTypePlus40; //0x28
};

signed int ChaosMachineGetCombinationType(unsigned int item, int argument2, int argument3)
{
	int unknownGlobal = *(int*)0x056F3BBC;//  0x056F3BBC //val=1024 - might be static
	int unknownGlobal2 = *(int*)0x0067196C; // 0x0067196C
	int unknownGlobal3[] = { 5 }; //0x00671968
	char unknownGlobal4 = *(char*)0x07CB2754; // 0x07CB2754
	int unknownGlobal5 = *(int*)0x076E0C50; //0x076E0C50
	int secondLvlWingsPercent = *(int*)0x07CB274C;// 0x07CB274C
	int chaosCombinationType = *(int*)0x07CB2744; // 0x07CB2744
	int allItemsCount;
	int cnt = 0;
	int v7;
	int v11;
	int v12;
	unsigned __int8 v21;
	signed int v22;
	int v24;
	BYTE v25;
	//signed int ItemTypev27;
	signed int result;
	unsigned int additionalItemAddPercent = 0; 
	int onlyWingsAddPercent = 0;
	char *v64;
	int v65;
	int chaosCount = 0;
	int v68 = 0;
	int devilEyeCount = 0;
	int devilKeyCount = 0;
	int isLvl9 = 0;
	int isLvl10 = 0;
	int isLvl11 = 0;
	int isLvl12 = 0;
	int blessCount = 0;
	int soulCount = 0;
	int unrilaCount = 0;
	int v78 = 0;
	int creationCount = 0;
	int featherCount = 0;
	int FirstLvlWingsCount = 0;
	int additionalItems_count = 0;
	int secondLvlWings_count = 0;
	int chaosWeapon_Count = 0;
	int scrollOfArchangelCount = 0;
	int bloodBoneCount = 0;
	int CapeOfLordCount = 0;
	int guardianCount = 0;
	int devilsKey_Level = 0;
	int devilsEye_Level = 0;
	int scrollOfArchangel_Level = 0;
	int bloodBone_Level = 0;
	int feather_Level = 0;
	char *v96;
	void* v97;
	int v98;

	scrollOfArchangel_Level = 0;
	additionalItemAddPercent = 0;
	bloodBone_Level = 0;
	onlyWingsAddPercent = 0;
	feather_Level = 0;
	*(int*)0x0067196C = 1; //unknounGlobal2
	unknownGlobal3[0] = 1; //unknounGlobal3[0]

	Item cmItem;


	if (argument3 <= 0)
	{
		allItemsCount = 0;
	}
	else
	{
		allItemsCount = 0;
		v97 = (LPVOID)argument3;
		v7 = 72 * argument2;
		v98 = 72 * argument2;
		do
		{
			if ( argument2 > 0 )
			{
				v65 = argument2;
				int i = 0;
				do
				{
					if ( *(WORD *)item!= -1 )
					{
						cmItem.ItemTypePlus40 = item + 40;

						if ( *(DWORD *)(item + 60) > 0 )
						{
							v96 = 0;
							argument3 = 0;
							allItemsCount++;
							v64 = &unknownGlobal4;
							v11 = unknownGlobal5 + 76 * *(WORD *)item;
							if ( unknownGlobal3[0] <= *(BYTE *)(v11 + 34) ) //unknownGlobal3
							{
								*(int*)0x00671968 = *(BYTE *)(v11 + 34); //unknownGlobal3
								unknownGlobal3[0] = *(BYTE *)(v11 + 34);
							}
							v12 = *(BYTE *)(v11 + 35);
							if ( unknownGlobal2 <= v12 )
								*(int*)0x0067196C = v12; //unknownGlobal2

							cmItem.itemType = *(WORD *)item;
							cmItem.itemLevel = (*(DWORD *)(item + 4) >> 3) & 0xF; //mask to get the 3rd byte, where the level is stored
							cmItem.itemDurability = *(BYTE *)(item + 26);

							if (cmItem.itemType < 384 || cmItem.itemType <= 390 || cmItem.itemType == 446 ) //ITEMGET(12,0) - Wings of Elf , ITEMGET(12,6) - Wings of Darkness , ITEMGET(13,30) - Cape of Lord
							{
								switch ( cmItem.itemLevel )
								{
								case 9:
									++isLvl9;
									*(char*)0x07CB2754 = 0; //unknownGlobal4
									argument3 = 1;
									v96 = &unknownGlobal4;
									break;
								case 10:
									++isLvl10;
									*(char*)0x07CB2754 = 0; //unknownGlobal4
									argument3 = 1;
									v96 = &unknownGlobal4;
									break;
								case 11:
									++isLvl11;
									*(char*)0x07CB2754 = 0; //unknownGlobal4
									argument3 = 1;
									v96 = &unknownGlobal4;
									break;
								case 12:
									++isLvl12;
									*(char*)0x07CB2754 = 0; //unknownGlobal4
									argument3 = 1;
									v96 = &unknownGlobal4;
									break;
								default:
									break;
								}
							}

							switch (cmItem.itemType)
							{
							case 465: //ITEMGET(14,17) - Devil's Eye
								devilsKey_Level = cmItem.itemLevel;
								++devilEyeCount;
								break;
							case 466: //ITEMGET(14,18) - Devil's Key
								devilsEye_Level = cmItem.itemLevel;
								++devilKeyCount;
								break;
							case 432: //ITEMGET(13,16) - Scroll of Archangel
								scrollOfArchangel_Level = cmItem.itemLevel;
								++scrollOfArchangelCount;
								break;
							case 433: //ITEMGET(13,17) - Blood Bone
								bloodBone_Level = cmItem.itemLevel;
								++bloodBoneCount;
								break;
							case 461: //ITEMGET(14,13) - Jewel of Bless
								++blessCount;
								break;
							case 462: //ITEMGET(14,14) - Jewel of Soul
								++soulCount;
								break;
							case 470: //ITEMGET(14,22) - Jewel of Creation
								++creationCount;
								break;
							case 479: //ITEMGET(14,31) - Jewel of Guardian
								++guardianCount;
								break;
							case 430: //ITEMGET(13,14) - Loch's Feather
								feather_Level = cmItem.itemLevel;
								++featherCount;
								break;
							case 384: //ITEMGET(12,0) - Wings of Elf
							case 385: //ITEMGET(12,1) - Wings of Heaven
							case 386: //ITEMGET(12,2) - Wings of Satan
								v64 = (char *)&argument3 + 3;
								*(int*)0x07CB2748 = 0; //unknownGlobal6
								++FirstLvlWingsCount;
								onlyWingsAddPercent = CalcItemAdditionalPercentAdd((signed int)((char *)&argument3 + 3), item, 0);

								cnt = 0;
								while ( cnt < *(BYTE *)cmItem.ItemTypePlus40 )
								{
									v21 = *(BYTE *)(cmItem.ItemTypePlus40 + cnt + 1);
									if ( v21 >= 80 && (v21 <= 81 || v21 == 85) )
									{
										//if ( v21 <= 81 )
										//{
											*(int*)0x07CB2748 = *(BYTE *)(item + cnt + 49); //unknownGlobal6
										//}
										//else if ( v21 == 85 )
										//{
										//	*(int*)0x07CB2748 = 4 * *(BYTE *)(item + cnt + 49); //unknownGlobal6
										//}
									}
									++cnt;
								}
								


								if ( *(BYTE *)cmItem.ItemTypePlus40 )
								{
									int j = 0;
									while ( j < *(BYTE *)cmItem.ItemTypePlus40 )
									{
										if ( *(BYTE *)(item + j + 41) == 84 )
										{
											char* cp = v96;
											i = v96 == 0; // if(v96==0) i=1;
											*v64 = 1;
											if ( !i )
												*cp = 1;
										}
										++j;
									}
								}

								break;
							case 418: //ITEMGET(13,2) - Horn of Uniria
								if ( cmItem.itemDurability >= 255 )
									++unrilaCount;
								break;
							case 399: //ITEMGET(12,15) - Jewel of Chaos
								++chaosCount;
								break;
							case 446: //ITEMGET(13,30) - Cape of Lord
								++CapeOfLordCount;
								break;
							default:
								v22 = 0;
								int j = 0;
								if ( cmItem.itemType >= 384 || cmItem.itemLevel < 4 ) //ITEMGET(12,0) - Wings of Elf
								{
									if ( v24 <= 0 )
									{
										++v78;
										BYTE test = *(BYTE *)(item + 27) & 0x3F;
										if ( *(BYTE *)(item + 27) & 0x3F && cmItem.itemLevel >= 4 )
										{
											if (cmItem.itemType < 387 || cmItem.itemType > 390 ) //ITEMGET(12,3) - Wings of Spirits < > ITEMGET(12,6) - Wings of Darkness
											{
												++additionalItems_count;
												additionalItemAddPercent += CalcItemAdditionalPercentAdd(LOWORD(cmItem.itemType), item, 0); 
											}
											else
											{
												++secondLvlWings_count;
											}
										}
									}

								}
								else
								{
									*(char*)0x07CB2754 = 0; //unknownGlobal4
									j = 0;

									v24 = *(BYTE *)cmItem.ItemTypePlus40;
									argument3 = 1;

									do
									{
										v25 = *(BYTE *)(cmItem.ItemTypePlus40 + j + 1);
										if ( v25 >= 80 && v25 <= 83 && !v22 )
										{
											++v68; // common with chaos weapon count
											if (cmItem.itemType == 70 || cmItem.itemType == 134 || cmItem.itemType == 167 ) //ITEMGET(2,6) - Chaos Dragon Axe, ITEMGET(4,6) - Chaos Nature Bow, ITEMGET(5,7) - Chaos Lightning Staff
												++chaosWeapon_Count;
											v22 = 1;
										}
										++j;
									}
									while ( j < v24 );

									if ( !v22 )
									{
										++v78;
									}

									BYTE asd = *(BYTE *)(item + 27) & 0x3F;
									if ( *(BYTE *)(item + 27) & 0x3F && cmItem.itemLevel >= 4 )
									{
										if ( cmItem.itemType < 387 || cmItem.itemType > 390 ) //ITEMGET(12,3) - Wings of Spirits < > ITEMGET(12,6) - Wings of Darkness
										{
											++additionalItems_count;
											additionalItemAddPercent += CalcItemAdditionalPercentAdd(LOWORD(cmItem.itemType), item, 0); 
										}
										else
										{
											++secondLvlWings_count;
										}
									}
								}
								break;
							}

							if ( argument3 )
							{
								int j = 0;
								if ( *(BYTE *)cmItem.ItemTypePlus40 )
								{
									do
									{
										if ( *(BYTE *)(item + j + 41) == 84 )
										{
											char* cp = v96;
											i = v96 == 0;
											*v64 = 1;
											if ( !i )
												*cp = 1;
										}
										++j;
									}
									while ( j < *(BYTE *)cmItem.ItemTypePlus40 );
								}
							}
						}
					}
					i = v65 == 1;
					item += 72;
					--v65;
				}
				while ( !i );
				v7 = v98;
			}
			v97 = (char *)v97 - 1;
		}
		while ( v97 );
	}


	//Devil Square Ticket and Invisible Cloak Combinations
	if ( allItemsCount == 3 && chaosCount == 1 )
	{
		if ( devilEyeCount == 1 && devilKeyCount == 1 ) //Check for Devil Square Ticket
		{
			if (devilsKey_Level == devilsEye_Level)
			{
				result = 2;
				*(int*)0x07CB2744 = devilsKey_Level + 1; //set chaosCombinationType
			}
			else
			{
				result = -2;
			}
			return result;
		}
		if ( scrollOfArchangelCount == 1 && bloodBoneCount == 1 ) //Check for Blood Castle Ticket
		{
			if (scrollOfArchangel_Level == bloodBone_Level )
			{
				result = 8;
				*(int*)0x07CB2744 = HIWORD(scrollOfArchangel_Level) + 1; //set chaosCombinationType
			}
			else
			{
				result = -8;
			}
			return result;
		}
	}

	//First Level Combination
	if ( FirstLvlWingsCount != 1 || secondLvlWings_count || featherCount != 1 || feather_Level != 1 )
	{
		if ( chaosCount == 1 && featherCount == 1 && !HIWORD(feather_Level) && FirstLvlWingsCount == 1 && !secondLvlWings_count && allItemsCount == additionalItems_count + 3 )
		{
			*(int*)0x07CB274C = onlyWingsAddPercent / 4000000 + additionalItemAddPercent / 40000; // secondLvlWingsPercent - calculating 2 lvl wings percent for probability
			if ( (signed int)(onlyWingsAddPercent / 4000000 + additionalItemAddPercent / 40000) >= 90 )
			{
				*(int*)0x07CB274C = 90;  // max percent 90%
			}
			return 7;
		}
	}

	if (allItemsCount == 0 )
	{
		return 0;
	}
	else if(allItemsCount == 4)
	{
		if ( isLvl9 == 1 && blessCount == 1 && soulCount == 1  && chaosCount == 1)
		{
			return 3;
		}
	}
	else if ( allItemsCount == 6 )
	{
		if ( isLvl10 == 1 && blessCount == 2 && soulCount == 2 && chaosCount == 1) // +11 combination
		{
			return 4;
		}
	}
	else if ( allItemsCount == 8 )
	{
		if ( isLvl11 == 1 && blessCount == 3 && soulCount == 3 && chaosCount == 1) // +12 combination
		{
			return 22;
		}
	}
	else if ( allItemsCount == 10 )
	{
		if ( isLvl12 == 1 && blessCount == 4 && soulCount == 4 && chaosCount == 1) // +13 combination
		{
			return 23;
		}
	}
	else if ( allItemsCount == 11 )
	{
		if ( unrilaCount == 10 && chaosCount == 1 )
		{
			return 5;
		}
	}


	if ( chaosCount == 1 )
	{
		if ( v68 > 0 && !devilEyeCount && !devilKeyCount && !unrilaCount && !v78 && !creationCount && !featherCount && !FirstLvlWingsCount && !secondLvlWings_count && !scrollOfArchangelCount && !bloodBoneCount && !guardianCount )
		{
			return chaosWeapon_Count <= 0 ? 1 : 11;
		}
		else if ( allItemsCount == 2 && creationCount == 1 && chaosCount == 1 ) // Fruits Combination
		{
			return 6;
		}
	}

	if ( allItemsCount == blessCount ) // Potion of Bless
	{
		return 15;
	}
	if ( allItemsCount == soulCount ) // Potion of Soul
	{
		return 16;
	}

	if ( allItemsCount != 12 || blessCount != 5 || soulCount != 5 || chaosCount != 1 || guardianCount != 1 )
	{
		return  0;
	}
	else
	{
		return 17;
	}

}

static DWORD CalcItemAdditionalPercentAdd_Address = 0x0052DDE0;

__declspec(naked) int __stdcall CalcItemAdditionalPercentAdd(int a1, int a2, int a3)
{
	__asm{
		PUSH EBP
			MOV EBP, ESP
			PUSH a3
			PUSH a2
			PUSH EAX //a1
			CALL CalcItemAdditionalPercentAdd_Address
			MOV ESP,EBP;
		POP EBP;
		retn 12
	}
}

Прикачам мейна и декомпилацията му от Hex-Rays, макар, че вече ги има в други мои теми, за да е по удобно за вас :)
 

Attachments

  • main.rar
    835.4 KB · Views: 263
  • Main 99.62XT (1.0M) Decompilation.rar
    1.6 MB · Views: 269
Last edited:
thank you very murch......... I waiting you continue...
 
I can't say when that will happen. Probably will not be soon, because i'm too busy with my business :)
 
  • Like
Reactions: Van_Bom