Skip to content

Commit

Permalink
Minor casting fix, log all unsupported shaders, try to fix logs not b…
Browse files Browse the repository at this point in the history
…eing saved in fatal exceptions
  • Loading branch information
MistressPlague committed Mar 29, 2024
1 parent c2022ce commit 0841488
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 107 deletions.
4 changes: 3 additions & 1 deletion Editor/KannaProteccRootEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,10 @@ void IgnoreDrawListItems(Rect rect, int index, bool isActive, bool isFocused)
GUI.color = old;
if (GUILayout.Button(new GUIContent(KannaProteccRoot.AutoFixLabel_Localized, KannaProteccRoot.AutoFixLingeringAvaCryptTooltip_Localized)))
{
foreach (AnimatorController controller in AllControllers)
foreach (var runtimeAnimatorController in AllControllers)
{
var controller = (AnimatorController)runtimeAnimatorController;

var layers = controller.layers.ToList();
layers.RemoveAll(o => o.name.StartsWith("BitKey"));
controller.layers = layers.ToArray();
Expand Down
5 changes: 5 additions & 0 deletions Scripts/KannaProteccMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ public static string GenerateDecodeShader(KannaProteccData data, bool[] keys)
public static bool IsShaderSupported(Shader shader, out KannaDynamicShaderData shaderData)
{
shaderData = Shaders.FirstOrDefault(o => o.ShaderName_StartsWith.Any(p => shader.name.Replace("Hidden/Locked/", "").StartsWith(p)));

if (shaderData == null)
{
KannaLogger.LogToFile($"Shader Unsupported: {shader.name}", KannaProteccRoot.LogLocation, KannaLogger.LogType.Warning);
}

return shaderData != null;
}
Expand Down
221 changes: 115 additions & 106 deletions Scripts/KannaProteccRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,172 +156,181 @@ public static bool IsMeshSupported(Mesh mesh)

public void EncryptAvatar()
{
if (ParameterRenamedValues.Count == 0 && !string.IsNullOrEmpty(GetComponent<PipelineManager>()?.blueprintId))
try
{
if (EditorUtility.DisplayDialog("Error!", "Do Not Encrypt A Previously Non-Encrypted Avatar That Was Uploaded! Detach The Blueprint ID And Upload This To A New One!\r\nBypassing This Can Lead To Rippers Using A Older Non-Encrypted Version Of Your Avatar! Only Bypass If You Know It Was Never Uploaded Non-Encrypted!", "Okay", "Bypass Warning"))
if (ParameterRenamedValues.Count == 0 && !string.IsNullOrEmpty(GetComponent<PipelineManager>()?.blueprintId))
{
return;
if (EditorUtility.DisplayDialog("Error!", "Do Not Encrypt A Previously Non-Encrypted Avatar That Was Uploaded! Detach The Blueprint ID And Upload This To A New One!\r\nBypassing This Can Lead To Rippers Using A Older Non-Encrypted Version Of Your Avatar! Only Bypass If You Know It Was Never Uploaded Non-Encrypted!", "Okay", "Bypass Warning"))
{
return;
}
}
}

var descriptor = gameObject.GetComponent<VRCAvatarDescriptor>();
var descriptor = gameObject.GetComponent<VRCAvatarDescriptor>();

if ((VRCExpressionParameters.MAX_PARAMETER_COST - descriptor.expressionParameters.CalcTotalCost()) is var freespace && freespace < 32)
{
if (EditorUtility.DisplayDialog("Error!", $"You Do Not Have 32 Bits Of Free Space In Your Expression Parameters!\r\nWould You Like To Use {freespace} Keys? Note This IS A SECURITY RISK.{(freespace < 16 ? " Less Than 16 Is Especially Insecure." : "")}", "Cancel", "I Understand The Danger"))
if ((VRCExpressionParameters.MAX_PARAMETER_COST - descriptor.expressionParameters.CalcTotalCost()) is var freespace && freespace < 32)
{
return;
}
if (EditorUtility.DisplayDialog("Error!", $"You Do Not Have 32 Bits Of Free Space In Your Expression Parameters!\r\nWould You Like To Use {freespace} Keys? Note This IS A SECURITY RISK.{(freespace < 16 ? " Less Than 16 Is Especially Insecure." : "")}", "Cancel", "I Understand The Danger"))
{
return;
}

_bitKeys = new bool[freespace];
GenerateNewKey();
}
_bitKeys = new bool[freespace];
GenerateNewKey();
}

if (File.Exists(LogLocation))
{
File.Delete(LogLocation); // Remove Old Log
KannaLogger.LogCache.Clear();
}
if (File.Exists(LogLocation))
{
File.Delete(LogLocation); // Remove Old Log
KannaLogger.LogCache.Clear();
}

Utilities.ResetRandomizer();
Utilities.ResetRandomizer();

var newName = $"{gameObject.name.Trim()}_Encrypted";
var newName = $"{gameObject.name.Trim()}_Encrypted";

// delete old GO, do as such in case its disabled
var scene = SceneManager.GetActiveScene();
var sceneRoots = scene.GetRootGameObjects();
foreach (var oldGameObject in sceneRoots)
{
if (oldGameObject.name.Trim() == newName)
// delete old GO, do as such in case its disabled
var scene = SceneManager.GetActiveScene();
var sceneRoots = scene.GetRootGameObjects();
foreach (var oldGameObject in sceneRoots)
{
KannaLogger.LogToFile($"Destroying Old Encrypted Object: {newName}", LogLocation);
DestroyImmediate(oldGameObject);
if (oldGameObject.name.Trim() == newName)
{
KannaLogger.LogToFile($"Destroying Old Encrypted Object: {newName}", LogLocation);
DestroyImmediate(oldGameObject);
}
}
}

var encodedGameObject = Instantiate(gameObject);
encodedGameObject.name = newName;
encodedGameObject.SetActive(true);
var encodedGameObject = Instantiate(gameObject);
encodedGameObject.name = newName;
encodedGameObject.SetActive(true);

var data = new KannaProteccData(_bitKeys.Length);
var decodeShader = KannaProteccMaterial.GenerateDecodeShader(data, _bitKeys);
var data = new KannaProteccData(_bitKeys.Length);
var decodeShader = KannaProteccMaterial.GenerateDecodeShader(data, _bitKeys);

KannaLogger.LogToFile($"Initialized, Getting All Meshes..", LogLocation);
KannaLogger.LogToFile($"Initialized, Getting All Meshes..", LogLocation);

var meshFilters = encodedGameObject.GetComponentsInChildren<MeshFilter>(true).Select(o => (o, o.gameObject.activeSelf));
var skinnedMeshRenderers = encodedGameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true).Select(o => (o, o.gameObject.activeSelf));
var meshFilters = encodedGameObject.GetComponentsInChildren<MeshFilter>(true).Select(o => (o, o.gameObject.activeSelf));
var skinnedMeshRenderers = encodedGameObject.GetComponentsInChildren<SkinnedMeshRenderer>(true).Select(o => (o, o.gameObject.activeSelf));

KannaLogger.LogToFile($"Got All Meshes, Encrypting Additional Materials..", LogLocation);
KannaLogger.LogToFile($"Got All Meshes, Encrypting Additional Materials..", LogLocation);

EncryptMaterials(null, m_AdditionalMaterials.ToArray(), decodeShader, m_IgnoredMaterials);
EncryptMaterials(null, m_AdditionalMaterials.ToArray(), decodeShader, m_IgnoredMaterials);

KannaLogger.LogToFile($"Additional Materials Encrypted, Processing MeshFilters..", LogLocation);
KannaLogger.LogToFile($"Additional Materials Encrypted, Processing MeshFilters..", LogLocation);

// Do encrypting
foreach (var meshFilter in meshFilters)
{
if (meshFilter.o.GetComponent<MeshRenderer>() != null)
// Do encrypting
foreach (var meshFilter in meshFilters)
{
meshFilter.o.gameObject.SetActive(true);
var materials = meshFilter.o.GetComponent<MeshRenderer>().sharedMaterials;
if (EncryptMaterials(meshFilter.o.sharedMesh, materials, decodeShader, m_IgnoredMaterials))
if (meshFilter.o.GetComponent<MeshRenderer>() != null)
{
meshFilter.o.sharedMesh = KannaProteccMesh.EncryptMesh(meshFilter.o.GetComponent<MeshRenderer>(), meshFilter.o.sharedMesh, _distortRatio, data, m_IgnoredMaterials) ?? meshFilter.o.sharedMesh;
meshFilter.o.gameObject.SetActive(true);
var materials = meshFilter.o.GetComponent<MeshRenderer>().sharedMaterials;
if (EncryptMaterials(meshFilter.o.sharedMesh, materials, decodeShader, m_IgnoredMaterials))
{
meshFilter.o.sharedMesh = KannaProteccMesh.EncryptMesh(meshFilter.o.GetComponent<MeshRenderer>(), meshFilter.o.sharedMesh, _distortRatio, data, m_IgnoredMaterials) ?? meshFilter.o.sharedMesh;
}
else
{
KannaLogger.LogToFile($"Ignoring Encrypt On Generic: {meshFilter.o.gameObject.name} - No Materials Encrypted", LogLocation, KannaLogger.LogType.Warning);
}

meshFilter.o.gameObject.SetActive(meshFilter.activeSelf);
}
else
{
KannaLogger.LogToFile($"Ignoring Encrypt On Generic: {meshFilter.o.gameObject.name} - No Materials Encrypted", LogLocation, KannaLogger.LogType.Warning);
KannaLogger.LogToFile($"WTF? MeshFilter Lacks A Renderer! -> {meshFilter.o.name}", LogLocation, KannaLogger.LogType.Error);
}

meshFilter.o.gameObject.SetActive(meshFilter.activeSelf);
}
else
{
KannaLogger.LogToFile($"WTF? MeshFilter Lacks A Renderer! -> {meshFilter.o.name}", LogLocation, KannaLogger.LogType.Error);
}
}

KannaLogger.LogToFile($"MeshFilters Done, Processing SkinnedMeshRenderers..", LogLocation);
KannaLogger.LogToFile($"MeshFilters Done, Processing SkinnedMeshRenderers..", LogLocation);

foreach (var skinnedMeshRenderer in skinnedMeshRenderers)
{
if (skinnedMeshRenderer.o.GetComponent<Cloth>() == null)
foreach (var skinnedMeshRenderer in skinnedMeshRenderers)
{
skinnedMeshRenderer.o.gameObject.SetActive(true);
var materials = skinnedMeshRenderer.o.sharedMaterials;
if (EncryptMaterials(skinnedMeshRenderer.o.sharedMesh, materials, decodeShader, m_IgnoredMaterials))
if (skinnedMeshRenderer.o.GetComponent<Cloth>() == null)
{
skinnedMeshRenderer.o.sharedMesh = KannaProteccMesh.EncryptMesh(skinnedMeshRenderer.o, skinnedMeshRenderer.o.sharedMesh, _distortRatio, data, m_IgnoredMaterials) ?? skinnedMeshRenderer.o.sharedMesh;
skinnedMeshRenderer.o.gameObject.SetActive(true);
var materials = skinnedMeshRenderer.o.sharedMaterials;
if (EncryptMaterials(skinnedMeshRenderer.o.sharedMesh, materials, decodeShader, m_IgnoredMaterials))
{
skinnedMeshRenderer.o.sharedMesh = KannaProteccMesh.EncryptMesh(skinnedMeshRenderer.o, skinnedMeshRenderer.o.sharedMesh, _distortRatio, data, m_IgnoredMaterials) ?? skinnedMeshRenderer.o.sharedMesh;
}
else
{
KannaLogger.LogToFile($"Ignoring Encrypt On Skinned: {skinnedMeshRenderer.o.gameObject.name} - No Materials Encrypted", LogLocation, KannaLogger.LogType.Warning);
}

skinnedMeshRenderer.o.gameObject.SetActive(skinnedMeshRenderer.activeSelf);
}
else
{
KannaLogger.LogToFile($"Ignoring Encrypt On Skinned: {skinnedMeshRenderer.o.gameObject.name} - No Materials Encrypted", LogLocation, KannaLogger.LogType.Warning);
KannaLogger.LogToFile($"Ignoring Encrypt On {skinnedMeshRenderer.o.gameObject.name} - Cloth Found.", LogLocation, KannaLogger.LogType.Warning);
}

skinnedMeshRenderer.o.gameObject.SetActive(skinnedMeshRenderer.activeSelf);
}
else
{
KannaLogger.LogToFile($"Ignoring Encrypt On {skinnedMeshRenderer.o.gameObject.name} - Cloth Found.", LogLocation, KannaLogger.LogType.Warning);
}
}

KannaLogger.LogToFile($"SkinnedMeshRenderers Done, Removing Lingering KannaProteccRoot On Encrypted Object..", LogLocation);
KannaLogger.LogToFile($"SkinnedMeshRenderers Done, Removing Lingering KannaProteccRoot On Encrypted Object..", LogLocation);

var KannaProteccRoots = encodedGameObject.GetComponentsInChildren<KannaProteccRoot>(true);
foreach (var KannaProteccRoot in KannaProteccRoots)
{
DestroyImmediate(KannaProteccRoot);
}
var KannaProteccRoots = encodedGameObject.GetComponentsInChildren<KannaProteccRoot>(true);
foreach (var KannaProteccRoot in KannaProteccRoots)
{
DestroyImmediate(KannaProteccRoot);
}

KannaLogger.LogToFile($"Done Removing, Disabling Original Avatar Object And Refreshing AssetDatabase..", LogLocation);
KannaLogger.LogToFile($"Done Removing, Disabling Original Avatar Object And Refreshing AssetDatabase..", LogLocation);

// Disable old for convienence.
gameObject.SetActive(false);
// Disable old for convienence.
gameObject.SetActive(false);

// Force unity to import things
AssetDatabase.Refresh();
// Force unity to import things
AssetDatabase.Refresh();

KannaLogger.LogToFile($"Done Refreshing, Beginning Obfuscation Stage..", LogLocation);
KannaLogger.LogToFile($"Done Refreshing, Beginning Obfuscation Stage..", LogLocation);

IsProtected = true;
IsProtected = true;

EditorSceneManager.MarkAllScenesDirty();
EditorSceneManager.MarkAllScenesDirty();

// Do Obfuscation
var newobj = obfuscator.Obfuscate(encodedGameObject, this);
// Do Obfuscation
var newobj = obfuscator.Obfuscate(encodedGameObject, this);

KannaLogger.LogToFile($"Done Obfuscating, Disabling Encrypted Object, Saving Assets And Scene, Then Refreshing AssetDatabase.", LogLocation);
KannaLogger.LogToFile($"Done Obfuscating, Disabling Encrypted Object, Saving Assets And Scene, Then Refreshing AssetDatabase.", LogLocation);

encodedGameObject.SetActive(false); // Temp
encodedGameObject.SetActive(false); // Temp

AssetDatabase.SaveAssets();
AssetDatabase.SaveAssets();

// Force unity to import things
AssetDatabase.Refresh();
// Force unity to import things
AssetDatabase.Refresh();

KannaLogger.LogToFile($"Done Refreshing, Writing Keys To ExpressionParameters", LogLocation);
KannaLogger.LogToFile($"Done Refreshing, Writing Keys To ExpressionParameters", LogLocation);

WriteBitKeysToExpressions(newobj.GetComponent<VRCAvatarDescriptor>().expressionParameters, true);
WriteBitKeysToExpressions(newobj.GetComponent<VRCAvatarDescriptor>().expressionParameters, true);

KannaLogger.LogToFile($"Done Writing Keys, Validating FX Controller And Obfuscating Kanna Protecc Layer Within It", LogLocation);
KannaLogger.LogToFile($"Done Writing Keys, Validating FX Controller And Obfuscating Kanna Protecc Layer Within It", LogLocation);

ValidateAnimatorController(newobj, AssetDatabase.LoadAssetAtPath<AnimatorController>(AssetDatabase.GetAssetPath(newobj.GetComponent<VRCAvatarDescriptor>().baseAnimationLayers.First(o => o.type == VRCAvatarDescriptor.AnimLayerType.FX).animatorController)));
ValidateAnimatorController(newobj, AssetDatabase.LoadAssetAtPath<AnimatorController>(AssetDatabase.GetAssetPath(newobj.GetComponent<VRCAvatarDescriptor>().baseAnimationLayers.First(o => o.type == VRCAvatarDescriptor.AnimLayerType.FX).animatorController)));

KannaLogger.LogToFile($"Done! Showing Dialog To User.", LogLocation);
KannaLogger.LogToFile($"Done! Showing Dialog To User.", LogLocation);

DestroyImmediate(encodedGameObject);
newobj.name = newobj.name.Replace("_Encrypted_Obfuscated", "_KannaProteccted");
DestroyImmediate(encodedGameObject);
newobj.name = newobj.name.Replace("_Encrypted_Obfuscated", "_KannaProteccted");

KannaLogger.WriteLogsToFile(LogLocation);
KannaLogger.WriteLogsToFile(LogLocation);

EditorSceneManager.MarkAllScenesDirty();
EditorSceneManager.MarkAllScenesDirty();

AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
EditorSceneManager.SaveOpenScenes();
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
EditorSceneManager.SaveOpenScenes();

EditorUtility.DisplayDialog("Successfully Encrypted!", $"{(string.IsNullOrEmpty(GetComponent<PipelineManager>()?.blueprintId) ? "" : "Keys were automatically written. ")}Your avatar should be ready to upload!", "Okay");
EditorUtility.DisplayDialog("Successfully Encrypted!", $"{(string.IsNullOrEmpty(GetComponent<PipelineManager>()?.blueprintId) ? "" : "Keys were automatically written. ")}Your avatar should be ready to upload!", "Okay");
}
catch (Exception ex)
{
KannaLogger.LogToFile(ex.ToString(), LogLocation, KannaLogger.LogType.Error);

KannaLogger.WriteLogsToFile(LogLocation);
}
}

public static Type GetTypeFromAnyAssembly(string FullName)
Expand Down

0 comments on commit 0841488

Please sign in to comment.