Skip to content

Commit b60f74b

Browse files
committed
feat: IL2CPP types translation, Mod overlay API, file logging, build script, bilingual docs
Added: - Il2Cpp/: Core/Types/Reflection/Unity/Coroutine/RuntimeInvokeHook C# translation - IModPlugin: OnBackgroundGUI/OnForegroundGUI(ImDrawListPtr) overlay draw API - Managed.cs: file logging (manager.log) + Benchmark startup timing - AndroidUtils: GetInternalFilesDir/GetExternalFilesDir - Scripts/build_release.sh: one-shot AAR + modmanager.tar.gz build - ModManagerJsonContext: STJ source-gen context (AOT-compatible) Docs: - GET_STARTED.md: bilingual 3-step guide (inject APK → deploy manager → write mod) - README.md: updated structure reflecting Il2Cpp/Native/Runtime/Manager - .gitignore: added /release/ output dir - XML doc comments on all public members (37 items) Fixes: - Benchmark: stack-based to fix nested timing overwrite - ModManagerUI.Panels: migrated to STJ source-gen serialization - build script: exclude runtimes/ dir (native libs already in AAR)
1 parent 034a4f9 commit b60f74b

34 files changed

Lines changed: 1132 additions & 107 deletions

‎.github/workflows/build.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v4
17+
with:
18+
submodules: recursive
1719

1820
- name: Set up JDK 17
1921
uses: actions/setup-java@v4
@@ -47,6 +49,8 @@ jobs:
4749
runs-on: ubuntu-latest
4850
steps:
4951
- uses: actions/checkout@v4
52+
with:
53+
submodules: recursive
5054

5155
- name: Set up .NET 10
5256
uses: actions/setup-dotnet@v4

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
*.aab
99
*.ap_
1010

11+
# Release artifacts
12+
/release/
13+
1114
# IDE
1215
.idea/
1316
*.suo

‎Android/library/src/main/cpp/core/unity_resolve.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,16 @@ const char *modmanager_resolve_method_get_param_name(void *method, int index) {
245245
return m->args[index]->name.c_str();
246246
}
247247

248+
/**
249+
* 获取方法参数类型名(按索引)。
250+
*/
251+
const char *modmanager_resolve_method_get_param_type_name(void *method, int index) {
252+
if (!method) return "";
253+
auto *m = static_cast<UnityResolve::Method*>(method);
254+
if (index < 0 || index >= (int)m->args.size()) return "";
255+
return m->args[index]->pType ? m->args[index]->pType->name.c_str() : "";
256+
}
257+
248258
/**
249259
* 获取方法返回类型名。
250260
*/

‎GET_STARTED.md‎

Lines changed: 103 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,123 @@
1-
# Getting Started
1+
# Getting Started / 快速开始
22

3-
## Build
3+
## 1. Inject into APK / 注入 APK
44

5-
```bash
6-
cd Android
7-
./gradlew :library:assembleRelease
8-
cd ../StArray.ModManager
9-
dotnet build -c Release
5+
Download `library-release.aar` from [Releases](https://github.com/StArraySharp/StArray.ModManager/releases).
6+
从 [Releases](https://github.com/StArraySharp/StArray.ModManager/releases) 下载 `library-release.aar`。
7+
8+
⚠️ **Add INTERNET permission in `AndroidManifest.xml`** (required for OTA updates & mod networking)
9+
⚠️ **在 `AndroidManifest.xml` 添加网络权限**(OTA 更新和 Mod 联网需要):
10+
11+
```xml
12+
<uses-permission android:name="android.permission.INTERNET" />
1013
```
1114

12-
Output:
13-
- `Android/library/build/outputs/aar/library-release.aar`
14-
- `StArray.ModManager/bin/Release/net10.0/StArray.ModManager.dll`
15+
```bash
16+
unzip library-release.aar -d aar_content
17+
apktool d target.apk -o target_src
18+
19+
# Copy .so → lib/
20+
cp aar_content/jni/arm64-v8a/*.so target_src/lib/arm64-v8a/
21+
22+
# Copy CoreCLR runtime DLLs → assets/
23+
cp aar_content/assets/runtime/*.dll target_src/assets/
1524

16-
## Deploy to Device
25+
# Decompile classes.jar → smali
26+
java -jar baksmali.jar d aar_content/classes.jar -o target_src/smali/starray/
1727

28+
# Add to UnityPlayerActivity.onCreate:
29+
# invoke-static {}, Lstarray/android/modmanager/ModManager;->launch()V
30+
#
31+
# ⚠️ launch() defaults to /sdcard/ModManager/. Paths are hardcoded in
32+
# ModManager.smali. Modify smali constants if your layout differs,
33+
# or use ModManagerUpdater (configurable paths + OTA auto-update).
34+
#
35+
# ⚠️ launch() 默认加载 /sdcard/ModManager/。路径硬编码在 ModManager.smali,
36+
# 如需自定义请修改 smali 内常量,或使用 ModManagerUpdater。
37+
38+
# Repack & sign
39+
apktool b target_src -o repacked.apk
40+
uber-apk-signer --apks repacked.apk
1841
```
19-
/sdcard/ModManager/manager/
20-
StArray.ModManager.dll built managed mod
21-
*.dll deps (ImGui.NET, OpenTK, etc.)
2242

23-
/sdcard/ModManager/runtime/
24-
*.dll .NET runtime assemblies
43+
## 2. Deploy Manager / 部署管理器
44+
45+
Place manager DLL and dependencies in `/sdcard/ModManager/manager/`.
46+
将管理器 DLL 及依赖放入 `/sdcard/ModManager/manager/`。
47+
48+
| File | From / 来源 |
49+
|---|---|
50+
| `StArray.ModManager.dll` | [Releases](https://github.com/StArraySharp/StArray.ModManager/releases) → `modmanager.zip` |
51+
| `ImGui.NET.dll` | Same dir as StArray.ModManager build output |
52+
| `OpenTK.Graphics.dll` | 同上 |
53+
54+
Final layout / 最终目录:
55+
56+
```
57+
/sdcard/ModManager/
58+
├── manager/
59+
│ ├── StArray.ModManager.dll
60+
│ ├── ImGui.NET.dll
61+
│ ├── OpenTK.Graphics.dll
62+
│ └── modmanager_config.json (auto-generated / 自动生成)
63+
└── mods/
64+
└── {YourModName}/
65+
├── {YourModName}.dll
66+
└── ...
2567
```
2668

27-
Runtime DLLs: [runtime-references release](https://github.com/StArraySharp/StArray.ModManager/releases/tag/0)
69+
## 3. Write a Mod / 写一个 Mod
2870

29-
## Inject into APK
71+
Reference `StArray.ModManager.dll` → implement `IModPlugin` → build DLL → drop into `mods/{ModName}/`.
72+
引用 `StArray.ModManager.dll` → 实现 `IModPlugin` → 编译 DLL → 放入 `mods/{ModName}/`。
3073

31-
```bash
32-
apktool d target.apk -o target_src
74+
```csharp
75+
using StArray.ModManager.Runtime;
76+
using System.Numerics;
77+
using ImGuiNET;
78+
79+
public class HelloMod : IModPlugin
80+
{
81+
public string Id => "com.example.hello";
82+
public string Name => "Hello";
83+
public string Version => "1.0.0";
84+
public string Author => "you";
85+
public string Description => "demo";
86+
public IReadOnlyList<string> Dependencies => Array.Empty<string>();
87+
88+
public void OnLoad() { }
89+
public void OnUnload() { }
90+
91+
// Draw HUD overlay on game screen / 在游戏画面上叠加 HUD
92+
public void OnForegroundGUI(ImDrawListPtr drawList)
93+
{
94+
drawList.AddText(new Vector2(10, 10), 0xFFFFFFFF, $"FPS: {ImGui.GetIO().Framerate:F0}");
95+
}
96+
}
3397
```
3498

35-
Copy `.so` files to `target_src/lib/arm64-v8a/`:
36-
- From AAR: `libmodmanager.so`, `libmonodroid.so`, `libcimgui.so`
37-
- CoreCLR: `libcoreclr.so`, `libclrjit.so`, `libSystem.Native.so`, etc.
99+
### Optional interfaces / 可选接口
38100

39-
Add to `UnityPlayerActivity.smali` onCreate:
101+
```csharp
102+
interface IModSettings { void OnGui(); } // Custom settings tab / 自定义设置页
103+
interface IModSettingCustomDraw { void DrawInspector(); } // Custom inspector / 自定义检查器
104+
```
105+
106+
### Field attributes / 设置特性
107+
108+
```csharp
109+
[ModSettingLabel("Health Multiplier / 血量倍率")]
110+
[ModSettingRange(0.1f, 10f)]
111+
public float HealthMultiplier = 1f;
40112

41-
```smali
42-
invoke-static {}, Lstarray/android/modmanager/ModManager;->launch()V
113+
[ModSettingLabelSide(ModInspector.LabelSide.Left)]
114+
[ModSettingJson(Lines = 10)]
115+
public string JsonConfig = "{}";
43116
```
44117

45-
Add `smali/starray/android/modmanager/ModManager.smali` and `ModManager$1.smali` from the AAR.
118+
### Overlay drawing / Overlay 绘制
46119

47-
```bash
48-
apktool b target_src -o repacked.apk
49-
uber-apk-signer --apks repacked.apk
120+
```csharp
121+
void OnBackgroundGUI(ImDrawListPtr d) { } // Behind ImGui windows / 窗口下方 (watermark / 水印)
122+
void OnForegroundGUI(ImDrawListPtr d) { } // Above ImGui windows / 窗口上方 (HUD)
50123
```

‎README.md‎

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,58 +13,48 @@ Android IL2CPP Unity mod manager with CoreCLR runtime embedding and ImGui overla
1313
## Project Structure
1414

1515
```
16-
StArray.ModManager/ C# mod manager (.NET 10)
17-
UI/
18-
ImGuiRender.cs EGL rendering + GL debug panel + rainbow shader
19-
ImGuiEGLRender.cs EGL renderer (IImGuiRenderer, split architecture)
20-
ImGuiInputHandler.cs Touch/key hooks + IME callback bridge
21-
ImGuiVulkanRenderer.cs Vulkan renderer (experimental)
22-
ModManagerUI.cs ImGui mod manager UI
23-
IImGuiRenderer.cs Renderer interface
24-
FontAwesome7.cs FA7 icon codepoints
25-
PInvoke/
26-
Dobby.cs Inline hook wrapper
27-
DL.cs dlopen/dlsym
28-
JniHelperNative.cs JNI ↔ C data bridge
29-
ImGuiBackends.cs cimgui P/Invoke (OpenGL3, Android, Vulkan)
30-
Misc.cs C callback registration
31-
AndroidLog.cs Logcat logging
32-
UnityResolve.cs IL2CPP reflection engine
33-
Manager/
34-
MotionEventHook.cs InputConsumer hook
35-
AndroidIME.cs IME manager
36-
Unity/
37-
UnitySurfaceHelper.cs ANativeWindow from Unity SurfaceView
38-
Mono.cs CoreCLR entry point (old)
39-
Managed.cs CoreCLR entry with argc/argv
40-
41-
Android/library/ Native library (libmodmanager.so)
42-
src/main/cpp/core/
43-
dobby_hook.cpp Dobby inline hook
44-
mono_droid_coreclr.c CoreCLR embedding + args delegate
45-
jni_helper.c JNI helpers, data bridge, C callback dispatch
46-
unity_resolve.cpp Unity symbol resolution
16+
StArray.ModManager/ C# mod manager (.NET 10)
17+
Managed.cs CoreCLR entry – Logger桥接 → 扫描Mod → 启动ImGui
18+
Il2Cpp/ IL2CPP 内部类型 C# 翻译
19+
Core.cs / Types.cs Vector2/3/4, Quaternion, Il2CppString, Il2CppArray<T> 等
20+
Reflection.cs Il2CppAssembly, Il2CppClass, Il2CppMethod, Il2CppField
21+
Unity.cs UnityObject, Component, Transform, GameObject, Camera
22+
Coroutine.cs
23+
Inspector/ ImGui 自动检查器 + 设置特性([ModSettingRange] 等)
24+
Manager/ 核心逻辑
25+
ModLoader.cs Mod 扫描/加载/卸载/状态管理
26+
ModManagerUI.cs ImGui 主面板 + 设置窗口 + Overlay 背景/前景渲染
27+
ModManagerConfig.cs 全局配置 JSON 持久化(STJ 源生成)
28+
Logger.cs 统一日志 → logcat + 文件双写
29+
Benchmark.cs 栈式嵌套计时
30+
Native/ 原生绑定(Dobby, DL, JNI, AndroidUtils, UnityResolve)
31+
Runtime/ Mod 接口
32+
IModPlugin.cs OnLoad/OnUnload/OnBackgroundGUI/OnForegroundGUI
33+
IModSettings.cs / IModSettingCustomDraw.cs
34+
UI/ ImGui EGL/Vulkan 渲染器 + 输入处理 + FA7 图标
35+
36+
Android/library/ 原生库 (libmodmanager.so)
37+
src/main/cpp/core/ Dobby hook / CoreCLR 嵌入 / JNI helper / UnityResolve
4738
src/main/java/
48-
MonoRunner.java CoreCLR launcher (supports args)
49-
ModManagerUtils.java KeyboardView IME + InputConnection bridge
50-
51-
Android/launcher/ Smali launcher module
52-
src/main/smali/ ModManager.smali, ModManager$1.smali
53-
54-
TestAndroidProject/ Test Unity app (IL2CPP, arm64-v8a)
39+
ModManager.java CoreCLR 启动器
40+
ModManagerUpdater.java OTA 自动更新(CompletableFuture + AlertDialog)
41+
ModManagerUtils.java IME KeyboardView + InputConnection
5542
```
5643

5744
## Features
5845

5946
- **EGL SwapBuffers hook** with Dobby — renders ImGui overlay every frame
6047
- **Touch & key input** via InputConsumer hooks + cimgui Android backend
6148
- **IME support** (Chinese/Japanese) via custom KeyboardView + InputConnection bridge
62-
- **C→C# callback pipeline** — Java `commitText` → native `nativeSendChar` → C# `AddInputCharacter` in real time
63-
- **GL debug panel** — caps toggles (depth, blend, cull, etc.), blend/depth func selectors, GL state queries, viewport info
64-
- **Rainbow text shader** — custom GLSL shader applied via ImDrawList callbacks
49+
- **Mod system** — scan/load/unload with dependency resolution + auto-enable on restart
50+
- **Mod overlay API** — `OnBackgroundGUI` / `OnForegroundGUI` for direct game-screen drawing
51+
- **Auto-update** — OTA version check + download + SHA-256 verification + restart
52+
- **Config persistence** — STJ source-gen JSON, AOT-compatible
53+
- **File logging** — dual-write to logcat + `manager.log`
54+
- **GL debug panel** — caps toggles, blend/depth func selectors, GL state queries
6555
- **FontAwesome 7** icon support via embedded resource
6656
- **IImGuiRenderer** interface — swap between EGL, Vulkan backends
67-
- **CoreCLR args** — pass `string[]` from Java `MonoRunner.run()` to managed `Entry(int, IntPtr)`
57+
- **CoreCLR args** — pass `string[]` from Java to managed `Entry(int, IntPtr)`
6858

6959
## Build
7060

‎Scripts/build_release.sh‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
set -e
3+
4+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5+
echo "=== Build Release ==="
6+
echo "Root: $ROOT"
7+
8+
# 1. Build native library (AAR)
9+
echo ""
10+
echo "--- [1/3] Android AAR ---"
11+
cd "$ROOT/Android"
12+
./gradlew :library:assembleRelease -q
13+
AAR_SRC="$ROOT/Android/library/build/outputs/aar/library-release.aar"
14+
AAR_DST="$ROOT/release/library-release.aar"
15+
mkdir -p "$ROOT/release"
16+
cp "$AAR_SRC" "$AAR_DST"
17+
echo " → $AAR_DST"
18+
19+
# 2. Build .NET mod manager
20+
echo ""
21+
echo "--- [2/3] .NET ModManager ---"
22+
cd "$ROOT/StArray.ModManager"
23+
dotnet build -c Release
24+
DLL_DIR="$ROOT/StArray.ModManager/bin/Release/net10.0"
25+
echo " DLLs in: $DLL_DIR"
26+
ls -1 "$DLL_DIR"/*.dll | while read f; do echo " $(basename "$f")"; done
27+
28+
# 3. Package manager tar (exclude runtimes/)
29+
echo ""
30+
echo "--- [3/3] modmanager.tar ---"
31+
TAR_DST="$ROOT/release/modmanager.tar"
32+
rm -f "$TAR_DST"
33+
cd "$DLL_DIR"
34+
tar cf "$TAR_DST" --exclude='runtimes' *.dll
35+
gzip -f "$TAR_DST"
36+
echo " → ${TAR_DST}.gz ($(du -h "${TAR_DST}.gz" | cut -f1))"
37+
38+
echo ""
39+
echo "=== Done ==="
40+
echo " AAR: $AAR_DST"
41+
echo " TAR: $TAR_DST.gz"

0 commit comments

Comments
 (0)