На форуме временно ведутся технические работы! Подробнее.

X   Сообщение сайта
(Сообщение закроется через 2 секунды)
Вход
Логин: Пароль:Забыли пароль?
Запомнить вас на этом компьютере?
Войти скрытым?

Здравствуйте, гость ( Вход | Регистрация )

> описание и правила

MU Development - раздел в котором каждый может предложить готовое и полезное решение для сервера/клиента/сайта mu online. Перед названием темы обезательно ставить приставку [Dev].
Каждый разработчик имеет второстепенную группу Developers.
Developers - могут в любое время закрывать и открывать свои темы.

[Гайд] Разбираем цены клиента, С примерами и прочим
Рейтинг 5
5/5
V

DarkSim
сообщение 6.12.2012, 16:21
Сообщение #1

zTeam
*****
Группа: V.I.P.
Сообщений: 380
Регистрация: 14.7.2008
Пользователь №: 1543
Спасибо сказали: 591 раз(а)



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

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

__int64 SetItemPrice(ObjItem * gItem, int Mode);

Название я сам придумал biggrin.gif

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

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

Не полная структура:
CODE
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. Создаем свою функцию, которая будет выполнять нужные нам действия перед оригинальной, пример:

CODE
__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 от суммы, если вещь лежит в инвентаре (продажа), следом проверяет изменение цены, если она была изменена то возвращает ее, если нет - вызывает оригинальную функцию

CODE
#define SetItemPrice            ((__int64(*)(ObjItem * gItem, int Mode)) 0x53D725)


2.2. Перехватываем все вызовы оригинальной функции на нашу собственную, делается это довольно просто:

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

Свёрнутая информация:
## здесь был скриншот ##


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

CODE
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

Сообщение отредактировал DarkSim - 9.11.2013, 23:26
Перейти в начало страницы
+Цитировать сообщение

Сообщений в этой теме (Чтобы изменить вид топиков, в ОПЦИИ выберите отображение СТАНДАРТНЫЙ)
- DarkSim   [Гайд] Разбираем цены клиента   6.12.2012, 16:21
- - Profesor08   При этом будет отображаться визуально нужная цена?   6.12.2012, 16:36
- - DarkSim   Да, та самая, которую вернет твоя функция   6.12.2012, 16:42
- - Crazzy-   Задрот. )) Свёрнутая информация: 111...   7.12.2012, 5:56
|- - MOHAPX   Цитата(Crazzy- @ 7.12.2012, 5:56) За...   7.12.2012, 15:25
- - KamatoZ   А кто подскажет как найти оффсет для мейна 2 сезон...   1.4.2013, 2:29
- - Crazzy-   Цитата(MOHAPX @ 7.12.2012, 20:25) Если бы...   4.4.2013, 14:16
|- - Profesor08   Цитата(Crazzy- @ 4.4.2013, 12:16) Да...   4.4.2013, 14:46
- - epmak   1 может начать, а потом уже пытаться заинтересоват...   4.4.2013, 15:34
- - gucciprado   Спасибо, то что нужно! Как раз искал этот гайд...   4.4.2013, 15:46
- - NeleGaL   неплохо спасибо большое   15.8.2013, 21:50
- - LetsToPlay   Выложите пожалуйста 1.03.28 GMO майн Спасибо, сд...   19.7.2014, 15:00
- - positive   Цитата- Открывает main.exe в Ollydbg, идем на адре...   19.7.2014, 16:00
|- - LetsToPlay   Цитата(positive @ 19.7.2014, 16:00) Как н...   19.7.2014, 18:23
- - GIF1985   эта инструкция для всех сезонов MU?   13.9.2014, 17:24


Ответить в данную темуНачать новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последнее сообщение
Нет новых сообщений Куплю файлы сервера, клиента (Android, Windows, iOS)
Клиент для Android и Windows, дополнительно iOS
1 Ominous 1708 30.12.2022, 16:04 Посл. сообщение: BlowMe
Нет новых сообщений Скины моделей MUonline для использования в дизайне сервера или клиента
в PNG и PSD форматах
5 MOHAPX 7148 8.7.2021, 9:14 Посл. сообщение: Thedevilslefthand
Нет новых Редактирование клиента
Создание персонажа
13 zverek 1068 13.12.2020, 9:25 Посл. сообщение: Wendigo
Нет новых сообщений Изменение клиента Season 6
3 vlad1993 1176 24.2.2020, 19:54 Посл. сообщение: vlad1993
Нет новых сообщений Эффекты для игрового клиента
Графон в му
5 NexT 2488 5.10.2018, 21:30 Посл. сообщение: KpacaBaa

 

RSS Текстовая версия Сейчас: 9.3.2023, 1:23
Яндекс.Метрика  Перевод с помощью Google English French German Italian Portuguese Russian Spanish