-
Notifications
You must be signed in to change notification settings - Fork 27
[+] BepInEx support #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
新的 Mod 加载器入口点(BepInEx 和 MelonLoader)的类图classDiagram
class AquaMai.BepInEx.Plugin {
+const string PluginName
+ManualLogSource LogSource
+void Awake()
+void OnGUI()
}
class AquaMai.MelonLoader.AquaMai {
+void OnInitializeMelon()
+void OnGUI()
}
AquaMai.BepInEx.Plugin --|> BepInEx.BaseUnityPlugin
AquaMai.MelonLoader.AquaMai --|> MelonLoader.MelonMod
AquaMai.BepInEx.Plugin ..> AquaMai.Common.AquaMai : calls Bootstrap/OnGUI
AquaMai.MelonLoader.AquaMai ..> AquaMai.Common.AquaMai : calls Bootstrap/OnGUI
文件级别更改
提示和命令与 Sourcery 互动
自定义您的体验访问您的 仪表板 以:
获得帮助Original review guide in EnglishReviewer's GuideThis PR refactors the bootstrap and logging system into a shared common library, adds first-class BepInEx support with a dedicated plugin entry, embeds the TinyJSON library for internal JSON handling, restructures project namespaces, and updates the CI pipeline to package and publish the BepInEx DLL alongside existing artifacts. Class diagram for new and refactored bootstrap and logging systemclassDiagram
class AquaMai.Common.BootstrapOptions {
+Assembly CurrentAssembly
+Harmony Harmony
+Action<string> MsgStringAction
+Action<object> MsgObjectAction
+Action<string> ErrorStringAction
+Action<object> ErrorObjectAction
+Action<string> WarningStringAction
+Action<object> WarningObjectAction
}
class AquaMai.Common.AquaMai {
+static void Bootstrap(BootstrapOptions options)
+static void OnGUI()
+static void EarlyStageLog(string message)
}
class AquaMai.Core.Environment.MelonLogger {
+static Action<string> MsgStringAction
+static Action<object> MsgObjectAction
+static Action<string> ErrorStringAction
+static Action<object> ErrorObjectAction
+static Action<string> WarningStringAction
+static Action<object> WarningObjectAction
+static void Msg(string message)
+static void Msg(object message)
+static void Error(string message)
+static void Error(object message)
+static void Warning(string message)
+static void Warning(object message)
}
AquaMai.Common.AquaMai ..> AquaMai.Common.BootstrapOptions : uses
AquaMai.Common.AquaMai ..> AquaMai.Core.Environment.MelonLogger : sets logger
Class diagram for new mod loader entry points (BepInEx and MelonLoader)classDiagram
class AquaMai.BepInEx.Plugin {
+const string PluginName
+ManualLogSource LogSource
+void Awake()
+void OnGUI()
}
class AquaMai.MelonLoader.AquaMai {
+void OnInitializeMelon()
+void OnGUI()
}
AquaMai.BepInEx.Plugin --|> BepInEx.BaseUnityPlugin
AquaMai.MelonLoader.AquaMai --|> MelonLoader.MelonMod
AquaMai.BepInEx.Plugin ..> AquaMai.Common.AquaMai : calls Bootstrap/OnGUI
AquaMai.MelonLoader.AquaMai ..> AquaMai.Common.AquaMai : calls Bootstrap/OnGUI
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嘿 @Menci - 我已经查看了你的更改 - 这里有一些反馈:
- 将整个 TinyJSON 实现 vendor 会增加大量的维护开销——考虑将其作为 NuGet 依赖项或 git 子模块引用,而不是内联其所有源代码。
- 你的 CI 工作流程仍然有一个 TODO 来上传 BepInEx DLL——请更新上传和 Releaser 步骤以包含
AquaMai.BepInEx.dll
,以便发布是完整的。 - Cake 脚本已更改为还原
AquaMai.slnx
;请验证是否已提交.slnx
文件,并且所有构建/CI 脚本都一致地引用它,以避免构建中断。
AI 代理的提示
请解决此代码审查中的评论:
## 总体评论
- 将整个 TinyJSON 实现 vendor 会增加大量的维护开销——考虑将其作为 NuGet 依赖项或 git 子模块引用,而不是内联其所有源代码。
- 你的 CI 工作流程仍然有一个 TODO 来上传 BepInEx DLL——请更新上传和 Releaser 步骤以包含 `AquaMai.BepInEx.dll`,以便发布是完整的。
- Cake 脚本已更改为还原 `AquaMai.slnx`;请验证是否已提交 `.slnx` 文件,并且所有构建/CI 脚本都一致地引用它,以避免构建中断。
## 单独评论
### 评论 1
<location> `AquaMai.BepInEx/Plugin.cs:17` </location>
<code_context>
+
+ public readonly static ManualLogSource LogSource = global::BepInEx.Logging.Logger.CreateLogSource(BuildInfo.Name);
+
+ public void Awake()
+ {
+ var harmony = new HarmonyLib.Harmony(PluginName);
</code_context>
<issue_to_address>
Awake 方法不处理来自 Bootstrap 的异常。
将 Bootstrap 调用包装在 try-catch 块中,并使用 LogSource 记录任何异常,以确保错误在 BepInEx 日志中可见。
</issue_to_address>
### 评论 2
<location> `AquaMai.MelonLoader/AquaMai.cs:8` </location>
<code_context>
+
+public class AquaMai : MelonMod
+{
+ public override void OnInitializeMelon()
+ {
+ Common.AquaMai.Bootstrap(new Common.BootstrapOptions
</code_context>
<issue_to_address>
OnInitializeMelon 中没有针对 Bootstrap 失败的错误处理。
将 Bootstrap 调用包装在 try-catch 块中,并使用 MelonLogger.Error 记录异常,以帮助调试并防止模组意外禁用。
</issue_to_address>
### 评论 3
<location> `MelonLoader.TinyJSON/README.md:177` </location>
<code_context>
+* `EncodeOptions.PrettyPrint` will output nicely formatted JSON to make it more readable.
+* `EncodeOptions.NoTypeHints` will disable the outputting of type hints into the JSON output. This may be desirable if you plan to read the JSON into another application that might choke on the type information. You can override this on a per-member basis with the `TinyJSON.TypeHint` attribute.
+* `EncodeOptions.IncludePublicProperties` will include public properties in the output.
+* `EncodeOptions.EnforceHeirarchyOrder` will ensure fields and properties are encoded in class heirarchy order, from the root base class on down, but comes at a slight performance cost.
+
+## Using Variants
</code_context>
<issue_to_address>
将“Heirarchy”的拼写更正为“Hierarchy”。
请更新选项名称及其描述,以使用正确的拼写。
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
* `EncodeOptions.EnforceHeirarchyOrder` will ensure fields and properties are encoded in class heirarchy order, from the root base class on down, but comes at a slight performance cost.
=======
* `EncodeOptions.EnforceHierarchyOrder` will ensure fields and properties are encoded in class hierarchy order, from the root base class on down, but comes at a slight performance cost.
>>>>>>> REPLACE
</suggested_fix>
### 评论 4
<location> `MelonLoader.TinyJSON/Types/Variant.cs:46` </location>
<code_context>
+ }
+
+
+ public virtual object ToType( Type conversionType, IFormatProvider provider )
+ {
+ throw new InvalidCastException( "Cannot convert " + GetType() + " to " + conversionType.Name );
</code_context>
<issue_to_address>
考虑使用 Convert.ChangeType 和集中式异常处理程序将重复的转换和异常逻辑重构为单个泛型方法。
以下是如何将大约 200 行几乎相同的 throws/implicit 运算符折叠为少量方法,而无需更改任何外部行为:
1) 集中“cannot‐convert”异常
2) 通过单个泛型方法 + Convert.ChangeType 实现所有转换
3) 删除所有重复的 ToXxx/implicit 运算符
```csharp
public abstract class Variant : IConvertible
{
protected static readonly IFormatProvider FormatProvider = NumberFormatInfo.InvariantInfo;
// each concrete Variant must expose its raw CLR value
protected abstract object UnderlyingValue { get; }
// only one place to throw
private Exception Unsupported(string targetTypeName) =>
new InvalidCastException($"Cannot convert {GetType().Name} to {targetTypeName}");
// the only real conversion entry‐point
public virtual object ToType(Type conversionType, IFormatProvider provider)
{
var val = UnderlyingValue;
if (val is IConvertible ic)
return Convert.ChangeType(ic, conversionType, provider);
throw Unsupported(conversionType.Name);
}
// IConvertible boilerplate—each call goes through ToType()
TypeCode IConvertible.GetTypeCode() =>
UnderlyingValue is IConvertible ic ? ic.GetTypeCode() : TypeCode.Object;
bool IConvertible.ToBoolean(IFormatProvider p) =>
(bool)ToType(typeof(bool), p);
byte IConvertible.ToByte(IFormatProvider p) =>
(byte)ToType(typeof(byte), p);
char IConvertible.ToChar(IFormatProvider p) =>
(char)ToType(typeof(char), p);
DateTime IConvertible.ToDateTime(IFormatProvider p) =>
(DateTime)ToType(typeof(DateTime), p);
decimal IConvertible.ToDecimal(IFormatProvider p) =>
(decimal)ToType(typeof(decimal), p);
double IConvertible.ToDouble(IFormatProvider p) =>
(double)ToType(typeof(double), p);
short IConvertible.ToInt16(IFormatProvider p) =>
(short)ToType(typeof(short), p);
int IConvertible.ToInt32(IFormatProvider p) =>
(int)ToType(typeof(int), p);
long IConvertible.ToInt64(IFormatProvider p) =>
(long)ToType(typeof(long), p);
sbyte IConvertible.ToSByte(IFormatProvider p) =>
(sbyte)ToType(typeof(sbyte), p);
float IConvertible.ToSingle(IFormatProvider p) =>
(float)ToType(typeof(float), p);
string IConvertible.ToString(IFormatProvider p) =>
(string)ToType(typeof(string), p);
ushort IConvertible.ToUInt16(IFormatProvider p) =>
(ushort)ToType(typeof(ushort), p);
uint IConvertible.ToUInt32(IFormatProvider p) =>
(uint)ToType(typeof(uint), p);
ulong IConvertible.ToUInt64(IFormatProvider p) =>
(ulong)ToType(typeof(ulong), p);
// Now callers can still do:
// int x = (int)variant; // via Convert.ChangeType
// string s = variant.ToString();
// and you’ve removed ~200 lines of duplication.
}
```
— 这保留了每个 IConvertible 和 implicit‐cast 用法,但分解了所有相同的 throw 存根,并删除了每个单独的 `public virtual Xxx(...)` + `implicit operator Xxx(Variant)` 块。
</issue_to_address>
### 评论 5
<location> `MelonLoader.TinyJSON/Types/ProxyArray.cs:57` </location>
<code_context>
+ }
+
+
+ internal bool CanBeMultiRankArray( int[] rankLengths )
+ {
+ return CanBeMultiRankArray( 0, rankLengths );
</code_context>
<issue_to_address>
考虑使用 LINQ 和表达式主体成员重构 CanBeMultiRankArray 方法,以减少样板代码并提高清晰度。
考虑使用 LINQ 和表达式主体成员简化 `CanBeMultiRankArray`。这保持了相同的行为,但减少了样板代码和分支:
```csharp
public sealed class ProxyArray : Variant, IEnumerable<Variant>
{
readonly List<Variant> list = new List<Variant>();
public void Add(Variant item) => list.Add(item);
public Variant this[int i]
{
get => list[i];
set => list[i] = value;
}
public int Count => list.Count;
public IEnumerator<Variant> GetEnumerator() => list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
internal bool CanBeMultiRankArray(int[] dims)
=> CheckMultiRank(0, dims);
bool CheckMultiRank(int depth, int[] dims)
{
if (dims == null) throw new ArgumentNullException(nameof(dims));
dims[depth] = Count;
if (depth == dims.Length - 1)
return true;
// must all be ProxyArray with equal counts
var children = list
.OfType<ProxyArray>()
.ToList();
if (children.Count != Count)
return false;
var expected = children[0].Count;
if (children.Any(c => c.Count != expected))
return false;
// recurse
return children.All(c => c.CheckMultiRank(depth + 1, dims));
}
}
```
主要变化:
- 将两个重载合并为单个 `CheckMultiRank` 帮助器。
- 使用 `OfType<ProxyArray>()` 进行过滤和强制转换。
- 提前返回不匹配的子计数。
- 用于简单方法/属性的表达式主体成员。
</issue_to_address>
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进你的评论。
Original comment in English
Hey @Menci - I've reviewed your changes - here's some feedback:
- Vendoring the entire TinyJSON implementation adds a lot of maintenance overhead—consider referencing it as a NuGet dependency or git submodule instead of inlining all of its source.
- Your CI workflow still has a TODO to upload the BepInEx DLL—please update the upload and Releaser steps to include
AquaMai.BepInEx.dll
so releases are complete. - The Cake script was changed to restore
AquaMai.slnx
; please verify that the.slnx
file is committed and all build/CI scripts reference it consistently to avoid build breakage.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Vendoring the entire TinyJSON implementation adds a lot of maintenance overhead—consider referencing it as a NuGet dependency or git submodule instead of inlining all of its source.
- Your CI workflow still has a TODO to upload the BepInEx DLL—please update the upload and Releaser steps to include `AquaMai.BepInEx.dll` so releases are complete.
- The Cake script was changed to restore `AquaMai.slnx`; please verify that the `.slnx` file is committed and all build/CI scripts reference it consistently to avoid build breakage.
## Individual Comments
### Comment 1
<location> `AquaMai.BepInEx/Plugin.cs:17` </location>
<code_context>
+
+ public readonly static ManualLogSource LogSource = global::BepInEx.Logging.Logger.CreateLogSource(BuildInfo.Name);
+
+ public void Awake()
+ {
+ var harmony = new HarmonyLib.Harmony(PluginName);
</code_context>
<issue_to_address>
Awake method does not handle exceptions from Bootstrap.
Wrap the Bootstrap call in a try-catch block and log any exceptions using LogSource to ensure errors are visible in BepInEx logs.
</issue_to_address>
### Comment 2
<location> `AquaMai.MelonLoader/AquaMai.cs:8` </location>
<code_context>
+
+public class AquaMai : MelonMod
+{
+ public override void OnInitializeMelon()
+ {
+ Common.AquaMai.Bootstrap(new Common.BootstrapOptions
</code_context>
<issue_to_address>
No error handling in OnInitializeMelon for Bootstrap failures.
Wrap the Bootstrap call in a try-catch block and log exceptions with MelonLogger.Error to aid debugging and prevent the mod from being disabled unexpectedly.
</issue_to_address>
### Comment 3
<location> `MelonLoader.TinyJSON/README.md:177` </location>
<code_context>
+* `EncodeOptions.PrettyPrint` will output nicely formatted JSON to make it more readable.
+* `EncodeOptions.NoTypeHints` will disable the outputting of type hints into the JSON output. This may be desirable if you plan to read the JSON into another application that might choke on the type information. You can override this on a per-member basis with the `TinyJSON.TypeHint` attribute.
+* `EncodeOptions.IncludePublicProperties` will include public properties in the output.
+* `EncodeOptions.EnforceHeirarchyOrder` will ensure fields and properties are encoded in class heirarchy order, from the root base class on down, but comes at a slight performance cost.
+
+## Using Variants
</code_context>
<issue_to_address>
Correct the spelling of 'Heirarchy' to 'Hierarchy'.
Please update both the option name and its description to use the correct spelling.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
* `EncodeOptions.EnforceHeirarchyOrder` will ensure fields and properties are encoded in class heirarchy order, from the root base class on down, but comes at a slight performance cost.
=======
* `EncodeOptions.EnforceHierarchyOrder` will ensure fields and properties are encoded in class hierarchy order, from the root base class on down, but comes at a slight performance cost.
>>>>>>> REPLACE
</suggested_fix>
### Comment 4
<location> `MelonLoader.TinyJSON/Types/Variant.cs:46` </location>
<code_context>
+ }
+
+
+ public virtual object ToType( Type conversionType, IFormatProvider provider )
+ {
+ throw new InvalidCastException( "Cannot convert " + GetType() + " to " + conversionType.Name );
</code_context>
<issue_to_address>
Consider refactoring the repeated conversion and exception logic into a single generic method using Convert.ChangeType and a centralized exception handler.
Here’s how you could collapse ~200 lines of nearly-identical throws/implicit operators down to a handful of methods, without changing any external behavior:
1) centralize the “cannot‐convert” exception
2) implement all conversions via a single generic method + Convert.ChangeType
3) drop all the duplicated ToXxx/implicit operators
```csharp
public abstract class Variant : IConvertible
{
protected static readonly IFormatProvider FormatProvider = NumberFormatInfo.InvariantInfo;
// each concrete Variant must expose its raw CLR value
protected abstract object UnderlyingValue { get; }
// only one place to throw
private Exception Unsupported(string targetTypeName) =>
new InvalidCastException($"Cannot convert {GetType().Name} to {targetTypeName}");
// the only real conversion entry‐point
public virtual object ToType(Type conversionType, IFormatProvider provider)
{
var val = UnderlyingValue;
if (val is IConvertible ic)
return Convert.ChangeType(ic, conversionType, provider);
throw Unsupported(conversionType.Name);
}
// IConvertible boilerplate—each call goes through ToType()
TypeCode IConvertible.GetTypeCode() =>
UnderlyingValue is IConvertible ic ? ic.GetTypeCode() : TypeCode.Object;
bool IConvertible.ToBoolean(IFormatProvider p) =>
(bool)ToType(typeof(bool), p);
byte IConvertible.ToByte(IFormatProvider p) =>
(byte)ToType(typeof(byte), p);
char IConvertible.ToChar(IFormatProvider p) =>
(char)ToType(typeof(char), p);
DateTime IConvertible.ToDateTime(IFormatProvider p) =>
(DateTime)ToType(typeof(DateTime), p);
decimal IConvertible.ToDecimal(IFormatProvider p) =>
(decimal)ToType(typeof(decimal), p);
double IConvertible.ToDouble(IFormatProvider p) =>
(double)ToType(typeof(double), p);
short IConvertible.ToInt16(IFormatProvider p) =>
(short)ToType(typeof(short), p);
int IConvertible.ToInt32(IFormatProvider p) =>
(int)ToType(typeof(int), p);
long IConvertible.ToInt64(IFormatProvider p) =>
(long)ToType(typeof(long), p);
sbyte IConvertible.ToSByte(IFormatProvider p) =>
(sbyte)ToType(typeof(sbyte), p);
float IConvertible.ToSingle(IFormatProvider p) =>
(float)ToType(typeof(float), p);
string IConvertible.ToString(IFormatProvider p) =>
(string)ToType(typeof(string), p);
ushort IConvertible.ToUInt16(IFormatProvider p) =>
(ushort)ToType(typeof(ushort), p);
uint IConvertible.ToUInt32(IFormatProvider p) =>
(uint)ToType(typeof(uint), p);
ulong IConvertible.ToUInt64(IFormatProvider p) =>
(ulong)ToType(typeof(ulong), p);
// Now callers can still do:
// int x = (int)variant; // via Convert.ChangeType
// string s = variant.ToString();
// and you’ve removed ~200 lines of duplication.
}
```
— this preserves every IConvertible and implicit‐cast usage, but factors out all the identical throw stubs and removes each individual `public virtual Xxx(...)` + `implicit operator Xxx(Variant)` block.
</issue_to_address>
### Comment 5
<location> `MelonLoader.TinyJSON/Types/ProxyArray.cs:57` </location>
<code_context>
+ }
+
+
+ internal bool CanBeMultiRankArray( int[] rankLengths )
+ {
+ return CanBeMultiRankArray( 0, rankLengths );
</code_context>
<issue_to_address>
Consider refactoring the CanBeMultiRankArray method using LINQ and expression-bodied members to reduce boilerplate and improve clarity.
Consider simplifying `CanBeMultiRankArray` with LINQ and expression‐bodied members. This keeps the same behavior but cuts down on boilerplate and branching:
```csharp
public sealed class ProxyArray : Variant, IEnumerable<Variant>
{
readonly List<Variant> list = new List<Variant>();
public void Add(Variant item) => list.Add(item);
public Variant this[int i]
{
get => list[i];
set => list[i] = value;
}
public int Count => list.Count;
public IEnumerator<Variant> GetEnumerator() => list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
internal bool CanBeMultiRankArray(int[] dims)
=> CheckMultiRank(0, dims);
bool CheckMultiRank(int depth, int[] dims)
{
if (dims == null) throw new ArgumentNullException(nameof(dims));
dims[depth] = Count;
if (depth == dims.Length - 1)
return true;
// must all be ProxyArray with equal counts
var children = list
.OfType<ProxyArray>()
.ToList();
if (children.Count != Count)
return false;
var expected = children[0].Count;
if (children.Any(c => c.Count != expected))
return false;
// recurse
return children.All(c => c.CheckMultiRank(depth + 1, dims));
}
}
```
Key changes:
- Combine the two overloads into a single `CheckMultiRank` helper.
- Use `OfType<ProxyArray>()` to both filter and cast.
- Early‐return on mismatched child counts.
- Expression‐bodied members for trivial methods/properties.
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Vendoring MelonLoader.TinyJSON for both platforms since MelonLoader is also deprecating it. |
谁会用 bepinex |
这 CI 怎么在 main 上跑的 |
@@ -59,6 +59,7 @@ public static void OnBeforePatch() | |||
Screen.SetResolution(width, height, FullScreenMode.Windowed); | |||
} | |||
|
|||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fawo Sinmai.app Sinmai.elf
以及我大概不想在 melonloader 用的 binary 里面也 bundle tinyjson,因为 sinmai 的 melonloader 大概已经停止在 0.6.4 了,更高版本有兼容性问题 |
0.7.0 好像能用 |
搞一份新的 sinmai,把 0.7.0 放进去,控制台里面会什么都没有,然后 melonloader 没有被加载上(0.6.5 及以上版本都是如此) 假如你放了 0.6.4 进去,启动一次,把 0.6.4 删掉,再把 0.7.0 放进去,诶,能用 神奇吧,这个事情挺普遍的,很多人包括我都复现了,但是我没搞明白为什么 所以我现在一般都是让别人用 0.6.4 |
不过好像也不太容易让 MelonLoader 版本去用 MelonLoader 的 TinyJSON(编译没法分开编译,好像只能 patch Assembly),而且 gzipped 十多 K 问题不大(( |
@clansty 我没遇到,我只遇到过有些版本 MelonLoader 用我替换进去的 debug mono 会崩溃的问题 |
bepinex 应该用什么版本,我这边起不来,没法调试 |
我就是用最新的 bepinex |
我试试用 segatools 行不行 |
尝试性只让 BepInEx embed TinyJson,暂存Subject: [PATCH] Changes
---
Index: AquaMai.Common/AquaMai.Common.csproj
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AquaMai.Common/AquaMai.Common.csproj b/AquaMai.Common/AquaMai.Common.csproj
--- a/AquaMai.Common/AquaMai.Common.csproj (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/AquaMai.Common/AquaMai.Common.csproj (date 1751184275857)
@@ -37,11 +37,7 @@
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="../MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj" />
<ProjectReference Include="../AquaMai.Config.Interfaces/AquaMai.Config.Interfaces.csproj" />
- <ProjectReference Include="../AquaMai.Config/AquaMai.Config.csproj" />
- <ProjectReference Include="../AquaMai.Core/AquaMai.Core.csproj" />
- <ProjectReference Include="../AquaMai.Mods/AquaMai.Mods.csproj" />
</ItemGroup>
<ItemGroup>
@@ -60,9 +56,6 @@
</Target>
<ItemGroup>
- <EmbeddedResource Include="$(OutputPath)MelonLoader.TinyJSON.dll">
- <LogicalName>MelonLoader.TinyJSON.dll</LogicalName>
- </EmbeddedResource>
<EmbeddedResource Include="$(OutputPath)AquaMai.Config.Interfaces.dll">
<LogicalName>AquaMai.Config.Interfaces.dll</LogicalName>
</EmbeddedResource>
Index: AquaMai.MelonLoader/AquaMai.MelonLoader.csproj
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AquaMai.MelonLoader/AquaMai.MelonLoader.csproj b/AquaMai.MelonLoader/AquaMai.MelonLoader.csproj
--- a/AquaMai.MelonLoader/AquaMai.MelonLoader.csproj (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/AquaMai.MelonLoader/AquaMai.MelonLoader.csproj (date 1751184295424)
@@ -13,7 +13,7 @@
<LangVersion>12</LangVersion>
<NoWarn>414</NoWarn>
<AssemblySearchPaths>$(ProjectDir)../Libs/;$(AssemblySearchPaths)</AssemblySearchPaths>
- <OutputPath>$(ProjectDir)../Output/</OutputPath>
+ <OutputPath>$(ProjectDir)../Output/MelonLoader/</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
@@ -34,10 +34,6 @@
</PropertyGroup>
<ItemGroup>
- <ProjectReference Include="../AquaMai.Config.Interfaces/AquaMai.Config.Interfaces.csproj" />
- <ProjectReference Include="../AquaMai.Config/AquaMai.Config.csproj" />
- <ProjectReference Include="../AquaMai.Core/AquaMai.Core.csproj" />
- <ProjectReference Include="../AquaMai.Mods/AquaMai.Mods.csproj" />
<ProjectReference Include="../AquaMai.Common/AquaMai.Common.csproj" />
</ItemGroup>
Index: AquaMai.BepInEx/AquaMai.BepInEx.csproj
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AquaMai.BepInEx/AquaMai.BepInEx.csproj b/AquaMai.BepInEx/AquaMai.BepInEx.csproj
--- a/AquaMai.BepInEx/AquaMai.BepInEx.csproj (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/AquaMai.BepInEx/AquaMai.BepInEx.csproj (date 1751184417454)
@@ -12,7 +12,7 @@
<LangVersion>12</LangVersion>
<NoWarn>414</NoWarn>
<AssemblySearchPaths>$(ProjectDir)../Libs/;$(AssemblySearchPaths)</AssemblySearchPaths>
- <OutputPath>$(ProjectDir)../Output/</OutputPath>
+ <OutputPath>$(ProjectDir)../Output/BepInEx/</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
@@ -33,12 +33,15 @@
</PropertyGroup>
<ItemGroup>
- <ProjectReference Include="../AquaMai.Config.Interfaces/AquaMai.Config.Interfaces.csproj" />
- <ProjectReference Include="../AquaMai.Config/AquaMai.Config.csproj" />
- <ProjectReference Include="../AquaMai.Core/AquaMai.Core.csproj" />
- <ProjectReference Include="../AquaMai.Mods/AquaMai.Mods.csproj" />
+ <ProjectReference Include="../MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj" />
<ProjectReference Include="../AquaMai.Common/AquaMai.Common.csproj" />
</ItemGroup>
+
+ <ItemGroup>
+ <EmbeddedResource Include="$(OutputPath)MelonLoader.dll">
+ <LogicalName>MelonLoader.dll</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
Index: build.ps1
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/build.ps1 b/build.ps1
--- a/build.ps1 (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/build.ps1 (date 1751184343544)
@@ -9,5 +9,7 @@
dotnet tool restore
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+taskkill /f /im "dotnet.exe" >$null
+
dotnet cake @args
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Index: MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj b/MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj
--- a/MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/MelonLoader.TinyJSON/MelonLoader.TinyJSON.csproj (date 1751184466402)
@@ -6,13 +6,14 @@
<OutputType>Library</OutputType>
<RootNamespace>MelonLoader.TinyJSON</RootNamespace>
<AssemblyName>MelonLoader.TinyJSON</AssemblyName>
+ <TargetName>MelonLoader</TargetName>
<TargetFramework>net48</TargetFramework>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<LangVersion>12</LangVersion>
<NoWarn>414</NoWarn>
<AssemblySearchPaths>$(ProjectDir)../Libs/;$(AssemblySearchPaths)</AssemblySearchPaths>
- <OutputPath>$(ProjectDir)../Output/</OutputPath>
+ <OutputPath>$(ProjectDir)../Output/BepInEx/</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
</PropertyGroup>
Index: AquaMai.Common/AssemblyLoader.cs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/AquaMai.Common/AssemblyLoader.cs b/AquaMai.Common/AssemblyLoader.cs
--- a/AquaMai.Common/AssemblyLoader.cs (revision 01f07bad1e1b763499bbc0e60384bbee32f11ffd)
+++ b/AquaMai.Common/AssemblyLoader.cs (date 1751184366753)
@@ -19,7 +19,7 @@
private static readonly Dictionary<AssemblyName, string> Assemblies = new()
{
- [AssemblyName.TinyJSON] = "MelonLoader.TinyJSON.dll",
+ [AssemblyName.TinyJSON] = "MelonLoader.dll",
[AssemblyName.ConfigInterfaces] = "AquaMai.Config.Interfaces.dll",
[AssemblyName.Config] = "AquaMai.Config.dll",
[AssemblyName.Core] = "AquaMai.Core.dll",
@@ -54,6 +54,11 @@
{
return AppDomain.CurrentDomain.Load(DecompressToBytes(compressedStream));
}
+ if (assemblyName == Assemblies[AssemblyName.TinyJSON])
+ {
+ // Special case for MelonLoader.TinyJSON.dll, will only be embedded in binary for BepInEx.
+ return null;
+ }
throw new Exception($"Embedded assembly \"{assemblyName}\" not found.");
}
懒得搞了,晚点我从别的地方抠十几 KB 出来 |
我觉得你可以考虑自己维护一个支持 BepInEX 的分支叫 BquaMai 说不定我什么时候改了啥就 break 了,比如说我想把 Tomlet Shim 掉,BepInEx 里面也没内置 Tomlet(虽然有个自己的 Toml 解析器) |
# Conflicts: # AquaMai.slnx
好的,这是翻译成中文的 pull request 总结:
Sourcery 总结
添加 BepInEx 支持并将项目重构为通用的引导和环境层,该层抽象了 MelonLoader 和 BepInEx 的日志记录和初始化,供应商 TinyJSON 解析器,调整构建脚本和命名空间,并相应地更新 CI 工作流程和文档。
新功能:
增强功能:
构建:
CI:
文档:
Original summary in English
Summary by Sourcery
Add BepInEx support and refactor the project into a common bootstrap and environment layer that abstracts logging and initialization for both MelonLoader and BepInEx, vendor the TinyJSON parser, adjust build scripts and namespaces, and update CI workflows and documentation accordingly.
New Features:
Enhancements:
Build:
CI:
Documentation: