UoKit.com Форумы > Кликер > UO Pilot > Плагины и доп. ПО
Linker
Пример плагина на одном из самых простых языков - бейсике.
Код
Код
#CountFunct = 4; Число фукнций плагина.

Structure InitStruct
  FunctionCount.l
  Array FunctionNames.s(#CountFunct-1)
EndStructure

Structure ParamStruct
  WindowHandle.i
  WindowPID.i
  Reserved.i
  ParamString.s
  ParamStringOrig.s
  Result.s{1048576}
EndStructure

EnableExplicit; Обязательная декларация переменных.

Global InitStruct.InitStruct

ProcedureDLL InitPlugin(App, Scr, *Version.Double)
  
  With InitStruct
    If *Version\d >= 2.37
      \FunctionCount = #CountFunct
      \FunctionNames(0) = "Function1"; Имена экспортируемых фунукций плагина.
      \FunctionNames(1) = "Function2"
      \FunctionNames(2) = "Function3"
      \FunctionNames(3) = "Function4"
    Else
      \FunctionCount = 0;
      *Version\d = 2.37
    EndIf
  EndWith
  
  ProcedureReturn InitStruct
EndProcedure

ProcedureDLL Function1(*ParamStruct.ParamStruct)
  Protected r
  r=Val(StringField(*ParamStruct\ParamString, 1, ",")) + Val(StringField(*ParamStruct\ParamString, 2, ","))
  *ParamStruct\Result = "Param1 + Param2 = " + r
EndProcedure

ProcedureDLL Function2(*ParamStruct.ParamStruct)
  *ParamStruct\Result = "Выполнена функция 2"
EndProcedure

ProcedureDLL Function3(*ParamStruct.ParamStruct)
  *ParamStruct\Result = "Выполнена функция 3"
EndProcedure

ProcedureDLL Function4(*ParamStruct.ParamStruct)
  *ParamStruct\Result = "Выполнена функция 4"
EndProcedure

ProcedureDLL DonePlugin()
EndProcedure
Код довольно прост и основан на примере из справки.
Чтобы процедура была доступна вне dll ее нужно объявлять с DLL в конце ключевого слова, т. е. ProcedureDLL.
Первая фукнция (Function1) складывает числа переданные в 2 параметрах и возращает результат. Остальные только сообщают номер своей фукнции.

Для компиляции необходима среда программирвоания PureBasic версии не выше 5.24. В версиях новее
выпилен ascii (остался только юникод, который не поддерживает UO Pilot). Из-за чего код будет сложнее из-за необходимости конвертирования с ascii в unicode иобратно.
Скачать версию 5.24 https://www.upload.ee/files/14232929/PureBa...Win_x86.7z.html
Это portable версия и после распаковки архива готова к работе. Запускается с помощью PureBasic Portable.exe
В редактор кода нужно скопировать исходник dll и открыть окно настроек компилятора из меню Компилятор -> Настроки компилятора. В нем выбрать формт исполняемого файла "Shared dll". Настройки сохранятся в исходнике на текущей вкладке.
После скомпилировать dll через меню Компилятор -> Создать приложение.

Нажмите для просмотра прикрепленного файла

Тестовый скрипт
Код
Msg PB_Plug.Function1(2, 8)
Msg PB_Plug.Function2()
Msg PB_Plug.Function3()
Msg PB_Plug.Function4()
exit

Вверх
Cockney
Тут стоит оставить комментарий о том, что этот плагин будет работать со "старым" пилотом, до интеграции с луа. В новых версиях такой тип плагинов вряд-ли будет работать без проблем.

Для новых версий в плагинах можно не использовать InitStruct и ParamStruct, а писать напрямую как обычные функции:

Код

int func1(int a, int b) {
   return a + b;
}



А в самом пилоте нужно объявить эту функцию:

Код

ffi.cdef[[
    int func1(int a, int b);
]]


И далее использовать:

Код

local res = mylib.func1(10, 10)

Вверх
Linker
Цитата(Cockney @ 16.6.2022, 10:54)
В новых версиях такой тип плагинов вряд-ли будет работать без проблем.
Какие возможны проблемы?
Я не нашел описания плагинов. Единственное что есть это два кода (на Си и паскале) в uopilot без каких-либо пояснений и несколько обсуждений на этом форуме.
Нет никаких пояснений как передаются параметры в функцию и как возвращаются. Пришлось выяснять экспериментально.

Цитата(Cockney @ 16.6.2022, 10:54)
Для новых версий в плагинах можно не использовать InitStruct и ParamStruct, а писать напрямую как обычные функции
Судя по примерам где вызываются функции из системных dll винды, эти плагины ничем не отличаются от обычных dll. То есть это не специально написанные плагины для пилота.
Вверх
Cockney
Цитата(Linker @ 16.6.2022, 11:43)

Какие возможны проблемы?
Я не нашел описания плагинов. Единственное что есть это два кода (на Си и паскале) в uopilot без каких-либо пояснений и несколько обсуждений на этом форуме.
Нет никаких пояснений как передаются параметры в функцию и как возвращаются. Пришлось выяснять экспериментально.

Судя по примерам где вызываются функции из системных dll винды, эти плагины ничем не отличаются от обычных dll. То есть это не специально написанные плагины для пилота.


Код примеров на C и Паскале это пример старой системы плагинов, т.е. нормально она будет работать если используется только язык пилота, а если использовать язык lua, то уже вряд ли. Как минимум нужно специально обрабатывать структуры InitStruct, ParamStruct.

DLL которая использует InitStruct, ParamStruct по сути прибита гвоздями к пилоту. Вызвать в любом стороннем приложении ее будет проблемно (нужно обрабатывать InitStruct, ParamStruct).

В качестве референса оставлю ссылку на примет плагина на C# https://forum.uokit.com/index.php?showtopic=69767

Код там простой и, думаю, ответит на вопросы, если они возникнут. Ключевое, что там не используется InitStruct, а это дает возможность вызывать плагин не только из пилота без проблем.

Вверх
DarkMaster
Сейчас действительно проще линковать через ffi, т.к. там нет почти никаких ограничений. Если есть какие-то вопросы по части, как все это работает - спрашивайте, объянсим так подробно, насколько это необходимо.
Вверх
Linker
Цитата(Cockney @ 16.6.2022, 11:53)
В качестве референса оставлю ссылку на примет плагина на C#
C# создает библиотеку классов...
Создание процедурной требует сторонние инструменты и много лишнего в коде.
ИМХО так код выглядит проще
Код
Код
Structure ArrI
  i.i[0]
EndStructure

ProcedureDLL.s Hello(arg.s)
  Static r.s
  r = "Hello " + arg
  ProcedureReturn r
EndProcedure

ProcedureDLL RGB_Func(r, g, b)
  ProcedureReturn RGB(r, g, b)
EndProcedure

ProcedureDLL mymul(argc, *args.ArrI)
  r=1
  
  If *args
    For i=0 To argc-1
      r * *args\i[i]
    Next
  EndIf
  
  ProcedureReturn r
EndProcedure

ProcedureDLL fill(size, *mem.ArrI)
  
  For i=0 To size-1
    *mem\i[i] = Random($7FFFFFFF)
  Next
  
EndProcedure


Вверх
Cockney
Цитата(Linker @ 16.6.2022, 13:02)

C# создает библиотеку классов...
Создание процедурной требует сторонние инструменты и много лишнего в коде.
ИМХО так код выглядит проще
Код
Код
Structure ArrI
  i.i[0]
EndStructure

ProcedureDLL.s Hello(arg.s)
  Static r.s
  r = "Hello " + arg
  ProcedureReturn r
EndProcedure

ProcedureDLL RGB_Func(r, g, b)
  ProcedureReturn RGB(r, g, b)
EndProcedure

ProcedureDLL mymul(argc, *args.ArrI)
  r=1
  
  If *args
    For i=0 To argc-1
      r * *args\i[i]
    Next
  EndIf
  
  ProcedureReturn r
EndProcedure

ProcedureDLL fill(size, *mem.ArrI)
  
  For i=0 To size-1
    *mem\i[i] = Random($7FFFFFFF)
  Next
  
EndProcedure




Да хоть COM объектов. Это не меняет сути того что завязка на Init(Param)Struct не нужна больше, если не требуется совместимость со старыми версиями.
Вверх
Invision Power Board © 2001-2024 Invision Power Services, Inc.
Version for Pocket PC © 2006-2024, IPBest Studio.