using System; using System.IO; using UnityEditor; namespace XGame.Editor.Build { [BuildCommand((uint)BuildCommandPriority.EncryptGlobalMetadata)] class CmdEncryptGlobalMetadata : BaseBuildCommand, ICommandExecuter { const string EncryptKey = @"DMMDyUKYp7z3orgK/bIImLojiy6/t3PUjIe6lojNGQVFB59AzSCRz7V7uSMI6DD2+"; const int Encryptoffset = 8; const int EncryptLength = 1024; public BuildErrorCode Execute() { BuildErrorCode rc = BuildErrorCode.CmdCompleted; if (Context.config.scriptImpl == ScriptingImplementation.IL2CPP) { string globalMetadata = GetMetadataPath(Context.config.target); try { BuildLog.Log($"CmdEncriptGlobalMetadata Encrypt: {globalMetadata}, Exists: {File.Exists(globalMetadata)}"); var bytes = File.ReadAllBytes(globalMetadata); Encrypt(bytes); File.WriteAllBytes(globalMetadata, bytes); } catch (Exception e) { BuildLog.Error($"CmdEncriptGlobalMetadata failed! Error: {e.Message}\nStackTrace: {e.StackTrace}"); rc = BuildErrorCode.EncryptGlobalMetadataError; } } return rc; } string GetMetadataPath(BuildTarget target) { string productName = Context.config.project.productName; const string relative = "Data/Managed/Metadata/global-metadata.dat"; return target switch { BuildTarget.Android => Path.Combine(Context.appOutputPath, "unityLibrary/src/main/assets/bin", relative), BuildTarget.iOS => Path.Combine(Context.appOutputPath, relative), BuildTarget.StandaloneWindows => Path.Combine(Directory.GetParent(Context.appOutputPath).ToString(), $"{productName}_Data/il2cpp_data/Metadata/global-metadata.dat"), BuildTarget.StandaloneWindows64 => Path.Combine(Directory.GetParent(Context.appOutputPath).ToString(), $"{productName}_Data/il2cpp_data/Metadata/global-metadata.dat"), _ => throw new NotImplementedException($"GetMetadataPath fail. target: {target}") }; } void Encrypt(byte[] bytes) { var keybuffer = System.Text.Encoding.UTF8.GetBytes(EncryptKey); var len = keybuffer.Length; for (int i = Encryptoffset; i < EncryptLength; i++) bytes[i] ^= keybuffer[(i - Encryptoffset) % len]; } } }