Разбираем цены клиента, С примерами и прочим

Автор DarkSim, 2012 Дек. 06, 15:21

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Ключевые слова [SEO] mu onlinewebzenmu разработки developmentx-muцены клиентовскидки

DarkSim

В общем не так давно решил пересмотреть свои функции и нашел интересную вещь, как оказалось WebZen не стали особо мудрить с ценами на вещи и менять их оказалось намного проще, чем я думал раньше.

1. Все начинается с функции, которая определяет цену предмета и возвращает long long значение

__int64 SetItemPrice(ObjItem * gItem, int Mode);

Название я сам придумал :D

И так, что есть ItemStruct и что есть Mode:

- ObjItem * gItem это структура передаваемая функции, в которой клиент хранит такие данные, как Defense / Damage / требования по статам и прочее.

Не полная структура:
struct ObjItem
{
/*0*/        WORD    ItemID;
/*2*/        DWORD    Level;
/*6*/        BYTE    Unknown6;
/*7*/        BYTE    Unknown7;
/*8*/        BYTE    Unknown8;
/*9*/        WORD    DamageMin;
/*11*/        WORD    DamageMax;
/*13*/        BYTE    Unknown13;
/*14*/        WORD    Unknown14;
/*16*/        WORD    Unknown16;
/*18*/        BYTE    Unknown18;
/*19*/        BYTE    Unknown19;
/*20*/        WORD    Unknown20;
/*22*/        BYTE    Durability;
/*23*/        WORD    Attribute2;
/*25*/        WORD    RequireStrenght;
/*27*/        WORD    RequireDextirity;
/*29*/        WORD    RequireEnergy;
/*31*/        WORD    RequireVitality;
/*33*/        WORD    RequireCommand;
/*35*/        WORD    RequireLevel;
/*37*/        BYTE    Unknown37;
/*38*/        BYTE    Unknown38;
};

- int Mode это тип с которым функция должна вернуть цену, 0 - Покупка, 1 - Продажа

2. Самый гибкий и простой вариант установки своих цен:

2.1. Создаем свою функцию, которая будет выполнять нужные нам действия перед оригинальной, пример:

__int64 gSetItemPrice(ObjItem * gItem, int Mode)
{
__int64 Money = -1;
// ----
if( (int)gItem == -1 )
{
return 0;
}
// ----
switch(gItem->ItemID)
{
case ITEM(14, 13):    //-> Jewel Of Bless
case ITEM(14, 14):    //-> Jewel Of Soul
{
Money = 15000000;
}
break;
}
// ----
if( Money != -1 )
{
if( Mode == 1 )
{
Money /= 3;
}
// ----
return Money;
}
// ----
return SetItemPrice(gItem, Mode);
}

В данной случае наша функция проверяет поинтер по ItemID на Jewel Of Soul и Jewel Of Bless, возвращает цену равную 15000000 Zen, если вещь лежит в магазине (покупка) и 1/3 от суммы, если вещь лежит в инвентаре (продажа), следом проверяет изменение цены, если она была изменена то возвращает ее, если нет - вызывает оригинальную функцию

#define SetItemPrice            ((__int64(*)(ObjItem * gItem, int Mode)) 0x53D725)
2.2. Перехватываем все вызовы оригинальной функции на нашу собственную, делается это довольно просто:

- Открывает main.exe в Ollydbg, идем на адрес функции (53D725) и нажимаем CTR+R, после чего к нам выходит список всех вызовов функции

Спойлер
## здесь был скриншот ##
[свернуть]

Пример перехвата:

SetHook((LPVOID)gSetItemPrice, (LPVOID)0x004D8E03, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x004F27E0, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x0053A820, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x0053A87C, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x0053A8D0, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005BF62F, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005BF9B8, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005C1ABC, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005C1AF1, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005C1B56, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x005CC10E, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x00753437, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x007A4570, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x007A45E8, ASM::CALL);
SetHook((LPVOID)gSetItemPrice, (LPVOID)0x007A4F0E, ASM::CALL);

Вот и все, теперь мы можем легко ставить любые цены на любые вещи, при этом применять сложные проверки на вроде Excellent опций и многое другое, тут уже все от фантазии.

Структура ObjItem может оказаться уникальной для 1.03.28 GMO, но я думаю, что она универсальна как минимум с 3.2 по 5.4 сезоны.

В случае, если возникнут проблемы с вызовом функции можно делать все немного иначе, заменить все ObjItem * gItem аргументы на int ItemStruct, и вызывать нужные аргументы в формате:

*(WORD*)(ItemStruct)    //-> ItemID
*(BYTE*)(ItemStruct + 22)    //-> Durability

И т.д.

Собственно конец, может кому будет интересно или даже пригодиться.

P.S.: Все оффсеты для 1.03.28 GMO

Profesor08

При этом будет отображаться визуально нужная цена?

DarkSim

Да, та самая, которую вернет твоя функция

Crazzy-

#3
Задрот. ))
Спойлер
111!11
[свернуть]

MOHAPX

Цитата: Crazzy- от 2012 Дек. 07, 03:56  Задрот. ))
Спойлер
111!11
[свернуть]


Если бы, хотя бы треть активных участников X-MU.NET проявляли подобное задротство, то MUonline не была бы в таком упадочном состоянии. А так, в основном, "интеллект" расходуется на загаживание актуальных тем, в направление чей конец ветвистей и на Ддос атаки даже не жизнеспособных серверов.

KamatoZ

А кто подскажет как найти оффсет для мейна 2 сезона  1.2.44.0?

Crazzy-

Цитата: MOHAPX от 2012 Дек. 07, 18:25  Если бы, хотя бы треть активных участников X-MU.NET проявляли подобное задротство, то MUonline не была бы в таком упадочном состоянии. А так, в основном, "интеллект" расходуется на загаживание актуальных тем, в направление чей конец ветвистей и на Ддос атаки даже не жизнеспособных серверов.
Да я не спорю, но то чем хочу занятся я никто неподдерживает :( а один я невытяну по времени...

Profesor08

Цитата: Crazzy- от 2013 Апр. 04, 11:16  Да я не спорю, но то чем хочу занятся я никто неподдерживает :( а один я невытяну по времени...
Тут даже время особого значения не имеет. "Один в поле не воин" - этим все сказано.

epmak

1 может начать, а потом уже пытаться заинтересовать остальных.

gucciprado

Спасибо, то что нужно! Как раз искал этот гайд! Вещь!

NeleGaL


LetsToPlay

Выложите пожалуйста  1.03.28 GMO майн

Спасибо, сделал. Может кто-то выложит подобный гайд для ГСа?)

positive

Цитировать- Открывает main.exe в Ollydbg, идем на адрес функции (53D725) и нажимаем CTR+R, после чего к нам выходит список всех вызовов функции

Как найти этот адрес? Не очень понятно.

Цитата: LetsToPlay от 2014 Июль 19, 14:00  Выложите пожалуйста  1.03.28 GMO майн

Спасибо, сделал. Может кто-то выложит подобный гайд для ГСа?)

В соседней теме Кернигана есть... Посмотреть же можно.

LetsToPlay

#13
Цитата: positive от 2014 Июль 19, 15:00  Как найти этот адрес? Не очень понятно.



В соседней теме Кернигана есть... Посмотреть же можно.
Насчет найти этот адрес, это начало функции в которой меняются цены например блесса.
например находишь где изменить цену на блес и поднимаешься до первого "PUSH EBP"

в моем майне 1.03.16 этот адрес 0x0050ED6E.

GIF1985


Похожие темы (5)

Сообщений: 90
Просмотров: 22764

Сообщений: 11
Просмотров: 4332