From 0f7b5028830c118969030c12e5af55683f02da28 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Sat, 14 Feb 2026 04:23:15 +0900 Subject: [PATCH 01/15] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75a4843..97a654b 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ OSC 소스 코드: https://github.com/Shell4026/ShellProtectorOSC ### 파라미터 멀티플렉싱 세부 원리:https://github.com/seanedwards/vrc-worldobject/blob/main/docs/parameter-multiplexing.md -파라미터 절약 기술입니다. 체크 후 OSC를 항상 켜둬야하며 OSC프로그램에도 Parameter-multiplexing을 체크 해야합니다. +파라미터 절약 기술입니다. 체크 후 OSC를 항상 켜둬야하며 OSC프로그램에도 **Parameter-multiplexing을 체크** 해야 합니다. 인게임에서 원래 모습으로 돌아오기까지 시간이 약간 증가합니다. @@ -62,6 +62,8 @@ OSC 소스 코드: https://github.com/Shell4026/ShellProtectorOSC 이 경우 OSC 1.5.0에 추가된 Refresh rate를 조금 올려보시길 바랍니다. +2.5.0beta부터 기본 적용 됩니다. + ### 아바타 폴백 암호화가 걸려있을 때 세이프티가 켜져있는 사람은 아바타를 볼 때 열화된 버전으로 보이게 하는 기능입니다. ![fallback](https://github.com/user-attachments/assets/d3ca69b0-ff08-4793-a4e4-73269bc8efd3) From 6d1a8a1e0150b0d83c8294d722b4890c3332b3ed Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Sat, 14 Feb 2026 04:24:33 +0900 Subject: [PATCH 02/15] Update README.ENG.md --- README.ENG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.ENG.md b/README.ENG.md index c1dbbe4..1dddcea 100644 --- a/README.ENG.md +++ b/README.ENG.md @@ -53,7 +53,7 @@ Source code of OSC: https://github.com/Shell4026/ShellProtectorOSC ### Parameter-multiplexing Detailed principle:https://github.com/seanedwards/vrc-worldobject/blob/main/docs/parameter-multiplexing.md -This is a parameter-saving technique. After checking, OSC must always be turned on and Parameter-multiplexing must be checked in the OSC program. +This is a parameter-saving technique. After checking, OSC must always be **turned on and Parameter-multiplexing** must be checked in the OSC program. This will slightly increase the time it takes to get back to your original avatar appearance in-game. @@ -63,6 +63,8 @@ When using parameter multiplexing, depending on the server or network conditions In this case, try increasing the refresh rate slightly, which was added in OSC 1.5.0. +It is applied by default from version 2.5.0beta. + ### Avatar fallback A feature that allows anyone with Safety On when encryption is in place to appear as a degraded version of themselves when viewing your avatar. ![fallback](https://github.com/user-attachments/assets/d3ca69b0-ff08-4793-a4e4-73269bc8efd3) From c380a6434be336a806fde07acd7089b18f1494d5 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Sat, 14 Feb 2026 04:30:01 +0900 Subject: [PATCH 03/15] Update README.JP.md --- README.JP.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.JP.md b/README.JP.md index 2bb2a18..f3b15ab 100644 --- a/README.JP.md +++ b/README.JP.md @@ -54,7 +54,7 @@ OSCのソースコード: https://github.com/Shell4026/ShellProtectorOSC ### パラメータマルチプレックス 詳細原理:https://github.com/seanedwards/vrc-worldobject/blob/main/docs/parameter-multiplexing.md -パラメータ節約技術です。チェック後、OSCを常にオンにしておく必要があり、OSCプログラムにもParameter-multiplexingをチェックする必要があります。 +パラメータ節約技術です。チェック後、OSCを常にオンにしておく必要があり、OSCプログラムにも**Parameter-multiplexingをチェック**する必要があります。 ゲーム内で元の姿に戻るまでの時間が若干増加します。 @@ -64,6 +64,8 @@ OSCのソースコード: https://github.com/Shell4026/ShellProtectorOSC この場合、OSC 1.5.0で追加されたRefresh rateを少し上げてみてください。 +2.5.0betaからデフォルトで適用されます。 + ### アバターフォールバック 暗号化がかかっているときにSafetyがオンになっている人は、アバターを見るときに劣化したバージョンに見えるようにする機能です。 ![fallback](https://github.com/user-attachments/assets/d3ca69b0-ff08-4793-a4e4-73269bc8efd3) From 17a77b94e964e08e8070f6e247077acdc387f9e0 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Mon, 13 Jul 2026 01:45:54 +0900 Subject: [PATCH 04/15] fix: Security issues!!! --- Runtime/Scripts/Pipeline/MaterialEncryptor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/Pipeline/MaterialEncryptor.cs b/Runtime/Scripts/Pipeline/MaterialEncryptor.cs index fd35645..7b2f64f 100644 --- a/Runtime/Scripts/Pipeline/MaterialEncryptor.cs +++ b/Runtime/Scripts/Pipeline/MaterialEncryptor.cs @@ -39,8 +39,8 @@ public Material CreateEncryptedMaterial(string folderGuid, string fileName, Mate var (widthOffset, heightOffset) = TextureEncryptManager.CalculateOffsets(originalTex); result.SetInteger(ShaderProperties.WidthOffset, widthOffset); result.SetInteger(ShaderProperties.HeightOffset, heightOffset); - for (int i = 0; i < keyBytes.Length; ++i) - result.SetFloat(ShaderProperties.KeyPrefix + i, keyBytes[i]); + //for (int i = 0; i < keyBytes.Length; ++i) + // result.SetFloat(ShaderProperties.KeyPrefix + i, keyBytes[i]); if (algorithm == (int)ShellProtectorAlgorithm.Chacha) { From d7c39e04985cbee0d9d67bb5162dfbf2d9171c5b Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Mon, 13 Jul 2026 01:49:16 +0900 Subject: [PATCH 05/15] build: 2.6.1 --- package.json | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1cf5999..ba6acc7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "shell.protector", "displayName": "Shell Protector", - "version": "2.6.0", + "version": "2.6.1", "unity": "2022.3", "description": "Texture encryption for VRChat. Save avatars from ripping", "author": { diff --git a/version.json b/version.json index 15fecae..9f16ac1 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "latestVersion": "2.6.0", "downloadPage": "/releases/tag/2.6.0" } \ No newline at end of file +{ "latestVersion": "2.6.1", "downloadPage": "/releases/tag/2.6.1" } \ No newline at end of file From a555329543a58833a52637f001b43b063b97c71d Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Mon, 13 Jul 2026 02:58:18 +0900 Subject: [PATCH 06/15] fix: Fix a bug where fixed key values were not reflected in the material --- Runtime/Scripts/Pipeline/MaterialEncryptor.cs | 6 +++--- Runtime/Scripts/ShellProtector.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Runtime/Scripts/Pipeline/MaterialEncryptor.cs b/Runtime/Scripts/Pipeline/MaterialEncryptor.cs index 7b2f64f..b138787 100644 --- a/Runtime/Scripts/Pipeline/MaterialEncryptor.cs +++ b/Runtime/Scripts/Pipeline/MaterialEncryptor.cs @@ -18,7 +18,7 @@ public MaterialEncryptor(AssetWriter writer, bool turnOnAllSafetyFallback, int a this.rounds = rounds; } - public Material CreateEncryptedMaterial(string folderGuid, string fileName, Material source, Shader shader, Texture2D fallback, Texture2D mip, AuxiliaryTextures auxiliary, ProcessedTexture texture, byte[] keyBytes, IEncryptor encryptor, Injector injector) + public Material CreateEncryptedMaterial(string folderGuid, string fileName, Material source, Shader shader, Texture2D fallback, Texture2D mip, AuxiliaryTextures auxiliary, ProcessedTexture texture, byte[] keyBytes, int fixedKeySize, IEncryptor encryptor, Injector injector) { Material result = new Material(source.shader); result.CopyPropertiesFromMaterial(source); @@ -39,8 +39,8 @@ public Material CreateEncryptedMaterial(string folderGuid, string fileName, Mate var (widthOffset, heightOffset) = TextureEncryptManager.CalculateOffsets(originalTex); result.SetInteger(ShaderProperties.WidthOffset, widthOffset); result.SetInteger(ShaderProperties.HeightOffset, heightOffset); - //for (int i = 0; i < keyBytes.Length; ++i) - // result.SetFloat(ShaderProperties.KeyPrefix + i, keyBytes[i]); + for (int i = 0; i < fixedKeySize; ++i) + result.SetFloat(ShaderProperties.KeyPrefix + i, keyBytes[i]); if (algorithm == (int)ShellProtectorAlgorithm.Chacha) { diff --git a/Runtime/Scripts/ShellProtector.cs b/Runtime/Scripts/ShellProtector.cs index a58919e..86e0031 100644 --- a/Runtime/Scripts/ShellProtector.cs +++ b/Runtime/Scripts/ShellProtector.cs @@ -1264,7 +1264,7 @@ Texture2D GenerateFallbackTexture(string fileName, MatOption option, Texture2D m Material GenerateEncryptedMaterial(string fileName, Material mat, Shader encryptedShader, Texture2D fallback, Texture2D mip, AuxiliaryTextures otherTex, ProcessedTexture processedTexture, byte[] keyBytes, IEncryptor encryptor) { MaterialEncryptor materialEncryptor = new MaterialEncryptor(_assetWriter, _turnOnAllSafetyFallback, _algorithm, _rounds); - Material newMat = materialEncryptor.CreateEncryptedMaterial(GetOutputPaths().Folders.MatGuid, fileName, mat, encryptedShader, fallback, mip, otherTex, processedTexture, keyBytes, encryptor, _injector); + Material newMat = materialEncryptor.CreateEncryptedMaterial(GetOutputPaths().Folders.MatGuid, fileName, mat, encryptedShader, fallback, mip, otherTex, processedTexture, keyBytes, _keySize, encryptor, _injector); Debug.LogFormat("{0} : create encrypted material : {1}", mat.name, AssetDatabase.GetAssetPath(newMat)); if (!EncryptedMaterials.ContainsKey(mat)) From d5981b5cb5eb8d26c459362f7cd584c104d28be9 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Mon, 13 Jul 2026 03:11:43 +0900 Subject: [PATCH 07/15] fix: Fix a bug where shape keys were obfuscated only the base layer --- Runtime/Scripts/ShellProtector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Runtime/Scripts/ShellProtector.cs b/Runtime/Scripts/ShellProtector.cs index 86e0031..6850a2a 100644 --- a/Runtime/Scripts/ShellProtector.cs +++ b/Runtime/Scripts/ShellProtector.cs @@ -905,7 +905,7 @@ public void ObfuscateBlendShape(GameObject avatar, bool clone) #endif for (int i = 0; i <= 4; ++i) { - AnimatorController playableLayer = GetFx(avatar, 0); + AnimatorController playableLayer = GetFx(avatar, i); if (playableLayer == null) continue; obfuscator.ObfuscateBlendshapeInAnim(playableLayer, selectRenderer.gameObject, paths, _assetWriter); From 7942c738b2422e7a5b27f687db6846bcab498a0d Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Mon, 13 Jul 2026 03:19:50 +0900 Subject: [PATCH 08/15] build: 2.6.2 --- package.json | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ba6acc7..3c38e57 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "shell.protector", "displayName": "Shell Protector", - "version": "2.6.1", + "version": "2.6.2", "unity": "2022.3", "description": "Texture encryption for VRChat. Save avatars from ripping", "author": { diff --git a/version.json b/version.json index 9f16ac1..a9e2abb 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "latestVersion": "2.6.1", "downloadPage": "/releases/tag/2.6.1" } \ No newline at end of file +{ "latestVersion": "2.6.2", "downloadPage": "/releases/tag/2.6.2" } \ No newline at end of file From 26a30ac349feabe3a65dd077d624db2d78d57ce9 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Tue, 14 Jul 2026 00:39:06 +0900 Subject: [PATCH 09/15] fix: Playable layers were not copied when manual encryption --- Runtime/Scripts/AnimatorManager.cs | 38 +++++++++++-- Runtime/Scripts/ShellProtector.cs | 18 +++++-- Tests/Editor/Integration/PipelineTests.cs | 65 +++++++++++++++++++++++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/Runtime/Scripts/AnimatorManager.cs b/Runtime/Scripts/AnimatorManager.cs index 6714c06..67a7ebc 100644 --- a/Runtime/Scripts/AnimatorManager.cs +++ b/Runtime/Scripts/AnimatorManager.cs @@ -17,15 +17,45 @@ public class AnimatorManager : ScriptableObject public static AnimatorController DuplicateAnimator(RuntimeAnimatorController anim, OutputPaths paths, AssetWriter writer) { - string dir = AssetDatabase.GetAssetPath(anim); - if (!writer.CopyAssetToFolder(dir, paths.Folders.AnimGuid, paths.ControllerName(anim), out string output)) + return DuplicateAnimators(new[] { anim }, paths, writer)[0]; + } + + public static AnimatorController[] DuplicateAnimators(RuntimeAnimatorController[] animators, OutputPaths paths, AssetWriter writer) + { + var sourcePaths = new string[animators.Length]; + var targetPaths = new Dictionary(); + + for (int i = 0; i < animators.Length; ++i) { - Debug.LogErrorFormat("Failed to copy a animator: {0}", anim.name); + RuntimeAnimatorController animator = animators[i]; + if (animator == null) + continue; + + string sourcePath = AssetDatabase.GetAssetPath(animator); + sourcePaths[i] = sourcePath; + if (targetPaths.ContainsKey(sourcePath)) + continue; + + if (!writer.CopyAssetToFolder(sourcePath, paths.Folders.AnimGuid, paths.ControllerName(animator), out string targetPath)) + { + Debug.LogErrorFormat("Failed to copy a animator: {0}", animator.name); + continue; + } + + targetPaths.Add(sourcePath, targetPath); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); - return AssetDatabase.LoadAssetAtPath(output, typeof(RuntimeAnimatorController)) as AnimatorController; + + var duplicatedAnimators = new AnimatorController[animators.Length]; + for (int i = 0; i < sourcePaths.Length; ++i) + { + if (!string.IsNullOrEmpty(sourcePaths[i]) && targetPaths.TryGetValue(sourcePaths[i], out string targetPath)) + duplicatedAnimators[i] = AssetDatabase.LoadAssetAtPath(targetPath); + } + + return duplicatedAnimators; } public static void CreateKeyAnimations(string animationDir, OutputPaths paths, AssetWriter writer, GameObject[] objs) diff --git a/Runtime/Scripts/ShellProtector.cs b/Runtime/Scripts/ShellProtector.cs index 6850a2a..141f732 100644 --- a/Runtime/Scripts/ShellProtector.cs +++ b/Runtime/Scripts/ShellProtector.cs @@ -726,14 +726,26 @@ static Texture2D GetLargestFallback(ProcessedTexture processedTexture) public void SetAnimations(GameObject avatar, bool clone) { var av3 = avatar.GetComponent(); - AnimatorController fx; OutputPaths paths = EnsureOutputFolders(); + AnimatorController fx; if (clone) - fx = AnimatorManager.DuplicateAnimator(av3.baseAnimationLayers[4].animatorController, paths, _assetWriter); + { + var sourceControllers = new RuntimeAnimatorController[av3.baseAnimationLayers.Length]; + for (int i = 0; i < av3.baseAnimationLayers.Length; ++i) + sourceControllers[i] = av3.baseAnimationLayers[i].animatorController; + + AnimatorController[] duplicatedLayers = AnimatorManager.DuplicateAnimators(sourceControllers, paths, _assetWriter); + for (int i = 0; i < duplicatedLayers.Length; ++i) + { + if (duplicatedLayers[i] != null) + av3.baseAnimationLayers[i].animatorController = duplicatedLayers[i]; + } + + fx = duplicatedLayers[4]; + } else fx = av3.baseAnimationLayers[4].animatorController as AnimatorController; - av3.baseAnimationLayers[4].animatorController = fx; string animationDir = _assetWriter.ResolveFolderPath(paths.Folders.AnimGuid); GameObject[] meshArray = new GameObject[Meshes.Count]; diff --git a/Tests/Editor/Integration/PipelineTests.cs b/Tests/Editor/Integration/PipelineTests.cs index 16fb9e1..17e2562 100644 --- a/Tests/Editor/Integration/PipelineTests.cs +++ b/Tests/Editor/Integration/PipelineTests.cs @@ -53,6 +53,38 @@ public void ManualEncrypt_CreatesEncryptedAvatarAndRewritesProtectionAssets() AssertAnimationMaterialWasRewritten(encryptedAvatar, fixture.Material); } + [Test] + public void ManualEncrypt_DuplicatesNonFxControllerBeforeObfuscatingBlendShapes() + { + Fixture fixture = CreateFixture("ControllerIsolation"); + VRCAvatarDescriptor originalDescriptor = fixture.Avatar.GetComponent(); + AnimationClip originalClip = CreateBlendShapeClip("ControllerIsolation"); + AnimatorController originalController = CreateBlendShapeController("ControllerIsolation", originalClip); + originalDescriptor.baseAnimationLayers[0] = new VRCAvatarDescriptor.CustomAnimLayer + { + type = VRCAvatarDescriptor.AnimLayerType.Base, + isDefault = false, + animatorController = originalController + }; + + GameObject encryptedAvatar = fixture.Protector.Encrypt(false); + sceneObjects.Add(encryptedAvatar); + + AnimatorController sourceController = originalDescriptor.baseAnimationLayers[0].animatorController as AnimatorController; + AnimatorController encryptedController = encryptedAvatar.GetComponent() + .baseAnimationLayers[0].animatorController as AnimatorController; + AnimationClip sourceClip = GetFirstClip(sourceController); + AnimationClip encryptedClip = GetFirstClip(encryptedController); + + Assert.That(sourceController, Is.SameAs(originalController)); + Assert.That(encryptedController, Is.Not.SameAs(originalController)); + Assert.That(sourceClip, Is.SameAs(originalClip)); + Assert.That(encryptedClip, Is.Not.SameAs(originalClip)); + Assert.That(AnimationUtility.GetCurveBindings(sourceClip).Single().propertyName, Is.EqualTo("blendShape.Smile")); + Assert.That(AnimationUtility.GetCurveBindings(encryptedClip).Single().propertyName, Does.StartWith("blendShape.")); + Assert.That(AnimationUtility.GetCurveBindings(encryptedClip).Single().propertyName, Is.Not.EqualTo("blendShape.Smile")); + } + [Test] public void InPlaceEncrypt_RewritesOriginalAvatarWhenNdmfStyleStepsRun() { @@ -190,6 +222,39 @@ private static AnimationClip CreateMaterialClip(string name, Material material) return AssetDatabase.LoadAssetAtPath(path); } + private static AnimationClip CreateBlendShapeClip(string name) + { + AnimationClip clip = new AnimationClip(); + clip.name = name + "BlendShape"; + EditorCurveBinding binding = new EditorCurveBinding + { + path = "Body", + type = typeof(SkinnedMeshRenderer), + propertyName = "blendShape.Smile" + }; + AnimationUtility.SetEditorCurve(clip, binding, AnimationCurve.Constant(0f, 1f, 100f)); + string path = TestAssetScope.CreateAsset(clip, name + "/blendShape.anim"); + return AssetDatabase.LoadAssetAtPath(path); + } + + private static AnimatorController CreateBlendShapeController(string name, AnimationClip clip) + { + string path = TestAssetScope.GeneratedRoot + "/" + name + "/base.controller"; + TestAssetScope.EnsureFolder(TestAssetScope.GeneratedRoot + "/" + name); + AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(path); + AnimatorControllerLayer layer = controller.layers[0]; + AnimatorState state = layer.stateMachine.AddState("BlendShape"); + state.motion = clip; + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + return AssetDatabase.LoadAssetAtPath(path); + } + + private static AnimationClip GetFirstClip(AnimatorController controller) + { + return controller.layers[0].stateMachine.states[0].state.motion as AnimationClip; + } + private static AnimatorController CreateFxController(string name, AnimationClip materialClip) { string path = TestAssetScope.GeneratedRoot + "/" + name + "/fx.controller"; From 07df1a14aade2bf1507926b8e9d090ac3fec4d75 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Tue, 14 Jul 2026 22:11:17 +0900 Subject: [PATCH 10/15] fix: Fix a bug where part of the key was included in the material --- Runtime/Scripts/ShellProtector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Runtime/Scripts/ShellProtector.cs b/Runtime/Scripts/ShellProtector.cs index 141f732..48b37d3 100644 --- a/Runtime/Scripts/ShellProtector.cs +++ b/Runtime/Scripts/ShellProtector.cs @@ -1276,7 +1276,7 @@ Texture2D GenerateFallbackTexture(string fileName, MatOption option, Texture2D m Material GenerateEncryptedMaterial(string fileName, Material mat, Shader encryptedShader, Texture2D fallback, Texture2D mip, AuxiliaryTextures otherTex, ProcessedTexture processedTexture, byte[] keyBytes, IEncryptor encryptor) { MaterialEncryptor materialEncryptor = new MaterialEncryptor(_assetWriter, _turnOnAllSafetyFallback, _algorithm, _rounds); - Material newMat = materialEncryptor.CreateEncryptedMaterial(GetOutputPaths().Folders.MatGuid, fileName, mat, encryptedShader, fallback, mip, otherTex, processedTexture, keyBytes, _keySize, encryptor, _injector); + Material newMat = materialEncryptor.CreateEncryptedMaterial(GetOutputPaths().Folders.MatGuid, fileName, mat, encryptedShader, fallback, mip, otherTex, processedTexture, keyBytes, 16 - _keySize, encryptor, _injector); Debug.LogFormat("{0} : create encrypted material : {1}", mat.name, AssetDatabase.GetAssetPath(newMat)); if (!EncryptedMaterials.ContainsKey(mat)) From 987b179edcbaa2b0293c59122a71d634d028999d Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Tue, 14 Jul 2026 22:11:33 +0900 Subject: [PATCH 11/15] build: 2.6.3 --- package.json | 2 +- version.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3c38e57..b609102 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "shell.protector", "displayName": "Shell Protector", - "version": "2.6.2", + "version": "2.6.3", "unity": "2022.3", "description": "Texture encryption for VRChat. Save avatars from ripping", "author": { diff --git a/version.json b/version.json index a9e2abb..3c35077 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{ "latestVersion": "2.6.2", "downloadPage": "/releases/tag/2.6.2" } \ No newline at end of file +{ "latestVersion": "2.6.3", "downloadPage": "/releases/tag/2.6.3" } \ No newline at end of file From 3afd9e81574ce0ba54cdfcec0ea11bb0a0860655 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:20:29 +0900 Subject: [PATCH 12/15] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bd60ec..5ab7f3b 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ OSC 소스 코드: https://github.com/Shell4026/ShellProtectorOSC **** -텍스쳐를 선택 후 Inspector에서 압축 포멧을 DXT1이나 DXT5중 하나로 바꿔주세요. (투명도가 있는 텍스쳐는 DXT5) +텍스쳐를 선택 후 Inspector에서 압축 포멧을 DXT1/RGB24나 DXT5/RGBA32중 하나로 바꿔주세요. (투명도가 있는 텍스쳐는 DXT5) ![texture](https://github.com/Shell4026/ShellProtector/assets/104874910/872f9d15-7b89-4381-b940-00514bd60638) @@ -105,6 +105,8 @@ OSC 소스 코드: https://github.com/Shell4026/ShellProtectorOSC 이 경우 OSC 1.5.0에 추가된 Refresh rate를 조금 올려보시길 바랍니다. +파라미터 압축 에셋이 있는 경우에도 발생할 수 있습니다. + **<메테리얼에서 있던 텍스쳐가 빠지는 경우>** 메인 컬러와 같은 텍스쳐 사용시 보안상의 이유로 해당 텍스쳐는 빠집니다. From 3c8c31786f3c2f18c52973cc07908b35670a472a Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:21:30 +0900 Subject: [PATCH 13/15] Update README.ENG.md --- README.ENG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.ENG.md b/README.ENG.md index a2ae330..b23c937 100644 --- a/README.ENG.md +++ b/README.ENG.md @@ -80,7 +80,7 @@ If you find the issue, please raise it in Issues. **[is not supported texture format! Error]** -Select the texture and change the compression format to either DXT1 or DXT5 in the Inspector. (DXT5 for textures with transparency) +Select the texture and change the compression format to either DXT1/RGB24 or DXT5/RGBA32 in the Inspector. (DXT5 for textures with transparency) ![texture](https://github.com/Shell4026/ShellProtector/assets/104874910/872f9d15-7b89-4381-b940-00514bd60638) @@ -106,6 +106,8 @@ When using parameter multiplexing, depending on the server or network conditions In this case, try increasing the refresh rate slightly, which was added in OSC 1.5.0. +This can also occur when there are parameter-compressed assets. + **[When a Texture that was present in a Material is missing]** When using a texture such as a main color/texture, it will be stripped for security reasons. From ce23f643605b758743022077fb38642b2db16527 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:22:04 +0900 Subject: [PATCH 14/15] Update README.JP.md --- README.JP.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.JP.md b/README.JP.md index 0f8453a..4a533b2 100644 --- a/README.JP.md +++ b/README.JP.md @@ -81,7 +81,7 @@ OSCのソースコード: https://github.com/Shell4026/ShellProtectorOSC **** -テクスチャを選択後、Inspectorで圧縮フォーマットをDXT1またはDXT5のいずれかに変更してください。 (透明度のあるテクスチャはDXT5) +テクスチャを選択後、Inspectorで圧縮フォーマットをDXT1/RGB24またはDXT5/RGBA32のいずれかに変更してください。 (透明度のあるテクスチャはDXT5) ![texture](https://github.com/Shell4026/ShellProtector/assets/104874910/872f9d15-7b89-4381-b940-00514bd60638) @@ -107,6 +107,8 @@ lilToonのバグなので、無視してアップロードするか、3つの方 この場合、OSC 1.5.0で追加されたRefresh rateを少し上げてみてください。 +パラメータ圧縮されたアセットがある場合にも発生する可能性があります。 + **<マテリアルにあったテクスチャが消える場合>** メインカラーと同じテクスチャを使用する場合、セキュリティ上の理由でそのテクスチャは削除されます。 From 13e0df2a63df3c8600a27892109dd9d8b66d1c18 Mon Sep 17 00:00:00 2001 From: Shell <104874910+Shell4026@users.noreply.github.com> Date: Wed, 15 Jul 2026 01:30:48 +0900 Subject: [PATCH 15/15] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5ab7f3b..3596671 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FShell4026%2FShellProtector&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) # VCC : https://shell4026.github.io/VCC/ +347042998-b6e62237-67fe-4a4b-a415-12080ca64f01 +https://Shell4026.github.io/VCC/index.json + + 권장 유니티 버전 : 2022 ## | 한국어 | [English](./README.ENG.md) | [日本語](./README.JP.md) |