Skip to content

Commit abbd225

Browse files
committed
2026.1.1
0 parents  commit abbd225

8 files changed

Lines changed: 705 additions & 0 deletions

File tree

.gitignore

Lines changed: 428 additions & 0 deletions
Large diffs are not rendered by default.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 557
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

NativeLibrary.csproj

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Library</OutputType>
5+
<RootNamespace>KKW557.WorldBox.NativeLibrary</RootNamespace>
6+
<AssemblyName>NativeLibrary</AssemblyName>
7+
<Version>2026.1.1</Version>
8+
<TargetFramework>net48</TargetFramework>
9+
<ImplicitUsings>disable</ImplicitUsings>
10+
<Nullable>disable</Nullable>
11+
<LangVersion>11</LangVersion>
12+
</PropertyGroup>
13+
14+
<PropertyGroup>
15+
<WorldBoxDir>..\..\worldbox\</WorldBoxDir>
16+
</PropertyGroup>
17+
18+
<ItemGroup>
19+
<Reference Include="Newtonsoft.Json">
20+
<HintPath>$(WorldBoxDir)worldbox_Data\Managed\Newtonsoft.Json.dll</HintPath>
21+
<Private>false</Private>
22+
</Reference>
23+
<Reference Include="UnityEngine.CoreModule">
24+
<HintPath>$(WorldBoxDir)worldbox_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
25+
<Private>false</Private>
26+
</Reference>
27+
<Reference Include="NeoModLoader">
28+
<HintPath>$(WorldBoxDir)worldbox_Data\StreamingAssets\mods\NeoModLoader.dll</HintPath>
29+
<Private>false</Private>
30+
</Reference>
31+
</ItemGroup>
32+
33+
<ItemGroup>
34+
<Content Include="assets\**\*">
35+
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
36+
</Content>
37+
</ItemGroup>
38+
39+
<ItemGroup>
40+
<None Remove=".gitignore" />
41+
</ItemGroup>
42+
43+
</Project>

READNE.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# WorldBox NativeLibrary Mod
2+
3+
**NativeLibrary** is a dependency mod for [WorldBox](https://www.superworldbox.com/) [NeoModLoader](https://github.com/WorldBoxOpenMods/ModLoader).
4+
It provides automated loading of managed DLLs and native libraries within the modding ecosystem.
5+
This mod simplifies the integration of external libraries by handling the loading process at runtime,
6+
eliminating the need for explicit calls to `LoadLibrary` or `Assembly.Load`.
7+
8+
Please note that due to the complexities involved in performing **shading** or **relocation** operations at runtime,
9+
**NativeLibrary** does **not offer any mechanisms for dependency isolation**.
10+
For native libraries, users may achieve isolation by manually renaming binary files.
11+
However, this approach is not possible for managed DLLs,
12+
and potential conflicts must be managed externally.
13+
14+
## Features
15+
16+
* **Automated Libraries Loading**: Automatically loads both **managed DLLs** and **native libraries** without requiring manual intervention in code.
17+
* **Dependency Integration**: Acts as a foundational mod that other mods can depend on for library management.
18+
* **No Isolation Support**: Explicitly does not provide **shading** or **relocation** to isolate dependencies, prioritizing simplicity and runtime efficiency.
19+
20+
## Usage
21+
22+
1. Include the GUID of `NativeLibrary` in the dependencies list of your `mod.json` file. For example:
23+
24+
```json5
25+
{
26+
"Dependencies": ["NATIVELIBRARY"],
27+
// or
28+
"OptionalDependencies": ["NATIVELIBRARY"]
29+
}
30+
```
31+
32+
2. Place managed DLLs directly in the `NativeLibrary` folder.
33+
34+
For native libraries, place them in architecture-specific subfolders under `NativeLibrary` (supported: `x86_64` and `arm64`, based on **WorldBox** target platform).
35+
36+
The mod automatically loads the correct binary (`.dll` on **Windows**, `.so` on **Linux**, `.dylib` on **macOS**) for the operating system.
37+
38+
For details on native library loading, see [Native library loading](https://learn.microsoft.com/dotnet/standard/native-interop/native-library-loading).
39+
40+
Example structure:
41+
42+
```
43+
NativeLibrary/
44+
├── Managed.dll
45+
├── x86_64/
46+
│ ├── native.dll
47+
│ ├── libnative.so
48+
│ └── libnative.dylib
49+
└── arm64/
50+
└── libnative.dylib
51+
```
52+
53+
3. For native libraries, you still need to use `DllImport`
54+
55+
```csharp
56+
[DllImport("example")]
57+
public static extern long foo();
58+
```
59+
60+
## License
61+
62+
This project is licensed under the [MIT License](LICENSE) © 2025 557.

assets/mod.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "NativeLibrary",
3+
"GUID": "NATIVELIBRARY",
4+
"author": "557",
5+
"version": "2026.1.1",
6+
"description": "A dependency mod to load libraries.",
7+
"RepoUrl": "https://github.com/KKW557/WorldBoxNativeLibrary"
8+
}

src/Mod.cs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Reflection;
5+
using NeoModLoader.api;
6+
using NeoModLoader.constants;
7+
using Newtonsoft.Json;
8+
using UnityEngine;
9+
10+
namespace KKW557.WorldBox.NativeLibrary;
11+
12+
public class Mod : BasicMod<Mod>
13+
{
14+
public const string Name = "NativeLibrary";
15+
public const string DllPattern = "*.dll";
16+
public const string SoPattern = "*.so";
17+
public const string DylibPattern = "*.dylib";
18+
public const string Apple = "Apple";
19+
public const string x86_64 = "x86_64";
20+
public const string arm64 = "arm64";
21+
22+
protected override void OnModLoad()
23+
{
24+
LogInfo("Author: " + GetDeclaration().Author);
25+
LogInfo("Version: " + GetDeclaration().Version);
26+
27+
LoadLibraries();
28+
}
29+
30+
private static void LoadLibraries()
31+
{
32+
var managedLoaded = 0;
33+
var managedFailed = 0;
34+
var nativeLoaded = 0;
35+
var nativeFailed = 0;
36+
37+
foreach (var dir in Directory.GetDirectories(Paths.ModsPath)
38+
.Concat(Directory.GetDirectories(Paths.CommonModsWorkshopPath)))
39+
{
40+
var file = Path.Combine(dir, Paths.ModDeclarationFileName);
41+
if (!File.Exists(file)) continue;
42+
43+
var mod = JsonConvert.DeserializeObject<ModDeclare>(File.ReadAllText(file));
44+
if (mod == null) continue;
45+
46+
var incompatibleWith = mod.IncompatibleWith ?? Array.Empty<string>();
47+
if (incompatibleWith.Contains(Instance.GetDeclaration().UID)) continue;
48+
49+
var dependencies = mod.Dependencies ?? Array.Empty<string>();
50+
var optionalDependencies = mod.OptionalDependencies ?? Array.Empty<string>();
51+
if (!dependencies.Contains(Instance.GetDeclaration().UID) &&
52+
!optionalDependencies.Contains(Instance.GetDeclaration().UID)) continue;
53+
54+
var lib = Path.Combine(dir, Name);
55+
if (!Directory.Exists(lib)) continue;
56+
57+
LoadManaged(lib, ref managedLoaded, ref managedFailed);
58+
59+
LoadNative(lib, ref nativeLoaded, ref nativeFailed);
60+
}
61+
62+
LogInfo($"Managed loaded {managedLoaded}, failed {managedFailed}");
63+
LogInfo($"Native loaded {nativeLoaded}, failed {nativeFailed}");
64+
}
65+
66+
private static void LoadManaged(string path, ref int loaded, ref int failed)
67+
{
68+
foreach (var dll in Directory.GetFiles(path, DllPattern))
69+
{
70+
try
71+
{
72+
Assembly.LoadFrom(dll);
73+
loaded++;
74+
}
75+
catch (Exception)
76+
{
77+
failed++;
78+
}
79+
}
80+
}
81+
82+
private static void LoadNative(string path, ref int loaded, ref int failed)
83+
{
84+
switch (Application.platform)
85+
{
86+
case RuntimePlatform.WindowsPlayer:
87+
var wTarget = Path.Combine(path, x86_64);
88+
if (!Directory.Exists(wTarget)) return;
89+
90+
foreach (var file in Directory.GetFiles(wTarget, DllPattern))
91+
{
92+
if (kernel32.LoadLibrary(file) == IntPtr.Zero) failed++;
93+
else loaded++;
94+
}
95+
96+
return;
97+
case RuntimePlatform.LinuxPlayer:
98+
var lTarget = Path.Combine(path, x86_64);
99+
if (!Directory.Exists(lTarget)) return;
100+
101+
foreach (var file in Directory.GetFiles(lTarget, SoPattern))
102+
{
103+
if (dl.dlopen(file, dl.RTLD_NOW) == IntPtr.Zero) failed++;
104+
else loaded++;
105+
}
106+
107+
return;
108+
case RuntimePlatform.OSXPlayer:
109+
var xTarget = Path.Combine(path, SystemInfo.processorType.Contains(Apple) ? arm64 : x86_64);
110+
if (!Directory.Exists(xTarget)) return;
111+
112+
foreach (var file in Directory.GetFiles(xTarget, DylibPattern))
113+
{
114+
if (dl.dlopen(file, dl.RTLD_NOW) == IntPtr.Zero) failed++;
115+
else loaded++;
116+
}
117+
118+
return;
119+
}
120+
}
121+
}

src/dl.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace KKW557.WorldBox.NativeLibrary;
5+
6+
internal static class dl
7+
{
8+
public const int RTLD_NOW = 2;
9+
10+
[DllImport("dl")]
11+
public static extern IntPtr dlopen(string path, int flags);
12+
}

src/kernel32.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace KKW557.WorldBox.NativeLibrary;
5+
6+
internal static class kernel32
7+
{
8+
[DllImport("kernel32", SetLastError = true)]
9+
public static extern IntPtr LoadLibrary(string lpLibFileName);
10+
}

0 commit comments

Comments
 (0)