Skip to content

Plugins ru RU

ArchiBot edited this page Nov 21, 2021 · 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 обнаруживать и загружать ваши библиотеки в процессе исполнения.


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

Мы подготовили для вас ** ASF-PluginTemplate **, который вы можете использовать в качестве шаблона для вашего проекта плагина. Использование шаблона не является обязательным (так как вы можете делать все с нуля), но мы настоятельно рекомендуем взять его в руки, поскольку он может ускорить вашу разработку и сократить время, необходимое для реализации правильной работы. Просто ознакомьтесь с ** README ** шаблона, и он поможет вам в дальнейшем. Тем не менее, мы рассмотрим основы ниже, если вы хотите начать с нуля или лучше понять концепции, используемые в шаблоне плагина.

Ваш проект должен быть стандартной библиотекой .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>net6.0</TargetFramework>
  </PropertyGroup>

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

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

    <!-- 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 и обратитесь ко встроенной документации чтобы узнать все доступные возможности.

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


Доступность 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).

Результат вашей сборки будет включать в себя вашу основную библиотеку YourPluginName.dll, а также все зависимости, на которые вы ссылаетесь. Поскольку вы разрабатываете плагин для уже работающей программы, вам нет необходимости, и даже не следует включать в пакет зависимости, которые уже присутствуют в ASF, например ArchiSteamFarm, SteamKit2 или Newtonsoft.Json. Удаление из вашей сборки всех зависимостей, общих с ASF, не является обязательным требованием для работы плагина, но это существенно уменьшит потребляемую память и размер вашего плагина, а также увеличит быстродействие, благодаря тому что ASF будет разделять свои зависимости с вами, и будет загружать только те библиотеки, о которых ему неизвестно.

В общем случае, рекомендуется включать в ваш плагин только те библиотеки, которые ASF либо не включает в себя, либо включает в неподходящей/несовместимой версии. Примером таких будут, очевидно, YourPluginName.dll, и, например, Discord.Net.dll если вы решите добавить такую зависимость, поскольку ASF её не включает. Сборка библиотек, общих с ASF, всё же может иметь смысл, если вы хотите обеспечить совместимость API (например, гарантировать что Newtonsoft.Json, от которого зависит ваш плагин, будет всегда в версии X, а не в той, с которой поставляется ASF), но очевидно что ценой за это будет увеличение памяти/размера на диске и ухудшение производительности, поэтому следует тщательно оценивать такую необходимость.

Если вы знаете, что нужная вам зависимость уже включена в ASF, вы можете отметить это с помощью IncludeAssets="compile", как показано на примере csproj выше. Это укажет компилятору не включать при публикации саму библиотеку, поскольку она уже включена в ASF. Аналогично, обратите внимание, что мы ссылаемся на проект ASF с параметрами ExcludeAssets="all" Private="false", что работает похожим образом - указывает компилятору не создавать файлов ASF (поскольку они уже есть у пользователя). Это применимо только к ссылке на проект ASF, поскольку если вы ссылаетесь на библиотеку в формате dll, вы не производите файлы ASF как часть вашего плагина.

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


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

Native dependencies are generated as part of OS-specific builds, as there is no .NET runtime available on the host and ASF is running through its own .NET runtime that is bundled as part of OS-specific build. С целью минимизировать размер сборки, ASF урезает все платформо-специфичные зависимости, чтобы они включали в себя только тот код, которому может реально быть передано управление в процессе работы программы, что по сути отрезает все неиспользуемые части среды исполнения. This can create a potential problem for you in regards to your plugin, if suddenly you find out yourself in a situation where your plugin depends on some .NET feature that isn't being used in ASF, and therefore OS-specific builds can't execute it properly, usually throwing System.MissingMethodException or System.Reflection.ReflectionTypeLoadException in the process.

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

К сожалению, нам пришлось сделать трудный выбор между публикацией всей среды исполнения в составе сборок под конкретную ОС и урезанием ненужных функций, что делает сборку на более чем 50 МБ меньше по сравнению с полной. Мы выбрали второй вариант, и к сожалению невозможно включить в ваш плагин недостающие в среде исполнения функции. Если ваш проект требует доступ к функциям среды исполнения, которые не были включены в сборку под конкретную ОС, вам придётся использовать полную среду исполнения .NET, а это значит что ваш плагин придётся запускать с ASF в варианте generic. You can't run your plugin in OS-specific builds, as those builds are simply missing a runtime feature that you need, and .NET runtime as of now is unable to "merge" native dependency that you could've provided with our own. Возможно в будущем такая возможность появится, но сейчас это невозможно.

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

Clone this wiki locally