Skip to content

Plugins ru RU

GitHub Action edited this page Nov 23, 2020 · 41 revisions

Плагины

Начиная с ASF V4, программа включает в себя поддержку пользовательских плагинов, которые могут загружаться в процессе выполнения. Плагины позволяют вам изменять поведение ASF, например добавляя дополнительные команды, новую логику принятия обменов или полную интеграцию со сторонними сервисами и API.


Для Пользователей

ASF загружает плагины из папки plugins расположенной в вашей папке с ASF. Рекомендованной практикой является поддержание отдельной папки для каждого плагина, который вы хотите использовать, она может иметь имя в соответствии с его названием, например MyPlugin. Это даст в результате структуру каталогов plugins/MyPlugin. Наконец, все двоичные файлы плагина следует положить в эту выделенную папку, и ASF обнаружит и начнёт использовать ваш плагин после перезапуска.

Обычно разработчики плагинов будут публиковать плагины в форме zip-файла, с уже подготовленной для вас структурой, так что вам будет достаточно распаковать этот zip-архив в папку plugins, что создаст необходимую папку автоматически.

Если плагин успешно загружен - вы увидите его название и версию в журнале ASF. В случае вопросов или проблем, связанных с используемым плагином, вам следует обратиться к разработчикам плагина.

Вы можете найти некоторые плагины в нашем разделе "Сторонние разработки".

Помните о том, что плагины ASF могут быть вредоносными. Вам всегда следует убедиться, что вы пользуетесь только теми плагинами, разработчикам которых вы можете доверять. Разработчики ASF не могут вам гарантировать обычных преимуществ ASF (как например отсутствие вирусов или гарантию отсутствия VAC) если вы решите использовать какие-либо пользовательские плагины. Мы также не можем поддерживать конфигурации с использованием пользовательских плагинов, поскольку вы больше не используете чистый код ASF.


Для разработчиков

Плагины это стандартные библиотеки .NET, унаследованные от общего интерфейса IPlugin в ASF. Вы можете разрабатывать плагины полностью независимо от развития основной ветки ASF, и повторно использовать их в текущей и будущей версиях ASF, до тех пор пока API остаётся совместимым. Система плагинов, используемая в ASF, основана на System.Composition, ранее известном как Managed Extensibility Framework, который позволяет ASF обнаруживать и загружать ваши библиотеки в процессе исполнения.


Начало работы

Ваш проект должен быть стандартной библиотекой .NET с целевой платформой соответствующей желаемой версии ASF, как описано в разделе "Компиляция". Мы рекомендуем целевую платформу .NET Core, но плагины могут быть и для .NET Framework.

Проект должен ссылаться на сборку ArchiSteamFarm, либо в виде собранной библиотеки ArchiSteamFarm.dll которую вы скачиваете как часть выпуска, либо в виде исходного проекта (например если вы добавили дерево ASF в качестве под-модуля). Это позволит вам получить доступ к структурам, методам и свойствам ASF, в особенностью к ядру интерфейса IPlugin, которое вам понадобится на следующем этапе. Проект также должен иметь ссылку как минимум на System.Composition.AttributedModel, что позволит вам сделать [Export] вашего IPlugin для использования в ASF. В добавок к этому, вам может захотеться/понадобиться сослаться на другие общие библиотеки с целью интерпретировать структуры данных, которые вам предоставлены в некоторых интерфейсах, но если они не являются необходимыми - этого будет пока достаточно.

Если вы сделали всё правильно, ваш файл csproj будет иметь примерно такой вид:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" Version="*" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="ArchiSteamFarm">
      <HintPath>C:\\Path\To\Downloaded\ArchiSteamFarm.dll</HintPath>
    </Reference>

    <!-- If building as part of ASF source tree, use this instead of <Reference> above -->
    <!-- <ProjectReference Include="C:\\Path\To\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" /> -->
  </ItemGroup>
</Project>

С точки зрения кода, класс вашего плагина должен быть унаследован от интерфейса IPlugin (либо напрямую, либо косвенно через наследование одного из специализированных интерфейсов, как например IASF) и иметь аттрибут [Export(typeof(IPlugin))] чтобы быть распознанным ASF в процессе работы. Самый простой пример реализации всего этого будет следующим:

using System;
using System.Composition;
using ArchiSteamFarm;
using ArchiSteamFarm.Plugins;

namespace YourNamespace.YourPluginName {
    [Export(typeof(IPlugin))]
    public sealed class YourPluginName : IPlugin {
        public string Name => nameof(YourPluginName);
        public Version Version => typeof(YourPluginName).Assembly.GetName().Version;

        public void OnLoaded() {
            ASF.ArchiLogger.LogGenericInfo("Meow");
        }
    }
}

Чтобы воспользоваться вашим плагином, его надо сначала скомпилировать. Вы можете сделать это либо из своей IDE, или из корневой папки вашего проекта с помощью команды:

# Если у вас самостоятельный проект (нет нужды указывать имя, поскольку оно только одно)
dotnet publish -c "Release" -o "out"

# Если ваш проект часть дерева ASF (чтобы избежать компиляции необязательных частей)
dotnet publish YourPluginName -c "Release" -o "out"

После этого, ваш плагин готов к развертыванию. Как именно вы хотите распространять и публиковать ваш плагин - решать вам, но мы рекомендуем создать zip-архив c единственной папкой YourNamespace.YourPluginName, внутри которой находится ваш скомпилированный плагин вместе со всеми зависимостями. Таким образом пользователю нужно будет просто распаковать ваш zip-архив в его папку plugins, и ничего более.

Это самый простой сценарий, просто чтобы помочь вам начать. У нас также есть проект ExamplePlugin который представляет собой пример интерфейсов и действий, которые вы можете использовать в своём плагине, включая полезные комментарии. Не стесняйтесь заглянуть туда, если предпочитаете учиться по работающему коду, или сами изучите пространство имён ArchiSteamFarm.Plugins и обратитесь ко встроенной документации чтобы узнать все доступные возможности.


Доступность API

ASF, помимо того к чему вы имеете доступ через сами интерфейсы, открывает вам множество своих внутренних API, которые вы можете использовать для расширения функционала. Например, если вы хотите отправить новый вид веб-запроса к Steam, вам не нужно изобретать всё с нуля, особенно решение всех тех проблем, с которыми мы столкнулись раньше вас. Просто используйте наш Bot.ArchiWebHandler, который предоставит вам возможность использовать множество методов UrlWithSession(), и возьмёт на себя обработку всех низкоуровневых задач, таких как аутентификация, обновление сессии или ограничение частоты запросов. Аналогично, для отправки веб-запросов за пределами платформы Steam, вы можете использовать стандартный класс .NET HttpClient, но гораздо лучшей идеей будет использовать доступный вам Bot.ArchiWebHandler.WebBrowser, который, опять же, предоставит вам свою помощь, например в части повторных запросов в случае неудачи.

У нас очень открытая политика относительно доступности нашего API, поэтому если вы хотели бы использовать что-то, что ASF уже включает в себя, просто откройте issue и объясните в нём планируемое использование наших внутренних API ASF. Мы скорее всего не будем иметь ничего против, если предполагаемое вами использование имеет смысл. Для нас просто невозможно открыть всё, что кто-то может захотеть использовать, поэтому мы открыли только то, что кажется нам осмысленным, и ожидаем ваших запросов в случае если вы хотите получить доступ к чему-то, что ещё не public. Это включает в себя также все предложения по поводу новых интерфейсов IPlugin, которые имеет смысл добавить чтобы расширить существующий функционал.

Фактически, внутренние API ASF это единственное реальное ограничение того, что может делать ваш плагин. Ничто не остановит вас, например, если вы добавите в своё приложение библиотеку Discord.Net и создадите мост между вашим Discord-ботом и командами ASF, поскольку ваш плагин может иметь свои собственные зависимости. Возможности безграничны, и мы изо всех сил старались дать вам максимум свободы и гибкости в вашем плагине, поэтому нет никаких искусственных ограничений на что-либо, просто мы не до конца уверены, какие части ASF необходимы вам для разработки плагинов (и это можно решить просто дав нам знать, или даже без этого вы всегда можете воссоздать необходимый функционал).


Совместимость API

Важно подчеркнуть, что ASF это пользовательское приложение, а не обычная библиотека с фиксированными API, на которых можно безусловно основываться. Это означает что вы не можете предположить что ваш плагин, будучи однажды скомпилирован, продолжит работать также и во всех будущих выпусках ASF, это сделало бы невозможным дальнейшее развитие программы, а невозможность адаптироваться к постоянным изменениям в Steam ради обратной совместимости в нашем случае недопустима. Это должно быть для вас логичным, но важно подчеркнуть этот факт.

Мы будем стараться поддерживать общедоступные части ASF стабильными и работающими, но мы не будем себя сдерживать если возникнет необходимость поломать совместимость, и при этом мы будем следовать нашей политике устаревания. Это в особенности касается внутренних структур ASF, которые доступны вам как часть инфраструктуры ASF, описанной выше (например, ArchiWebHandler), которые могут быть улучшены (и потому переписаны) как часть улучшений ASF в одной из будущих версий. Мы будем стараться информировать об устаревшем функционале в списке изменений, и выдавать соответствующие предупреждения в процессе работы. У нас нет цели переписывать всё подряд только ради того чтобы переписать, так что вы можете быть относительно уверены в том, что следующая минорная версия не сломает полностью ваш плагин только потому, что увеличился номер версии, но вам стоит следить за списками изменений и периодически проверять, что всё работает.


Зависимости плагинов

Ваш плагин будет включать в себя по умолчанию как минимум две зависимости, ссылку на ArchiSteamFarm для внутренних API и PackageReference из System.Composition.AttributedModel, что необходимо чтобы ASF мог распознать ваш плагин. В добавок к этому, он может иметь больше зависимостей, если они нужны для того, что вы решили реализовать в своём плагине (например, библиотеку Discord.Net если вы решили сделать интеграцию с Discord).

The output of your build will include your core YourPluginName.dll library, as well as all the dependencies that you've referenced. Since you're developing a plugin to already-working program, you don't have to, and even shouldn't include dependencies that ASF already includes, for example ArchiSteamFarm, SteamKit2 or Newtonsoft.Json. Удаление из вашей сборки всех зависимостей, общих с ASF, не является обязательным требованием для работы плагина, но это существенно уменьшит потребляемую память и размер вашего плагина, а также увеличит быстродействие, благодаря тому что ASF будет разделять свои зависимости с вами, и будет загружать только те библиотеки, о которых ему неизвестно.

In general, it's a recommended practice to include only those libraries that ASF either doesn't include, or includes in the wrong/incompatible version. Examples of those would be obviously YourPluginName.dll, but for example also Discord.Net.dll if you decided to depend on it, as ASF doesn't include it itself. Bundling libraries that are shared with ASF can still make sense if you want to ensure API compatibility (e.g. being sure that Newtonsoft.Json which you depend on in your plugin will always be in version X and not the one that ASF ships with), but obviously doing that comes for a price of increased memory/size and worse performance, and therefore should be carefully evaluated.

If you know that the dependency which you need is included in ASF, you can mark it with IncludeAssets="compile" as we showed you in the example csproj above. This will tell the compiler to avoid publishing referenced library itself, as ASF already includes that one. Likewise, notice that we reference the ASF project with ExcludeAssets="all" Private="false" which works in a very similar way - telling the compiler to not produce any ASF files (as the user already has them). This applies only when referencing ASF project, since if you reference a dll library, then you're not producing ASF files as part of your plugin.

Если из-за вышесказанного вы запутались, и не знаете что делать, проверьте, какие dll-библиотеки включены в пакете ASF-generic.zip, и убедитесь что ваш плагин включает в себя только те библиотеки, которых там нет. В случае самых простых плагинов это будет только YourPluginName.dll. Если у вас при выполнении возникнут проблемы с какими-то библиотеками, включите в пакет также эти библиотеки. Если ничего не работает - вы всегда можете решить добавить в пакет вообще все зависимости.


Платформо-специфичные зависимости

Платформо-специфичные зависимости создаются как часть сборок для конкретных ОС, поскольку на целевой машине отсутствует среда исполнения .NET Core, и ASF работает через собственную среду исполнения .NET Core, включенную в состав сборки под данную ОС. С целью минимизировать размер сборки, ASF урезает все платформо-специфичные зависимости, чтобы они включали в себя только тот код, которому может реально быть передано управление в процессе работы программы, что по сути отрезает все неиспользуемые части среды исполнения. Это может создать вам потенциальные проблемы с вашим плагином, в ситуации если ваш плагин зависит от какого-то функционала .NET Core, который не используется в ASF, и поэтому сборка под конкретную ОС не может его запустить.

Вы никогда не столкнётесь с этой проблемой в универсальной сборкой, потому что они никогда не имеют платформо-специфичных зависимостей (поскольку в этом случае для запуска ASF на целевой машине должна быть работоспособная среда исполнения). Поэтому использование вашего плагина исключительно на универсальных сборках автоматически решает проблему, но очевидным недостатком будет невозможность использовать ваш плагин у пользователей, которые используют сборки ASF под конкретную ОС. Если вы сомневаетесь, что ваша проблема связана с платформо-специфичными зависимостями - вы можете также использовать этот метод для проверки, загрузив ваш плагин в универсальную сборку ASF и посмотрев, решит ли это проблему. Если проблема пропала, то с зависимостями плагина всё в порядке, и вам нужно поработать только над платформо-специфичными зависимостями.

Решением данной проблемы, аналогично обычным зависимостям, будет опять же включение в состав плагина зависимостей, которые в ASF отсутствуют или имеют неправильную/неполную (например урезанную) версию. По сравнению с зависимости плагинов, вы не можете знать заранее, достаточно ли вам урезанной версии платформо-специфичной зависимости ASF или нет, поэтому вы либо идёте по простому пути, и включаете в пакет с плагином всё подряд, или же по сложному пути, и вручную проверяете, каких частей не хватает в ASF и включаете только эти части. Чтобы получить необходимые зависимости вам понадобиться сначала вручную скомпилировать ASF в необходимом варианте под конкретную ОС (без урезания функций), а затем скопировать необходимые для работы вашего плагина файлы.

Это также означает, что вам может понадобится делать отдельную сборку вашего плагина под каждый вариант ASF, поскольку в сборках под разные ОС может отсутствовать различный функционал, который вам нужно предоставить, и ваш универсальный плагин не может предоставить их все. Это в большой степени зависит от того, что именно делает ваш плагин, и какие у него зависимости, поскольку очень простые плагины, основанные исключительно на функциях ASF будут гарантировано работать во всех вариантах, поскольку они не вносят никаких собственных зависимостей, и все платформно-специфичные зависимости будут покрыты. Более сложные плагины (особенно те, у которых есть собственные зависимости) могут потребовать дополнительных мер с целью убедится, что им действительно доступны все необходимые части кода, не только высокоуровневые зависимости плагина (описанные в разделе выше), но и низкоуровневые платформо-специфичные зависимости. Если всё остальное не помогло, то, как и в случае выше, вы всегда можете скомпилировать ваш плагин в варианте под используемую конкретную ОС, а затем объединить все сгенерированные завимости с теми, которые сгенерированы при сборке ASF для варианта под ту же ОС.

ASF's OS-specific builds include the bare minimum of additional functionality which is required to run our official plugins. Apart of that being possible, this also slightly extends the surface to extra dependencies required for the most basic plugins. Therefore not all plugins will need to worry about native dependencies to begin with - only those that go beyond what ASF and our official plugins directly need. This is done as an extra, since if we need to include additional native dependencies ourselves for our own use cases anyway, we can as well ship them directly with ASF, making them available, and therefore easier to cover, also for you.

Clone this wiki locally