Initial commit
This commit is contained in:
209
Core/BuildSettings.cs
Normal file
209
Core/BuildSettings.cs
Normal file
@@ -0,0 +1,209 @@
|
||||
// Undead Universal Patch - for patching Rec Room builds
|
||||
// Copyright (C) 2026 proxnet.dev (@zombieb)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY
|
||||
|
||||
using HarmonyLib;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UndeadUniversalPatch.Core.Exceptions;
|
||||
|
||||
namespace UndeadUniversalPatch.Core;
|
||||
|
||||
internal static class BuildSettings
|
||||
{
|
||||
public static Assembly GetAssemblyCSharp()
|
||||
{
|
||||
if (!Init.GetIsRecRoom())
|
||||
throw new NotRecRoomException();
|
||||
|
||||
return AccessTools.TypeByName("BootSequence").Assembly; // always unobfuscated
|
||||
}
|
||||
|
||||
private static Type GetBuildSettings()
|
||||
{
|
||||
var assembly = GetAssemblyCSharp();
|
||||
|
||||
try
|
||||
{
|
||||
Type type = assembly.GetTypes().First(type => Symbols.BuildSettings.Contains(type.Name));
|
||||
return type;
|
||||
} catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Type type = ex.Types.First(type => Symbols.BuildSettings.Contains(type.Name));
|
||||
return type;
|
||||
} catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetVersion()
|
||||
{
|
||||
var unknown = "Unknown Version";
|
||||
|
||||
var buildSettings = GetBuildSettings();
|
||||
if (buildSettings == null)
|
||||
#if NET35
|
||||
{
|
||||
try
|
||||
{
|
||||
// doesn't exist? -> error will be caught & unknown will be returned
|
||||
var field = AccessTools.Field("PUNNetworkManager:BUILD_VERSION");
|
||||
|
||||
if (field != null) return (string)field.GetValue(null);
|
||||
else return "Unknown Legacy Version";
|
||||
} catch
|
||||
{
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return unknown;
|
||||
#endif
|
||||
|
||||
Func<string, bool> check = (string value) =>
|
||||
{
|
||||
if (value == null) return false;
|
||||
return value.StartsWith("20") || value.EndsWith("_EA");
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
#if NET6_0
|
||||
return (string)buildSettings.GetRuntimeProperties().Where(prop => prop.PropertyType == typeof(string)).First(prop =>
|
||||
{
|
||||
var value = (string)prop.GetValue(null);
|
||||
return check(value);
|
||||
}).GetValue(null);
|
||||
#else
|
||||
return (string)buildSettings.GetFields().Where(field => field.FieldType == typeof(string)).First(field =>
|
||||
{
|
||||
var value = (string)field.GetValue(null);
|
||||
return check(value);
|
||||
}).GetValue(null);
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
{
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetBuildTimestamp()
|
||||
{
|
||||
var unknown = "Unknown Timestamp";
|
||||
|
||||
var buildSettings = GetBuildSettings();
|
||||
if (buildSettings == null) return unknown;
|
||||
|
||||
// Only one `long` exists on BuildSettings across all supported builds
|
||||
try
|
||||
{
|
||||
#if NET6_0
|
||||
var foundProp = buildSettings.GetRuntimeProperties()
|
||||
.First(prop => prop.PropertyType == typeof(long));
|
||||
|
||||
var value = (long)foundProp.GetValue(null);
|
||||
return new DateTime(value).ToString();
|
||||
#else
|
||||
var foundField = buildSettings.GetFields()
|
||||
.First(field => field.FieldType == typeof(long));
|
||||
|
||||
var value = (long)foundField.GetValue(null);
|
||||
return new DateTime(value).ToString();
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
{
|
||||
return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Symbols
|
||||
{
|
||||
// type list compiled by @zombieb
|
||||
public static string[] BuildSettings = [
|
||||
"BuildSettings",
|
||||
"BBHENFCNLAB",
|
||||
"KMJJGELKNAP",
|
||||
"FJEEPOKGDNG",
|
||||
"LACHJMJGMPK",
|
||||
"NNBKABHFGFB",
|
||||
"KMGJBIHAAJL",
|
||||
"FALNDOJFPMN",
|
||||
"IODMKGDNMID",
|
||||
"HIPJBMLBLHH",
|
||||
"LEADBBLICBL",
|
||||
"NPPACKKFLIK",
|
||||
"MOFAAFLMFJO",
|
||||
"EMIDOAHOJNO",
|
||||
"IKJNDDBHIAC",
|
||||
"OOCIKEIJMCA",
|
||||
"HPFCOJFIIKK",
|
||||
"MONBJIBCJFA",
|
||||
"GFDKEKGOMCP",
|
||||
"MIMHAGFDGND",
|
||||
"LFJMHJPHKOK",
|
||||
"NOHBMMJBMIP",
|
||||
"GJBEJNGDEJM",
|
||||
"OGBGLFJGKJL",
|
||||
"PEJOGOOEOKE",
|
||||
"FDKFNHNNDEE",
|
||||
"EDNIOJBEKLL",
|
||||
"FEKFIFPGDDP",
|
||||
"POOFEABAPOB",
|
||||
"JHFKADKFKPD",
|
||||
"GGKABOEOKMI",
|
||||
"FAPDBIGGJHM",
|
||||
"EPKEIOCFFMO",
|
||||
"ECLPNEHKLEP",
|
||||
"BGMDPOMLCKD",
|
||||
"IMJIAGILBOG",
|
||||
"OGGKBKOBHLP",
|
||||
"DMAKDOEIOFE",
|
||||
"HHGCEDNGMDD",
|
||||
"OFDPCKGMCFG",
|
||||
"FPABNHKCIDD",
|
||||
"NEOOKMCECAL",
|
||||
"CKEBMNKBEAH",
|
||||
"IBPMLICGIOI",
|
||||
"LMJOEPJHBLC",
|
||||
"HJINOEPLIMF",
|
||||
"JMHFJIBKCMG",
|
||||
"HJKAEMGCIGB",
|
||||
"BNOEINBHPIG",
|
||||
"AJJAIFIKCJP",
|
||||
"FCPHGJMAGPI",
|
||||
"DDCENHLJGNM",
|
||||
"AEPEEKCCDJL",
|
||||
"IDDIAODMAPP",
|
||||
"CHIMGKLHFMK",
|
||||
"OGDOAJJPBOC",
|
||||
"EMABNNHNJIB",
|
||||
"JNEAMPKAHFM",
|
||||
"FPGILFHDJNI",
|
||||
"MDPMNBEPOKF",
|
||||
"FNKGHFILBEE",
|
||||
"AEOMDHAKPGC",
|
||||
"OGEBJBBMDEO",
|
||||
"CJMCNIDOMCP",
|
||||
"LCCKMCOLKFI",
|
||||
"DEIHAEKLPDJ",
|
||||
"LENMMNLPJOL",
|
||||
"JKNIDJECBFD",
|
||||
"FMEMABGECKK",
|
||||
"HAOBGEPJMAN",
|
||||
"FDCGGKFBOPN",
|
||||
"OKCPMCEGCOK",
|
||||
"BNKCNOFCGDK"
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user