Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,31 @@ jobs:
- name: Restore Dependencies
run: dotnet restore

- name: Build Project (Development)
run: dotnet build --no-restore
- name: Build Project (Default)
run: dotnet build src/RegionInstaller.csproj --no-restore -c Default

- name: Upload Build Artifact
- name: Build Project (Lite)
run: dotnet build src/RegionInstaller.csproj --no-restore -c Lite

- name: Wait for file system sync
run: sleep 5

- name: Upload Build Artifact (Default)
uses: actions/upload-artifact@v4
with:
name: RegionInstaller.dll
path: src/bin/Debug/net6.0/RegionInstaller.dll
path: src/bin/Default/net6.0/RegionInstaller.dll

- name: Upload Build Artifact (Lite)
uses: actions/upload-artifact@v4
with:
name: RegionInstallerLite.dll
path: src/bin/Lite/net6.0/RegionInstallerLite.dll

- name: Upload Release Asset
- name: Upload Release Asset (Default)
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: src/bin/Debug/net6.0/RegionInstaller.dll
files: src/bin/Default/net6.0/RegionInstaller.dll
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
108 changes: 108 additions & 0 deletions src/Api/RegionApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace RegionInstaller
{
public static class RegionApi
{
#if LITE
public static void AddRegion(string name, string address, bool https, bool dtls, ushort port1, ushort port2)
{
throw new NotSupportedException("RegionInstallerLite does not include the API, please use default RegionInstaller.");
}

public static void DisableInnerslothRegions()
{
throw new NotSupportedException("RegionInstallerLite does not include the API, please use default RegionInstaller.");
}

public static void ReloadRegionInfo()
{
throw new NotSupportedException("RegionInstallerLite does not include the API, please use default RegionInstaller.");
}

internal static bool IsInnerslothForcedDisabled() => false;
#else
private static readonly List<ParsedRegion> DynamicRegions = new();
private static bool forceDisableInnersloth = false;

public static void AddRegion(string name, string address, bool https, bool dtls, ushort port1, ushort port2)
{
var region = new ParsedRegion
{
Name = name,
Address = address,
Https = https,
Dtls = dtls,
Port1 = port1,
Port2 = port2
};

if (region.IsValid)
{
DynamicRegions.Add(region);
TriggerRefresh();
Debug.Log($"[RegionInstaller.Api] Dynamic region '{name}' added successfully.");
}
else
{
Debug.LogError($"[RegionInstaller.Api] Failed to add invalid region '{name}'.");
}
}

public static void DisableInnerslothRegions()
{
if (forceDisableInnersloth)
{
Debug.LogWarning("[RegionInstaller.Api] Innersloth regions are already disabled by another plugin/API call!");
return;
}

forceDisableInnersloth = true;
TriggerRefresh();
Comment on lines +63 to +64
Debug.Log("[RegionInstaller.Api] Innersloth regions forcefully disabled via API.");
}

public static void ReloadRegionInfo()
{
TriggerRefresh();
Debug.Log("[RegionInstaller.Api] Region info manually reloaded via API.");
}

internal static List<ParsedRegion> GetDynamicRegions() => DynamicRegions;

internal static bool IsInnerslothForcedDisabled() => forceDisableInnersloth;

private static void TriggerRefresh()
{
try
{
ConfigData configData = ConfigFile.LoadOrCreate(RegionInstallerPlugin.ConfigPath);

configData.Regions.AddRange(DynamicRegions);

string regionJsonPath = Path.Combine(Application.persistentDataPath, "regionInfo.json");
RegionFileGenerator.RegenerateRegionFile(regionJsonPath, configData, forceDisableInnersloth);
Comment on lines +86 to +87

if (ServerManager.Instance != null)
{
ServerManager.Instance.LoadServers();
}

UnityEngine.Object.FindObjectOfType<RegionTextMonitor>()?.Start();
if (UnityEngine.Object.FindObjectOfType<RegionMenu>() is { } regionMenu)
{
regionMenu.OnDisable();
regionMenu.OnEnable();
}
}
catch (Exception ex)
{
Debug.LogError($"[RegionInstaller.Api] Error during dynamic refresh: {ex.Message}");
}
}
#endif
}
}
32 changes: 26 additions & 6 deletions src/RegionFileGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ namespace RegionInstaller
{
public static class RegionFileGenerator
{
public static void RegenerateRegionFile(string regionFilePath, ConfigData configData)
public static void RegenerateRegionFile(string regionFilePath, ConfigData configData, bool ignoreInnerslothAndGlitch = false)
{
try
{
bool needsRewrite = true;
JsonNode? rootNode = null;

if (File.Exists(regionFilePath) && new FileInfo(regionFilePath).Length > 0)
if (!ignoreInnerslothAndGlitch && File.Exists(regionFilePath) && new FileInfo(regionFilePath).Length > 0)
{
string content = File.ReadAllText(regionFilePath);
rootNode = JsonNode.Parse(content);
Expand All @@ -29,26 +29,46 @@ public static void RegenerateRegionFile(string regionFilePath, ConfigData config
}
}

if (needsRewrite)
if (needsRewrite || ignoreInnerslothAndGlitch)
{
if (File.Exists(regionFilePath))
{
File.Delete(regionFilePath);
}

Debug.Log("[RegionInstaller] Rewriting regionInfo.json...");
Debug.Log("[RegionInstaller] Rewriting regionInfo.json (with strict filters if requested)...");
rootNode = CreateEmptyRegionStructure();
var regionsArray = rootNode["Regions"]!.AsArray();

foreach (var reg in configData.Regions)
var regionsToProcess = new List<ParsedRegion>(configData.Regions);

if (!ignoreInnerslothAndGlitch)
{
if (configData.GlitchedLobbiesRegion)
{
GlitchedLobbies.AddGlitchedLobbiesRegion(regionsToProcess);
}
if (configData.KeepInnerslothRegions)
{
InnerslothRegions.AddInnerslothRegions(regionsToProcess);
}
}

foreach (var reg in regionsToProcess)
{
if (!reg.IsValid) continue;

if (ignoreInnerslothAndGlitch && InnerslothRegions.IsOfficialInnersloth(reg.Name))
{
continue;
}

regionsArray.Add(BuildRegionNode(reg.Name, reg.FullUrl, reg.SelectedPort, reg.Dtls));
}

var options = new JsonSerializerOptions { WriteIndented = true };
File.WriteAllText(regionFilePath, rootNode.ToJsonString(options));
Debug.Log("Region file reloaded!");
Debug.Log("Region file reloaded successfully!");
}
}
catch (Exception ex)
Expand Down
16 changes: 11 additions & 5 deletions src/RegionInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@ namespace RegionInstaller
public class RegionInstallerPlugin : BasePlugin
{
public const string Id = "com.nb1x.regioninstaller";

#if LITE
public const string Name = "RegionInstallerLite";
#else
public const string Name = "RegionInstaller";
public const string Version = "1.2.1";
#endif

public const string Version = "1.0.0";

public static string ConfigPath => Path.Combine(Paths.ConfigPath, "CustomRegions.cfg");
public Harmony Harmony { get; } = new Harmony(Id);

public override void Load()
{
Log.LogInfo($"[RegionInstaller] Loading {Name} v{Version}...");
Log.LogInfo($"[{Name}] Loading {Name} v{Version}...");

ConfigData configData = ConfigFile.LoadOrCreate(ConfigPath);

Expand All @@ -47,7 +53,7 @@ public override void Load()
{
if (scene.name == "MainMenu")
{
Log.LogInfo("[RegionInstaller] MainMenu loaded, injecting regions...");
Log.LogInfo($"[{Name}] MainMenu loaded, injecting regions...");
InjectRegions(configData.Regions);
}
}));
Expand All @@ -68,7 +74,7 @@ private void InjectRegions(List<ParsedRegion> parsedRegions)
var regionInfo = new StaticHttpRegionInfo(reg.Name, (StringNames)1003, reg.FullUrl, serversArray);

serverMngr.AddOrUpdateRegion(regionInfo.Cast<IRegionInfo>());
Log.LogInfo($"[RegionInstaller] Region '{reg.Name}' injected into memory.");
Log.LogInfo($"[{Name}] Region '{reg.Name}' injected into memory.");
}
}
}
Expand All @@ -79,4 +85,4 @@ public static class PatchCleanAndMerge
[HarmonyPrefix]
public static bool Prefix() => false;
}
}
}
27 changes: 22 additions & 5 deletions src/RegionInstaller.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,44 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>RegionInstaller</AssemblyName>
<Version>1.0.0</Version>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<Version>1.0.0</Version>
<DebugType>embedded</DebugType>
<Description>Auto-manages and injects custom modded regions into Among Us while filtering out official servers.</Description>
<Authors>Nb1X</Authors>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Default|AnyCPU'">
<AssemblyName>RegionInstaller</AssemblyName>
<DefineConstants>TRACE</DefineConstants>
<OutputPath>bin\Default\</OutputPath>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Lite|AnyCPU'">
<AssemblyName>RegionInstaller</AssemblyName>
<TargetName>RegionInstaller</TargetName>
<DefineConstants>TRACE;LITE</DefineConstants>
<OutputPath>bin\Lite\</OutputPath>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" ExcludeAssets="runtime;native" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" />

<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.9.29" PrivateAssets="all" />

<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />

<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" />
</ItemGroup>

<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
</Target>

</Project>
<Target Name="RenameLiteDll" AfterTargets="Build" Condition="'$(Configuration)' == 'Lite'">
<Move SourceFiles="$(OutDir)$(TargetFileName)" DestinationFiles="$(OutDir)RegionInstallerLite.dll" />
</Target>

</Project>
25 changes: 17 additions & 8 deletions src/ReloadButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
public static class ReloadButtonPatch
{
private static PassiveButton refreshButton;

Check warning on line 13 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'refreshButton' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 13 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'refreshButton' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 13 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'refreshButton' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 13 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'refreshButton' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

public static void Postfix(MainMenuManager __instance)
{
Expand All @@ -25,7 +25,7 @@
private static PassiveButton CreateOrangeRefreshButton(MainMenuManager menu)
{
var parent = menu.transform.Find("MainUI/AspectScaler/LeftPanel/Main Buttons");
if (parent == null) return null;

Check warning on line 28 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

Check warning on line 28 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

Check warning on line 28 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

Check warning on line 28 in src/ReloadButton.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

var button = Object.Instantiate(menu.quitButton, parent);
button.name = "RefreshRegionsButton";
Expand All @@ -44,19 +44,28 @@
{
ConfigData configData = ConfigFile.LoadOrCreate(RegionInstallerPlugin.ConfigPath);

if (configData.GlitchedLobbiesRegion)
{
configData.KeepInnerslothRegions = true;
GlitchedLobbies.AddGlitchedLobbiesRegion(configData.Regions);
}
#if LITE
bool shouldDisableInnersloth = false;
#else
bool shouldDisableInnersloth = RegionApi.IsInnerslothForcedDisabled();
#endif

if (configData.KeepInnerslothRegions)
if (!shouldDisableInnersloth)
{
InnerslothRegions.AddInnerslothRegions(configData.Regions);
if (configData.GlitchedLobbiesRegion)
{
configData.KeepInnerslothRegions = true;
GlitchedLobbies.AddGlitchedLobbiesRegion(configData.Regions);
}

if (configData.KeepInnerslothRegions)
{
InnerslothRegions.AddInnerslothRegions(configData.Regions);
}
}

string regionJsonPath = Path.Combine(Application.persistentDataPath, "regionInfo.json");
RegionFileGenerator.RegenerateRegionFile(regionJsonPath, configData);
RegionFileGenerator.RegenerateRegionFile(regionJsonPath, configData, shouldDisableInnersloth);

if (ServerManager.Instance != null)
{
Expand Down
Loading