Jump to content
Sign in to follow this  
Slavyan

Слет профессий 1.38

Recommended Posts

вообщем не могу вспомнить где фиксить но проблема остается не решенной.

Профессия слетает на newbie при релоге или тп.

до смены гс всегда слетал на hunter, после смены на newbie.

если кто знает как решить проблему, подскажите пожалуйста) 

Share this post


Link to post
Share on other sites

Привет, @Slavyan!

 

Если ты используешь GameServer.exe версии 1.38, то там действительно присутствует такой баг. Нужно патчить GameServer.exe или использовать GameServer версии 1.36, там такого бага нет.

 

Вот исходный код DLL, которая исправляет баг:

#include <windows.h>
#include <iostream>


// Адрес функции g_GetJobName()
DWORD fGetJobNameAddress = 0x00459C40;

// Адрес функции g_GetJobID()
DWORD fGetJobIdAddress = 0x00483870;


// Названия профессий
const char *szJobNames[] = {
		"Новичок",
		"Мечник",
		"Охотник",
		"Моряк",
		"Мореплаватель",
		"Знахарка",
		"Ремесленник",
		"Торговец",
		"Чемпион",
		"Воитель",
		"Белый Рыцарь",
		"Укротитель Животных",
		"Стрелок",
		"Целительница",
		"Колдунья",
		"Капитан",
		"Покоритель морей",
		"Выскочка",
		"Инженер"
};


// Получить название профессии по ID
const char* __cdecl GetJobName_Hooked(short sJobID);

// Получить ID по названию профессии
short __cdecl GetJobID_Hooked(const char* szJobName);

// Установить хук на функцию
void SetGetJobNameHook(DWORD dwOrigAddress, 
							DWORD dwHookAddress);

// Функция-пустышка для импорта в GameServer.exe
__declspec(dllexport) void __cdecl ExportedFunction() {}


// Точка входа
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	// Подключение DLL
	if (ul_reason_for_call == DLL_PROCESS_ATTACH)
	{
		// Ставим хуки на функции 

		// g_GetJobName()
		SetGetJobNameHook(
			fGetJobNameAddress,
			reinterpret_cast<DWORD>(&GetJobName_Hooked)
		);

		// g_GetJobID()
		SetGetJobNameHook(
			fGetJobIdAddress,
			reinterpret_cast<DWORD>(&GetJobID_Hooked)
		);
	}

    return TRUE;
}

// Получить профессию по ID
const char* __cdecl GetJobName_Hooked(short sJobID)
{
	// Количество профессий
	unsigned short n = sizeof(szJobNames) 
							/ sizeof(szJobNames[0]);

	// Ищем профессию в списке
	if (sJobID < 0 || sJobID >= n) {
		return szJobNames[0];
	}

	return szJobNames[sJobID];
}

// Получить ID по названию профессии
short __cdecl GetJobID_Hooked(const char* szJobName)
{
	// Количество профессий
	unsigned short n = sizeof(szJobNames)
							/ sizeof(szJobNames[0]);

	// Ищем ID профессии в списке
	for (unsigned int i = 0; i < n; i++)
	{
		if (std::strcmp(szJobNames[i], szJobName) == 0)
		{
			return i;
		}
	}

	return 0;
}

// Установить хук на функцию
void SetGetJobNameHook( DWORD dwOrigAddress, 
						DWORD dwHookAddress )
{
	// Структура перехода на нашу функцию
#pragma pack(push, 1)
	struct jump
	{
		BYTE opcode;
		UINT dif;
		BYTE retn;
	};
#pragma pack(pop)

	// Создаем последовательность байт для
	// перехода на нашу функцию:
	//  jmp GetJobName_Hooked
	//  retn
	jump jmp;
	jmp.opcode = 0xe9;
	jmp.dif = (
		dwHookAddress
		-
		dwOrigAddress
		-
		5
	);
	jmp.retn = 0xc3;

	// Делаем память доступной для записи
	DWORD dwOldProt = PAGE_EXECUTE_READWRITE;
	VirtualProtect(
		reinterpret_cast<LPVOID>(dwOrigAddress),
		sizeof(jmp),
		dwOldProt,
		&dwOldProt
	);

	// Записываем наши байты в память GameServer.exe
	*reinterpret_cast<jump *>(dwOrigAddress) = jmp;

	// Возвращаем свойства памяти обратно
	VirtualProtect(
		reinterpret_cast<LPVOID>(dwOrigAddress),
		sizeof(jmp),
		dwOldProt,
		&dwOldProt
	);
}

Либо вот скомпилированная DLL. 

 

Присоединить DLL к GameServer.exe можно с помощью CFF Explorer, например.


Share this post


Link to post
Share on other sites
В 23.03.2019 в 22:52, V3ct0r сказал:

Привет, @Slavyan!

 

Если ты используешь GameServer.exe версии 1.38, то там действительно присутствует такой баг. Нужно патчить GameServer.exe или использовать GameServer версии 1.36, там такого бага нет.

 

Вот исходный код DLL, которая исправляет баг:


#include <windows.h>
#include <iostream>


// Адрес функции g_GetJobName()
DWORD fGetJobNameAddress = 0x00459C40;

// Адрес функции g_GetJobID()
DWORD fGetJobIdAddress = 0x00483870;


// Названия профессий
const char *szJobNames[] = {
		"Новичок",
		"Мечник",
		"Охотник",
		"Моряк",
		"Мореплаватель",
		"Знахарка",
		"Ремесленник",
		"Торговец",
		"Чемпион",
		"Воитель",
		"Белый Рыцарь",
		"Укротитель Животных",
		"Стрелок",
		"Целительница",
		"Колдунья",
		"Капитан",
		"Покоритель морей",
		"Выскочка",
		"Инженер"
};


// Получить название профессии по ID
const char* __cdecl GetJobName_Hooked(short sJobID);

// Получить ID по названию профессии
short __cdecl GetJobID_Hooked(const char* szJobName);

// Установить хук на функцию
void SetGetJobNameHook(DWORD dwOrigAddress, 
							DWORD dwHookAddress);

// Функция-пустышка для импорта в GameServer.exe
__declspec(dllexport) void __cdecl ExportedFunction() {}


// Точка входа
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	// Подключение DLL
	if (ul_reason_for_call == DLL_PROCESS_ATTACH)
	{
		// Ставим хуки на функции 

		// g_GetJobName()
		SetGetJobNameHook(
			fGetJobNameAddress,
			reinterpret_cast<DWORD>(&GetJobName_Hooked)
		);

		// g_GetJobID()
		SetGetJobNameHook(
			fGetJobIdAddress,
			reinterpret_cast<DWORD>(&GetJobID_Hooked)
		);
	}

    return TRUE;
}

// Получить профессию по ID
const char* __cdecl GetJobName_Hooked(short sJobID)
{
	// Количество профессий
	unsigned short n = sizeof(szJobNames) 
							/ sizeof(szJobNames[0]);

	// Ищем профессию в списке
	if (sJobID < 0 || sJobID >= n) {
		return szJobNames[0];
	}

	return szJobNames[sJobID];
}

// Получить ID по названию профессии
short __cdecl GetJobID_Hooked(const char* szJobName)
{
	// Количество профессий
	unsigned short n = sizeof(szJobNames)
							/ sizeof(szJobNames[0]);

	// Ищем ID профессии в списке
	for (unsigned int i = 0; i < n; i++)
	{
		if (std::strcmp(szJobNames[i], szJobName) == 0)
		{
			return i;
		}
	}

	return 0;
}

// Установить хук на функцию
void SetGetJobNameHook( DWORD dwOrigAddress, 
						DWORD dwHookAddress )
{
	// Структура перехода на нашу функцию
#pragma pack(push, 1)
	struct jump
	{
		BYTE opcode;
		UINT dif;
		BYTE retn;
	};
#pragma pack(pop)

	// Создаем последовательность байт для
	// перехода на нашу функцию:
	//  jmp GetJobName_Hooked
	//  retn
	jump jmp;
	jmp.opcode = 0xe9;
	jmp.dif = (
		dwHookAddress
		-
		dwOrigAddress
		-
		5
	);
	jmp.retn = 0xc3;

	// Делаем память доступной для записи
	DWORD dwOldProt = PAGE_EXECUTE_READWRITE;
	VirtualProtect(
		reinterpret_cast<LPVOID>(dwOrigAddress),
		sizeof(jmp),
		dwOldProt,
		&dwOldProt
	);

	// Записываем наши байты в память GameServer.exe
	*reinterpret_cast<jump *>(dwOrigAddress) = jmp;

	// Возвращаем свойства памяти обратно
	VirtualProtect(
		reinterpret_cast<LPVOID>(dwOrigAddress),
		sizeof(jmp),
		dwOldProt,
		&dwOldProt
	);
}

Либо вот скомпилированная DLL. 

 

Присоединить DLL к GameServer.exe можно с помощью CFF Explorer, например.

А я за него платил. 🙄

Share this post


Link to post
Share on other sites
27 минут назад, Waka~ сказал:

смена гс помоему

Редактирование названий Профессий. То есть в клиенте может быть на русском, а на сервере на английском. Я пофиксил у себя.

Ибо если кастомный GameServer, над которым ты парился, то менять его не вариант.

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...