SLA Posted November 28, 2010 Share Posted November 28, 2010 Патч 2.0.01 - Ремонтируем Drag&Drop Итак, в патче 2.0.01, во всех аддонах поломалось перетаскивание окон (Drag&Drop). Все заметили, да? Не найдя никаких изменений в документации API 2.0.01, я пытался выяснить, что же случилось, экспериментируя с LibDnD. Но так и не разобрался. И наверное, пришлось бы декомпилировать пару-тройку LUAC-файлов, если бы не нашёлся доброжелатель, который передал от разработчиков игры, что же именно случилось с Drag&Drop. Оказывается, они просто поменяли формулу, по которой вычисляется ID для функции mission.DNDRegister(). Поскольку, старый код Drag&Drop гарантированно вызывает конфликты с перетаскиванием иконок в АО 2.0.01, то нам придётся починить Darg&Drop во всех (без исключения!) живых аддонах, которые его используют. Через неделю, я сделаю ревизию всех аддонов, и если найду такие, в которых Drag&Drop не будет отремонтирован их авторами, то отремонтирую и перезалью эти аддоны сам. А теперь, три варианта ремонта аддонов: A) LibDnD для пользователей Если вы НЕ разработчик, а обычный пользователь, который просто хочет быстро починить свои аддоны, не дожидаясь их обновления на сайте, то для вас есть быстрый способ (авторы аддонов, этот способ НЕ для вас, для вас есть кое-что получше, вы см. вариант B). Если в папке аддона есть файл LibDnD.lua, то просто замените его на этот: LibDnD-QuickFixForUsersOnly.zip А если файла LibDnD.lua в аддоне нет, тогда либо просто дождитесь, пока аддоны обновятся на сайте, либо побудьте чуть-чуть программистом, и посмотрите вариант C. LibDnD для разработчиков аддонов А для вас, друзья, есть интересный квест , который займёт всего 10-15 минут, и сделает код ваших аддонов проще, а работу с Drag&Drop надёжнее и стабильнее - новая версия LibDnD! Почему именно сейчас? Потому, что она не совместима с предыдущими версиями, а вводить такие кардинальные изменения удобно именно в такие моменты, когда код аддонов нужно обновлять в любом случае. То есть, сейчас именно такой момент. Я давно хотел сделать некоторые существенные изменения в LibDnD, но никак не доходили руки, к тому же, в самое последнее время, я был очень занят. И тут подвернулся такой удобный случай - патч 2.0.01, поломавший старый код Drag&Drop. Не упускать же шанс! Пришлось в ускоренном темпе переписать и протестировать новый код LibDnD. Что нового? Функции DnD:Reg() и DnD:Unreg() отправились на свалку истории =)) Но мы не будем по ним скучать, правда? Именно так, они больше не нужны, т.к. теперь, регистрация виджетов происходит автоматически, при показе/сокрытии виджетов. То есть, теперь, для полноценной работы всей системы Drag&Drop, достаточно всего лишь одного-единственного вызова DnD:Init() где-нибудь в инициализации аддона - сбылась моя давняя мечта Кроме того, специально для поддержки "AddonManager", добавилась удобная и надёжная функция DnD:Enable(). Теперь, обо всём по порядку: Возьмите новую версию файла LibDnD.lua отсюда: HOW-TO: LibDnD.lua (Библиотека Drag&Drop) (LibDnD.lua находится в архиве SampleLibDnD_2010-11-28.zip, прицепленном к первому сообщению темы) А теперь, откроем код вашего аддона, и пробежимся по списку типичных мест обитания DnD:Reg() и DnD:Unreg(). Всё просто как 1-2-3: 1) "SCRIPT_TOGGLE_UI" (Что это?). Если у вашего аддона есть виджеты, но всё ещё нет реакции на это событие, то ПОЖАЛУЙСТА добавьте его. А если она у вас уже есть, и её содержимое отличается от нижеприведённого примера, то смело сотрите всё содержимое этой функции, и замените его на одну-единственную строку: Code: mainForm:Show( params.visible ) 2) "U_EVENT_TOGGLE_DND" (Что это?). Если у вас есть реакция на это событие, то она, вероятно, имеет примерно такой вид: Code: if params.target == common.GetAddonName() then if params.state then DnD:Reg( MyWidget1 ) DnD:Reg( MyWidget2 ) else DnD:Unreg( MyWidget1 ) DnD:Unreg( MyWidget2 ) end end Замените всё это на примерно такой код: Code: if params.target == common.GetAddonName() then DnD:Enable( MyWidget1, params.state ) DnD:Enable( MyWidget2, params.state ) end 3) Теперь, у вас остались только те вызовы DnD:Reg() и DnD:Unreg(), которые используются при показе/сокрытии виджетов: Code: DnD:Unreg( MyWidget1 )MyWidget1:Show( false ) MyWidget2:Show( true ) DnD:Reg( MyWidget2 ) Смело стирайте из своего аддона все эти DnD:Reg() и DnD:Unreg(), так как этих двух функций больше нет в LinDnD. Должно получиться как-то так: Code: MyWidget1:Show( false )MyWidget2:Show( true ) Как видите, всё совсем не трудно, и аддон, прямо на глазах, становится проще и красивее C) Другие, нестандартные реализации поддержки Drag&Drop Ваш аддон всё ещё не использует LibDnD? - Тогда мы идём к вам! Куча нестандартных Dnd_Core.lua и других файлов, каждый из которых не похож ни на один другой - это довольно неудобно, когда случаются такие казусы, как например, патч 2.0.01. Единый стандарт - это очень удобно. Если это возможно, то рекомендую, всё же, перейти на LibDnD. Она уже достаточно хорошо отшлифована, и умеет обходить многие "подводные камни". Если же вам чего-то не хватает в LibDnD - предлагайте идеи улучшения этой библиотеки, там ещё есть над чем поработать. Если я вас не уговорил , то вот, что нужно сделать, чтобы починить Drag&Drop в вашем коде: 1) Найти примерно такой код: Code: mission.DNDRegister( <Anything>, DND_WIDGET_MOVE * DND_CONTAINER_STEP + ID, true ) и заменить на примерно такой: Code: if mission.GetLocalTimeHMS then -- AO 2.0.01+ mission.DNDRegister( <Anything>, ID * DND_CONTAINER_STEP + DND_WIDGET_MOVE, true ) else -- AO 1.1.02-2.0.00 mission.DNDRegister( <Anything>, DND_WIDGET_MOVE * DND_CONTAINER_STEP + ID, true ) end 2) Найти примерно такой код: Code: <Anything> = math.mod( params.srcId, DND_CONTAINER_STEP ) и заменить на примерно такой: Code: if mission.GetLocalTimeHMS then -- AO 2.0.01+ <Anything> = ( params.srcId - DND_WIDGET_MOVE ) / DND_CONTAINER_STEP else -- AO 1.1.02-2.0.00 <Anything> = math.mod( params.srcId, DND_CONTAINER_STEP ) end Зачем разработчики игры изменили формулу Разработчики игры изменили формулу: DND_WIDGET_MOVE * DND_CONTAINER_STEP + ID на такую: ID * DND_CONTAINER_STEP + DND_WIDGET_MOVE Зачем? Чтобы расширить диапазон ID-номеров. Поскольку DND_CONTAINER_STEP и DND_WIDGET_MOVE - это константы, и они равны 1000 и 14 соответственно, а рядом с DND_WIDGET_MOVE есть другие константы, равные 13 и 15, то это значит, что по старой формуле, доступен был диапазон 0-999 (по формуле, он превращался в 14000-14999). Но знайте, что пока в EU/US не выпущена АО 2.0.01, мы по прежнему НЕ можем использовать числа больше 999 в вызовах функции DnD:Init(), чтобы сохранить обратную совместимость с современными EU/US версиями АО. По новой формуле, диапазон значений становится, как бы, "неограниченным", т.к. он больше не зажат между 14000 и 14999, и максимальное значение ID теперь ( MAX_NUMBER - 14 ) / 1000. Здесь, MAX_NUMBER - это максимальное возможное значение number в Lua, насколько знаю, это IEEE 64-Bit Float, то есть 2^52. Значит, максимальный ID теперь не 999, а примерно ( 2^52 - 14 ) / 1000 ~= 4.50359963 * 10^12. Четыре с половиной триллиона. Неплохо, правда? Нам этого хватит на всё третье тысячелетие, ну а потом, попросим добавки. Quote Link to comment Share on other sites More sharing options...
SLA Posted November 28, 2010 Author Share Posted November 28, 2010 < Место зарезервировано / This post is reserved > Quote Link to comment Share on other sites More sharing options...
ramirez Posted November 28, 2010 Share Posted November 28, 2010 Хинт: Можно избежать кучи вызовов с гарантированно провальными проверками, если подписываться на EVENT_DND_DRAG_TO, EVENT_DND_DROP_ATTEMPT и EVENT_DND_DRAG_CANCELLED только на время перетаскивания, после того, как убедился, что EVENT_DND_PICK_ATTEMPT действительно пришел тебе, и сразу отписываясь от них на EVENT_DND_DROP_ATTEMPT или EVENT_DND_DRAG_CANCELLED. Quote Link to comment Share on other sites More sharing options...
SLA Posted November 29, 2010 Author Share Posted November 29, 2010 Ага, нужно будет так сделать. А ещё, Nikon подсказал, что LibDnD до сих пор не использует функцию mission.DNDConfirmPickAttempt(). ЛОЛ, как же оно, тогда, работает? Если сегодня вечером доберусь до LibDnD, то попробую всё это (и ещё кое-что) и всё протестирую. Но что хорошо, это всё касается лишь внутренней начинки LibDnD, а значит, все эти усовершенствования могут немного подождать. Сейчас же, важно пропихнуть эту новую LibDnD v2010-11-28 с её новым синтаксисом. В будущем, LibDnD ещё развиваться и развиваться... Поэтому и говорю, чтобы все предлагали свои идеи. А пока, вижу необходимость таких шагов: 1) Нужно будет снять ограничение, требующее, чтобы перетаскиваемый виджет позиционировался исключительно как WIDGET_ALIGN_LOW. 2) Нужно "зашивать" ID виджета в сам виджет, а не искать его в DnD:Enable() перебором и сравнением виджетов-ссылок, т.к. всё это сейчас работает только в том случае, если используется одна и та же ссылка, которая хранится в глобальной переменной. А если, например, при вызовах DnD:Init() и DnD:Enable() каждый раз брать новую ссылку на виджет (GetChildChecked), то это разные ссылки, и они между собой НЕ равны - в такой ситуации, функции не находят виджетов, это fail. 3) Есть ещё кое-какие сложности с InitialPlace (сохраняемое в библиотеке "дефолтное" положение виджета, которое при некоторых обстоятельствах может НЕ совпадать с его фактическим положением). Нужна возможность для пользователя, изменять эти координаты извне. Нужен либо хук SetPlacementPlain(), либо отдельная пользовательская функция для этого. Хук лучше. Но сначала, нужно всё это хорошо обдумать, чтобы ничего не запороть. 4) Нужно будет добавить в параметры DnD:Init() возможность указывать callback-функции. Например, callback-функция, вызываемая во время перетаскивания, получающая виртуальные координаты левого-верхнего угла перетаскиваемого виджета, а также, его размер, и виртуальный размер экрана. Так, пользователь сможет расширять функционал библиотеки, не влазя в её код. Например, двигать ещё что-то, помимо самого передвигаемого виждета. Конечно, можно сказать, что у такого пользователя, просто неправильная иерархия виджетов, если ему требуется двигать вручную что-то ещё. Но ведь, бывают и исключения. Иногда, это удобно. А в таком аддоне как PlayerHUD, например, с помощью callback-функции, можно было бы двигать левую арку, и СИММЕТРИЧНО, синхронно двигать правую (зеркально отражённую), и наоборот. 5) И всё это должно, по прежнему, оставаться простым в использовании, чтобы не отпугивало начинающих аддоностроителей. А также, было бы здорово, не распухнуть более чем до 10Кб, а то, уже 6.5Кб. Quote Link to comment Share on other sites More sharing options...
ramirez Posted November 29, 2010 Share Posted November 29, 2010 widget:GetInstanceId() в документации. Quote Link to comment Share on other sites More sharing options...
Nikon Posted November 29, 2010 Share Posted November 29, 2010 0. Я как то давным-давно пытался сам делать реализацию ДнД по выданой документации. Дошел до этой гребаной mission.DNDConfirmPickAttempt()... Оно не работало так как описано в документации. Т.е. при использовании этой функции ДнД не отрабатывался... Плюнул на доки и пошел смотреть чужой уже готовый рабочий код 2. Расскажите мне разницу между GetChildChecked и GetChildUnchecked. Использую GetChildUnchecked - проблем с поиском уже существующих виджетов не было 4. Голубая мечта - сделать уголок, при таскании которого изменяется размер виджета (как его называют по научному я уж забыл). Но думать над этим неохота Еще раз: все что ты описал в 1-м посте.... лишнее и не нужно, ИМХО. Попробуй вставить ту функцию в старый код Quote Link to comment Share on other sites More sharing options...
SLA Posted November 30, 2010 Author Share Posted November 30, 2010 0. mission.DNDConfirmPickAttempt()? Хм. Попробовал. В новом коде, оно не работает ) В самом деле, как только попробовал вставить эту функцию, LibDnD перестала работать. 2. Имхо, для нас, разница не существенная. Для GetChildChecked() требуется, чтобы контрол существовал, если его нет, то... выдаст ошибку? Я не пробовал. А для GetChildUnchecked, этого не требуется, просто, если контрола нет, то она вернёт nil. В общем, эта парочка функций - что-то наподобие require() и include() в PHP. 4. Такое уже сделано в аддоне Minimap. Причём, ничего особо сложного тут нет, просто слегка модифицированный код Drag&Drop... Но на самом деле, существует более правильный способ, но мы его ещё не открыли - в XDB есть тег <sizingWidget href="" />, а в Lua-константах АО, кроме DND_WIDGET_MOVE (=14), есть ещё DND_WIDGET_RESIZE (=15). Как этим всем пользоваться, я не разбирался. Quote Link to comment Share on other sites More sharing options...
SLA Posted December 5, 2010 Author Share Posted December 5, 2010 SLA (2010-11-28) wrote: Через неделю, я сделаю ревизию всех аддонов, и если найду такие, в которых Drag&Drop не будет отремонтирован их авторами, то отремонтирую и перезалью эти аддоны сам. Неделя прошла Вот список оставшихся неотремонтированных аддонов, которые я отремонтирую и перезалью сегодня вечером, если авторы этих аддонов не сделают это быстрее меня )The week passed Here is a list of remaining broken addons. I will repair and upload all those addons this evening, if the addons' authors don't do it faster than me ) AnatomySelfDefence - Fixed by me AOChatExtension - Fixed by author & me CT_Total - Fixed by author DarkDPSMeter - Fixed by me LightDPS - Fixed by author Minimap - Fixed by me SpamProtect - Fixed by me Quote Link to comment Share on other sites More sharing options...
Ciuine Posted December 5, 2010 Share Posted December 5, 2010 Creepy. Quote Link to comment Share on other sites More sharing options...
Guest Carnifex Posted December 5, 2010 Share Posted December 5, 2010 I see it more like this: (orginal from xkcd: http://xkcd.com/149/ ) just joking... At the moment I havn't enough time to do this, because things in my rl have more priority the programming ao-addons. But I think, in a few weeks a should have enough time to continue working on aochatextension. BTW: Some other good ones from xkcd: [x] [x] [x] [x] [x] [x] ... (I can't find everything I had looked for) File: w0iLPgqbaVY8VAr.png Quote Link to comment Share on other sites More sharing options...
Nikon Posted December 6, 2010 Share Posted December 6, 2010 Фтопку это лагающее "бесплатное" УГ, основной фичей которого является (Острал? Это че такое?) открывание различных сундуков-коробок-ящиков КАТАКЛИЗМ!!!!11111111111 Quote: ...Скоро Азерот будет разрушен!И все сгорит до тла в тени моих крыльев! ЗЫ. Клоун наконец-то окончательно забанил меня на оффоруме "за хамство" )) И я ему безмерно благодарен: есть и в этой конторе хорошие люди, которые, в меру своих сил, отбивают у нормальных людей все желание соприкасаться с этим УГ-шным проектом Quote Link to comment Share on other sites More sharing options...
Guest Carnifex Posted December 6, 2010 Share Posted December 6, 2010 why you hadn't sad, that I only have to replace LibDnD with the new one? It sounds much more complicated in your description. But: sudo fix SpamProtect (which uses not LibDnD but the dnd part of AOClassLib) (but I think this have time, because itis more ore less useless in the ru version and we will get 2.0.01 in 2,5m+) fuck: dnd is now working in the russian gameversion, but know the uireleatedtextures make problems in the classpreviewicon, @SLA: can you fix this? I havn't enough time for this at the moment. While you're at it, can you also have a look on my checkboxes?^^ BTW: I think we have one similarity: we make big development plans, but we can't stay on schedule with them, because of a lack of freetime^^ Quote Link to comment Share on other sites More sharing options...
SLA Posted December 8, 2010 Author Share Posted December 8, 2010 <imho> КАТАКЛИЗМ - это начало конца ВоВ. </imho> ИМХО, в связи с тем, что ВоВ - очень старая игра, и с постоянно возрастающей конкуренцией со стороны других ММОРПГ, Близзард уже не знает, что бы такое придумать, чтобы... просто удержать старых подписчиков. Именно старых, т.к. новых привлечь уже не получается, ведь все потенциальные игроки уже давным-давно попробовали ВоВ. Новые люди больше не приходят в ВоВ, иначе бы Близзард не лез из шкуры вон, переделывая все стартовые локации. Что мы видим в Катаклизме? Некоторые упрощения геймплея, чтобы можно было побыстрее пройти игру (не нужно бегать сдавать квесты, не нужно далеко бегать по территориям) - это всё последняя, отчаянная попытка привлечь новых пользователей, лебединая песня. Конечно, квесты стали разнообразнее. Вместо пойди-убей-собери, разыгрываются целые сценки, актёрами в которых выступают... НПЦ. Почему приходится бегать с квестовым напарником-НПЦ, ведь это, как бы, "социальная" игра? Потому, что в Близзард даже не рассчитывают, что стартовые локации будут настолько насыщены новыми игроками, чтобы игроки не умерли со скуки. Они всё понимают, поэтому, приходится "развлекать" одиноких игроков мини-играми с участием безмозглых НПЦ. ВоВ превращается в single-player игру. Из нового, понравилась техническая сторона квестов - они стали "неожиданно" технически разнообразными. Квестовые НПЦ-напарники могут теперь таскать лут на спине, могут скакать с тобой на лошади, и т.д. Но это "техническое разнообразие" очень скоро приестся, имхо, зря они проделали такой, поистине титанический, труд над "техническим разнообразием" квестов. А там, на территориях для хаев, всё по-старому, в основном. А это тупик, старые подписчики пройдут до этого места, и бросят играть. Новые игроки тоже не захотят продолжать играть в пойди-убей-собери, их внезапно одолеет скука. Или, может, есть там что-то новое на территориях для хаев? Может, я чего-то не знаю. Guild-leveling? Это только для прокачанных задротов, которые никогда не уходили из игры. Новичкам с ними не тягаться. Есть мнение, что Близзард сильно преувеличивает количество "активных подписчиков". Однажды, они объявили, что у них 11.5 млн игроков. Затем, они замолчали аж на несколько лет. В это время, у них были проблемы с Китаем, а значит, были периоды, когда они теряли бОльшую часть своих подписчиков... И тут, внезапно, после нескольких лет молчания, недавно, они сообщают, что как-то дотянули до 12 млн подписчиков. Что-то не верится... Ну и, в конце-концов, игра подошла к кульминации абсурда. Представьте - имеется дракон, который взмахом крыльев умеет уродовать ландшафт Азерота. Нифига себе! И что? Скоро этого дракона можно будет УБИТЬ, т.к. он будет обычным рейдовым боссом!!! Что дальше, Близзард? Расскажи мне свою СЛЕДУЮЩУЮ шизофреническую фантазию Как ни крути, а после Катаклизма, Близзард уже ничем не сможет удивить игроков. У них просто фантазия иссякла, если они уже берутся за создание "технически навороченных" квестов. Как-то примитивно, не масштабно мыслят они... Столько шума наделали своей вездесущей кричащей рекламой Катаклизма... А заходишь в игру, и видишь, каким ВоВ был, таким и остался. После такой мощной рекламной компании, я ожидал от них чего-то гораздо бОльшего, но нет, Катаклизм сильно разочаровал. Близзард просто выдохся, насилуя труп ВоВ. Quote Link to comment Share on other sites More sharing options...
Guest bryl Posted December 8, 2010 Share Posted December 8, 2010 SLA, не могли бы вы взглянуть на ShowMePrice? В нем также используется DND и он тоже не работает после патча. Quote Link to comment Share on other sites More sharing options...
SLA Posted December 8, 2010 Author Share Posted December 8, 2010 Все аддоны отремонтированы. All addons are repaired now. P.S. Втихаря, обновил библиотеку LibDnD до версий 2010-12-08 и 2010-12-10: Лог изменений. Silently updated the LibDnD library to versions 2010-12-08 and 2010-12-10: Changelog. Quote Link to comment Share on other sites More sharing options...
SLA Posted December 8, 2010 Author Share Posted December 8, 2010 Да, он поломался в патче 2.0.01. Попробую его починить. Quote Link to comment Share on other sites More sharing options...
Recommended Posts