Добавлен , опубликован
Предназначение:
Версия игры: 1.26a
При помощи этой системы можно встроить в карту динамические библиотеки (Win32/DLL).
Это может помочь тем, кто не хочет писать сценарий карты на JASS, а предпочитает другие языки как: C, C++, Rust, Pascal... Если поднапрячься с загрузкой виртуальной машины, то можно использовать и языки вроде Python, Lua, Ruby, C#, Java.
Нет нужды просить игроков установить специальные лаунчеры — всё уже встроено в карту.

Работа системы

Сначала, предоставленный JASS-скрипт, используя уязвимости в виртуальной машине, выделяет исполняемую память и записывает туда мини-программу, которая распаковывает и загружает библиотеку "bin\Loader.dll", после чего вызывает её функцию "DoIt". Та же, в свою очередь, распаковывает и загружает библиотеки, перечисленные в списке "libraries" файла "config.json".
Когда игра собирается уничтожить главный поток JASS-скрипта, система выгружает все ранее загруженные библиотеки в обратном порядке и удаляет их файлы из временной директории.
Также чистка временного хранилища происходит при начале работы системы, на случай, если в прошлый раз мусор не был удален из-за нештатного завершения игры.
Поддерживается запуск множества экземпляров игры — у каждого процесса своё личное хранилище.
По завершению игры загрузчик остается в памяти, так как он не может выгрузить сам себя.
При запуске, система проверяет остался ли с прошлого раза висящий загрузчик и если обнаруживает такой, то выгружает его. Так что, они не будут накапливаться.

Установка

  • Скачайте архив и распакуйте куда-нибудь.
  • Импортируйте в карту "bin\Loader.dll" и "scripts\common.j".
  • Импортируйте в карту требуемые библиотеки.
  • Пропишите путь к своим библиотекам в "config.json" и импортируйте его тоже.
  • Скопируйте в карту код из "loader.j" (используется cjass).

Пример

Можете ознакомиться с моим примером:
  • pascal.w3x — карта со внедренными библиотеками.
  • ExampleSource.zip — исходники библиотеки со сценарием на FreePascal.
На карте создается толпа вражеских рабочих и один злой работник для вас.
Когда он смотрит на других, применяя свою способность, их разрывает в клочья.
Для работы с нативками используются JassAPI и RedirectCalls.

Генератор кода

В примере выше используется файл "jass_common_j.pas" сгенерированный на основе "common.j".
Прикладываю исходники генератора на python'е (зависит от funcparserlib) на случай, если кто-то захочет сгенерировать привязку для других языков.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
11
IceFog, в твоих исходниках Example\Natives.pas, есть две одинаковые константы
ITEM_TYPE_POWERUP: HITEMTYPE = 2;
ITEM_TYPE_TOME: HITEMTYPE = 2;
Это ошибка или нет?
Если посудить ITEM_TYPE один и тот же.
19
Этот файл автоматически сгенерирован на основе "common.j".
Отрывок из common.j
constant itemtype ITEM_TYPE_PERMANENT                   = ConvertItemType(0)
constant itemtype ITEM_TYPE_CHARGED                     = ConvertItemType(1)
constant itemtype ITEM_TYPE_POWERUP                     = ConvertItemType(2)
constant itemtype ITEM_TYPE_ARTIFACT                    = ConvertItemType(3)
constant itemtype ITEM_TYPE_PURCHASABLE                 = ConvertItemType(4)
constant itemtype ITEM_TYPE_CAMPAIGN                    = ConvertItemType(5)
constant itemtype ITEM_TYPE_MISCELLANEOUS               = ConvertItemType(6)
constant itemtype ITEM_TYPE_UNKNOWN                     = ConvertItemType(7)
constant itemtype ITEM_TYPE_ANY                         = ConvertItemType(8)
// Deprecated, should use ITEM_TYPE_POWERUP
constant itemtype ITEM_TYPE_TOME                        = ConvertItemType(2)
11
Интересно, но это будет работать с мультиплеерными картами?
19
Интересно, но это будет работать с мультиплеерными картами?
Разумеется, в этом и есть вся суть. Нет нужды просить всех игроков качать специальные лаунчеры, которые добавят новые возможности, карта сама распакует и загрузит DLL'ки.
Учтите, что данный ресурс использует старые версии JassAPI и RedirectCalls, так что, примеры из него не получится использовать с последними версиями.
19
Вышла новая версия! Прокрутить к ресурсу
  • Адаптировал к новым версиям JassAPI и RedirectCalls.
  • Больше деталей о работе системы.
  • Выложил исходники cJASS-скрипта и встроенной в него программы.
  • Упростил процесс установки.
  • Приложил генератор кода для нативок.
11
IceFog, можешь объяснить, как запустить только один экземпляр библиотеки при загрузке карты, как у тебя в Example.dll, чтобы не было дизсинхронизации, только на С++. Аналог твоего запуска библиотеки на паскале:
begin
	InitCamera;
	InitSpell;
	CreateAngryWorker;
	CreateMeat;
end.
Пробывал следующий код:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{	
	if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
	DisableThreadLibraryCalls(hModule);

	if (fRegistrJassApi() == FALSE) return TRUE;
	if (fRegistrNatives() == FALSE) return TRUE;
	HUNIT u;
	u = CreateUnit(GetLocalPlayer(),ID_UNIT_MAIN_HUMAN1,0,0,0);
	IssuePointOrder(u,"move",1000,1000);
	return TRUE;
}
Он запускается на обоих машинах. Как перевести с паскаля на С++ твой Example.dll?
19
Vampir_kolik, создание юнита для локального игрока вызовет десинк на любом языке.
На игровом клиенте красного игрока создается юнит, принадлежащий игроку красному, а на клиенте синего - синему. В итоге состояние мира отличается и они играют в разные игры.
В моём примере главный работник создается для красного игрока, а прочие для игроков 1-10.
Вижу, ты цитируешь старую версию исходников библиотеки со скриптом, советую скачать последнюю.
11
А, как работать с общими данными для всех машин на одной машине?
19
Библиотека с твоим скриптом загружается и исполняется паралельно у всех игроков.
Просто пиши код также, как ты делал это на JASS'е. Правила те же: все действия должны быть одинаковы на компьютерах всех игроков. Локально можно делать лишь некоторые, такие как смена цвета/размера юнита.
11
То есть основная база данных должна быть на JASS'e?
19
Хранить данные ты можешь где угодно и делать что захочешь до тех пор, пока состояние всех игровых клиентов одинаковое. И не важно, на C++ ты пишешь или же на JASS'е, в итоге, если ты сделал опасные изменения локально лишь у одного игрока, то его отсоединит от остальных.
Используй нативку GetLocalPlayer с осторожностью.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.