Van Damm
wait... what?
offline
Опыт:
22,268Активность: |
Добавление собственных Native функций в Warcraft III
Часть статьи является вольным переводом руководства с WC3C авторства PipeDream
Часть 0: ВступлениеДумаю, почти всем людям, занимающимся созданием карт для Warcraft 3 и использующим возможности скриптового языка JASS2 на полную, приходили в голову мысли вроде "А вот если бы вот здесь сделать как в C++ (подставить другой язык программирования по желанию)". Но это было невозможно до тех пор, пока xttocs не написал JAPI - подгрузчик собственных native-функций в запущенный процесс игры. Это случилось давно - почти три года назад (релиз japi 1.0 состоялся 24.01.2006), но до сих пор остается малоизвестным и редко используется. С помощью статьи я хочу распостранить эти знания среди русскоговорящих картостроителей.Скажу сразу: эта статья не предназначена для новичков и людей, не понимающих в программировании. В процессе написания статьи, я буду давать некоторые сведения, не обязательные к прочтению - они будут скрыты под катами. Часть 1: Инструменты и знанияИтак, для начала определимся, что нам понадобится в этом нелегком деле:
Часть 2: Порядок действий и простейший примерИтак, обозначим порядок наших действий:
Для начала возьмем классический пример "Hello world": напишем функцию, которая не принимает параметров, а возвращает некоторую строку. Вот наш test.cpp Код:
Два важных места здесь - это: Код:
Код:
Теперь скомпилируем DLL. Для этого в командной строке напишем Код:
Следующим шагом нам необходимо добавить эту функцию в common.j (если у вас его нет, всегда можно достать последнюю версию из war3patch.mpq): Код:
Теперь создадим карту, в которой будет вызвана наша функция. Назовем её test.w3m и сохраним в папку Maps директории варкрафта. В карте создадим триггер Test, выполняющийся при инициализации и в действия добавим: Код:
Пришло время запускать игру. Распакуйте Grimoire в какую-то директорию неподалеку и приготовьтесь печатать. Открываем startwar3.bat, пишем и сохраняем: Код:
Код:
» Что такое луа? Lua — интерпретируемый язык программирования, разработанный подразделением Tecgraf Католического университета Рио-де-Жанейро. Является свободно распространяемым, с открытыми исходными текстами на языке Си. По возможностям, идеологии и реализации язык ближе всего к JavaScript, однако Lua отличается более мощными и гораздо более гибкими конструкциями, спроектирован с целью «не плодить сущности сверх необходимого». Хотя Lua не содержит понятия класса и объекта в явном виде, механизмы объектно-ориентированного программирования с поддержкой прототипов (включая множественное наследование) легко реализуются с использованием метатаблиц, которые также позволяют перегрузку операций и т. п. Реализуемая модель ООП (как и в JavaScript) — прототипная. Lua в переводе с португальского значит «луна», поэтому неправильно писать «LUA» — так же, как и неправильно писать любое другое слово одними только прописными символами. ~Википедия Предварительные ласки завершены. Теперь можно, скрепя сердце, запускать startwar3.bat, не забыв перед этим удостовериться что наша test.dll находится в папке grimoire\bin\. (да, и проверьте чтобы в папке с игрой не валялся scripts\common.j) Если вы все сделали правильно, игра запустится и сразу загрузит нашу тестовую карту, которая не преминет удивиться в ответ =) Данный этап можно считать завершенным успешно. » А что собственно происходит? Перехватчиком вызовов jass-функций выступает библиотека japi.dll, которая внедряется в процесс варкрафта с помощью Grimoire. Конкретно внедрением занимается exehack.exe, который принимает параметры для своей работы из файла script.lua, расположенного с ним в одной папке. При запуске с ключом -s, парсит переданный ему в качестве аргумента файл lua. Мы аргументом передаем war3.lua, в котором сначала определяется путь к варкрафту, а затем запускается игра и в процесс внедряется ongameload.dll ongameload.dll считывает ongameload.lua и внедряет в процесс вызовы библиотек, указанных в нем, после чего процесс размораживается и идет его нормальное выполнение. Вот и вся схема подгрузки библиотек в нашем случае. Часть 3: Пишем что-то полезноеТеперь перед вами раскрываются достаточно широкие горизонты. Вот лишь несколько примеров: 1) Быстрая конвертация строки типа "A001" в целое число и обратно: Код:
2) Динамически аллоцируемый массив Код:
В дальнейшем поможет лишь анализ japi.dll и личные опыты. Также полезным может оказаться вот эта ссылка Часть 4: Личные наблюдения4.1 Достаточный минимумПутем некоторых исследований, мной было установлено, что для простой подгрузки своих native-функций нет надобности возить за собой весь grimoire: достаточно минимального комплекта:Код:
Его прилагаю к сему сообщению 4.2 Код базовой библиотеки для DelphiБлагодаря AiwaDoter, теперь доступен код базовой библиотеки для добавления native функций для Delphi. Вот он: Код:
4.3 Избавление от придирок антивирусовИспользуя небольшую хитрость, можно добиться отказа от использования exehack.exe, что положительно повлияет на весь комплект: именно этот файл антивирусы чаще всего считают вредным. Также использование этой хитрости позволяет запускать варкрафт с добавленными native функциями в linux (естественно, из-под wine). Итак, порядок действий:
Важно! При выполнении пункта 5, PEditor может выдать ошибку плана "Сan't find the "DllMain" function in the dll". Тогда вам нужно открыть ongameload.dll в любом просмотрщике ресурсов (рекомендую CFF Explorer — кстати в нем можно и импорт прописывать, даже удобнее: на PEditor антивирусы все еще могут ругнуться), найти таблицу экспорта и в ней посмотреть, имя какой функции содержит что-то, намекающее на загрузку ^_^ (в моем случае это было _Z16LoadLibraryAWrapPKc@4) — её и использовать в этом шаге. Часть 5: ПримечанияВнимание! Некоторые антивирусы могут ругаться на grimoire, а конкретно на файлы bin\exehack.exe, bin\ongameload.dll и bin\japi.dll, определяя в них троянов.Никакой опасности для вашего компьютера эти файлы не несут! Дело в том, что в них используется потенциально подозрительный код (для динамического изменения памяти процесса игры), на который и реагируют антивирусы. Просто добавьте их в исключения вашего антивируса. Отредактировано Van Damm, 16.02.2009 в 23:44. |
01.11.2008, 15:03 | #1
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
adic3x
offline
Опыт:
107,539Активность: |
очень мило, ток надо проверить)
ADOLF добавил: dword наше все (ну в 32), остальные типы от лукавого, мну это всегда бесит |
01.11.2008, 16:41 | #2
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
PlayerDark
Coraline
offline
Опыт:
10,569Активность: |
Теперь вопрос, как все это будет работать на чужом компьютере ? |
01.11.2008, 20:38 | #3
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Toadcop
offline
Опыт:
53,013Активность: |
PlayerDark нужен лоудер и всё (набор файлов и запуск вара через спец ехе)... и что бы у него патчилась вся контора ясно что =)
|
01.11.2008, 20:59 | #4
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Van Damm
wait... what?
offline
Опыт:
22,268Активность: |
PlayerDark того, что есть в прилагаемом архиве, вполне достаточно
Van Damm добавил: ну еще моск дабы сделать так, чтоб игрок запускал карту именно лоадером ) |
01.11.2008, 21:34 | #5
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
это насилование варика =) вармейкинг недостоин таких извратов, гораздо разумнее писать что-то более полезное |
02.11.2008, 17:31 | #6
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
adic3x
offline
Опыт:
107,539Активность: |
смотря для чего, какой то мего мод как раз и может использовать что то подобное |
02.11.2008, 19:54 | #7
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
понятно, все взаимодействие возможно через приведение к типу HANDLE (jINT), значит теоретически возможно пристроить сишный класс матриц (который, пожалуй, все программисты пишут на 1 курсе ВУЗа) или класс рациональных чисел так что бы он мог создаваться из jass и делать все необходимые преобразования/подсчеты меня интересует насколько реально добавление чистых классов (обьектов типа класс) в jass? то есть реально ли перенести интерфейсы с хандлей на типизированные ссылки (ссылки на обьекты типа класс, что впринципе одно и то же, но более юзабельно) вполне очевидно, что скрипт работает через хандли, и это видно из строки return jStrMap(s) |
05.11.2008, 11:24 | #8
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
о, блин, заработало! |
05.11.2008, 16:43 | #9
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Van Damm
wait... what?
offline
Опыт:
22,268Активность: |
с почином вас =) |
05.11.2008, 16:53 | #10
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
успешно добавил stl::map<int,int> |
05.11.2008, 17:59 | #11
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
провел познавательный тест на лимит операций
Код:
В переменной 42856 Код:
В переменной 33332 (красивое число =) Код:
Внешний(DLL) обьект типа STL::map<int,int> 24999 Код:
Внешний(DLL) обьект типа STL::map<int,string> 21427 (в этом случае добавляется приведение типа ссылка jString к const char * и, понятное дело, строка копируется и полностью хранится в памяти отведенной внешней dll Код:
В кеше 18749 NETRAT добавил: Рофл Код:
NETRAT добавил: отсюда вывод - физику нужно писать внешнюю =) |
06.11.2008, 14:27 | #12
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Van Damm
wait... what?
offline
Опыт:
22,268Активность: |
я догадывался =) в принципе, если делать вообще_все по уму, то вар будет использоваться только для вывода картинки |
06.11.2008, 14:55 | #13
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
мелькнула мыслишка приспособить шахматный ai с интерфейсом варкрафта =)
NETRAT добавил: варкрафт в качестве i/o |
06.11.2008, 16:34 | #14
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
J
expert
offline
Опыт:
48,747Активность: |
может вам просто написать игру с нуля и использовать в ней ресурсы варика? |
06.11.2008, 17:17 | #15
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
эх, жаль не удается оверрайдить функции работы с кешем... видать japi на такое не способен...
Jon это не спортивно, где дух компетишна?! рофл по лимиту операций стандартный кеш не отличается от внешнего обьекта типа map<string,*> (подозреваю что hashmap будет то же самое) NETRAT добавил: почитал сишные файлеги гримойра и rtc... молодцы ребята Отредактировано NETRAT, 06.11.2008 в 17:37. |
06.11.2008, 18:52 | #16
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
agentex
offline
Опыт:
34,534Активность: |
Цитата:
то есть как integer в кеше можно сохранить макс. 18749 число? |
|
06.11.2008, 19:00 | #17
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
нет, это значит что в одном потоке можно вызвать не более 18749 (+10 возможно) операций сохранения в кеш, после этого будет превышение лимита и поток принудительно завершится |
06.11.2008, 19:11 | #18
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
Toadcop
offline
Опыт:
53,013Активность: |
Цитата:
ну реально что тормознутое это... функции, для щастя надо бы было напрямую в юнита писать X\Y фейсинг и высоту полёта ^_^ |
|
06.11.2008, 20:47 | #19
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|
NETRAT
offline
Опыт:
83,762Активность: |
угу, в системке обрабатывать и каждые 0.04 секунды перерисовывать агейю туда впихнуть ^^ |
06.11.2008, 21:34 | #20
+0/−0
Профиль |
Приват |
Поиск |
IP: Записан
|