Skip to content
This repository was archived by the owner on Apr 21, 2024. It is now read-only.

Commit bdb6ecf

Browse files
author
BuildTools
committed
Merge branch 'dev'
2 parents e65b85d + 51b7e3a commit bdb6ecf

File tree

7 files changed

+233
-23
lines changed

7 files changed

+233
-23
lines changed

Event.cs

+32-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using HarmonyLib;
2+
using Splotch.Event.GameEvents;
23
using Splotch.Loader;
34
using System;
45
using System.Collections.Generic;
@@ -44,21 +45,21 @@ public static void RegisterEventListener(Type eventListener)
4445
}
4546
registeredEventHandlers[eventType].Add(eventHandler);
4647

47-
Logger.Debug($"Successfully registered event handler \"{eventHandler.Name}\"!");
48+
Logger.Debug($"Successfully registered event handler \"{eventHandler.FullDescription()}\"!");
4849
}
4950
else
5051
{
51-
Logger.Error($"Could not register event handler \"{eventHandler.Name}\" as the argument \"{eventType} {eventHandlerArguments[0].Name}\" does not extend \"{nameof(Event)}\"!");
52+
Logger.Error($"Could not register event handler \"{eventHandler.FullDescription()}\" as the argument \"{eventType} {eventHandlerArguments[0].Name}\" does not extend \"{nameof(Event)}\"!");
5253
}
5354
}
5455
else
5556
{
56-
Logger.Error($"Could not register event handler \"{eventHandler.Name}\" as it has {eventHandlerArguments.Length} arguments, not 1!");
57+
Logger.Error($"Could not register event handler \"{eventHandler.FullDescription()}\" as it has {eventHandlerArguments.Length} arguments, not 1!");
5758
}
5859
}
5960
else
6061
{
61-
Logger.Error($"Could not register event handler \"{eventHandler.Name}\" as it is not static!");
62+
Logger.Error($"Could not register event handler \"{eventHandler.FullDescription()}\" as it is not static!");
6263
}
6364
}
6465
}
@@ -118,7 +119,13 @@ public static void RunHandlers(Event e)
118119
{
119120
foreach (MethodInfo method in EventManager.registeredEventHandlers[e.GetType()])
120121
{
121-
method.Invoke(null, new object[] { e });
122+
try
123+
{
124+
method.Invoke(null, new object[] { e });
125+
} catch(Exception ex)
126+
{
127+
Logger.Error($"An error occurred while running the event handler {method.FullDescription()}:\n{ex.Message}\n{ex.StackTrace}");
128+
}
122129
}
123130
}
124131
}
@@ -127,9 +134,9 @@ public static void RunHandlers(Event e)
127134
/// <summary>
128135
/// An event that can be cancelled
129136
/// </summary>
130-
public abstract class CancellableEvent : Event
137+
public interface Cancellable
131138
{
132-
public bool Cancelled { get; set; } = false;
139+
bool Cancelled { get; set; }
133140
}
134141

135142
/// <summary>
@@ -144,8 +151,9 @@ namespace Splotch.Event.AbilityEvents
144151
/// <summary>
145152
/// A class that should be extended by any ability-related events
146153
/// </summary>
147-
public abstract class AbilityEvent : CancellableEvent
154+
public abstract class AbilityEvent : GameEvent, Cancellable
148155
{
156+
public bool Cancelled { get; set; } = false;
149157

150158
/// <summary>
151159
/// Gets the ability related to the event
@@ -225,13 +233,18 @@ namespace Splotch.Event.PlayerEvents
225233
/// <summary>
226234
/// A class that should be extended by any player-related events
227235
/// </summary>
228-
public abstract class PlayerEvent : Event
236+
public abstract class PlayerEvent : GameEvent
229237
{
230238
/// <summary>
231239
/// Retrieves the player related to the event
232240
/// </summary>
233241
/// <returns></returns>
234242
public abstract Player GetPlayer();
243+
244+
public SlimeController GetSlimeController()
245+
{
246+
return SplotchUtils.GetSlimeControllers()[GetPlayer().Id - 1];
247+
}
235248
}
236249

237250
public class PlayerDeathEvent : PlayerEvent
@@ -294,7 +307,7 @@ public override Player GetPlayer()
294307
/// <summary>
295308
/// Gets the PlayerBody object of the event
296309
/// </summary>
297-
/// <returns>The PlayerBodt object</returns>
310+
/// <returns>The PlayerBody object</returns>
298311
public PlayerBody GetPlayerBody()
299312
{
300313
return _playerBody;
@@ -308,4 +321,13 @@ public static void Patch(ref PlayerBody __instance)
308321
RunHandlers(e);
309322
}
310323
}
324+
325+
}
326+
327+
namespace Splotch.Event.GameEvents
328+
{
329+
public abstract class GameEvent : Event
330+
{
331+
332+
}
311333
}

Loader.cs

+35-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
using UnityEngine.SceneManagement;
22
using System.Reflection;
33
using Splotch.Event;
4+
using Splotch;
5+
using UnityEngine;
6+
using System;
7+
using System.Diagnostics;
48

59
namespace Splotch.Loader
610
{
@@ -16,9 +20,6 @@ struct SplotchConfigContainer
1620
public int someValue;
1721
}
1822

19-
20-
21-
2223
public static bool enteredScene = false;
2324

2425
/// <summary>
@@ -37,21 +38,29 @@ public static void OnEnterScene(Scene scene, LoadSceneMode loadSceneMode)
3738
Patcher.DoPatching();
3839
ModLoader.ModLoader.LoadMods();
3940
EventManager.Load();
41+
42+
GameObject obj = new GameObject("Unloader", new Type[] { typeof(UnLoader) });
4043
}
4144

4245
/// <summary>
4346
/// The main entrypoint for Splotch, called by Doorstop.
4447
/// </summary>
4548
public static void Main()
4649
{
47-
Splotch.Config.CreateConfigAndLoadSplotchConfig();
50+
Config.CreateConfigAndLoadSplotchConfig();
4851

4952
if (!Config.LoadedSplotchConfig.splotchEnabled)
50-
{
5153
return;
52-
}
5354

5455
SceneManager.sceneLoaded += SceneLoaded;
56+
57+
58+
}
59+
60+
internal static void GameExit()
61+
{
62+
ModLoader.ModLoader.UnloadMods();
63+
Logger.Log("Finished unloading!");
5564
}
5665

5766
/// <summary>
@@ -69,4 +78,24 @@ private static void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
6978
BaseGuiModifications.RunMainMenuModifications();
7079
}
7180
}
81+
82+
class UnLoader : MonoBehaviour
83+
{
84+
public static UnLoader Instance
85+
{
86+
get;
87+
set;
88+
}
89+
90+
void Awake()
91+
{
92+
DontDestroyOnLoad(transform.gameObject);
93+
Instance = this;
94+
}
95+
96+
public void OnApplicationQuit()
97+
{
98+
Loader.GameExit();
99+
}
100+
}
72101
}

ModLoader.cs

+72-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
using YamlDotNet.Serialization.NamingConventions;
44
using System.Reflection;
55
using System;
6+
using HarmonyLib;
7+
using ICSharpCode.SharpZipLib.Core;
8+
using ICSharpCode.SharpZipLib.Zip;
69

710
namespace Splotch.Loader.ModLoader
811
{
@@ -11,19 +14,39 @@ namespace Splotch.Loader.ModLoader
1114
/// </summary>
1215
internal static class ModLoader
1316
{
14-
const string MOD_FOLDER_PATH = "splotch_mods";
15-
const string MOD_INFO_FILE_NAME = "modinfo.yaml";
17+
static readonly string MOD_FOLDER_PATH = "splotch_mods";
18+
static readonly string MOD_INFO_FILE_NAME = "modinfo.yaml";
19+
static readonly string UNZIPPED_MOD_TEMP_FOLDER = @"splotch_mods\temp";
20+
1621
public static DirectoryInfo modFolderDirectory;
22+
public static DirectoryInfo modFolderTempDirectory;
1723
/// <summary>
1824
/// Called by the <c>Loader</c>, loads all detected mods and logs any issues encountered during loading.
1925
/// </summary>
2026
internal static void LoadMods()
2127
{
2228
Logger.Log("Starting to load mods...");
23-
int modCountLoaded = 0;
24-
int modCountTot = 0;
25-
modFolderDirectory = Directory.CreateDirectory(MOD_FOLDER_PATH);
26-
foreach (DirectoryInfo modFolder in modFolderDirectory.GetDirectories())
29+
int modCountLoaded = 0;
30+
int modCountTot = 0;
31+
modFolderDirectory = Directory.CreateDirectory(MOD_FOLDER_PATH);
32+
modFolderTempDirectory = Directory.CreateDirectory(UNZIPPED_MOD_TEMP_FOLDER);
33+
34+
ZipConstants.DefaultCodePage = System.Text.Encoding.UTF8.CodePage;
35+
foreach (FileInfo modZipFile in modFolderDirectory.GetFiles())
36+
{
37+
if (modZipFile.Extension.ToLower() == ".zip")
38+
{
39+
Logger.Debug($"Unzipped mod {modZipFile.Name} detected!");
40+
41+
FastZip fastZip = new FastZip();
42+
fastZip.ExtractZip(modZipFile.FullName, modFolderTempDirectory.CreateSubdirectory(
43+
Path.GetFileNameWithoutExtension(modZipFile.Name)
44+
).FullName, null);
45+
}
46+
}
47+
48+
49+
foreach (DirectoryInfo modFolder in modFolderDirectory.GetDirectories().AddRangeToArray(modFolderTempDirectory.GetDirectories()))
2750
{
2851
modCountTot++;
2952
string modFolderPath = modFolder.FullName;
@@ -70,6 +93,37 @@ internal static void LoadMods()
7093

7194
Logger.Log($"Loaded {modCountLoaded}/{modCountTot} mods successfully!");
7295
}
96+
97+
public static void RecursiveDelete(DirectoryInfo baseDir)
98+
{
99+
if (!baseDir.Exists)
100+
return;
101+
102+
foreach (var dir in baseDir.EnumerateDirectories())
103+
{
104+
RecursiveDelete(dir);
105+
}
106+
var files = baseDir.GetFiles();
107+
foreach (var file in files)
108+
{
109+
file.IsReadOnly = false;
110+
File.SetAttributes(file.FullName, FileAttributes.Normal);
111+
file.Delete();
112+
}
113+
baseDir.Delete();
114+
}
115+
116+
internal static void UnloadMods()
117+
{
118+
Logger.Log("Unloading mods...");
119+
foreach (var loadedMod in ModManager.loadedMods)
120+
{
121+
loadedMod.splotchMod.OnUnload();
122+
Logger.Debug($"Unloaded {loadedMod.name}");
123+
}
124+
Logger.Debug("Clearing temp...");
125+
RecursiveDelete(modFolderTempDirectory);
126+
}
73127
}
74128

75129
/// <summary>
@@ -125,6 +179,7 @@ public class ModInfo
125179
public string[] authors;
126180

127181
public SplotchMod splotchMod;
182+
public Assembly assembly;
128183
internal ModInfo(string dll, string className, string id, string name, string description, string version, string[] authors)
129184
{
130185
this.dll = dll;
@@ -146,8 +201,18 @@ internal bool LoadMod(string modFolder)
146201
try
147202
{
148203
string dllAbsolutePath = Path.Combine(modFolder, dll);
149-
Assembly assembly = Assembly.LoadFile(dllAbsolutePath);
204+
Logger.Debug($"Loading {dllAbsolutePath}");
205+
206+
assembly = Assembly.Load(File.ReadAllBytes(dllAbsolutePath));
207+
208+
Logger.Debug($"Loaded {assembly}");
150209
Type assemblyEntrypoint = assembly.GetType(className);
210+
if (assemblyEntrypoint == null)
211+
{
212+
Logger.Error($"{className} is not a valid class! Valid classes are: {string.Join<Type>(", ", assembly.GetTypes())}, if this is wrong, try changing the name of your assembly (your dll)");
213+
return false;
214+
}
215+
151216
if (assemblyEntrypoint.BaseType == typeof(SplotchMod))
152217
{
153218
splotchMod = (SplotchMod)Activator.CreateInstance(assemblyEntrypoint);

Splotch.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<Compile Include="ModLoader.cs" />
5050
<Compile Include="ModManager.cs" />
5151
<Compile Include="Properties\AssemblyInfo.cs" />
52+
<Compile Include="SplotchUtils.cs" />
5253
<Compile Include="SplotchMod.cs" />
5354
<Compile Include="VersionChecker.cs" />
5455
</ItemGroup>
@@ -79,6 +80,9 @@
7980
<HintPath>..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Bopl Battle\BoplBattle_Data\Managed\Facepunch.Steamworks.Win64.dll</HintPath>
8081
<Private>False</Private>
8182
</Reference>
83+
<Reference Include="ICSharpCode.SharpZipLib, Version=0.85.4.369, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
84+
<HintPath>packages\ICSharpCode.SharpZipLib.dll.0.85.4.369\lib\net20\ICSharpCode.SharpZipLib.dll</HintPath>
85+
</Reference>
8286
<Reference Include="Microsoft.CSharp" />
8387
<Reference Include="Mono.Cecil, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
8488
<HintPath>packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.dll</HintPath>

SplotchMod.cs

+4
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,9 @@ internal void Setup(ModInfo modInfo)
2121
/// Runs as soon as the mod is loaded after Splotch is done loading.
2222
/// </summary>
2323
public abstract void OnLoad();
24+
public void OnUnload()
25+
{
26+
27+
}
2428
}
2529
}

0 commit comments

Comments
 (0)