Use System.Text.Json with BepInEx

This commit is contained in:
Adele Reed 2024-07-23 12:14:01 -07:00
parent 971f8f6c2b
commit 8fa1c72b63
24 changed files with 284 additions and 61 deletions

View File

@ -20,24 +20,22 @@
https://nuget.bepinex.dev/v3/index.json
</RestoreAdditionalProjectSources>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BepInEx (Debug)|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\BepInEx (Debug)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BepInEx (Release)|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\BepInEx (Release)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System"/>

10
Rizu.Core/App.config Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?><configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -29,11 +29,21 @@ public class Exporter
{
yield break;
}
var user = Singleton<UserDataManager>.Instance.GetUserData(score.PlayerIndex);
var import = ScoreConversion.CreateScoreBatchManual(score);
yield return SubmitImport(import, user.Detail.AccessCode);
var user = Singleton<UserDataManager>.Instance.GetUserData(score.PlayerIndex);
string import = "";
try
{
import = ScoreConversion.CreateScoreBatchManual(score);
}
catch (Exception exception)
{
Logger.Error(exception.ToString());
}
if (import != "")
yield return SubmitImport(import, user.Detail.AccessCode);
}
public IEnumerator ExportDan(UserDetail userDetail)
@ -123,9 +133,10 @@ public class Exporter
TachiResponse<BatchManualResponseBody> resp;
Logger.Debug("Received response from Tachi (Response code {1}): {0}", req.downloadHandler.text, req.responseCode);
try
{
resp = JsonUtility.FromJson<TachiResponse<BatchManualResponseBody>>(req.downloadHandler.text);
resp = JsonShim.Deserialize<TachiResponse<BatchManualResponseBody>>(req.downloadHandler.text);
}
catch (Exception e)
{
@ -139,12 +150,11 @@ public class Exporter
yield break;
}
Logger.Info("{0}", resp.description);
var pollUrl = resp.body?.url;
if (string.IsNullOrEmpty(pollUrl))
{
Logger.Debug("Received no poll uri!");
yield break;
}
@ -170,7 +180,7 @@ public class Exporter
try
{
pollResp = JsonUtility.FromJson<TachiResponse<ImportStatusResponseBody>>(pollReq.downloadHandler.text);
pollResp = JsonShim.Deserialize<TachiResponse<ImportStatusResponseBody>>(pollReq.downloadHandler.text);
}
catch (Exception e)
{

39
Rizu.Core/JsonShim.cs Normal file
View File

@ -0,0 +1,39 @@
namespace Rizu.Core;
/*
* JsonShim creates a single place that JSON APIs get called from, to avoid having to manually write precompiler directives every time.
* Never call a JSON package directly, always call via JsonShim.
*/
#if MONOMOD
using UnityEngine;
using System;
#else
using System.Text.Json;
#endif
public class JsonShim
{
public static string Serialize(object Target)
{
#if MONOMOD
return JsonUtility.ToJson(Target);
#else
return JsonSerializer.Serialize(Target);
#endif
}
public static T Deserialize<T>(string data)
{
#if MONOMOD
return JsonUtility.FromJson<T>(data);
#else
return JsonSerializer.Deserialize<T>(data);
#endif
}
}
#if MONOMOD
[AttributeUsage(AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)]
public class JsonIncludeAttribute : Attribute { }
#endif

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManual
{
[JsonInclude]
public BatchManualMeta meta = new();
public BatchManualScore[] scores;
[JsonInclude]
public BatchManualScore[] scores;
[JsonInclude]
public BatchManualMatchingClass classes;
}

View File

@ -1,9 +1,14 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualDan
{
[JsonInclude]
public string dan;
}

View File

@ -1,9 +1,14 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualMatchingClass
{
[JsonInclude]
public string matchingClass;
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualMeta
{
[JsonInclude]
public string game = "maimaidx";
[JsonInclude]
public string playtype = "Single";
[JsonInclude]
public string service = "Rizu";
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualOptional
{
[JsonInclude]
public uint fast;
[JsonInclude]
public uint slow;
[JsonInclude]
public uint maxCombo;
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualRankUp
{
[JsonInclude]
public BatchManualMeta meta = new();
[JsonInclude]
public BatchManualScore[] scores;
[JsonInclude]
public BatchManualDan classes;
}

View File

@ -1,9 +1,14 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualResponseBody
{
[JsonInclude]
public string url;
}

View File

@ -1,16 +1,28 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualScore
{
[JsonInclude]
public float percent;
[JsonInclude]
public string lamp;
[JsonInclude]
public string matchType = "songTitle";
[JsonInclude]
public string identifier;
[JsonInclude]
public string difficulty;
[JsonInclude]
public long timeAchieved;
[JsonInclude]
public BatchManualScoreJudgements judgements;
[JsonInclude]
public BatchManualOptional optional;
}

View File

@ -1,13 +1,22 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class BatchManualScoreJudgements
{
[JsonInclude]
public uint pcrit;
[JsonInclude]
public uint perfect;
[JsonInclude]
public uint great;
[JsonInclude]
public uint good;
[JsonInclude]
public uint miss;
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class ImportDocument
{
[JsonInclude]
public string[] scoreIDs;
[JsonInclude]
public ImportErrContent[] errors;
[JsonInclude]
public SessionInfoReturn[] createdSessions;
}

View File

@ -1,10 +1,16 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class ImportErrContent
{
[JsonInclude]
public string type;
[JsonInclude]
public string message;
}

View File

@ -1,10 +1,16 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class ImportProgress
{
[JsonInclude]
public string description;
[JsonInclude]
public int value;
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class ImportStatusResponseBody
{
[JsonInclude]
public string importStatus;
[JsonInclude]
public ImportProgress progress;
[JsonInclude]
public ImportDocument import;
}

View File

@ -1,10 +1,16 @@
using System;
#if BEPINEX
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class SessionInfoReturn
{
[JsonInclude]
public string type;
[JsonInclude]
public string sessionID;
}

View File

@ -1,11 +1,18 @@
using System;
#if BEPINEX // When we're building for BepInEx, the dummy JsonInclude is *not* defined, so let's cover that base.
using System.Text.Json.Serialization;
#endif
namespace Rizu.Core.Models;
[Serializable]
public class TachiResponse<T>
{
[JsonInclude]
public bool success;
[JsonInclude]
public string description;
[JsonInclude]
public T body;
}

View File

@ -15,25 +15,83 @@
<FileAlignment>512</FileAlignment>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoMod (Release)|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>MONOMOD;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\MonoMod (Release)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoMod (Debug)|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>MONOMOD;DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\MonoMod (Debug)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<ItemGroup Condition="$(DefineConstants.Contains(MONOMOD))">
<Reference Include="UnityEngine.JSONSerializeModule">
<HintPath>..\External\UnityEngine.JSONSerializeModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BepInEx (Debug)|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<DefineConstants>BEPINEX;DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\BepInEx (Debug)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'BepInEx (Release)|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>BEPINEX;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<OutputPath>bin\BepInEx (Release)\</OutputPath>
</PropertyGroup>
<ItemGroup Condition="$(DefineConstants.Contains(BEPINEX))">
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
</Reference>
<Reference Include="System.Text.Json, Version=8.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Json.8.0.4\lib\net462\System.Text.Json.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="System"/>
<Reference Include="System.Core"/>
@ -47,10 +105,6 @@
<HintPath>..\External\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.JSONSerializeModule">
<HintPath>..\External\UnityEngine.JSONSerializeModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.UnityWebRequestModule">
<HintPath>..\External\UnityEngine.UnityWebRequestModule.dll</HintPath>
<Private>False</Private>
@ -60,6 +114,7 @@
<Compile Include="Config.cs" />
<Compile Include="Exporter.cs" />
<Compile Include="ForceAcceptAllCertificateHandler.cs" />
<Compile Include="JsonShim.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Models\BatchManual.cs" />
<Compile Include="Models\BatchManualDan.cs" />

View File

@ -3,7 +3,6 @@ using DB;
using MAI2.Util;
using Manager;
using Rizu.Core.Models;
using UnityEngine;
namespace Rizu.Core;
@ -89,7 +88,7 @@ public static class ScoreConversion
score.matchType = "tachiSongID";
}
return JsonUtility.ToJson(new BatchManual
return JsonShim.Serialize(new BatchManual
{
meta = new BatchManualMeta(),
scores = [score],
@ -108,7 +107,7 @@ public static class ScoreConversion
return null;
}
return JsonUtility.ToJson(new BatchManualRankUp
return JsonShim.Serialize(new BatchManualRankUp
{
meta = new BatchManualMeta(),
scores = [],

12
Rizu.Core/packages.config Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net462" />
<package id="System.Buffers" version="4.5.1" targetFramework="net462" />
<package id="System.Memory" version="4.5.5" targetFramework="net462" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net462" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net462" />
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net462" />
<package id="System.Text.Json" version="8.0.4" targetFramework="net462" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
</packages>

View File

@ -15,24 +15,11 @@
<FileAlignment>512</FileAlignment>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoMod (Debug)|AnyCPU' ">
<OutputPath>bin\MonoMod (Debug)\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'MonoMod (Release)|AnyCPU' ">
<OutputPath>bin\MonoMod (Release)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System"/>

View File

@ -8,21 +8,31 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rizu.BepInEx", "Rizu.BepInE
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
MonoMod (Debug)|Any CPU = MonoMod (Debug)|Any CPU
MonoMod (Release)|Any CPU = MonoMod (Release)|Any CPU
BepInEx (Release)|Any CPU = BepInEx (Release)|Any CPU
BepInEx (Debug)|Any CPU = BepInEx (Debug)|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4241A369-1619-4450-8182-CB66F447985F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.Release|Any CPU.Build.0 = Release|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.Release|Any CPU.Build.0 = Release|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.Release|Any CPU.Build.0 = Release|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.MonoMod (Debug)|Any CPU.ActiveCfg = BepInEx (Debug)|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.MonoMod (Release)|Any CPU.ActiveCfg = BepInEx (Release)|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.BepInEx (Release)|Any CPU.ActiveCfg = BepInEx (Release)|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.BepInEx (Release)|Any CPU.Build.0 = BepInEx (Release)|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.BepInEx (Debug)|Any CPU.ActiveCfg = BepInEx (Debug)|Any CPU
{4DDF918E-7A74-4266-B56A-028D66ED336F}.BepInEx (Debug)|Any CPU.Build.0 = BepInEx (Debug)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.MonoMod (Debug)|Any CPU.ActiveCfg = MonoMod (Debug)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.MonoMod (Debug)|Any CPU.Build.0 = MonoMod (Debug)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.MonoMod (Release)|Any CPU.ActiveCfg = MonoMod (Release)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.MonoMod (Release)|Any CPU.Build.0 = MonoMod (Release)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.BepInEx (Release)|Any CPU.ActiveCfg = BepInEx (Release)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.BepInEx (Release)|Any CPU.Build.0 = BepInEx (Release)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.BepInEx (Debug)|Any CPU.ActiveCfg = BepInEx (Debug)|Any CPU
{4241A369-1619-4450-8182-CB66F447985F}.BepInEx (Debug)|Any CPU.Build.0 = BepInEx (Debug)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.MonoMod (Debug)|Any CPU.ActiveCfg = MonoMod (Debug)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.MonoMod (Debug)|Any CPU.Build.0 = MonoMod (Debug)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.MonoMod (Release)|Any CPU.ActiveCfg = MonoMod (Release)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.MonoMod (Release)|Any CPU.Build.0 = MonoMod (Release)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.BepInEx (Release)|Any CPU.ActiveCfg = MonoMod (Release)|Any CPU
{888E076C-8A77-453F-87DC-BC0186FDBB55}.BepInEx (Debug)|Any CPU.ActiveCfg = MonoMod (Debug)|Any CPU
EndGlobalSection
EndGlobal