Skip to content

Commit

Permalink
Merge pull request #124 from SlimeCubed/master
Browse files Browse the repository at this point in the history
fix crash upon saving after removing regions, (reverted; Fix XML docs), Dependency checker, CRS API
  • Loading branch information
Garrakx committed Dec 13, 2021
2 parents 98ab596 + a87a72b commit 539d122
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 9 deletions.
5 changes: 5 additions & 0 deletions Custom-Regions/Custom-Regions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\References\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="BepInEx">
<HintPath>..\References\BepInEx.dll</HintPath>
</Reference>
<Reference Include="ConfigMachine, Version=1.4.4.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\References\ConfigMachine.dll</HintPath>
Expand Down Expand Up @@ -77,6 +81,7 @@
<Compile Include="Creatures\ScavengerAbstractAIHook.cs" />
<Compile Include="CustomMenu\PauseMenuHook.cs" />
<Compile Include="DevInterface\TriggersPageHook.cs" />
<Compile Include="Mod\API.cs" />
<Compile Include="Music\MultiplayerDJHook.cs" />
<Compile Include="Arena\MultiplayerUnlocksHook.cs" />
<Compile Include="Creatures\BigEelHook.cs" />
Expand Down
28 changes: 28 additions & 0 deletions Custom-Regions/CustomMenu/SlugcatSelectMenuHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ private static void SlugcatSelectMenu_ctor(On.Menu.SlugcatSelectMenu.orig_ctor o

self.pages[0].subObjects.Add(menuLabel);
}
if (CustomWorldMod.missingDependencies.Count > 0)
{
string errorText = CustomWorldMod.Translate($"You have missing dependencies, please reinstall the following packs: " +
$"[{string.Join(", ", CustomWorldMod.missingDependencies.Keys.ToArray())}]");

MenuLabel menuLabel = new MenuLabel(self, self.pages[0],
errorText,
new Vector2(self.manager.rainWorld.options.ScreenSize.x * 0.5f, self.manager.rainWorld.options.ScreenSize.y * 0.95f),
new Vector2(0, 0), true);

menuLabel.label.color = new Color((108f / 255f), 0.001f, 0.001f);
menuLabel.label.alignment = FLabelAlignment.Center;

self.pages[0].subObjects.Add(menuLabel);

// Second line

MenuLabel menuLabel2 = new MenuLabel(self, self.pages[0],
$"Missing dependencies: [{string.Join(", ", CustomWorldMod.missingDependencies.Values.SelectMany(i => i).Distinct().ToArray())}]",
new Vector2(self.manager.rainWorld.options.ScreenSize.x * 0.5f, self.manager.rainWorld.options.ScreenSize.y * 0.91f),
new Vector2(0, 0), false);

menuLabel2.label.color = new Color((108f / 255f), 0.001f, 0.001f);
menuLabel2.label.alignment = FLabelAlignment.Center;

self.pages[0].subObjects.Add(menuLabel2);

}
}

/// <summary>
Expand Down
60 changes: 60 additions & 0 deletions Custom-Regions/Mod/API.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomRegions.Mod
{
public static class API
{

public class RegionInfo
{
/// <summary>
/// Pack name, empty used for vanilla.
/// </summary>
public string PackName { get; internal set; }

public string RegionID { get; internal set; }
/// <summary>
/// World lines from world_XX.txt file.
/// </summary>
public List<string> Lines { get; internal set; }

public bool Vanilla { get; internal set; } = false;
}

public delegate void RegionPreprocessor(RegionInfo info);

public static Dictionary<string, CustomWorldStructs.RegionPack> InstalledPacks { get => CustomWorldMod.installedPacks; }
public static Dictionary<string, string> ActivatedPacks { get => CustomWorldMod.activatedPacks; }
public static List<CustomWorldStructs.PackDependency> InstalledDependencies { get => CustomWorldMod.installedDependencies; }

/// <summary>
/// Indicates wheter CRS is currently downloading a pack or not.
/// </summary>
public static bool DownloadInProcess { get => (CustomWorldMod.scripts.Count > 0 && CustomWorldMod.scripts.FindAll(x => x is PackDownloader).Count != 0); }


/// <summary>
/// Enables/Disables the provided pack. Make sure to check if there is a download in process first
/// </summary>
/// <param name="packName"></param>
public static void DisableEnablePack(string packName)
{
if (DownloadInProcess) { throw new AccessViolationException("Mod tried to disable a pack while CRS was downloading a pack... Use the API.DownloadInProcess bool"); }

CRExtras.DisableTogglePack(packName);
}

/// <summary>
/// Forces CRS to reset, make sure you know what you are doing. Check for API.DownloadInProcess first.
/// </summary>
public static void ForceReloadCRS()
{
if (DownloadInProcess) { throw new AccessViolationException("Mod tried to reset CRS while CRS was downloading a pack... Use the API.DownloadInProcess bool"); }
CustomWorldMod.LoadCustomWorldResources();
}

}
}
12 changes: 12 additions & 0 deletions Custom-Regions/Mod/CRExtras.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public enum CustomFolder
Assets,
World,
Levels,
PackDependencies,
// Depth 2.1
Gates_Shelters,
Gates,
Expand Down Expand Up @@ -51,6 +52,16 @@ public enum CustomFolder

}

public static void DisableTogglePack(string packName)
{
// Disable

CustomWorldStructs.RegionPack pack = CustomWorldMod.installedPacks[packName];
pack.activated = !pack.activated;
CustomWorldMod.SerializePackInfoJSON(CRExtras.BuildPath(pack.folderName, CRExtras.CustomFolder.None, file: "packInfo.json"), pack);
CustomWorldMod.LoadCustomWorldResources();
}


public static CustomWorldStructs.ProcessedThumbnail ProccessThumbnail(Texture2D oldTex, byte[] data, string packName)//, bool activated, bool raindb)
{
Expand Down Expand Up @@ -169,6 +180,7 @@ public static CustomWorldStructs.ProcessedThumbnail ProccessThumbnail(Texture2D
case CustomFolder.Assets:
case CustomFolder.Levels:
case CustomFolder.World:
case CustomFolder.PackDependencies:
if (includeRoot)
{
// Rain World/
Expand Down
156 changes: 155 additions & 1 deletion Custom-Regions/Mod/CustomWorldMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ public static string[] VanillaRegions()
/// </summary>
public static List<string> activeModdedRegions;

/// <summary>
/// List containing installed dependencies
/// </summary>
public static List<PackDependency> installedDependencies;

/// <summary>
/// Dictionary containing the thumbnails bytes. Key is the pack name and value is the thumb in byte array.
/// </summary>
Expand All @@ -205,6 +210,16 @@ public static string[] VanillaRegions()
/// </summary>
public static List<CustomWorldScript> scripts;

/// <summary>
/// Missing / corrupted dependencies, key is packName and value are the dependencies
/// </summary>
public static Dictionary<string, List<string>> missingDependencies;

/// <summary>
/// List of all filters to be applied
/// </summary>
public static List<API.RegionPreprocessor> regionPreprocessors;


readonly static string[] ResourceFolders = {
"Atlases", "Audio", "Decals", "Illustrations", "LoadedSoundEffects", "Music", "Palettes", "Projections"
Expand Down Expand Up @@ -489,6 +504,8 @@ public static void Log(string logText, bool throwException, DebugLevel minDebugL
}

static System.Diagnostics.Stopwatch crsPackIntializationWatch = null;


/// <summary>
/// Builds available regions, loaded regions and save analyzer
/// </summary>
Expand Down Expand Up @@ -531,7 +548,11 @@ public static void LoadCustomWorldResources()

CustomWorldMod.LoadInstalledPacks();

CustomWorldMod.BuildModRegionsDictionary();
CustomWorldMod.BuildModRegionsDictionary();

CustomWorldMod.LoadInstalledDependencies();

CustomWorldMod.VerifyDependencies();

if (OfflineMode) { CustomWorldMod.LoadThumbnails(); }

Expand All @@ -556,6 +577,138 @@ public static void LoadCustomWorldResources()

}

private static void VerifyDependencies()
{
CustomWorldMod.missingDependencies = new Dictionary<string, List<string>>();

foreach (var keyPar in CustomWorldMod.activatedPacks)
{
// Verify if dependencyPack exists
string pathToDependencies = CRExtras.BuildPath(keyPar.Value, CRExtras.CustomFolder.PackDependencies);
if (Directory.Exists(pathToDependencies))
{
RegionPack pack = CustomWorldMod.installedPacks[keyPar.Key];
CustomWorldMod.Log($"Verifying dependencies for [{pack.name}]");
foreach (var file in Directory.GetFiles(CRExtras.BuildPath(keyPar.Value, CRExtras.CustomFolder.PackDependencies)))
{
if (!file.Contains(".dll")) { continue; }
PackDependency dependency = new PackDependency();
try
{
//dependency.assemblyInfo = System.Reflection.Assembly.LoadFile(file);
dependency.assemblyName = System.Reflection.AssemblyName.GetAssemblyName(file).Name;
dependency.location = file;
dependency.SetHash();
CustomWorldMod.Log($"PackDependency: [{dependency.assemblyName}]", false, DebugLevel.MEDIUM);
}
catch (Exception e)
{
CustomWorldMod.Log($"Could not load dependency at [{file}]: {e}", true);
continue;
}

if (CustomWorldMod.installedDependencies.FindAll(x => x.hash.Equals(dependency.hash)).Count == 0)
{
// could not found installed dependency with same hash

// search dependencies with same name
PackDependency installedDependency = CustomWorldMod.installedDependencies.FirstOrDefault(x => x.assemblyName.Equals(dependency.assemblyName));
if (!installedDependency.Equals(default) && installedDependency.assemblyName != null && installedDependency.assemblyName != string.Empty)
{
// Dependency installed but different hash

if (installedDependency.audbVersion > dependency.audbVersion)
{
// Outdated dependency inside pack folder
CustomWorldMod.Log($"Pack [{pack.name}] has an outdated reference inside the PackDependencies folder. " +
$"CRS found [{installedDependency.assemblyName}] installed with version [{installedDependency.audbVersion}], and the packs comes with " +
$"version [{dependency.audbVersion}]", false, DebugLevel.MEDIUM);
}
else
{
// Corrupted dependency
CustomWorldMod.Log($"Found outdated / corrupted dependency for [{pack.name}]. Please reinstall with CRS and make sure to download AutoUpdate. " +
$"Dependency: [{installedDependency.assemblyName}], installed audbVersion [{installedDependency.audbVersion}]", true);
/*
packsAffected.Add(pack.name);
dependenciesAffected.Add(dependency.assemblyName);
*/
if (!CustomWorldMod.missingDependencies.ContainsKey(pack.name))
{
CustomWorldMod.missingDependencies.Add(pack.name, new List<string>()) ;
}
CustomWorldMod.missingDependencies[pack.name].Add(dependency.assemblyName);
}
}
else
{
// dependency missing
CustomWorldMod.Log($"Missing dependency for [{pack.name}]. Please reinstall with CRS and make sure to download AutoUpdate. " +
$"Dependency: [{dependency.assemblyName}]", true);

if (!CustomWorldMod.missingDependencies.ContainsKey(pack.name))
{
CustomWorldMod.missingDependencies.Add(pack.name, new List<string>());
}
CustomWorldMod.missingDependencies[pack.name].Add(dependency.assemblyName);
}

}
else
{
// dependency found
}
}
}
else
{
CustomWorldMod.Log($"Pack [{keyPar.Key}] does not have dependencies folder.");
}
}

CustomWorldMod.Log($"Missing dependencies: [{string.Join(", ", CustomWorldMod.missingDependencies.Values.SelectMany(i => i).Distinct().ToArray())}]");
}

private static void LoadInstalledDependencies()
{
CustomWorldMod.installedDependencies = new List<PackDependency>();

foreach (var mod in Partiality.PartialityManager.Instance.modManager.loadedMods)
{
PackDependency dependency = new PackDependency();
System.Reflection.FieldInfo version = mod.GetType().GetField("version");
if (version != null && version.FieldType == typeof(int))
{
dependency.audbVersion = (int)version.GetValue(mod);
}
//dependency.assemblyInfo = mod.GetType().Assembly;
dependency.assemblyName = mod.GetType().Assembly.GetName().Name;
dependency.location = mod.GetType().Assembly.Location;

dependency.SetHash();

installedDependencies.Add(dependency);
}

foreach (var mod in UnityEngine.Object.FindObjectsOfType<BepInEx.BaseUnityPlugin>())
{
PackDependency dependency = new PackDependency();
System.Reflection.FieldInfo version = mod.GetType().GetField("version");
if (version != null && version.FieldType == typeof(int))
{
dependency.audbVersion = (int)version.GetValue(mod);
}
//dependency.assemblyInfo = mod.GetType().Assembly;
dependency.assemblyName = mod.GetType().Assembly.GetName().Name;
dependency.location = mod.GetType().Assembly.Location;

dependency.SetHash();

installedDependencies.Add(dependency);
}

}

private static void InitializeDictionaries()
{
CustomWorldMod.installedPacks = new Dictionary<string, RegionPack>();
Expand All @@ -569,6 +722,7 @@ private static void InitializeDictionaries()
{
CustomWorldMod.processedThumbnails = new Dictionary<string, ProcessedThumbnail>();
}
CustomWorldMod.regionPreprocessors = new List<API.RegionPreprocessor>();

crashPlacedObjects = false;
}
Expand Down
7 changes: 1 addition & 6 deletions Custom-Regions/Mod/CustomWorldOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@ public override void Signal(UItrigger trigger, string signal)
}
else if (signal.Contains(OptionSignal.DisableToggle.ToString()))
{
// Disable
try
{
CRExtras.TryPlayMenuSound(SoundID.HUD_Exit_Game);
Expand All @@ -453,11 +452,7 @@ public override void Signal(UItrigger trigger, string signal)
}
OpTab tab = CompletelyOptional.ConfigMenu.currentInterface.Tabs.First(x => !x.isHidden);
string packName = Regex.Split(signal, "_")[1];
RegionPack pack = CustomWorldMod.installedPacks[packName];
pack.activated = !pack.activated;
CustomWorldMod.SerializePackInfoJSON(CRExtras.BuildPath(pack.folderName, CRExtras.CustomFolder.None, file: "packInfo.json"), pack);
CustomWorldMod.LoadCustomWorldResources();

CRExtras.DisableTogglePack(packName);
}
catch (Exception e) { CustomWorldMod.Log($"Could not disable pack [{signal}] {e}", true); }
}
Expand Down
Loading

0 comments on commit 539d122

Please sign in to comment.