-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Plugins development it IT
ASF include il supporto per plugin personalizzati che possono essere caricati durante l'esecuzione. I plugin consentono di personalizzare il comportamento di ASF, ad esempio aggiungendo comandi personalizzati, una logica di trading personalizzata o una completa integrazione con servizi e API di terze parti.
Questa pagina descrive i plugin ASF dal punto di vista degli sviluppatori - creare, mantenere, pubblicare e allo stesso modo. Se vuoi vedere la prospettiva dell'utente, muovi here invece.
I plugin sono librerie .NET standard che definiscono una classe ereditaria dall'interfaccia IPlugin
comune dichiarata in ASF. Γ possibile sviluppare plugin completamente indipendentemente dalla linea principale ASF e riutilizzarli nelle versioni attuali e future di ASF, finchΓ© l'API interna di ASF rimane compatibile. Il sistema plugin utilizzato in ASF Γ¨ basato su System. omposition
, precedentemente noto come Managed Extensibility Framework che permette a ASF di scoprire e caricare le tue librerie durante il runtime.
Abbiamo preparato ASF-PluginTemplate per te, che puoi (e dovresti usare) come base per il tuo progetto di plugin. L'utilizzo del template Γ¨ non un requisito (poichΓ© puoi fare tutto da zero), ma raccomandiamo fortemente di prenderlo in quanto puΓ² dare un impulso drastico al vostro sviluppo e tagliare il tempo necessario per ottenere tutte le cose bene. Basta controllare il README del modello e ti guiderΓ ulteriormente. Indipendentemente da ciΓ², copriremo le basi sottostanti nel caso in cui volessi partire da zero, o capire meglio i concetti utilizzati nel modello di plugin - in genere non Γ¨ necessario fare uno di questi se hai deciso di utilizzare il nostro modello di plugin.
Il tuo progetto dovrebbe essere uno standard . La libreria ET che mira ad un framework appropriato della versione di ASF di destinazione, come specificato nella sezione compilation.
Il progetto deve fare riferimento all'assemblaggio principale ArchiSteamFarm
, o al suo ArchiSteamFarm. la libreria ll
che hai scaricato come parte del rilascio, o il progetto sorgente (ad esempio, se hai deciso di aggiungere l'albero ASF come sottomodulo). Questo vi permetterΓ di accedere e scoprire le strutture, i metodi e le proprietΓ di ASF, specialmente l'interfaccia IPlugin
core da cui dovrai ereditare nel passo successivo. Il progetto deve anche fare riferimento a System.Composition.AttributedModel
al minimo, che ti permette di [Export]
il tuo IPlugin
per ASF da usare. Oltre a ciΓ², potresti volere/avere bisogno di fare riferimento ad altre librerie comuni per interpretare le strutture di dati che ti sono date in alcune interfacce, ma a meno che non ne abbiate bisogno esplicitamente, sarΓ sufficiente per ora.
Se hai fatto tutto correttamente, il tuo csproj
sarΓ simile a sotto:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.</TargetFramework>
</PropertyGroup>
<ItemGroup>
<! - Dal momento che stai caricando il plugin nel processo ASF, che include giΓ questa dipendenza, IncludeAssets="compile" ti permette di omettere dall'output finale -->
<PackageReference Include="System.Composition.AttributedModel" IncludeAssets="compile" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="C:\\Path\To\ArchiSteamFarm\ArchiSteamFarm.csproj" ExcludeAssets="all" Private="false" />
<! - Se si costruisce con DLL scaricato binario, utilizzare questo invece di <ProjectReference> sopra -->
<! - <Reference Include="ArchiSteamFarm" HintPath="C:\\Path\To\Downloaded\ArchiSteamFarm.dll" /> -->
</ItemGroup>
</Project>
Dal lato del codice, la classe plugin deve ereditare dall'interfaccia IPlugin
(esplicitamente, o implicitamente ereditando da un'interfaccia piΓΉ specializzata, come IASF
) e [Export(typeof(IPlugin)]
per essere riconosciuti da ASF durante il runtime. L'esempio piΓΉ nudo che ottiene sarebbe il seguente:
usando System;
usando System.Composition;
usando System.Threading.Tasks;
usando ArchiSteamFarm;
usando ArchiSteamFarm.Plugins;
namespace YourNamespace. ourPluginName;
[Export(typeof(IPlugin))]
public sealed class YourPluginName : IPlugin {
<unk> public string Name => nameof(YourPluginName);
<unk> public Version Version => typeof(YourPluginName). ssembly.GetName().Version;
<unk> public Task OnLoaded() {
<unk> <unk> ASF.ArchiLogger.LogGenericInfo("Ciao Mondo!");
<unk> <unk> return Task.CompletedTask;
<unk> }
}
Al fine di utilizzare il plugin, Γ¨ necessario in primo luogo compilarlo. Puoi farlo dal tuo IDE, o dalla directory radice del tuo progetto tramite un comando:
# Se il tuo progetto Γ¨ autonomo (non Γ¨ necessario definire il suo nome poichΓ© Γ¨ l'unico) dotnet
pubblica -c "Rilascio" -o "out"
# Se il tuo progetto fa parte dell'albero sorgente di ASF (per evitare di compilare parti non necessarie)
dotnet pubblica YourPluginName -c "Rilascio" -o "out"
In seguito, il plugin Γ¨ pronto per l'implementazione. Sta a te come esattamente vuoi distribuire e pubblicare il tuo plugin, ma raccomandiamo di creare un archivio zip dove metterai il plugin compilato insieme alla sua dependencies. In questo modo l'utente avrΓ semplicemente bisogno di scompattare il tuo archivio zip in una sottodirectory standalone all'interno della loro directory plugins
e non fare altro.
Questo Γ¨ solo lo scenario piΓΉ basilare per iniziare. Abbiamo un progetto EsempioPlugin
che mostra interfacce e azioni di esempio che puoi fare all'interno del tuo plugin, inclusi commenti utili. Sentitevi liberi di dare un'occhiata se si desidera imparare da un codice di lavoro, o scoprire ArchiSteamFarm. namespace di lugins
e fai riferimento alla documentazione inclusa per tutte le opzioni disponibili. Inoltre approfondiremo ulteriormente alcuni concetti fondamentali qui sotto per spiegarli meglio.
Se invece del plugin di esempio si desidera imparare dai progetti reali, ci sono diversi plugin ufficiali sviluppati da noi, ad es. ItemsMatcher
, MobileAuthenticator
o SteamTokenDumper
. Oltre a ciΓ², ci sono anche plugin sviluppati da altri sviluppatori, nella nostra sezione third-party.
ASF, a parte quello a cui si ha accesso nelle interfacce stesse, espone a Lei un sacco di sue API interne che Lei puΓ² fare uso di, al fine di estendere la funzionalitΓ . Ad esempio, se si desidera inviare una sorta di nuova richiesta a Steam web, allora non Γ¨ necessario implementare tutto da zero, in particolare affrontando tutti i problemi che abbiamo dovuto affrontare prima di te. Basta usare il nostro Bot. rchiWebHandler
che giΓ espone molti metodi UrlWithSession()
da usare, gestire tutte le cose di livello inferiore come l'autenticazione, l'aggiornamento della sessione o la limitazione web per voi. Allo stesso modo, per l'invio di richieste web al di fuori della piattaforma Steam, Γ¨ possibile utilizzare la classe standard .NET HttpClient
, ma Γ¨ molto meglio utilizzare Bot. rchiWebHandler.WebBrowser
che Γ¨ disponibile per voi, che ancora una volta vi offre una mano utile, per esempio per quanto riguarda la riprovazione delle richieste fallite.
Abbiamo una politica molto aperta in termini di disponibilitΓ delle API, quindi se vuoi fare uso di qualcosa che il codice ASF giΓ include, semplicemente apri un problema e spieghi in esso il tuo caso di utilizzo previsto dell'API interna del nostro ASF. Molto probabilmente non avremo nulla contro, finchΓ© il tuo caso di utilizzo ha senso. Questo include anche tutti i suggerimenti per quanto riguarda le nuove interfacce IPlugin
che potrebbero avere senso da aggiungere al fine di estendere le funzionalitΓ esistenti.
Indipendentemente dalla disponibilitΓ di ASF API, tuttavia, nulla ti impedisce di includere, ad esempio, Discord. et
libreria nella tua applicazione e creazione di un ponte tra il tuo bot Discord e i comandi ASF, dal momento che il plugin puΓ² anche avere dipendenze da solo. Le possibilitΓ sono infinite e abbiamo fatto del nostro meglio per darvi la massima libertΓ e flessibilitΓ possibile all'interno del vostro plugin, quindi non ci sono limiti artificiali su nulla - il vostro plugin Γ¨ caricato nel processo principale di ASF e puΓ² fare tutto ciΓ² che Γ¨ realisticamente possibile da fare all'interno del codice C# .
Γ importante sottolineare che ASF Γ¨ un'applicazione di consumo e non una tipica libreria con superficie API fissa che si puΓ² dipendere incondizionatamente. CiΓ² significa che non si puΓ² presumere che il plugin una volta compilato continuerΓ a lavorare con tutte le versioni future di ASF indipendentemente da ciΓ², Γ¨ semplicemente impossibile se vogliamo continuare a sviluppare ulteriormente il programma, e non essere in grado di adattarsi alle continue modifiche di Steam per motivi di retrocompatibilitΓ non Γ¨ proprio appropriato per il nostro caso. Questo dovrebbe essere logico per voi, ma Γ¨ importante evidenziare questo fatto.
Faremo del nostro meglio per mantenere le parti pubbliche di ASF funzionanti e stabili, ma non avremo paura di rompere la compatibilitΓ se ci sono ragioni sufficienti, seguendo la nostra politica deprecation nel processo. CiΓ² Γ¨ particolarmente importante per quanto riguarda le strutture interne di ASF che sono esposte a voi come parte dell'infrastruttura di ASF (ad es. ArchiWebHandler
) che potrebbe essere migliorato (e quindi riscritto) come parte di miglioramenti di ASF in una delle versioni future. Faremo del nostro meglio per informarti in modo appropriato nei changelog, e includeremo avvisi appropriati durante il runtime sulle funzionalità obsolete. Non intendiamo riscrivere tutto per riscriverlo, così si può essere abbastanza sicuri che la prossima versione minore di ASF non solo distruggere il plugin interamente perché ha un numero di versione superiore, ma tenere d'occhio i cambi e la verifica occasionale se tutto funziona bene è una buona idea.
Il tuo plugin includerΓ almeno due dipendenze per impostazione predefinita, il riferimento ArchiSteamFarm
per le API interne (IPlugin
al minimo) e PackageReference
di System. omposition.AttributedModel
che Γ¨ necessario per essere riconosciuto come plugin ASF per iniziare con ([Export]
clause). In aggiunta a questo, puΓ² includere piΓΉ dipendenze per quanto riguarda ciΓ² che avete deciso di fare nel vostro plugin (e. . Libreria Discord.Net
se hai deciso di integrarti con Discord).
L'output della tua build includerΓ la tua libreria YourPluginName.dll
, così come tutte le dipendenze che hai menzionato. Dal momento che stai sviluppando un plugin per il programma già funzionante, non è necessario, e anche dovrebbe includere dipendenze che ASF già include, per esempio ArchiSteamFarm
, SteamKit2
o AngleSharp
. Eliminare le dipendenze di build off condivise con ASF non è il requisito assoluto per il vostro plugin di lavorare, ma così facendo taglierà drasticamente l'impronta di memoria e la dimensione del plugin, insieme all'aumento delle prestazioni, a causa del fatto che ASF condividerà con te le proprie dipendenze, e caricherà solo quelle librerie che non sa di sé.
In generale, Γ¨ una pratica consigliata per includere solo quelle librerie che ASF non include, o include nella versione sbagliata/incompatibile. Esempi di questi sarebbero ovviamente YourPluginName.dll
, ma per esempio anche Discord.Net.dll
se hai deciso di dipendere da esso, poichΓ© ASF non lo include da solo. Le librerie di raggruppamento che sono condivise con ASF possono comunque avere senso se si desidera garantire la compatibilitΓ API (ad es. essere sicuri che AngleSharp
da cui dipende nel tuo plugin sarΓ sempre nella versione X
e non quella con cui ASF viene spedita), ma ovviamente ciΓ² avviene a un prezzo di maggiore memoria/dimensione e prestazioni peggiori, e quindi dovrebbe essere attentamente valutato.
Se sai che la dipendenza di cui hai bisogno Γ¨ inclusa in ASF, puoi contrassegnarlo con IncludeAssets="compile"
come ti abbiamo mostrato nell'esempio csproj
sopra. Questo dirΓ al compilatore di evitare di pubblicare la libreria di riferimento stessa, come ASF giΓ include quella. Allo stesso modo, nota che facciamo riferimento al progetto ASF con ExcludeAssets="all" Private="false"
che funziona in modo molto simile - dicendo al compilatore di non produrre alcun file ASF (come l'utente li ha giΓ ). Questo si applica solo quando si fa riferimento al progetto ASF, poichΓ© se si fa riferimento a una libreria dll
, allora non si producono file ASF come parte del plugin.
Se sei confuso con la dichiarazione di cui sopra e non sai meglio, controlla quali librerie dll
sono incluse in ASF-generic. pacchetto ip
e assicurati che il tuo plugin includa solo quelli che ancora non ne fanno parte. Questo sarΓ solo YourPluginName.dll
per i plugin piΓΉ semplici. Se si ottengono problemi durante il runtime per quanto riguarda alcune librerie, includere quelle colpite librerie pure. Se tutto il resto fallisce, si puΓ² sempre decidere di raggruppare tutto.
Le dipendenze native sono generate come parte di build specifiche per OS, in quanto non c'Γ¨ . ET runtime disponibile sull'host e ASF Γ¨ in esecuzione attraverso il proprio .NET runtime che viene raggruppato come parte di OS specifica costruzione. Al fine di ridurre al minimo la dimensione di generazione, ASF trims le sue dipendenze native per includere solo il codice che puΓ² essere raggiunto all'interno del programma, che taglia effettivamente le parti inutilizzate del runtime. Questo puΓ² creare un potenziale problema per voi per quanto riguarda il plugin, se improvvisamente scoprite voi stessi in una situazione in cui il vostro plugin dipende da alcuni. La funzione ET che non Γ¨ utilizzata in ASF, e quindi le build specifiche per il sistema operativo non possono eseguire correttamente, di solito lanciando System.MissingMethodException
o System.Reflection.ReflectionTypeLoadException
nel processo. Man mano che il vostro plugin cresce di dimensioni e diventa sempre piΓΉ complesso, prima o poi colpirai la superficie che non Γ¨ coperta dal nostro sistema operativo specifico.
Questo non Γ¨ mai un problema con le build generiche, perchΓ© non hanno mai a che fare con dipendenze native in primo luogo (come hanno tempo di lavoro completo sull'host, eseguendo ASF). Questo Γ¨ il motivo per cui Γ¨ una pratica consigliabile utilizzare il plugin in generici build esclusivamente, ma ovviamente che ha il proprio lato negativo di tagliare il plugin da utenti che stanno eseguendo build OS-specific di ASF. Se ti stai chiedendo se il tuo problema Γ¨ correlato alle dipendenze native, Γ¨ anche possibile utilizzare questo metodo per la verifica, caricare il plugin in ASF generico build e vedere se funziona. Se lo fa, hai coperto le dipendenze dei plugin, ed Γ¨ la dipendenza nativa che causa problemi.
Purtroppo, abbiamo dovuto fare una scelta difficile tra la pubblicazione intera come parte delle nostre costruzioni specifiche del sistema operativo, e decidere di tagliarlo fuori dalle funzioni inutilizzate, rendendo la costruzione di oltre 80 MB piΓΉ piccolo rispetto a quella piena. Abbiamo scelto la seconda opzione, ed Γ¨ purtroppo impossibile per voi includere le funzioni di runtime mancanti insieme al vostro plugin. Se il progetto richiede l'accesso alle funzionalitΓ di runtime che vengono lasciate, Γ¨ necessario includere completo. ET runtime su cui si dipende e questo significa eseguire il plugin in generic
ASF flavour. Non Γ¨ possibile eseguire il plugin nelle build specifiche del sistema operativo, in quanto quelle build sono semplicemente mancanti una funzione di runtime di cui hai bisogno, e . Il runtime ET a partire da ora non Γ¨ in grado di "unire" la dipendenza nativa che si poteva fornire con la nostra. Forse migliorerΓ un giorno in futuro, ma a partire da ora semplicemente non Γ¨ possibile.
Le build specifiche per il sistema operativo di ASF includono il minimo nudo di funzionalitΓ aggiuntive necessarie per eseguire i nostri plugin ufficiali. A parte quello che Γ¨ possibile, questo anche leggermente estende la superficie alle dipendenze extra richieste per i plugin piΓΉ di base. Pertanto non tutti i plugin dovranno preoccuparsi di dipendenze native per cominciare - solo quelli che vanno oltre ciΓ² che ASF e i nostri plugin ufficiali hanno bisogno direttamente. Questo Γ¨ fatto come un extra, poichΓ© se abbiamo bisogno di includere ulteriori dipendenze native noi stessi per i nostri casi di uso proprio, possiamo anche spedirli direttamente con ASF, rendendoli disponibili, e quindi piΓΉ facile da coprire, anche per voi. Purtroppo, questo non Γ¨ sempre sufficiente, e come il plugin diventa piΓΉ grande e piΓΉ complesso, la probabilitΓ di correre in rifilato funzionalitΓ aumenta. Pertanto, di solito ti consigliamo di eseguire esclusivamente i tuoi plugin personalizzati nel sapore ASF generic
. à ancora possibile verificare manualmente che la compilazione specifica del sistema operativo di ASF ha tutto ciò che il plugin richiede per la sua funzionalità - ma dal momento che tali modifiche sui vostri aggiornamenti così come il nostro, potrebbe essere difficile da mantenere.
A volte potrebbe essere possibile "funzionare" funzioni mancanti utilizzando opzioni alternative o reimplementarle nel plugin. Questo perΓ² non Γ¨ sempre possibile o praticabile, soprattutto se la funzione mancante proviene da dipendenze di terze parti che si includono come parte del plugin. Si puΓ² sempre provare a eseguire il plugin in OS specifico build e tentare di farlo funzionare, ma potrebbe diventare troppo fastidio nel lungo periodo, soprattutto se si desidera dal codice per il solo lavoro, piuttosto che combattere con la superficie di ASF.
ASF offre due interfacce per l'implementazione di aggiornamenti automatici nel plugin:
-
IGitHubPluginUpdates
fornisce un modo semplice per implementare aggiornamenti basati su GitHub simili al meccanismo generale di aggiornamento di ASF -
IPluginUpdates
fornisce funzionalitΓ di livello inferiore che consentono un meccanismo di aggiornamento personalizzato, se hai bisogno di qualcosa di piΓΉ complesso
La lista di controllo minima delle cose che sono necessarie per gli aggiornamenti per funzionare:
- Γ necessario dichiarare
RepositoryName
, che definisce da dove vengono prelevati gli aggiornamenti. - Γ necessario fare uso di tag e rilasci forniti da GitHub. Il tag deve essere in formato analizzabile a una versione del plugin, ad esempio
1.0.0.0
. - La proprietΓ
Version
del plugin deve corrispondere al tag da cui proviene. CiΓ² significa che il binario disponibile sotto il tag1.2.3.4
deve presentarsi come1.2.3.4
. - Ogni tag dovrebbe avere un rilascio appropriato disponibile su GitHub con asset di rilascio file zip che include i file binari del plugin. I file binari che includono le classi
IPlugin
dovrebbero essere disponibili nella directory radice all'interno del file zip.
CiΓ² consentirΓ al meccanismo di ASF di:
- Risolvi l'attuale
Version
del tuo plugin, ad esempio1.0.1
. - Usa l'API GitHub per recuperare gli ultimi
tag
disponibili nel repoRepositoryName
, ad esempio1.0.2
. - Determina che
1.0.2
>1.0.1
, controlla il rilascio del tag1.0.2
per trovare il file.zip
con l'aggiornamento del plugin. - Scaricare il file
.zip
, estrarlo e mettere il suo contenuto nella directory che includevaYourPlugin.dll
prima. - Riavvia ASF per caricare il tuo plugin nella versione
1.0.2
.
Note complementari:
- Gli aggiornamenti dei plugin potrebbero richiedere valori di configurazione ASF appropriati, vale a dire
PluginsUpdateMode
e/oPluginsUpdateList
. - Il nostro modello di plugin include giΓ tutto ciΓ² che ti serve, semplicemente rename il plugin per i valori corretti, e funzionerΓ fuori dalla scatola.
- Γ possibile utilizzare la combinazione di ultima release e pre-release, che saranno utilizzati come
UpdateChannel
che l'utente ha definito. - C'Γ¨ una proprietΓ booleana
CanUpdate
che puoi sovrascrivere per disabilitare/abilitare l'aggiornamento dei plugin dal tuo lato, per esempio se si desidera saltare temporaneamente gli aggiornamenti, o per qualsiasi altra ragione. - Γ possibile avere piΓΉ file zip nel rilascio se si desidera destinare diverse versioni di ASF. Vedi
GetTargetReleaseAsset()
remarks. Ad esempio, puoi avereMyPlugin-V6-0.zip
eMyPlugin.zip
, che causerΓ ASF nella versioneV6. .x.x
per scegliere la prima, mentre tutte le altre versioni di ASF useranno la seconda. - Se quanto sopra non Γ¨ sufficiente per te e hai bisogno di una logica personalizzata per scegliere il corretto
. file ip
, puoi sovrascrivere la funzioneGetTargetReleaseAsset()
e fornire l'artefatto per ASF da usare. - Se il tuo plugin ha bisogno di fare qualche lavoro extra prima/dopo l'aggiornamento, puoi sovrascrivere i metodi
OnPluginUpdateProceeding()
e/oOnPluginUpdateFinished()
.
Questa interfaccia ti permette di implementare una logica personalizzata per gli aggiornamenti se per qualsiasi motivo IGithubPluginUpdates
non Γ¨ sufficiente per te, per esempio perchΓ© hai tag che non analizzano le versioni, o perchΓ© non stai usando la piattaforma GitHub affatto.
C'Γ¨ una singola funzione GetTargetReleaseURL()
da sovrascrivere, che si aspetta da te Uri?
della posizione di aggiornamento del plugin di destinazione. ASF fornisce alcune variabili di base che si riferiscono al contesto con cui Γ¨ stata chiamata la funzione, ma diverse da quello, sei responsabile per implementare tutto ciΓ² che ti serve in quella funzione e fornire ASF l'URL che dovrebbe essere utilizzato, o null
se l'aggiornamento non Γ¨ disponibile.
A parte questo, Γ¨ simile agli aggiornamenti di GitHub, dove l'URL dovrebbe puntare a un . file ip
con i file binari disponibili nella directory radice. Hai anche i metodi OnPluginUpdateProceeding()
e OnPluginUpdateFinished()
disponibili.
![]() |
![]() |
![]() |
![]() |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
---|---|---|---|
- π‘ Casa
- π§ Configurazione
- π¬ Domande frequenti
- Installazione (inizia qui)
- π₯ Riscatto giochi in background
- π’ Comandi
- π οΈ CompatibilitΓ
- π§© ItemsMatcherPlugin
- π Gestione
- β±οΈ Prestazioni
- π‘ Comunicazione remota
- πͺ Condivisione familiare di Steam
- π Trading
- β¨οΈ Argomenti da riga di comando
- π§ Deprecation
- π³ Docker
- π€ FAQ Estese
- π Configurazione ad alte prestazioni
- π IPC
- π Localizzazione
- π Registrazione
- πΎ Configurazione bassa memoria
- π΅πΌββοΈ MonitoringPlugin
- π Plugin
- π Sicurezza
- π§© SteamTokenDumperPlugin
- π¦ Terze parti
- π΅ Autenticazione due fattori