mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 15:08:47 -07:00
feat: Implement admin account deletion with confirmation and update documentation
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(TargetFramework)' == '' and '$(TargetFrameworks)' == ''">net6.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>DorkNet.ClientMod</RootNamespace>
|
||||
<AssemblyName>DorkNet.ClientMod</AssemblyName>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendTargetFrameworkToOutputPath Condition="'$(TargetFrameworks)' == ''">false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendTargetFrameworkToOutputPath Condition="'$(TargetFrameworks)' != ''">true</AppendTargetFrameworkToOutputPath>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
<NoWarn>$(NoWarn);CS8602;CS8604;CS0436</NoWarn>
|
||||
</PropertyGroup>
|
||||
@@ -19,21 +20,28 @@
|
||||
they would be derivative works of the game anyway, so we never
|
||||
reference them. Only MelonLoader's own DLLs are needed.
|
||||
|
||||
By default the project downloads the pinned MelonLoader release
|
||||
into DorkNet.ClientMod/build/ and references those DLLs. Pass
|
||||
-p:MelonLoaderDir=<path-to-extracted-MelonLoader> only when you
|
||||
deliberately want to use a local override.
|
||||
By default the project downloads the pinned desktop MelonLoader release
|
||||
into DorkNet.ClientMod/build/ and references its net6 DLLs. For Quest /
|
||||
LemonLoader builds, pass:
|
||||
|
||||
-p:TargetFrameworks=net8.0
|
||||
-p:MelonLoaderDir=<path-to-LemonLoader-melon_data/MelonLoader>
|
||||
|
||||
The reference folder follows the target framework unless explicitly
|
||||
overridden with -p:MelonLoaderReferenceTfm=...
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<MelonLoaderVersion Condition="'$(MelonLoaderVersion)' == ''">v0.6.6</MelonLoaderVersion>
|
||||
<MelonLoaderCacheRoot>$(MSBuildThisFileDirectory)build\melonloader</MelonLoaderCacheRoot>
|
||||
<MelonLoaderZip>$(MelonLoaderCacheRoot)\MelonLoader.x64.$(MelonLoaderVersion).zip</MelonLoaderZip>
|
||||
<MelonLoaderDir Condition="'$(MelonLoaderDir)' == ''">$(MelonLoaderCacheRoot)\MelonLoader</MelonLoaderDir>
|
||||
<MelonLoaderReferenceTfm Condition="'$(MelonLoaderReferenceTfm)' == '' and '$(TargetFramework)' == 'net8.0'">net8</MelonLoaderReferenceTfm>
|
||||
<MelonLoaderReferenceTfm Condition="'$(MelonLoaderReferenceTfm)' == ''">net6</MelonLoaderReferenceTfm>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="EnsureMelonLoaderReferences"
|
||||
BeforeTargets="ResolveAssemblyReferences"
|
||||
Condition="!Exists('$(MelonLoaderDir)\net6\MelonLoader.dll')">
|
||||
Condition="'$(MelonLoaderReferenceTfm)' == 'net6' and !Exists('$(MelonLoaderDir)\$(MelonLoaderReferenceTfm)\MelonLoader.dll')">
|
||||
<MakeDir Directories="$(MelonLoaderCacheRoot)" />
|
||||
<DownloadFile
|
||||
SourceUrl="https://github.com/LavaGang/MelonLoader/releases/download/$(MelonLoaderVersion)/MelonLoader.x64.zip"
|
||||
@@ -47,19 +55,19 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="MelonLoader">
|
||||
<HintPath>$(MelonLoaderDir)\net6\MelonLoader.dll</HintPath>
|
||||
<HintPath>$(MelonLoaderDir)\$(MelonLoaderReferenceTfm)\MelonLoader.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>$(MelonLoaderDir)\net6\0Harmony.dll</HintPath>
|
||||
<HintPath>$(MelonLoaderDir)\$(MelonLoaderReferenceTfm)\0Harmony.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppInterop.Runtime">
|
||||
<HintPath>$(MelonLoaderDir)\net6\Il2CppInterop.Runtime.dll</HintPath>
|
||||
<HintPath>$(MelonLoaderDir)\$(MelonLoaderReferenceTfm)\Il2CppInterop.Runtime.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Il2CppInterop.Common">
|
||||
<HintPath>$(MelonLoaderDir)\net6\Il2CppInterop.Common.dll</HintPath>
|
||||
<HintPath>$(MelonLoaderDir)\$(MelonLoaderReferenceTfm)\Il2CppInterop.Common.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -179,10 +179,16 @@ public class Mod : MelonMod
|
||||
// EMGGKBALALH returns Photon.Realtime.AuthenticationValues —
|
||||
// verified at PUNNetworkManager.txt:7560. Builds AuthValues with
|
||||
// environment + accessToken AuthGetParameters.
|
||||
TryPatchByName("PUNNetworkManager", "FJOLIPKKIBE",
|
||||
postfix: nameof(PhotonPatches.LogAppSettings_Postfix));
|
||||
TryPatchByName("PUNNetworkManager", "EMGGKBALALH",
|
||||
postfix: nameof(PhotonPatches.LogAuthValues_Postfix));
|
||||
//
|
||||
// Quest-Dec uses the same obfuscation seed as PC-Dec, but discover by
|
||||
// return type first so a future platform/reseed does not make these
|
||||
// two critical hooks depend on the private method names.
|
||||
TryPatchDeclaredMethodByReturnType("PUNNetworkManager", "AppSettings",
|
||||
fallbackMethodName: "FJOLIPKKIBE",
|
||||
postfix: nameof(PhotonPatches.LogAppSettings_Postfix));
|
||||
TryPatchDeclaredMethodByReturnType("PUNNetworkManager", "AuthenticationValues",
|
||||
fallbackMethodName: "EMGGKBALALH",
|
||||
postfix: nameof(PhotonPatches.LogAuthValues_Postfix));
|
||||
// PUNNetworkManager.OnCustomAuthenticationFailed — accepts whatever
|
||||
// string-like arg the IL2CPP method takes (declared `string` in
|
||||
// dump.cs but Il2CppInterop wraps it in a way that breaks
|
||||
@@ -723,6 +729,58 @@ public class Mod : MelonMod
|
||||
return TryPatch(label, type, methodName, args, prefix, postfix, logMiss);
|
||||
}
|
||||
|
||||
private bool TryPatchDeclaredMethodByReturnType(string typeName, string returnTypeName,
|
||||
string fallbackMethodName,
|
||||
string? prefix = null, string? postfix = null,
|
||||
bool logMiss = true)
|
||||
{
|
||||
var type = ResolveType(typeName);
|
||||
var label = $"{typeName}.<returns {returnTypeName}>";
|
||||
if (type is null)
|
||||
{
|
||||
if (logMiss) Log.Warning($"[patch-miss] {label}: type not found");
|
||||
return TryPatchByName(typeName, fallbackMethodName, args: null, prefix, postfix, logMiss);
|
||||
}
|
||||
|
||||
var matches = new List<MethodInfo>();
|
||||
foreach (var method in AccessTools.GetDeclaredMethods(type))
|
||||
{
|
||||
if (method.IsAbstract || method.ContainsGenericParameters || method.IsSpecialName) continue;
|
||||
if (ReturnTypeMatches(method.ReturnType, returnTypeName)) matches.Add(method);
|
||||
}
|
||||
|
||||
if (matches.Count == 1)
|
||||
{
|
||||
var method = matches[0];
|
||||
try
|
||||
{
|
||||
HarmonyInstance.Patch(method,
|
||||
prefix: prefix is null ? null : new HarmonyMethod(GetPatchMethod(prefix)),
|
||||
postfix: postfix is null ? null : new HarmonyMethod(GetPatchMethod(postfix)));
|
||||
Log.Msg($"[patch-ok] {typeName}.{method.Name} (returns {returnTypeName})");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"[patch-fail] {typeName}.{method.Name} (returns {returnTypeName}): {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches.Count > 1)
|
||||
{
|
||||
var names = new List<string>();
|
||||
foreach (var method in matches) names.Add(method.Name);
|
||||
Log.Warning($"[patch-ambiguous] {label}: {string.Join(", ", names)}; falling back to {fallbackMethodName}");
|
||||
}
|
||||
else if (logMiss)
|
||||
{
|
||||
Log.Warning($"[patch-miss] {label}; falling back to {fallbackMethodName}");
|
||||
}
|
||||
|
||||
return TryPatchByName(typeName, fallbackMethodName, args: null, prefix, postfix, logMiss);
|
||||
}
|
||||
|
||||
internal static Type? ResolveType(string name)
|
||||
{
|
||||
if (ResolvedTypeCache.TryGetValue(name, out var cached))
|
||||
@@ -795,6 +853,15 @@ public class Mod : MelonMod
|
||||
type.FullName?.EndsWith(".Il2Cpp" + requested, StringComparison.Ordinal) == true;
|
||||
}
|
||||
|
||||
private static bool ReturnTypeMatches(Type type, string requested)
|
||||
{
|
||||
var prefixed = "Il2Cpp" + requested;
|
||||
if (type.FullName == requested || type.FullName == prefixed) return true;
|
||||
if (type.Name == requested || type.Name == prefixed) return true;
|
||||
return type.FullName?.EndsWith("." + requested, StringComparison.Ordinal) == true ||
|
||||
type.FullName?.EndsWith(".Il2Cpp" + requested, StringComparison.Ordinal) == true;
|
||||
}
|
||||
|
||||
private static string FormatPatchLabel(string typeName, string methodName, Type[]? args)
|
||||
{
|
||||
if (args is null) return $"{typeName}.{methodName}";
|
||||
|
||||
Reference in New Issue
Block a user