diff --git a/Rizu.BepInEx/Rizu.BepInEx.csproj b/Rizu.BepInEx/Rizu.BepInEx.csproj index 13bc3a3..9baccb4 100644 --- a/Rizu.BepInEx/Rizu.BepInEx.csproj +++ b/Rizu.BepInEx/Rizu.BepInEx.csproj @@ -20,24 +20,22 @@ https://nuget.bepinex.dev/v3/index.json - - AnyCPU + true full false - bin\Debug\ DEBUG;TRACE prompt 4 + bin\BepInEx (Debug)\ - - AnyCPU + pdbonly true - bin\Release\ TRACE prompt 4 + bin\BepInEx (Release)\ diff --git a/Rizu.Core/App.config b/Rizu.Core/App.config new file mode 100644 index 0000000..9816074 --- /dev/null +++ b/Rizu.Core/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Rizu.Core/Exporter.cs b/Rizu.Core/Exporter.cs index cedb595..352df79 100644 --- a/Rizu.Core/Exporter.cs +++ b/Rizu.Core/Exporter.cs @@ -29,11 +29,21 @@ public class Exporter { yield break; } - - var user = Singleton.Instance.GetUserData(score.PlayerIndex); - var import = ScoreConversion.CreateScoreBatchManual(score); - yield return SubmitImport(import, user.Detail.AccessCode); + var user = Singleton.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 resp; + Logger.Debug("Received response from Tachi (Response code {1}): {0}", req.downloadHandler.text, req.responseCode); try { - resp = JsonUtility.FromJson>(req.downloadHandler.text); + resp = JsonShim.Deserialize>(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>(pollReq.downloadHandler.text); + pollResp = JsonShim.Deserialize>(pollReq.downloadHandler.text); } catch (Exception e) { diff --git a/Rizu.Core/JsonShim.cs b/Rizu.Core/JsonShim.cs new file mode 100644 index 0000000..ffaa38c --- /dev/null +++ b/Rizu.Core/JsonShim.cs @@ -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(string data) + { +#if MONOMOD + return JsonUtility.FromJson(data); +#else + return JsonSerializer.Deserialize(data); +#endif + } +} + +#if MONOMOD +[AttributeUsage(AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)] +public class JsonIncludeAttribute : Attribute { } +#endif \ No newline at end of file diff --git a/Rizu.Core/Models/BatchManual.cs b/Rizu.Core/Models/BatchManual.cs index cb8a20f..c8c446a 100644 --- a/Rizu.Core/Models/BatchManual.cs +++ b/Rizu.Core/Models/BatchManual.cs @@ -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; } diff --git a/Rizu.Core/Models/BatchManualDan.cs b/Rizu.Core/Models/BatchManualDan.cs index c27d419..0ebceaf 100644 --- a/Rizu.Core/Models/BatchManualDan.cs +++ b/Rizu.Core/Models/BatchManualDan.cs @@ -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; } \ No newline at end of file diff --git a/Rizu.Core/Models/BatchManualMatchingClass.cs b/Rizu.Core/Models/BatchManualMatchingClass.cs index 7095b3d..36593d8 100644 --- a/Rizu.Core/Models/BatchManualMatchingClass.cs +++ b/Rizu.Core/Models/BatchManualMatchingClass.cs @@ -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; } diff --git a/Rizu.Core/Models/BatchManualMeta.cs b/Rizu.Core/Models/BatchManualMeta.cs index a1081b0..935fd17 100644 --- a/Rizu.Core/Models/BatchManualMeta.cs +++ b/Rizu.Core/Models/BatchManualMeta.cs @@ -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"; } diff --git a/Rizu.Core/Models/BatchManualOptional.cs b/Rizu.Core/Models/BatchManualOptional.cs index 17f1764..e527299 100644 --- a/Rizu.Core/Models/BatchManualOptional.cs +++ b/Rizu.Core/Models/BatchManualOptional.cs @@ -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; } diff --git a/Rizu.Core/Models/BatchManualRankUp.cs b/Rizu.Core/Models/BatchManualRankUp.cs index 5c72557..c4fb0cc 100644 --- a/Rizu.Core/Models/BatchManualRankUp.cs +++ b/Rizu.Core/Models/BatchManualRankUp.cs @@ -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; } \ No newline at end of file diff --git a/Rizu.Core/Models/BatchManualResponseBody.cs b/Rizu.Core/Models/BatchManualResponseBody.cs index b2cd261..c255f70 100644 --- a/Rizu.Core/Models/BatchManualResponseBody.cs +++ b/Rizu.Core/Models/BatchManualResponseBody.cs @@ -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; } diff --git a/Rizu.Core/Models/BatchManualScore.cs b/Rizu.Core/Models/BatchManualScore.cs index a7c72ea..e43f715 100644 --- a/Rizu.Core/Models/BatchManualScore.cs +++ b/Rizu.Core/Models/BatchManualScore.cs @@ -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; } diff --git a/Rizu.Core/Models/BatchManualScoreJudgements.cs b/Rizu.Core/Models/BatchManualScoreJudgements.cs index 7b61af2..ecd65a2 100644 --- a/Rizu.Core/Models/BatchManualScoreJudgements.cs +++ b/Rizu.Core/Models/BatchManualScoreJudgements.cs @@ -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; } diff --git a/Rizu.Core/Models/ImportDocument.cs b/Rizu.Core/Models/ImportDocument.cs index bb1f382..68c4e2f 100644 --- a/Rizu.Core/Models/ImportDocument.cs +++ b/Rizu.Core/Models/ImportDocument.cs @@ -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; } diff --git a/Rizu.Core/Models/ImportErrContent.cs b/Rizu.Core/Models/ImportErrContent.cs index 816db5c..8652949 100644 --- a/Rizu.Core/Models/ImportErrContent.cs +++ b/Rizu.Core/Models/ImportErrContent.cs @@ -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; } \ No newline at end of file diff --git a/Rizu.Core/Models/ImportProgress.cs b/Rizu.Core/Models/ImportProgress.cs index 555b45a..2b46527 100644 --- a/Rizu.Core/Models/ImportProgress.cs +++ b/Rizu.Core/Models/ImportProgress.cs @@ -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; } diff --git a/Rizu.Core/Models/ImportStatusResponseBody.cs b/Rizu.Core/Models/ImportStatusResponseBody.cs index af6994b..541e03e 100644 --- a/Rizu.Core/Models/ImportStatusResponseBody.cs +++ b/Rizu.Core/Models/ImportStatusResponseBody.cs @@ -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; } diff --git a/Rizu.Core/Models/SessionInfoReturn.cs b/Rizu.Core/Models/SessionInfoReturn.cs index d8fecd0..54a9ef5 100644 --- a/Rizu.Core/Models/SessionInfoReturn.cs +++ b/Rizu.Core/Models/SessionInfoReturn.cs @@ -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; } \ No newline at end of file diff --git a/Rizu.Core/Models/TachiResponse.cs b/Rizu.Core/Models/TachiResponse.cs index aa31dcd..ab45db5 100644 --- a/Rizu.Core/Models/TachiResponse.cs +++ b/Rizu.Core/Models/TachiResponse.cs @@ -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 { + [JsonInclude] public bool success; + [JsonInclude] public string description; + [JsonInclude] public T body; } diff --git a/Rizu.Core/Rizu.Core.csproj b/Rizu.Core/Rizu.Core.csproj index 34f15b8..c014a2b 100644 --- a/Rizu.Core/Rizu.Core.csproj +++ b/Rizu.Core/Rizu.Core.csproj @@ -15,25 +15,83 @@ 512 latest - - AnyCPU + + + pdbonly + true + MONOMOD;TRACE + prompt + 4 + bin\MonoMod (Release)\ + + true full false - bin\Debug\ - DEBUG;TRACE + MONOMOD;DEBUG;TRACE prompt 4 + bin\MonoMod (Debug)\ - - AnyCPU + + + ..\External\UnityEngine.JSONSerializeModule.dll + False + + + + + true + full + false + BEPINEX;DEBUG;TRACE + prompt + 4 + bin\BepInEx (Debug)\ + + pdbonly true - bin\Release\ - TRACE + BEPINEX;TRACE prompt 4 + bin\BepInEx (Release)\ + + + ..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll + + + ..\packages\System.Text.Json.8.0.4\lib\net462\System.Text.Json.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + + + + + + @@ -47,10 +105,6 @@ ..\External\UnityEngine.CoreModule.dll False - - ..\External\UnityEngine.JSONSerializeModule.dll - False - ..\External\UnityEngine.UnityWebRequestModule.dll False @@ -60,6 +114,7 @@ + diff --git a/Rizu.Core/ScoreConversion.cs b/Rizu.Core/ScoreConversion.cs index ac6beaa..2159572 100644 --- a/Rizu.Core/ScoreConversion.cs +++ b/Rizu.Core/ScoreConversion.cs @@ -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 = [], diff --git a/Rizu.Core/packages.config b/Rizu.Core/packages.config new file mode 100644 index 0000000..b5afb59 --- /dev/null +++ b/Rizu.Core/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Rizu.MonoMod/Rizu.MonoMod.csproj b/Rizu.MonoMod/Rizu.MonoMod.csproj index ae0a2c3..8a3eb38 100644 --- a/Rizu.MonoMod/Rizu.MonoMod.csproj +++ b/Rizu.MonoMod/Rizu.MonoMod.csproj @@ -15,24 +15,11 @@ 512 latest - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 + + bin\MonoMod (Debug)\ - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + bin\MonoMod (Release)\ diff --git a/Rizu.sln b/Rizu.sln index 1738134..84f57a9 100644 --- a/Rizu.sln +++ b/Rizu.sln @@ -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