forked from Reloaded-Project/Reloaded-II
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added: Basic Documentation for Internal Libraries
- Loading branch information
Showing
12 changed files
with
397 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Community Index Library | ||
|
||
!!! info | ||
|
||
API for [Reloaded II's Community Index](https://github.com/Reloaded-Project/Reloaded.Community) which provides compatibility and user suggestions for games. | ||
[[NuGet Package]](https://www.nuget.org/packages/Reloaded.Mod.Loader.Community) | ||
|
||
## Index API | ||
|
||
!!! info | ||
|
||
Shows how to fetch data from the community index. | ||
|
||
```csharp | ||
// Can specify optional parameter to fetch index from alternative URL or from filesystem. | ||
// Get the Index | ||
var indexApi = new IndexApi(); | ||
var index = await indexApi.GetIndexAsync(); | ||
``` | ||
|
||
### Get Application in Index | ||
|
||
!!! info | ||
|
||
Shows how to find an application within the index. | ||
|
||
```csharp | ||
// exeLocation contains the absolute file path to an EXE. | ||
await using var fileStream = new FileStream(exeLocation, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 524288); | ||
var hash = Hashing.ToString(await Hashing.FromStreamAsync(fileStream)); | ||
|
||
// index variable taken from previous example. | ||
// appId is the name of the EXE, in lower case, e.g. tsonic_win.exe [Path.GetFileName(filePath).ToLower()] | ||
var applications = index.FindApplication(hash, appId, out bool hashMatches); | ||
|
||
if (applications.Count == 1 && hashMatches) | ||
{ | ||
if (hashMatches) | ||
{ | ||
// Guaranteed match! Get the application info. | ||
var application = await indexApi.GetApplicationAsync(applications[0]); | ||
|
||
// use TryGetError to validate game data against possible incompatibilities. | ||
} | ||
else | ||
{ | ||
// Hash does not match. | ||
// Either wrong game, or EXE was modified by user. | ||
// Must be resolved by user. | ||
} | ||
} | ||
else if (applications.Count > 1) | ||
{ | ||
// Multiple matches, must be resolved by user. | ||
// Rare! | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# I/O Library | ||
|
||
!!! info | ||
|
||
The [I/O library](https://www.nuget.org/packages/Reloaded.Mod.Loader.IO) is used for discovery, monitoring changes and parsing of Reloaded-II's configuration files. | ||
|
||
## Read/Write Loader Configuration | ||
|
||
!!! info | ||
|
||
Shows how to read and write to the mod loader configuration. | ||
|
||
Read: | ||
```csharp | ||
var config = IConfig<LoaderConfig>.FromPathOrDefault(Paths.LoaderConfigPath); | ||
``` | ||
|
||
Write: | ||
```csharp | ||
IConfig<LoaderConfig>.ToPath(config, Paths.LoaderConfigPath); | ||
``` | ||
|
||
The `IConfig` API can be used with all structures inside the `Reloaded.Mod.Loader.IO.Config` namespace, as such you can also use this API to read app or mod configurations. | ||
|
||
## Monitor Available Configurations | ||
|
||
!!! info | ||
|
||
Shows how to use create services which keep track of all currently available configurations. | ||
|
||
These services actively monitor the FileSystem and update their contents whenever a user deletes a mod, modifies a mod or creates a new mod. | ||
|
||
Mods: | ||
```csharp | ||
// Read Loader Config | ||
var config = IConfig<LoaderConfig>.FromPathOrDefault(Paths.LoaderConfigPath); | ||
|
||
// Monitor Mods | ||
var modConfigService = new ModConfigService(config); | ||
|
||
// modConfigService.ItemsByFolder | A dictionary of all Folders -> Configurations | ||
// modConfigService.ItemsByPath | A dictionary of all Config File Paths -> Configurations | ||
// modConfigService.ItemsById | A dictionary of all ModIds -> Configurations | ||
``` | ||
|
||
The following services are also available: | ||
|
||
| Service | Contents | | ||
|--------------------------|--------------------------------------------------------------------------------| | ||
| ApplicationConfigService | All Application/Game Configurations. | | ||
| ModUserConfigService | All User Specified Overrides for Mods, e.g. 'Allow Updating to Beta Versions'. | | ||
|
||
## Batch Read Configurations | ||
|
||
!!! info | ||
|
||
Shows how to read multiple configurations at once. | ||
|
||
The `ConfigReader<T>` class can be used for the batch reading of configurations. | ||
|
||
```csharp | ||
// Read all mod configurations. | ||
var configs = ConfigReader<ModConfig>.ReadConfigurations(loaderConfig.GetModConfigDirectory(), ModConfig.ConfigFileName, token, 2, 2); | ||
``` | ||
|
||
## Useful Utility Methods | ||
|
||
!!! info | ||
|
||
This section lists some static commonly used utility methods. | ||
|
||
| Method | Purpose | | ||
|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| ModConfig.GetAllMods | Reads all available mod configurations. | | ||
| ModConfig.SortMods | Sorts a list of mods taking into account their individual dependencies. i.e. Ensures that Mod A is loaded before Mod B if Mod B depends on Mod A. | | ||
| ModConfig.GetDependencies | Returns a list of all dependencies' mod configurations for a given mod. | | ||
| ModUserConfig.GetAllUserConfigs | Retrieves all user configurations that override mod properties. | | ||
| ModUserConfig.GetUserConfigPathForMod | Retrieves the path of a user configuration for a given mod. | | ||
| ModUserConfig.GetUserConfigFolderForMod | Retrieves the path where mod configuration files are stored. | | ||
| ApplicationConfig.GetAllApplications | Retrieves a list of all application configurations. | | ||
| ApplicationConfig.GetAllMods | Retrieves a list of all mods for a given application. | | ||
|
||
## Other Utilities | ||
|
||
A list of other utilities that may be helpful. | ||
|
||
| Class | Purpose | | ||
|------------------------------|---------------------------------------------------------------------------------------------| | ||
| Paths | Used to get the file paths of various Reloaded components, such as logs and configurations. | | ||
| IOEx | Various utility methods for I/O operations. | | ||
| FileSystemWatcherFactory | Factory method(s) for creating functions that monitor FileSystem events. | | ||
| NtQueryDirectoryFileSearcher | [Windows Only] Very, very fast directory and file searcher. | | ||
| BasicPeParser | Basic fast parser for Windows PE files [EXE, DLL] with limited functionality. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Internal Libraries | ||
|
||
!!! warning | ||
|
||
Some of following libraries are considered 'internal' to Reloaded. | ||
|
||
While most are relatively 'stable' in terms of API surface, it is still possible that some internal implementation details might change; meaning you might need to update your packages from one Reloaded release to another. | ||
|
||
The following pages here will provide an 'Introduction' to each library; showing common use cases; they do not document the entire available API. | ||
|
||
If you need alternative overloads, etc. consider contributing to Reloaded. | ||
|
||
!!! note | ||
|
||
These pages are based on the current development version of Reloaded. | ||
Some APIs may not be available in current NuGet packages, they will release soon. | ||
|
||
With that in mind, please enjoy. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Packaging Library | ||
|
||
!!! info | ||
|
||
Library for creating downloadable packages and updates for Reloaded II mods. | ||
[[NuGet Package]](https://www.nuget.org/packages/Reloaded.Mod.Loader.Update.Packaging) | ||
|
||
## Create Packages | ||
|
||
!!! info | ||
|
||
Shows how to create an update package. | ||
|
||
```csharp | ||
// Use the Publisher.PublishAsync API | ||
await Publisher.PublishAsync(new PublishArgs() | ||
{ | ||
ModTuple = new PathTuple<ModConfig>(configPath, config), | ||
OutputFolder = options.OutputFolder, | ||
IncludeRegexes = options.IncludeRegexes.ToList(), | ||
IgnoreRegexes = options.IgnoreRegexes.ToList(), | ||
OlderVersionFolders = options.OlderVersionFolders.ToList(), | ||
AutomaticDelta = options.AutomaticDelta, | ||
CompressionLevel = options.CompressionLevel, | ||
CompressionMethod = options.CompressionMethod, | ||
Progress = progressBar.AsProgress<double>(), | ||
PackageName = options.PackageName, | ||
PublishTarget = options.PublishTarget, | ||
ChangelogPath = options.ChangelogPath, | ||
MetadataFileName = config.ReleaseMetadataFileName | ||
}); | ||
``` | ||
|
||
The parameters are functionally identical to those in the `Reloaded.Publisher` CLI tool. | ||
Refer to parameters' documentation for definitions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Server Library | ||
|
||
!!! info | ||
|
||
Library for communicating with 'Reloaded II Server' mod (formerly part of mod loader). | ||
Allows for remote querying of information as well as mod manipulation (e.g. load/unload mods) in real time. | ||
[[NuGet Package]](https://www.nuget.org/packages/Reloaded.Mod.Loader.Server) | ||
|
||
## Connect to Server | ||
|
||
!!! info | ||
|
||
Connects to the server for remote control. | ||
|
||
```csharp | ||
// Create a new client. will automatically asynchronously connect. | ||
// Can specify remote IP address, but user must enable 'Allow External Connections' in 'Reloaded II Server' Mod. | ||
// ... and port forward | ||
Client = new LiteNetLibClient(IPAddress.Loopback, "", _port, true); | ||
|
||
// If the server restarts, e.g. user unloaded and reloaded the mod, | ||
// you should probably try to get the server's new port number (in case it changed). | ||
Client.OnTryReconnect += (peer) => TryGetPort(out _port); // see below how to get new port | ||
Client.OverrideDetailsOnReconnect += () => (null, _port); // overrides port in reconnect attempt | ||
// Report back exceptions. | ||
Client.OnReceiveException += ClientOnReceiveException; | ||
|
||
// Useful: | ||
// Client.OnConnected | When client connects to host. | ||
// Client.IsConnected | If client is connected. | ||
``` | ||
|
||
If the server is hosted on the same machine, you can get the port number programmatically: | ||
```csharp | ||
ServerUtility.GetPort(processId); | ||
``` | ||
|
||
## Check if Reloaded is Present | ||
|
||
!!! info | ||
|
||
Checks if Reloaded has been loaded into a process with a given ID. | ||
|
||
```csharp | ||
ReloadedMappedFile.Exists(processId); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Update Library | ||
|
||
!!! info | ||
|
||
Library for resolving dependencies, searching and downloading Reloaded II mod updates. | ||
[[NuGet Package]](https://www.nuget.org/packages/Reloaded.Mod.Loader.Update) | ||
|
||
## Check & Apply Mod Updates | ||
|
||
!!! info | ||
|
||
Checks and applies updates for Reloaded mods. | ||
|
||
```csharp | ||
// modConfigService: See IO Library | ||
// modUserConfigService: See IO Library | ||
var updater = new Updater(modConfigService, modUserConfigService, updaterData); | ||
var updateDetails = await updater.GetUpdateDetailsAsync(); | ||
|
||
if (updateDetails.HasUpdates()) | ||
{ | ||
// Warning: Consider checking if files are in use. | ||
// Otherwise might be stuck waiting for a very long time, there is no timeout. | ||
await Updater.Update(Summary); | ||
} | ||
``` | ||
|
||
Alternative lower level API: `PackageResolverFactory`. | ||
|
||
## Search for Mods | ||
|
||
!!! info | ||
|
||
Shows how to search for mods (NuGet, GameBanana, other supported providers). | ||
|
||
```csharp | ||
// May return null if none are available. | ||
// appConfig represents ApplicationConfig from IO. | ||
var aggregateProvider = PackageProviderFactory.GetProvider(appConfig); | ||
|
||
// Search for 'Cool Mod' return, 20 entries, skip 0. | ||
var results = await aggregateProvider.SearchAsync("Cool Mod", 0, 20); | ||
``` | ||
|
||
To search for NuGet packages, you will need to manually create `NuGetPackageProvider`: | ||
|
||
```csharp | ||
// loaderConfig is Mod Loader config | ||
var nuGetRepository = new AggregateNugetRepository(loaderConfig.NuGetFeeds); | ||
var nuGetProvider = new NuGetPackageProvider(nuGetRepository); | ||
``` | ||
|
||
You can use `AggregatePackageProvider` to combine multiple providers: | ||
|
||
```csharp | ||
// Extract from existing provider. | ||
var provider = new AggregatePackageProvider(new IDownloadablePackageProvider[] { nuGetProvider, aggregateProvider }, "NuGet"); | ||
``` | ||
|
||
## Resolve Missing Dependencies For Mod | ||
|
||
!!! info | ||
|
||
Shows how to check and download missing dependencies for mods. | ||
|
||
Download dependencies for a mod: | ||
```csharp | ||
// nuGetRepository is AggregateNugetRepository | ||
// mod is ModConfig | ||
var resolver = DependencyResolverFactory.GetInstance(nuGetRepository); | ||
var result = await resolver.ResolveAsync(mod.ModId, mod.PluginData); | ||
``` | ||
|
||
For multiple mods: | ||
```csharp | ||
// The loop is used to resolve nested dependencies (dependencies of dependencies). | ||
// Non-NuGet sources usually do not have the ability to resolve those. | ||
ModDependencyResolveResult resolveResult = null!; | ||
|
||
do | ||
{ | ||
var missingDeps = modConfigService.GetMissingDependencies(); | ||
var resolver = DependencyResolverFactory.GetInstance(nuGetRepository); | ||
|
||
var results = new List<Task<ModDependencyResolveResult>>(); | ||
foreach (var dependencyItem in missingDeps.Items) | ||
foreach (var dependency in dependencyItem.Dependencies) | ||
results.Add(resolver.ResolveAsync(dependency, dependencyItem.Mod.PluginData, token)); | ||
|
||
await Task.WhenAll(results); // wait for completion | ||
resolveResult = ModDependencyResolveResult.Combine(results.Select(x => x.Result)); // merge results | ||
// Download dependencies here using resolveResult.FoundDependencies | ||
// so on next loop, will find less dependencies. | ||
} | ||
while (resolveResult.FoundDependencies.Count > 0); | ||
``` | ||
|
||
## Write Dependency Metadata | ||
|
||
!!! info | ||
|
||
Modifies mod configurations to insert data required for resolving dependencies. | ||
|
||
e.g. If Mod A depends on Mod B, which receives updates from GitHub, Mod A's config will be modified to include Mod B's update configuration. This will allow people to download Mod B if they have Mod A. | ||
|
||
```csharp | ||
// modConfigService is ModConfigService | ||
await DependencyMetadataWriterFactory.ExecuteAllAsync(modConfigService); | ||
``` | ||
|
||
## Check Reloaded Dependencies | ||
|
||
!!! info | ||
|
||
Shows how to check if all runtimes required to run Reloaded are available. | ||
|
||
```csharp | ||
// loaderConfig is LoaderConfig from IO library. | ||
var deps = new DependencyChecker(loaderConfig, IntPtr.Size == 8); // 64-bit check | ||
if (deps.AllAvailable) | ||
return; | ||
|
||
// In deps array you can get install urls for any missing runtimes via the interface. | ||
``` | ||
|
||
Grabs loader path from the loader config. This is used to check for missing dependencies on boot in cases where e.g. user installed 64-bit runtime but not 32-bit after ignoring the installer. |
Oops, something went wrong.