misc stuff from other avatars

This commit is contained in:
Lillith Rose (Device: Lucia) 2025-06-18 12:31:45 -04:00
parent 99420739e0
commit e2b229edfc
13 changed files with 273 additions and 0 deletions

View file

@ -0,0 +1,27 @@
{
"name": "GestureManagerExporter",
"rootNamespace": "",
"references": [
"GUID:184316a0752f3c74fbd758a2fb0f0d46",
"GUID:f5ea942962a55ed488e8a2962adce217"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"VRCSDK_HAS_HARMONY"
],
"versionDefines": [
{
"name": "com.vrchat.base",
"expression": "(3.3.99999,)",
"define": "VRCSDK_HAS_HARMONY"
}
],
"noEngineReferences": false
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 599cb6f19c2a83441af2b00cd74d0ee3
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using HarmonyLib;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
using VRC.SDKBase;
using BlackStartX.GestureManager.Editor.Modules.Vrc3;
using BlackStartX.GestureManager.Editor.Modules.Vrc3.Params;
[InitializeOnLoad]
internal static class GestureManagerExporter
{
private static bool excludeAnimatorParameters = true;
private static bool sortByDescriptor = true;
static GestureManagerExporter()
{
var harmony = new Harmony("gay.lilyy.GestureManagerExporter");
harmony.PatchAll();
}
[HarmonyPatch]
private static class PatchParametersLayout
{
static MethodBase TargetMethod()
{
var nestedClass = typeof(ModuleVrc3).Assembly
.GetType("BlackStartX.GestureManager.Editor.Modules.Vrc3.Vrc3Debug.Avatar.Vrc3AvatarDebugWindow+Static");
return nestedClass?.GetMethod("ParametersLayout", BindingFlags.NonPublic | BindingFlags.Static);
}
static void Postfix(ModuleVrc3 module, float width)
{
excludeAnimatorParameters = GUILayout.Toggle(excludeAnimatorParameters, "Exclude Animator-Only Parameters", GUILayout.Width(width));
sortByDescriptor = GUILayout.Toggle(sortByDescriptor, "Sort by Parameters File", GUILayout.Width(width));
if (!GUILayout.Button("Export Parameters to JSON", GUILayout.Width(width))) return;
var path = EditorUtility.SaveFilePanel(
"Export Parameters",
"Assets",
"avatar_parameters.json",
"json"
);
if (string.IsNullOrEmpty(path)) return;
var parameters = new Dictionary<string, object>();
var avatarDescriptor = module.AvatarDescriptor;
foreach (var param in module.Params)
{
if (excludeAnimatorParameters) {
if (avatarDescriptor.expressionParameters.FindParameter(param.Key) == null) {
continue;
}
}
object value = param.Value.Type switch
{
AnimatorControllerParameterType.Float => param.Value.FloatValue(),
AnimatorControllerParameterType.Int => param.Value.IntValue(),
AnimatorControllerParameterType.Bool => param.Value.BoolValue(),
AnimatorControllerParameterType.Trigger => param.Value.BoolValue(),
_ => throw new ArgumentOutOfRangeException(nameof(param.Value.Type), param.Value.Type, null)
};
parameters[param.Key] = new
{
type = param.Value.TypeText,
value
};
}
if (sortByDescriptor) {
var orderedParams = new Dictionary<string, object>();
var paramNamesInDescriptor = avatarDescriptor.expressionParameters.parameters
.Select(p => p.name)
.Where(name => parameters.ContainsKey(name));
foreach (var name in paramNamesInDescriptor)
orderedParams[name] = parameters[name];
var unmatchedParams = parameters.Keys
.Where(k => !orderedParams.ContainsKey(k))
.OrderBy(k => k);
foreach (var name in unmatchedParams)
orderedParams[name] = parameters[name];
parameters = orderedParams;
}
var settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
FloatFormatHandling = FloatFormatHandling.String, // We'll format floats ourselves
Converters = new List<JsonConverter> { new Float2DecimalConverter() }
};
var json = JsonConvert.SerializeObject(parameters, settings);
File.WriteAllText(path, json);
EditorUtility.DisplayDialog("Export Complete", $"{parameters.Count} Parameters have been exported successfully!", "OK");
}
}
}
class Float2DecimalConverter : JsonConverter
{
public override bool CanConvert(Type objectType) =>
objectType == typeof(float) || objectType == typeof(double);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is float f)
writer.WriteRawValue(f.ToString("0.00"));
else if (value is double d)
writer.WriteRawValue(d.ToString("0.00"));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) =>
throw new NotImplementedException();
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc83507142543124eb3c70264bc802ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,3 @@
# GestureManagerExporter
A Harmony patch that adds an `Export Parameters` button to the GestureManager avatars debug menu, pulling out all of your parameters so you can diff them

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8c6cf20c81a2101499ba6f2091da6d2e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b19908d38fd94146aa0be6de761e3c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,3 @@
# VRCFAllowRootFeatures
A Harmony patch to disable the `To avoid abuse by prefab creators, this component can only be placed on the root object containing the avatar descriptor, OR a child object containing ONLY vrcfury components.` message

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 45c06a4ce7dc45042a050e36ab0dbc2c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,18 @@
{
"name": "VRCFAllowRootFeatures",
"rootNamespace": "",
"references": [
"GUID:3a48074f337050d4c987242d92d466b6"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c14d83102ee44b14bb9088ece79690e3
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,31 @@
using System.Reflection;
using HarmonyLib;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class VRCFAllowRootFeatures {
static VRCFAllowRootFeatures() {
var harmony = new Harmony("gay.lilyy.VRCFAllowRootFeatures");
var featureFinderType = AccessTools.TypeByName("VF.Feature.Base.FeatureFinder");
if (featureFinderType == null) {
Debug.LogError("FeatureFinder type not found");
return;
}
var method = AccessTools.Method(featureFinderType, "AllowRootFeatures");
if (method == null) {
Debug.LogError("AllowRootFeatures method not found");
return;
}
var prefix = typeof(VRCFAllowRootFeatures).GetMethod(nameof(Prefix), BindingFlags.Static | BindingFlags.NonPublic);
harmony.Patch(method, prefix: new HarmonyMethod(prefix));
}
private static bool Prefix(object gameObject, object avatarObject, ref bool __result) {
__result = true;
return false;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 63d5a4749805a33428c808b6ae6c0dcf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: