Skip to content

Commit

Permalink
Tons of fixes, changes, and overall improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nomnomab committed May 8, 2024
1 parent 4cd2179 commit aed084e
Show file tree
Hide file tree
Showing 209 changed files with 6,425 additions and 4,153 deletions.
Binary file added Assets~/AssetRipperSettings_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets~/AssetRipperSettings_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets~/UPPatcherSettings_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets~/UPPatcherSettings_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
248 changes: 207 additions & 41 deletions Editor/AssetCatalogue.cs

Large diffs are not rendered by default.

843 changes: 689 additions & 154 deletions Editor/AssetScrubber.cs

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions Editor/GuidReplacementWindow.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
using UnityEditor;
using UnityEngine;

namespace Nomnom.UnityProjectPatcher.Editor {
sealed internal class GuidReplacementWindow: EditorWindow {
[MenuItem("Tools/UPP/Replace GUID")]
public static void ShowWindow() {
var window = GetWindow<GuidReplacementWindow>("Replace GUID");
window.Show();
}

private string _guidString = string.Empty;

private void OnGUI() {
var guid = EditorGUILayout.TextField("GUID", _guidString);
if (GUILayout.Button("Replace")) {

}
}
}
}
// using UnityEditor;
// using UnityEngine;
//
// namespace Nomnom.UnityProjectPatcher.Editor {
// sealed internal class GuidReplacementWindow: EditorWindow {
// [MenuItem("Tools/UPP/Replace GUID")]
// public static void ShowWindow() {
// var window = GetWindow<GuidReplacementWindow>("Replace GUID");
// window.Show();
// }
//
// private string _guidString = string.Empty;
//
// private void OnGUI() {
// var guid = EditorGUILayout.TextField("GUID", _guidString);
// if (GUILayout.Button("Replace")) {
//
// }
// }
// }
// }
51 changes: 35 additions & 16 deletions Editor/PatcherSteps.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Reflection;
using Nomnom.UnityProjectPatcher.Editor.Steps;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.PlayerLoop;

namespace Nomnom.UnityProjectPatcher.Editor {
/// <summary>
Expand All @@ -10,24 +13,40 @@ public static class PatcherSteps {
[InitializeOnLoadMethod]
private static void OnLoad() {
// locate game patcher
foreach (var type in TypeCache.GetTypesWithAttribute<UPPatcherAttribute>()) {
// does it have a Run function?
var runFunction = type.GetMethod("Run", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic);
if (runFunction is null) continue;
if (runFunction.GetParameters().Length > 0) continue;

// Debug.Log($"Found Patcher: {type.Name}");

EditorApplication.delayCall += () => {
var progress = StepsProgress.FromPath(StepsProgress.SavePath);
if (progress is null) return;
var gameWrapperType = PatcherUtility.GetGameWrapperType();
if (gameWrapperType is null) return;

var runFunction = PatcherUtility.GetGameWrapperRunFunction(gameWrapperType);
if (runFunction is null) return;

runFunction.Invoke(null, null);
};
StartDelay(runFunction);

//! only run one patcher
break;
}
// if (!InternalEditorUtility.isApplicationActive) {
// EditorApplication.update -= Update;
// EditorApplication.update += Update;
// RunFunction(runFunction);
// } else {
// StartDelay(runFunction);
// }
}

// private static void Update() {
// if (!InternalEditorUtility.isApplicationActive) {
// EditorApplication.delayCall?.Invoke();
// }
// }

private static void StartDelay(MethodInfo runFunction) {
EditorApplication.delayCall += () => {
RunFunction(runFunction);
};
}

private static void RunFunction(MethodInfo runFunction) {
var progress = StepsProgress.FromPath(StepsProgress.SavePath);
if (progress is null) return;

runFunction.Invoke(null, null);
}
}
}
228 changes: 216 additions & 12 deletions Editor/PatcherUtility.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Lachee.Utilities.Serialization;
using Nomnom.UnityProjectPatcher.AssetRipper;
using Nomnom.UnityProjectPatcher.Editor.Steps;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.SceneManagement;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
using UObject = Lachee.Utilities.Serialization.UObject;

namespace Nomnom.UnityProjectPatcher.Editor {
public static class PatcherUtility {
Expand Down Expand Up @@ -54,6 +63,80 @@ private static void CreateAssetRipperSettings() {
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}

public static bool ScriptsAreStubs(this IPatcherStep step) {
return GetAssetRipperSettings().ConfigurationData.Export.scriptExportMode != ScriptExportMode.Decompiled;
}

public static Type GetGameWrapperType() {
foreach (var type in TypeCache.GetTypesWithAttribute<UPPatcherAttribute>()) {
// does it have a Run function?
if (GetGameWrapperRunFunction(type) is null) continue;
return type;
}

return null;
}

public static MethodInfo GetGameWrapperRunFunction(Type wrapperType) {
var runFunction = wrapperType.GetMethod("Run", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic);
if (runFunction is null) return null;
if (runFunction.GetParameters().Length > 0) return null;

return runFunction;
}

public static MethodInfo GetGameWrapperOnGUIFunction(Type wrapperType) {
var guiFunction = wrapperType.GetMethod("OnGUI", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic);
if (guiFunction is null) return null;
if (guiFunction.GetParameters().Length > 0) return null;

return guiFunction;
}

public static (string version, string gameWrapperVersion) GetVersions() {
EditorUtility.DisplayProgressBar("Fetching...", "Fetching versions...", 0.5f);
try {
var list = Client.List();
while (!list.IsCompleted) { }

var patcher = list.Result.FirstOrDefault(x => x.name == "com.nomnom.unity-project-patcher");
(string, string) results = (null, null);
if (patcher != null) {
results.Item1 = patcher.version;
}

var gameWrapperType = GetGameWrapperType();
var assembly = gameWrapperType.Assembly;
var packageName = assembly.GetName().Name.ToLower();
if (packageName.EndsWith(".editor")) {
packageName = packageName.Replace(".editor", string.Empty);
}
patcher = list.Result.FirstOrDefault(x => x.name == packageName);
if (patcher != null) {
results.Item2 = patcher.version;
}

return results;
} catch (Exception e) {
Debug.LogError(e);
return (null, null);
}
finally {
EditorUtility.ClearProgressBar();
}
}

public static bool IsProbablyPatched() {
var settings = GetSettings();
if (!AssetDatabase.IsValidFolder(settings.ProjectGameAssetsPath)) {
return false;
}

return AssetDatabase.FindAssets(string.Empty, new string[] {
settings.ProjectGameAssetsPath
}).Length > 0;
}

public static bool TryToCreatePath(string path) {
if (Directory.Exists(path)) {
Expand All @@ -78,8 +161,49 @@ public static Object GetGraphicsSettings() {
public static Object GetQualitySettings() {
return AssetDatabase.LoadAssetAtPath<Object>("ProjectSettings/QualitySettings.asset");
}

public static Object GetProjectSettings() {
return AssetDatabase.LoadAssetAtPath<Object>("ProjectSettings/ProjectSettings.asset");
}

public static string GetPathRoot(string path) {
var separatorChar = Path.DirectorySeparatorChar;
path = path.Replace('/', separatorChar);
var indexOfSeparator = path.IndexOf(separatorChar);
if (indexOfSeparator == -1) {
return path;
}
return path.Substring(0, indexOfSeparator);
}

public static string GetPathWithoutRoot(string path) {
var separatorChar = Path.DirectorySeparatorChar;
path = path.Replace('/', separatorChar);
var indexOfSeparator = path.IndexOf(separatorChar);
if (indexOfSeparator == -1) {
return path;
}
return path.Substring(indexOfSeparator + 1);
}

public static string GetStartingFolders(string path, int count) {
var separatorChar = Path.DirectorySeparatorChar;
path = path.Replace('/', separatorChar);
var indexOfSeparator = path.IndexOf(separatorChar);
if (indexOfSeparator == -1) {
return path;
}

var split = path.Split(separatorChar);
var result = string.Join(separatorChar.ToString(), split.Take(count));
return result;
}

#if UNITY_2020_3_OR_NEWER
public static SerializedProperty? GetCustomRenderPipelineProperty() {
#else
public static SerializedProperty GetCustomRenderPipelineProperty() {
#endif
var qualitySettings = PatcherUtility.GetQualitySettings();
var serializedObject = new SerializedObject(qualitySettings);

Expand Down Expand Up @@ -176,40 +300,120 @@ public static void ExcludeDllFromLoading(string path) {
}
}

[MenuItem("CONTEXT/Object/Debug Guid")]
[MenuItem("CONTEXT/Object/Debug/Guid")]
[MenuItem("Edit/Test/Debug/Guid")]
public static void DebugGuid() {
var selection = Selection.activeObject;
if (!selection) return;

var path = AssetDatabase.GetAssetPath(selection);
var guid = AssetDatabase.AssetPathToGUID(path);
Debug.Log(guid);

if (string.IsNullOrEmpty(guid)) {
Debug.Log(GlobalObjectId.GetGlobalObjectIdSlow(selection));
return;
}

var instance = AssetDatabase.LoadMainAssetAtPath(path);
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(instance, out guid, out long fileId)) {
Debug.Log($"{guid} {fileId}");
}

var globalID = GlobalObjectId.GetGlobalObjectIdSlow(instance);
Debug.Log(globalID);
}

[MenuItem("CONTEXT/Object/Debug/Local FileId")]
[MenuItem("CONTEXT/GameObject/Debug/Local FileId")]
[MenuItem("Edit/Test/Debug/Local FileId")]
public static void DebugLocalFileId() {
var selection = Selection.activeObject;
if (!selection) return;

var inspectorModeInfo =
typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);

var serializedObject = new SerializedObject(selection);
inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null);

var localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile"); //note the misspelling!
var localId = localIdProp.intValue;

Debug.Log(localId);
}

// [MenuItem("CONTEXT/Object/Debug Guid2")]
// public static void DebugGuid2() {
// var selection = Selection.activeObject;
// if (!selection) return;
//
// Debug.Log(FileIDUtil.Compute(typeof(ES3Defaults)));
// }

[MenuItem("CONTEXT/MonoScript/Debug FullTypeName")]
[MenuItem("Assets/Debug FullTypeName")]
[MenuItem("CONTEXT/MonoScript/Debug/FullTypeName")]
[MenuItem("Assets/Debug/FullTypeName")]
public static void DebugFullTypeName() {
var selection = Selection.activeObject;
if (!selection) return;
if (selection is not MonoScript monoScript) return;
if (!(selection is MonoScript)) return;

var monoScript = (MonoScript)selection;
var assetPath = AssetDatabase.GetAssetPath(monoScript);
foreach (var entry in AssetScrubber.ScrubNonMonoData(monoScript, assetPath, 0)) {
Debug.Log(entry);
}
}

private readonly static Regex FileIdPattern = new Regex(@"fileID:\s(?<fileId>[0-9A-Za-z]+)", RegexOptions.Compiled);

[MenuItem("Assets/Experimental/Re-import from Export")]
public static void ReimportFromExport() {
var activeObject = Selection.activeObject;
var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
var settings = GetSettings();
var arSettings = GetAssetRipperSettings();

var exportPath = AssetScrubber.GetExportPathFromProjectPath(assetPath, settings, arSettings);
if (string.IsNullOrEmpty(exportPath)) {
Debug.LogWarning("Could not find export path");
return;
}

if (!File.Exists(exportPath)) {
Debug.LogWarning("Export file does not exist");
return;
}

Debug.Log($"Reimporting {assetPath} from {exportPath}");

var metaFilePath = exportPath + ".meta";
try {
File.Copy(exportPath, assetPath, true);

if (File.Exists(metaFilePath)) {
File.Copy(metaFilePath, assetPath + ".meta", true);
}
} catch {
Debug.LogError($"Failed to reimport {assetPath} from {exportPath}");
throw;
}

AssetDatabase.ImportAsset(assetPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}

[MenuItem("Assets/Experimental/Re-import from Export", true)]
public static bool ReimportFromExportValidate() {
if (Selection.count != 1) return false;

var activeObject = Selection.activeObject;
var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
var settings = GetSettings();

if (!assetPath.StartsWith(settings.ProjectGameAssetsPath)) {
return false;
}

var extension = Path.GetExtension(assetPath);
if (extension == ".unity" || extension == ".prefab" || string.IsNullOrEmpty(extension)) {
return false;
}

return true;
}
}
}
Loading

0 comments on commit aed084e

Please sign in to comment.