Jump to content
Sign in to follow this  
3tata

кружок под персонажем как в св

Recommended Posts

Все же знают что в Священной Войне пираты/нави подсвечиваются кружочками красными/зелеными. Можно ли сделать такое на стороне клиента? Чтбы согильдейцы подсвечивались зелеными кружком, все остальные красным?

Share this post


Link to post
Share on other sites

GuildCircleMod.png

 

Персонажи отмечаются на всех картах кроме Священной войны (guildwar и guildwar2).

 

Выкладываю исходный код C++ DLL, которая заставляет ру. оф. 1.3x клиент отмечать персонажей кругами.

 

dllmain.cpp

#include <string>
#include <windows.h>
#include <detours.h>


// Адрес персонажа игрока
const DWORD MainChaStaticAddr = 0x0067061C; // Для EN клиента 0x0067052C;

// Адрес функции NetSwitchMap( )
const DWORD NetSwitchMapAddr = 0x005071A0; // Для EN клиента 0x00507090;

// Адрес метода CCharacter::setSideID( )
const DWORD SetSideIdAddr =  0x004A2950; //Для EN клиента 0x004A2840;


// Класс персонажа
class CCharacter
{
	public:

		// Получить ID персонажа
		int get_id() const {
			return m_id;
		}

		// Получить ID гильдии
		int get_guild_id() const {
			return m_guildId;
		}

	private:
		char m_nop1[0x04E4];   // Смещение 1
		int  m_guildId;        // ID гильдии
		char m_nop2[0x07FC];   // Смещение 2
		int  m_id;             // ID персонажа
};

// Структура с информацией о смене карты
struct stNetSwitchMap
{
	short	sEnterRet;
	char	*szMapName;
	char	chEnterType;
	bool	bIsNewCha;
	bool	bCanTeam;
};


// Тип указателя на оригинальный
//  метод void CCharacter::setSideID(long side_id)
typedef void (__thiscall *setSideIdPtr)(void *, unsigned int);

// Тип указателя на оригинальную функцию
//  void NetSwitchMap(stNetSwitchMap &switchmap)
typedef void (__cdecl *netSwitchMapPtr)(stNetSwitchMap&);

// Указатель на оригинальный метод
// void CCharacter::setSideID(long side_id)
setSideIdPtr original_SetChaSide = (setSideIdPtr)(void *)(SetSideIdAddr);

// Указатель на оригинальную функцию
// void NetSwitchMap(stNetSwitchMap &switchmap)
netSwitchMapPtr original_SwitchMap = (netSwitchMapPtr)(void *)(NetSwitchMapAddr);


// Текущая карта персонажа
std::string OurMap = "";


// Прочитать целое число из памяти по 
//  указанному адресу
DWORD ReadDword(DWORD address)
{
	DWORD Temp = 0;
	ReadProcessMemory( GetCurrentProcess(),  (void *)address,  &Temp, sizeof(Temp),   0 );
	return Temp;
}


// Функция, которая выполняет перехват функции смены карты
void __cdecl hooked_SwitchMap(stNetSwitchMap &switchmap)
{
	// Получим текущую карту персонажа
	OurMap = switchmap.szMapName;

	// Вызываем оригинальную функцию
	original_SwitchMap(switchmap);
}

// Функция, которая выполняет перехват установки цветного круга 
// в зависимости от стороны персонажа
void __fastcall hooked_SetChaSide(void *This,
	void *notUsed, unsigned int side_id)
{
	// Указатель на нашего персонажа
	CCharacter *pMainCha = reinterpret_cast<CCharacter *>( ReadDword(MainChaStaticAddr) );

	// Указатель на персонажа
	CCharacter *pCha = reinterpret_cast<CCharacter *>(This);

	if ( pMainCha != nullptr && pCha != nullptr )
	{
		if ( pMainCha->get_id() != pCha->get_id() )
		{
			// Проверим, что персонажи не находятся в СВ
			if ( OurMap != "guildwar" && OurMap != "guildwar2")
			{
				if (pMainCha->get_guild_id() == pCha->get_guild_id())
				{
					// Если персонажи в одной гильдии
					//  то устанавливаем зеленый круг
					side_id = 1;
				}
				else
				{
					// Если персонажи не в одной гильдии
					//  то устанавливаем красный круг
					side_id = 2;
				}
			}
		}
	}
	
	// Вызываем оригинальный метод
	original_SetChaSide(This, side_id);
}


// Точка входа
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	switch (ul_reason_for_call)
    {
		case DLL_PROCESS_ATTACH:
				
			// Устанавливаем хуки
			DetourRestoreAfterWith();
			DetourTransactionBegin();
			DetourUpdateThread(GetCurrentThread());
			DetourAttach(&(PVOID&)original_SwitchMap, hooked_SwitchMap);
			DetourAttach(&(PVOID&)original_SetChaSide, hooked_SetChaSide);
			DetourTransactionCommit();

			break;

		case DLL_PROCESS_DETACH:

			// Снимаем хуки
			DetourTransactionBegin();
			DetourUpdateThread(GetCurrentThread());
			DetourDetach(&(PVOID&)original_SwitchMap, hooked_SwitchMap);
			DetourDetach(&(PVOID&)original_SetChaSide, hooked_SetChaSide);
			DetourTransactionCommit();

			break;
    }

    return TRUE;
}

Предоставляю замечательную возможность изучить код и скомпилировать DLL, а также подключить её к клиенту самостоятельно. Для этого понадобятся Microsoft Visual Studio Community 2017 и библиотека Microsoft Detours. Как собрать библиотеку Detours можно почитать на Хабре. Как присоединить DLL к Game.exe можно найти в гугле.

  • Like 3
  • Thanks 2

Share this post


Link to post
Share on other sites

@mkhzaleh, this version of DLL works only with Russian client. You need to find the following addresses in Game.exe from your client and correct the source code:

// Main Character address
const DWORD MainChaStaticAddr = 0x0067061C;
// Address of the function NetSwitchMap( )
const DWORD NetSwitchMapAddr = 0x005071A0;
// Address of the method CCharacter::setSideID( )
const DWORD SetSideIdAddr =  0x004A2950;

// Given addresses are for Russian client

 


Share this post


Link to post
Share on other sites
On 9/3/2018 at 10:29 PM, Stinger said:

Use dll injector , dll is written in such a way that you can only connect to the active process.

А как её надо написать, чтобы работало как надо?

 

On 8/29/2018 at 8:50 PM, Stinger said:

P.S Отряд эта штука не учитывает.

Все что эта штука учитывает задано в исходнике и про пати, как было отмечено выше, здесь речи нет:

if ( pMainCha != nullptr && pCha != nullptr )
{
	if ( pMainCha->get_id() != pCha->get_id() )
	{
		// Проверим, что персонажи не находятся в СВ
		if ( OurMap != "guildwar" && OurMap != "guildwar2")
		{
			if (pMainCha->get_guild_id() == pCha->get_guild_id())
			{
				// Если персонажи в одной гильдии
				//  то устанавливаем зеленый круг
				side_id = 1;
			}
			else
			{
				// Если персонажи не в одной гильдии
				//  то устанавливаем красный круг
				side_id = 2;
			}
		}
	}
}

 


Share this post


Link to post
Share on other sites
On 9/10/2018 at 12:15 AM, V3ct0r said:

@mkhzaleh, this version of DLL works only with Russian client. You need to find the following addresses in Game.exe from your client and correct the source code:


// Main Character address
const DWORD MainChaStaticAddr = 0x0067061C;
// Address of the function NetSwitchMap( )
const DWORD NetSwitchMapAddr = 0x005071A0;
// Address of the method CCharacter::setSideID( )
const DWORD SetSideIdAddr =  0x004A2950;

// Given addresses are for Russian client

 

can you please Compile it for those addresses?

00507260 NetSwitchMap
0x67061c  MainChaStaticAddr
004A29E0 SetSideIdAddr

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...