Сейчас 28.11.2024, 22:22



  • Страница 1 из 1
  • 1
[Manual]Основы правки спеллов
AndrqhaДата: Вторник, 26.07.2011, 09:51 | Сообщение # 1
Генерал-майор
Группа: Модераторы
Сообщений: 288
Награды: 2
Репутация: 1
Статус:
Внимание! Данная тема предназначена для програмистов, начинающих разбиратся в больших проектах. Сам я являюсь начинающим - поэтому запишу свои заметки (пока помню=)

1. Вы нашли неработающий спелл и хотите его исправить. Самый очевидный путь решения проблемы - посмотреть исходники МаНГОСа, понять как должен спел работать и исправить. Дальше перекомпилить сервер и протестировать. Если не помогло - вернутся в исходники, подумать, исправить, протестить... и так до победного конца.

Так вот, данный способ в основном не помогает!

2. Начинаем гуглить на тему обнаружение ошибок.
Википедия

Отладка — этап разработки компьютерной программы, на котором обнаруживают, локализуют и устраняют ошибки. Чтобы понять, где возникла ошибка, приходится…
узнавать текущие значения переменных;
и выяснять, по какому пути выполнялась программа. Количество ошибок в программах заранее неизвестно, поэтому заранее неизвестна продолжительность отладки.
Существуют две взаимодополняющие технологии отладки.
Использование отладчиков — программ, которые включают в себя пользовательский интерфейс для пошагового выполнения программы: оператор за оператором, функция за функцией, с остановками на некоторых строках исходного кода или при достижении определённого условия.
Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода — на экран, принтер, громкоговоритель или в файл. Вывод отладочных сведений в файл называется журналированием.

Отладка — это часто тяжёлая и утомительная задача.

Отладка начинается с попытки воспроизвести проблему

3. Как использовать дебаггер (примеру от Visual Studio) в больших проектах - я не знаю, поэтому предоставлю данную часть другим хорошим людям.

4. А вот

Code
Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода
рассмотрим поподробнее. Это важно! Википедия, чья-то там цитата

«Наш личный выбор — стараться не использовать отладчики, кроме как для просмотра стека вызовов или же значений пары переменных. Одна из причин этого заключается в том, что очень легко потеряться в деталях сложных структур данных и путей исполнения программы. Мы считаем пошаговый проход по программе менее продуктивным, чем усиленные размышления и код, проверяющий сам себя в критических точках.

Щёлканье по операторам занимает больше времени, чем просмотр сообщений операторов выдачи отладочной информации, расставленных в критических точках. Быстрее решить, куда поместить оператор отладочной выдачи, чем проходить шаг за шагом критические участки кода, даже предполагая, что мы знаем, где находятся такие участки. Более важно то, что отладочные операторы сохраняются в программе, а сессии отладчика переходящи.

Слепое блуждание в отладчике, скорее всего, непродуктивно. Полезнее использовать отладчик, чтобы выяснить состояние программы, в котором она совершает ошибку, затем подумать о том, как такое состояние могло возникнуть. Отладчики могут быть сложными и запутанными программами, особенно для новичков, у которых они вызовут скорее недоумение, чем принесут какую либо пользу…»

5.Итак, начали
Изучаем все про наш спел. Для этого используем wowhead.com, thottbot.com, C.S.W.O.W.D., мангос.вики, Spell.dbc.
Используем поиск на getmangos.ru, getmangos.com (опционально на thetrinitycore.org) в попытках засечь обсуждения, патчи, комментарии. Можно также выложить запрос на патч или просто спросить на форуме у знатоков - возможно их ответом и будет патч=) Но, как правило, такое редко случается, у знатоков своих дел предостаточно.
Ставим чистый мангос - чтоб не править чужие патчи(если это не планируется), чистую базу - чтобы быстрее поднимался сервер, компилим без дополнений (в виде СД2)
Первым делом - включение в конфиге логирования на уровень 3 (debug), желательно и для файла, для поиска в нем нужной информации

Code
LogSQL = 1
PidFile = ""
LogLevel = 3
LogTime = 1
LogFile = "Server.log"
LogTimestamp = 1
LogFileLevel = 3
LogFilter_TransportMoves = 1
LogFilter_CreatureMoves = 1
LogFilter_VisibilityChanges = 1

Дальше, врубаем сервер и воспроизводим ошибку. В консоли отображается некоторая информация, изучаем ее, она нам понадобится. При воспроизведении ошибки нужно попытатся также решить ее. У меня, к примеру, при включеном ГМ режиме спелл начинал работать Оо. Примечание. Постарайтесь ограничить количество игроков оналйн, лишние засоряют консоль
Врубаем метод научного тыка - в поиске по сорцам вводим ИД спелла, либо его название, либо название класса(если это классовый спел) и ходим по коду, внимательно всматриваясь и включив интуицию. Данный метод помогает редко, но помогает. Помогает также начать раздуплятся в коде (теперь вы будете понимать важность комментариев).
Если предыдущий способ прямого поиска ошибочного места не привел к успеху, используем консольные сообщения для поиска. Пример(реальный). Я кастую спелл, а мне на екране клиента выводит - "Нельзя использовать сдесь". В консоли при попытке каста отображается следущее:

Code
2009-04-14 16:26:21 WORLD: got cast spell packet, spellId - 28622, cast_count: 10, unk_flags 0, data length = 10
2009-04-14 16:26:21 WORLD: got cast spell packet, spellId - 28622, cast_count: 11, unk_flags 0, data length = 10
2009-04-14 16:26:21 WORLD: got cast spell packet, spellId - 28622, cast_count: 12, unk_flags 0, data length = 10
2009-04-14 16:26:21 WORLD: got cast spell packet, spellId - 28622, cast_count: 13, unk_flags 0, data length = 10
2009-04-14 16:26:22 WORLD: got cast spell packet, spellId - 28622, cast_count: 14, unk_flags 0, data length = 10
2009-04-14 16:26:22 WORLD: got cast spell packet, spellId - 28622, cast_count: 15, unk_flags 0, data length = 10

и больше ничего. А должно быть так:

Code
2009-04-14 16:29:38 WORLD: got cast spell packet, spellId - 28622, cast_count: 52, unk_flags 0, data length = 10
2009-04-14 16:29:38 Sending SMSG_SPELL_START id=28622
2009-04-14 16:29:38 Sending SMSG_SPELL_GO id=28622
2009-04-14 16:29:38 Spell: Effect : 6
2009-04-14 16:29:38 Spell: Aura is: 201
2009-04-14 16:29:38 Aura: construct Spellid : 28622, Aura : 201 Duration : 60000 Target : 1 Damage : 0
2009-04-14 16:29:38 Aura 201 now is in use
2009-04-14 16:29:38 Spell: Effect : 6
2009-04-14 16:29:38 Spell: Aura is: 3
2009-04-14 16:29:38 Aura: construct Spellid : 28622, Aura : 3 Duration : 60000 Target : 1 Damage : 3260
2009-04-14 16:29:38 Aura 3 now is in use
2009-04-14 16:29:38 Spell: Effect : 6
2009-04-14 16:29:38 Spell: Aura is: 12
2009-04-14 16:29:38 Aura: construct Spellid : 28622, Aura : 12 Duration : 60000 Target : 1 Damage : 0

Взято с Mangos.ru
2009-04-14 16:29:38 Aura 12 now is in use
2009-04-14 16:29:38 WORLD: CMSG_MOVE_SET_CAN_FLY_ACK
2009-04-14 16:29:40 PeriodicTick: 449 (TypeId: 4) attacked 449 (TypeId: 4) for 3260 dmg inflicted by 28622 abs is 0
2009-04-14 16:29:40 DealDamageStart
2009-04-14 16:29:40 deal dmg:3260 to health:3729

Делаем вывод, что после определенного текста дебаг-лога начинаются проблеммы.
Копируем строчку(только нужные слова, не указывайте конкретные числа!), кнтрл-F, находим кусок кода.
Теперь у нас есть отправная точка. Крутим код вниз, проверяя разветления. Также переходим по функциям дальше вглубь кода до основ, пока не убедимся в их правильности(или неправильности). Если ошибочное место до сих пор не определено, начинаем использовать
Цитата:Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода

Для этого существует ф-я sLog.outDebug(), работающая так же как и printf(). С ее помощью мы розставляем контрольные точки по коду - от начальной позиции и до предполагаемого конца. Чем больше - тем лучше, легче потом будет локализовать ошибку. Перекомпил, перезапуск, тест, всматриваемся в консоль - ооп, видим нужные нам отклонения от предполагаемого хода. Вообщем говоря, методом контрольных точек и логирования можна локализовать почти любой баг.
Ошибка локализована, что дальше?
Нуу, багу можна приписать категорию: хак, оставленый кем-то на память; грубая очепятка, призведшая к поломке спелла; некорректная проверка; ошибка при проэктировании структуры МаНГОСа; отсуствие возможности реализации. Последние 2 категории - из разряда сложных, без досконального знания кода мангоса и С++ не обойтись. Остальные уже решать по ходу дела
Если окажется, что вы знаете маловато функций Мангоса для устранения бага - самое время начать изучать код. Вот список файлов для изучения в первую очередь

Code
Player.h/Player.cpp
Unit.cpp/Unit.h
Spell.h/Spell.cpp
SpellAuras.h/SpellAuras.cpp
SpellEffects.cpp
SpellHandler.cpp
SpellAuraDefines.h
SpellMgr.cpp/SpellMgr.h
Object.h/Object.cpp
SharedDefines.h
- особо!!!
В конце-концов баг исправлен))) похвалите себя=)

Что еще добавить?

- Если бага легко исправляется правкой ДБЦ - ни в коем случае так не делаем! Правка ДБЦ есть неправильный путь
- Не тупите(особенно при вопросах на форуме. мну зафукали за тупой вопрос... теперь красное пятно осталось... недоверие...)
- Просматривайте аналогичные проблемы и способы их решений
- *еще может чё придумаю..

Вот так. Критика и улучшения приветствуются. А еще хотелось бы услышать мнения девов, ведь сдесь все написано новичком


 
  • Страница 1 из 1
  • 1
Поиск:

Unread posts Есть новые сообщения    No unread posts Нету новых сообщений    No unread posts [ Locked ] Закрытый форум