• Страница 1 из 1
  • 1
Модератор форума: Dimitro  
Макс. ХП 2147 миллионов
M1sTerY
Database Developer
Доброго времени суток, столкнулся с проблемой на которую не нашел ни где ответа. Как убрать максимальное значение жизней (Макс. значение 2147 миллионов) Как сделать более ? К примеру 30 миллиардов ? Поиском пользоваться умею, но ответа так и не нашел. Знаю ранее присутствовали сервера без ограничениями по хп (жизням) Но эти сервера уже не работают давным давно, поэтому поинтересоваться как они добились данного результата не у кого, так же знаю что нужен будет патчик в клиент - который будет отображать жизни. 
Прошу помощи, кто знает где копать, как копать, чем копать, любая "полезная" информация будет приветствоваться. Ядро тринити
Сообщение # 1 написано 11.05.2017 в 12:03
Ranege
Чемпион
А ты посмотри в типы данных в ядре и посмотри диапазон принимаемого значения просматриваемого типа и всё становится ясно. Хочешь больше - используй другой диапазон
Сообщение # 2 написано 11.05.2017 в 13:16
p620
Маршал
Код
::std::numeric_limits<signed int>::max()
на x32 платформах вернет искомое значение, т.к. оно является максимальным, укладывающимся в 31 бит (+1 знаковый). Клиент существует только в x32 виде. Полагаю, выводы сделать нетрудно. Проблема, кстати, уже обсуждалась на этом форуме.
Сообщение # 3 отредактировано p620 - Четверг, 11.05.2017, 14:33
Ranege
Чемпион
p620, что мешает использовать выше тип данных на 32 битной платформе?

Добавлено (11.05.2017, 17:19)
---------------------------------------------
Серверную часть думаю без проблем настроить можно, а вот клиентскую - не знаю как ты будешь делать

Сообщение # 4 написано 11.05.2017 в 17:19
M1sTerY
Database Developer
спасибо за информацию. В каком файлике смотреть нужно?
Цитата Ranege ()
Серверную часть думаю без проблем настроить
Подскажи где )
Сообщение # 5 написано 11.05.2017 в 19:22
Ranege
Чемпион
Тебе нужно весь проект серверной части переписывать) Только какой в этом смысл. Пусть даже в серверной части у тебя будет хп 30 милиардов, ты это отправляешь в клиент, но клиент не примет у тебя 30 милиардов, он максимум примет 2147М, то есть 32 бита, будет просто переполнение или какой-то бред и хп просто будет прыгать либо в 0, либо в макс, либо просто какое-то значение выдаст, всё зависит от поведения WoW.exe приложения.

Unit.h

Код
uint32 GetHealth()    const { return GetUInt32Value(UNIT_FIELD_HEALTH); }
        uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }

        bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); }
        bool HealthBelowPct(int32 pct) const { return GetHealth() * uint64(100) < GetMaxHealth() * uint64(pct); }
        bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return (int32(GetHealth()) - damage) * int64(100) < GetMaxHealth() * int64(pct); }
        bool HealthAbovePct(int32 pct) const { return GetHealth() * uint64(100) > GetMaxHealth() * uint64(pct); }
        float GetHealthPct() const { return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; }

        void SetHealth(uint32 val);
        void SetMaxHealth(uint32 val);


Просто взял кусок из исходников. К примеру, void SetMaxHealth(uint32 val);, uint32 означает, что ты сюда можешь передать значени от до до 4294М, то есть больше чем 2147М. 2147М - это тип данных знаковый, 31 бит для значения, а тридцать второй бит просто для знака, таким образом значение от -2147М до +2147М, а тут в uint32 тридцать второй бит не используется для знака, а используется как значение, поэтому добавляется куча разных комбинаций значений и в итоге значение может достичь не 2147М, а до 4294М, но уже от нуля, отрицательное число быть не может. Если передать в метод этот допустим чилос -5, то оно будет просто интерпретировано как положительное и выдаст какое-то большое соответствующе положительное число. Получается, что если uint32, то всё хорошо, а вот где int32, то это уже 2147М предел. Если переделать тип в double, то там нереальный диапазон значений.

Казалось бы, функция задания хп имеет предел до 4294М, а команда .mod hp не даёт столько хп. Всё потому что в файле cs_modify.cpp:

Код
static bool HandleModifyHPCommand(ChatHandler* handler, const char* args)
    {
        if (!*args)
            return false;

        int32 hp = atoi((char*)args);
target->SetMaxHealth(hp);
.....
}


в метод передаётся int32, а он ограничен, если его уже поправить, то дальше тоже пойдёт значение уже более 2147М.

Такие методы, как HealthBelowPct(int32 pct) int32 нужно тоже наверно менять, наверно - потому что если тут задаётся хп в процентах, то можно вообще использовать тип uint8, т.к максимальное логическое значение 100, а в тип uint8 войдёт число до 255. Но всё конечно зависит от метода, что в нём прописано. Двигаться нужно по цепочке. Объясняю:

Ты задаешь персонажу хп командой .mod hp, вызывается укаанная функция. В этой функции вызываются методы сответствующих объектов. Для объекта игрока вызывается SetMaxHealth, SetHealth, в этих же методах вызываются другие методы. И нужно по цепочке следить чтобы тип данных был такой, который обеспечит хранение здоровья более 2147М. В сетхелсе вызывается SetUInt32Value, это метод из Object.h, потом задействуется ObjectAccesor, с этим уже не знаком, но судя по uint32 значение будет нормальным, больше 2147М, гдето в итоге это отправляется в клиент, а там уже он примет допустим int32,а ты передал uint32, в итоге у тебя тридцать второй бит будет заполнен, а для int32 это означает, что это отрицательное значение и как поведёт себя клиент на это - я не знаю, явно какая-то муть будет, это и решается типа патчем, но по сути нужно менять код клиента, а исходного кода нет, не знаю как ты будешь менять, собственно о чём и сказал раньше(может никто не проверял и клиент принимает не int32, а uint32 ? smile )

ты ещё можешь спросить как всё же или же где в клиент отправляются эти данные об изменение хп. Есть метод SendPacket в WorldSession.cpp. Если не удалось по той цепочке отследить где он вызвался, то можно в нём сделать вывод информации какая в него заходит и по заголовкам найти где она отправляется. Или просто логически смотреть и искать. Как-то так)
Сообщение # 6 написано 11.05.2017 в 20:23
M1sTerY
Database Developer
спасибо за ответ! Благодарен, понимаю что очень не легкий путь ждет...
Сообщение # 7 написано 11.05.2017 в 21:39
p620
Маршал
Цитата Ranege ()
p620, что мешает использовать выше тип данных на 32 битной платформе?

Отсутствие исходников клиентской стороны. Это придется гнить в выхлопе дизассемблера (+ HexRays, если повезет), чтобы во всю ту сотню мест, где здоровье обрабатывается на клиенте, добавить поддержку составного целочисленного типа.
Цитата M1sTerY ()
Благодарен, понимаю что очень не легкий путь ждет...

Более того, если нет уверенных знаний в области C/ASM и C++, а также глубокого понимания времени исполнения, путь окончится встречей с тупиком довольно быстро.
Сообщение # 8 отредактировано p620 - Четверг, 11.05.2017, 23:47
TomasKezho
Скаут
Было бы не плохо убрать огр.
Сообщение # 9 написано 04.07.2017 в 15:42
Ranege
Чемпион
На серверной части многие это могут сделать, а в клиентском части - это уже нет. Напишешь свой клиент, будет без ограничений) Либо изучай асемблер и много именно подробных таких вещей, которые не просто даются и убирай ограничение
Сообщение # 10 написано 05.07.2017 в 01:22
  • Страница 1 из 1
  • 1
Поиск: