Hj Updater API

Published on 25 December 2019
6 min read
Documentation
Mods
API
C#
Hj Updater API

HJ Updater API

This tool has been created and opensourced by HijackHornet. While I’m the one releasing the tool, this is now a collab between (Hijack Hornet#5298), (Mister_Name#0001) and myself (Lodington#9215). In short this API let modders implement an update availability check, warn the mod user, or even install the update automaticly while the game is running.

How does it work?

I won’t enter the details but BepInEx loads all of your mods into your RAM when you start the game. That means that while still playing, modifications of your mods files are possible without impacting your gameplay experience. For mods that require runtime access to files resources (assets, sandbanks,etc.)., Hj will wait for you to close the game before deploying the changes.

How much time is needed to add it to my mod ?

About 5 minutes for one dll mods, maybe 10 for complex mods with multiple non embed ressources. The docs seems hard but just add the dependency and copypast one of the case study if you don’t want to enter into the details.

Is it safe to use?

Depends. Every update is logged, and every old mod version is kept into a Backup folder under BepInEx/plugin/HijackHornet-HjUpdaterAPI/Backup. Also, Hj create an interface between mods and the folder structure in which they exist. So no matter if a user put the dll file into the root of /plugin or into a folder inside another folder named pepeDontLikeToFeel : the mod will still update and keep this folder structure. However this can become an issue if modders start implementing malware in their mods or exploit the api to delete other mods files. Don’t worry tho as the api won’t let any mod change any files outside of the RoR2 mod folder. For futher details, see here. This is not a security issue created by this mod, but one that has always been there.

User Guide

As a user, you can install this mod by unzipping the archive into the plugin folder. Don’t forget to add BOTH dll next to each other. However, this mod won’t do anything if the other mods you are using aren’t compatible with it. Some mods might put Hj as a dependency, however this api should always be optional. It’s not a hard dependency.

Config

If a mod has been updated automatically but the update is broken and you would like to use the backup files (previous version), you should change values in the config file as you please. Just go to /BepInEx/config/hjupdaterapi.config and change things according to your preferences. You can even choose to overwriter modders decisions over what type of updates should be performed.

Developer Guide

As a modder, you can use Hj function to add an update behaviour for your mod. It’s very simple to do and should provide enough flexibility to work with basically any mod. Here is how to setup Hj into your mods. It also ensures that if your mod end up being deprecated, it will be automatically deactivated on users’ computers (configurable by the user). I’m available to help you getting it setup, just pm me on the modded discord : @Hijack Hornet.

Adding the dll into your project lib folder In Visual Studio (or whichever IDE you use) add both dll included in the mod download link into your library folder, and add a reference to them into your project settings.

Adding the dependency

You can choose to HjUpdaterAPI as a dependency so that you are assured that everyone using it will get the latest version or at least be informed that a new version is available. However, you should always use it like an optional dependency and check in the awake function if the mod is installed and if so perform the command call. To add it as required dependency (note that it will not prevent your users to use your mod without this dependency, it’s only to display it on thunderstore) :

json
//manifest.json
{
    "name": "MyModName",
    "version_number": "1.0.0",
    "website_url": "myWebSite",
    "description": "Restart a run with a simple key !",
    "dependencies": [
        "bbepis-BepInExPack-3.0.0",
		"Lodington-HjUpdaterAPI-1.4.1" <--- Add this !
    ]
}

No need to update the dependency version when HjUpdaterApi will be updated.

Using the namespace

First add the namespace usage at the beginning of your mods main class.

C#
using Hj; //your other namespace

Now go into your awake function (it has to be put into Awake and not into Start) and call the register function :

C#
void Awake(){  
if (BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(HjUpdater.GUID)){
HjUpdaterAPI.Register(  
	string packageFullName,  
	[enum flag],  
	[List<string> otherFilesLocationRelativeToTheDll],  
	[bool modUseRuntimeRessourceLoading]
	);  
	}
} 

Let’s go through each parameter Mandatory parameters

  • packageFullName - The name of your mod inside the manifest.json example : `HijackHornet-EpicSoundReplacer`Optional parameters

Optional parameters

  • flag - This is used to specify the behaviour of the update. Options are : HjUpdaterAPI.Flag.UpdateAlways HjUpdaterAPI.Flag.UpdateIfSameDependencyOnlyElseWarnOnly HjUpdaterAPI.Flag.UpdateIfSameDependencyOnlyElseWarnAndDeactivate HjUpdaterAPI.Flag.WarnOnly HjUpdaterAPI.Flag.WarnAndDeactivate

By default, UpdateIfSameDependencyOnlyElseWarnOnly is used. DO NOT use UpdateAlways except if you know what you are doing. It could be useful for instance if you know that the next dependency update will not break your mod, but it’s risky and could end up breaking your mod.

  • otherFilesLocationRelativeToTheDll - Other files relative path inside of you mod. You do not have to add the readme, manifest and icon positions here. Those files could be other dll, resources, assets.
  • modUseRuntimeRessourceLoading - True if your mod is loading files at runtime (in or after the Start() call. Default : false. If this value is true, then the deployment process of the update is postponed to the game closure call, so that it doesn’t affect the mod usage at runtime.

That’s it ! Your mod is now able to self-update at runtime when newer versions are uploaded on the thunderstore.

Case study / Example

A simple dll mod with no other files

C#
void Awake(){  
if (BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(HjUpdater.GUID)){
	Register("MyModNameAsInTheManifest");  
	}
//...your other function calls  
}

A mod with one dll but that don’t update and just warn the user that a new version exists

C#
void Awake(){  
    if (BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(HjUpdater.GUID)){
        List<string> files = new List<string>();  
        files.Add('mySecondDll.dll');  
        Register(  
	        "MyModNameAsInTheManifest",
	        HjUpdaterAPI.Flag.WarnOnly  
        );
    }
    //...your other function calls  
    }  
}

A mod with two dll next to each other

C#
void Awake(){  
    if (BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(HjUpdater.GUID)){
        List<string> files = new List<string>();  
        files.Add('mySecondDll.dll');  
        Register(  
	        "MyModNameAsInTheManifest",  
	        HjUpdaterAPI.Flag.UpdateIfSameDependencyOnlyElseWarnOnly,  
	        files  
        );  
        }
    //...your other function calls  
}  

A mod with resources loaded at runtime inside a subfolder

C#
void Awake(){  
    if (BepInEx.Bootstrap.Chainloader.PluginInfos.ContainsKey(HjUpdater.GUID)){
        List<string> files = new List<string>();  
        files.Add('/asset/myAssetPack.asset');  
        files.Add('/font/myFont.ttf');  
        files.Add('/sounds/mySoundBank.bnk');  
        Register(  
	        "MyModNameAsInTheManifest",  
	        HjUpdaterAPI.Flag.UpdateIfSameDependencyOnlyElseWarnOnly,  
	        files,  
	        true  
	    );  
	}
    //...your other function calls  
}  
Powered by SvelteKit. Icons by Iconoir.