using UnityEngine; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; using System.IO; using System.Text; using System.Security.Cryptography; using AOT; using System.Reflection; namespace NetEase { public enum RequestCmdID { // iOS Cmd_GetSignInfo = 0, // 越狱状态 Cmd_IsRootDevice = 2, // SDK版本 Cmd_GetHTPVersion = 7, // 获取超时数据 Cmd_GetCollectData = 8, // 初始化配置内容,防止初始化失败情况下,客户可以通过服务端请求初始化配置并传递给SDK Cmd_SetConfigData = 16, // 客户服务端将check结果传递给SDK,便于执行后续动作 Cmd_SetResponseData = 17, // 获取服务端设备指纹 Cmd_GetDeviceId = 20, }; // 反外挂初始化配置类 public class HTProtectConfig { private int serverType; private string channel; private string gameKey; private Dictionary ext_data = new Dictionary(); private string host; private string key; private string value; private bool initThread; private bool initThreadExit; private bool initThreadCrash; private int initWaitSecond; public static bool ie { set; get; } public static bool ic { set; get; } public static int isec { set; get; } public HTProtectConfig() { this.serverType = 1; this.channel = ""; this.gameKey = ""; initThread = false; initThreadExit = false; initThreadCrash = false; initWaitSecond = 60; } public void setServerType(int server) { this.serverType = server; } public int getServerType() { return this.serverType; } public void setChannel(string channel) { this.channel = channel; } public string getChannel() { return this.channel; } public string getKey() { return this.key; } public string getValue() { return this.value; } public void setExtraData(string key, string value) { this.key = key; this.value = value; ext_data.Add(key, value); } private static string DataToJson(Dictionary data) { var str = new StringBuilder(); str.Append("{"); if (data.Count != 0) { foreach (var pair in data) { str.Append("\""); str.Append(pair.Key); str.Append("\":\""); str.Append(pair.Value); str.Append("\","); } str.Length -= 1; } str.Append("}"); return str.ToString(); } public string getExtraData() { return DataToJson(ext_data); } public void setGameKey(string gameKey) { this.gameKey = gameKey; } public string getGameKey() { return this.gameKey; } public void setHost(string host) { this.host = host; } public string getHost() { return this.host; } public void setInitThread(bool status) { initThread = status; } public bool getInitThread() { return initThread; } public void setInitThreadExit(bool status) { initThreadExit = status; } public bool getInitThreadExit() { return initThreadExit; } public void setInitThreadCrash(bool status) { initThreadCrash = status; } public bool getInitThreadCrash() { return initThreadCrash; } public void setInitWaitSecond(int sec) { initWaitSecond = sec; } public int getInitWaitSecond() { return initWaitSecond; } } public interface HTPCallback { void onReceive(int code, string msg); } public interface GetTokenCallback { void onResult(AntiCheatResult antiCheatResult); } #if UNITY_ANDROID public class AndroidCallback : AndroidJavaProxy { public AndroidCallback() : base("com.netease.htprotect.callback.HTPCallback") { } public virtual void onReceive(int code, string msg) { } } // 反作弊token回调类 public class NetEaseGetTokenCallback : AndroidJavaProxy { public NetEaseGetTokenCallback() : base("com.netease.htprotect.callback.GetTokenCallback") { } public virtual void onResult(AndroidJavaObject javaResult) { } } public class InnerCallback : AndroidCallback { private HTPCallback hTPCallback = null; public void SetCallBack(HTPCallback cb) { hTPCallback = cb; } public override void onReceive(int code, string msg) { if (hTPCallback != null) { MethodInfo onReceiveMethodInfo = typeof(HTPCallback).GetMethod("onReceive"); onReceiveMethodInfo.Invoke(hTPCallback, new object[] { code, msg}); } } } public class InnerGetTokenCallback : NetEaseGetTokenCallback { private GetTokenCallback getTokenCallback = null; public void SetCallBack(GetTokenCallback cb) { getTokenCallback = cb; } public override void onResult(AndroidJavaObject javaResult) { int code = javaResult.Get("code"); string codeStr = javaResult.Get("codeStr"); string token = javaResult.Get("token"); if (getTokenCallback != null) { NetEase.AntiCheatResult antiCheatResult = new NetEase.AntiCheatResult(code, codeStr, token); MethodInfo onReceiveMethodInfo = typeof(GetTokenCallback).GetMethod("onResult"); onReceiveMethodInfo.Invoke(getTokenCallback, new object[] { antiCheatResult }); } } } #endif // 安全通信结果类 public class SafeCommResult { public static int SC_CODE_OK = 0; public static int SC_FILE_NOTEXIST = -1; // apk包文件无文件 public static int SC_FILE_IS_BROKEN = -2; // apk包文件损坏 public static int SC_PROTOCOL_VERSION_ERROR = -3; // 协议版本不匹配 public static int SC_PARAM_ERROR = -4; // 参数错误 public static int SC_DATA_TAMPERED = -5; // 数据被篡改 public static int SC_DATA_DECRYPT_ERROR = -6; // 数据解密失败 public static int SC_ALG_ERROR = -7; // 算法不匹配,指定算法解密 public static int SC_TIMEOUT = -8; // 超时 public static int SC_NOSUPPORT = -9; // 功能不支持 public static int SC_NOT_INIT = -201; // 未初始化 public static int SC_CLOSED = -202; // 试用到期 public static int SC_BUFF_MALLOC_ERROR = -98; // 这种情况一般不会出现 public static int SC_INSIDE_ERROR = -99; //内部错误,一般不会出现 public int ret; public byte[] encBytes; public string encResult; public string signResult; public byte[] decResult; public SafeCommResult() { ret = SC_INSIDE_ERROR; decResult = null; encBytes = null; } } // 反作弊token结果类 public class AntiCheatResult { public static int OK = 200; public static string OK_STR = "success"; public static int ERROR_NOT_INIT = 201; public static string ERROR_NOT_INIT_STR = "error. not init"; public static int ERROR_ON_MAIN = 202; public static string ERROR_ON_MAIN_STR = "error. run on main thread"; public static int ERROR_BUSINESSID_INVALID = 203; public static string ERROR_BUSINESSID_INVALID_STR = "businessId invalid"; public static int ERROR_GEN_TOKEN = 204; public static String ERROR_GEN_TOKEN_STR = "gen token error"; public int code; public string codeStr; public string token; public string businessId; public AntiCheatResult(int code, string codeStr, string token) { this.code = code; this.codeStr = codeStr; this.token = token; } public AntiCheatResult(int code, string codeStr, string token, string businessId) { this.code = code; this.codeStr = codeStr; this.token = token; this.businessId = businessId; } public AntiCheatResult(int code, string token) : this(code, "", token) { } } public class NetSecProtect : MonoBehaviour { private static bool isInitialized = false; #if UNITY_ANDROID private const string strUUU_0 = "fZ434bpcoVuEg4egt6smXLGyYqq7mK9HKCv6+/9Rbe69IhXUaqaTI66/VCW1kN92L7md4h5J5u0x5z+l9S5+vQ=="; private const string strCCC_0 = "zg92y1ai5CJ0PPUSp4qiiClkDK6wFLRU4XvvuQTfxSI="; private const string strHHH_0 = "PSGLjT3zlSDO9iaG/j7Pr+yQcvUwxs1FdfbuAeJPFTNTAEHw2YbQmPLR0siO1i87TXeIq8bFszG+MyiSnyUhTw=="; private const string strIII_0 = "pObByb497KH0lJXQHeI7Cw=="; private const string strJJ0_0 = "PSGLjT3zlSDO9iaG/j7Pr+yQcvUwxs1FdfbuAeJPFTNTAEHw2YbQmPLR0siO1i87bFsGhO001wi0Dki1hL0Tb6WlgTf5KC4QJQiwhsQxoQE="; private const string strJJ3_0 = "dYxogZlQCdQ6sszrPSwI3v23LrTZQ77I0Wr84ZAZQb0="; private const string strJJ4_0 = "6M/pga7TT8g/vucazu+P9e0HIJ+CXgtkK+6IntvkXfg="; private const string strJJ5_0 = "9Ao2+MgC1ADNATEQckcaXWWxrFsGKq6Exxbxwr0YhK0="; private const string strJJ6_0 = "Y9j8iY2XSY7ZGciVx109ZFLQQITg9iZbTozKPqIMfjA="; private const string strJJ7_0 = "weuJtbp+j96ZsW20tiDfOg=="; private static string strUUU = ""; private static string strCCC = ""; private static string strHHH = ""; private static string strIII = ""; private static string strJJ0 = ""; private static string strJJ1 = ""; private static string strJJ2 = ""; private static string strJJ3 = ""; private static string strJJ4 = ""; private static string strJJ5 = ""; private static string strJJ6 = ""; private static string strJJ7 = ""; #endif #if UNITY_IPHONE || UNITY_IOS public delegate void InitCallback(int code, string msg, string content); public delegate void TokenBlockCallbackWithIOS(string token, int code, string codeStr, string businessId); private static NetEase.HTPCallback iosInitcallback; private static NetEase.GetTokenCallback iosTokencallback; #endif private static string initDecrypt(string cipherText) { string encryptionKey = "906f4ef72ca2048251"; byte[] cipherBytes = Convert.FromBase64String(cipherText); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { 0xa8, 0x79, 0x61, 0x6e, 0x20, 0xa5, 0x38, 0x64, 0x76, 0x56, 0x54, 0x65, 0x40 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); cs.Close(); } cipherText = Encoding.Unicode.GetString(ms.ToArray()); } } return cipherText; } private static AndroidJavaObject getAndroidConfig(NetEase.HTProtectConfig hTProtectConfig) { #if UNITY_ANDROID strJJ0 = initDecrypt(strJJ0_0); strJJ3 = initDecrypt(strJJ3_0); strJJ4 = initDecrypt(strJJ4_0); strJJ5 = initDecrypt(strJJ5_0); strJJ6 = initDecrypt(strJJ6_0); strJJ7 = initDecrypt(strJJ7_0); AndroidJavaObject config = new AndroidJavaObject(strJJ0); if (config == null || hTProtectConfig == null) return config; config.Call(strJJ3, hTProtectConfig.getServerType()); config.Call(strJJ4, hTProtectConfig.getChannel()); config.Call(strJJ5, hTProtectConfig.getExtraData()); config.Call(strJJ6, hTProtectConfig.getGameKey()); config.Call(strJJ7, hTProtectConfig.getHost()); return config; #else return null; #endif } public static void init(string productId, NetEase.HTPCallback cb, NetEase.HTProtectConfig hTProtectConfig) { if (isInitialized) { return; } #if UNITY_ANDROID strUUU = initDecrypt(strUUU_0); strCCC = initDecrypt(strCCC_0); strHHH = initDecrypt(strHHH_0); strIII = initDecrypt(strIII_0); if (hTProtectConfig.getInitThread()) { HTProtectConfig.ie = hTProtectConfig.getInitThreadExit(); HTProtectConfig.ic = hTProtectConfig.getInitThreadCrash(); HTProtectConfig.isec = hTProtectConfig.getInitWaitSecond(); if (HTProtectConfig.isec < 60) { HTProtectConfig.isec = 60; } Thread daemonThread = new Thread(() => { InitDaemonThread(); }); daemonThread.Start(); } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaObject curAC = actClass.GetStatic(strCCC); if (curAC != null) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject config = getAndroidConfig(hTProtectConfig); if (cb != null) { NetEase.InnerCallback myCallback = new NetEase.InnerCallback(); myCallback.SetCallBack(cb); HTPClass.CallStatic(strIII, curAC, productId, myCallback, config); } else{ HTPClass.CallStatic(strIII, curAC, productId, null, config); } isInitialized = true; } } } } catch (System.Exception e) { Debug.LogError("InitSDK" + e.ToString()); Application.Quit(); } #endif #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { InitCallback initCallback = new InitCallback(initProductIdCallback); iosInitcallback = cb; if (hTProtectConfig != null) { ___setServerType(hTProtectConfig.getServerType()); ___setChannel(hTProtectConfig.getChannel()); ___setHost(hTProtectConfig.getHost()); ___setExtraData(hTProtectConfig.getValue(), hTProtectConfig.getKey()); } ___initWithProductId(productId, initCallback); } #endif } #if UNITY_IPHONE || UNITY_IOS [MonoPInvokeCallback(typeof(InitCallback))] public static void initProductIdCallback(int code, string msg, string content) { isInitialized = true; if (iosInitcallback == null) { return; } MethodInfo sellMethodInfo = typeof(NetEase.HTPCallback).GetMethod("onReceive"); // 当返回199时,替换content if (code == 199) { content = msg; } sellMethodInfo.Invoke(iosInitcallback, new object[] {code, content}); } #endif public static string getDataSign(string inputData, int algIndex) { string sign = ""; #if UNITY_ANDROID if (!isInitialized) { return sign; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { string encedKey = "5gS14O4oV73TDX/RFvTQYiFrchts4GoOyErXXMv8bvyERoXTX2Kg4BFcuoG2yPeqbayIiPw71O0bZbZnWAst+uSnD977HY2g1+Y3orjWhK8="; string encryptionKey = "906f4ef72ca2048251"; byte[] cipherBytes = Convert.FromBase64String(encedKey); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { 0xa8, 0x79, 0x61, 0x6e, 0x20, 0xa5, 0x38, 0x64, 0x76, 0x56, 0x54, 0x65, 0x40 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(cipherBytes, 0, cipherBytes.Length); cs.Close(); } string decedKey = Encoding.Unicode.GetString(ms.ToArray()); string nativeSign = HTPClass.CallStatic("getDataSign", inputData, algIndex); nativeSign = nativeSign + decedKey; MD5 md5 = MD5.Create(); byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(nativeSign)); for (int i = 0; i < s.Length; i++) { sign = sign + s[i].ToString("x2"); } } } } } } catch (System.Exception e) { Debug.LogError("getDataSign" + e.ToString()); } #endif return sign; } public static int setRoleInfo(string businessId, string roleId, string roleName, string roleAccount, string roleServer, int serverId, string gameJson) { #if UNITY_ANDROID try { if (!isInitialized) { return NetEase.AntiCheatResult.ERROR_NOT_INIT; } using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { return HTPClass.CallStatic("setRoleInfo", businessId, roleId, roleName, roleAccount, roleServer, serverId, gameJson); } } } catch (System.Exception e) { Debug.LogError("setRoleInfo:\n" + e.ToString()); Application.Quit(); } #endif #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { return ___setRoleInfo(businessId, roleId, roleName, roleAccount, roleServer, serverId, gameJson); } #endif return 0; } public static void logOut() { #if UNITY_ANDROID if (!isInitialized) { return; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { HTPClass.CallStatic("logOut"); } } } catch (System.Exception e) { Debug.LogError("logOut" + e.ToString()); } #endif #if UNITY_IPHONE || UNITY_IOS if (!isInitialized) { return; } if (Application.platform == RuntimePlatform.IPhonePlayer) { ___logOut(); } #endif } public static string localSaveEncode(string inputData, int algIndex) { string ret = ""; #if UNITY_ANDROID if (!isInitialized) { return ret; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { ret = HTPClass.CallStatic("localSaveEncode", inputData, algIndex); } } } catch (System.Exception e) { Debug.LogError("EncodeLocal" + e.ToString()); } #endif return ret; } public static string localSaveDecode(string inputData, int algIndex) { string ret = ""; #if UNITY_ANDROID if (!isInitialized) { return ""; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { ret = HTPClass.CallStatic("localSaveDecode", inputData, algIndex); } } } catch (System.Exception e) { Debug.LogError("DecodeLocal" + e.ToString()); } #endif return ret; } public static string localSaveBytesEncode(byte[] inputData, int algIndex) { string ret = ""; #if UNITY_ANDROID if (!isInitialized) { return ""; } string tmp = Convert.ToBase64String(inputData); ret = localSaveEncode(tmp, algIndex); #endif return ret; } public static byte[] localSaveBytesDecode(string inputData, int algIndex) { byte[] ret = { 0 }; #if UNITY_ANDROID if (!isInitialized) { return ret; } string tmp = localSaveDecode(inputData, algIndex); ret = Convert.FromBase64String(tmp); #endif return ret; } public static string ioctl(RequestCmdID request, string data) { string ret = ""; #if UNITY_ANDROID try { if (!isInitialized) { return ret; } using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { ret = HTPClass.CallStatic("ioctl",(int)request,data); } } } catch (System.Exception e) { Debug.LogError("ioctl:\n" + e.ToString()); Application.Quit(); } #endif #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { ret = ___ioctl(request, data); } #endif return ret; } public static void registerTouchEvent(int gameplayId, int sceneId) { #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { ___registerTouchEvent((ulong)gameplayId, (ulong)sceneId); } #endif #if UNITY_ANDROID if (!isInitialized) { return; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { HTPClass.CallStatic("registerTouchEvent", gameplayId, sceneId); } } } catch (System.Exception e) { Debug.LogError("registerTouchEvent" + e.ToString()); } #endif } public static void unregisterTouchEvent() { #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { ___unregisterTouchEvent(); } #endif #if UNITY_ANDROID if (!isInitialized) { return; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { HTPClass.CallStatic("unregisterTouchEvent"); } } } catch (System.Exception e) { Debug.LogError("unregisterTouchEvent" + e.ToString()); } #endif } public static NetEase.SafeCommResult safeCommToServerByteV30(int version, int alg, byte[] inputData, bool isCrucial) { NetEase.SafeCommResult safeCommResult = new NetEase.SafeCommResult(); if (inputData == null || inputData.Length == 0) { safeCommResult.ret = NetEase.SafeCommResult.SC_PARAM_ERROR; return safeCommResult; } #if UNITY_IPHONE || UNITY_IOS safeCommResult.ret = NetEase.SafeCommResult.SC_NOSUPPORT; safeCommResult.encResult = "iOS暂不支持"; #endif #if UNITY_ANDROID string inputString = Convert.ToBase64String(inputData); try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject scClass = HTPClass.CallStatic("safeCommToServerCSharp", version, alg, inputString, true, isCrucial); int ret = scClass.Get("ret"); safeCommResult.ret = ret; if (ret == NetEase.SafeCommResult.SC_CODE_OK) { string encResult = scClass.Get("encResult"); safeCommResult.encBytes = Convert.FromBase64String(encResult); safeCommResult.ret = ret; } } } } catch (System.Exception e) { Debug.LogError("safeCommToServer" + e.ToString()); } #endif return safeCommResult; } public static NetEase.SafeCommResult safeCommToServerV30(int version, int alg, byte[] inputData, bool isCrucial) { NetEase.SafeCommResult safeCommResult = new NetEase.SafeCommResult(); if (inputData == null || inputData.Length == 0) { safeCommResult.ret = NetEase.SafeCommResult.SC_PARAM_ERROR; return safeCommResult; } #if UNITY_IPHONE || UNITY_IOS safeCommResult.ret = NetEase.SafeCommResult.SC_NOSUPPORT; safeCommResult.encResult = "iOS暂不支持"; #endif #if UNITY_ANDROID string inputString = Convert.ToBase64String(inputData); try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject scClass = HTPClass.CallStatic("safeCommToServerCSharp", version, alg, inputString, true, isCrucial); int ret = scClass.Get("ret"); safeCommResult.ret = ret; if (ret == NetEase.SafeCommResult.SC_CODE_OK) { safeCommResult.encResult = scClass.Get("encResult"); safeCommResult.ret = ret; } } } } catch (System.Exception e) { Debug.LogError("safeCommToServer" + e.ToString()); } #endif return safeCommResult; } #if UNITY_IPHONE || UNITY_IOS private static NetEase.SafeCommResult safeCommIOSToServer(int alg, byte[] inputData, NetEase.SafeCommResult safeCommResult) { if (Application.platform == RuntimePlatform.IPhonePlayer) { string result = null; IntPtr outData = IntPtr.Zero; int outLen = 0; int ret = ___safeCommToServer(alg, inputData, inputData.Length, ref outData, ref outLen); if (ret == NetEase.SafeCommResult.SC_CODE_OK) { byte[] cc = new byte[outLen]; Marshal.Copy(outData, cc, 0, outLen); result = Encoding.ASCII.GetString(cc); safeCommResult.encResult = result; safeCommResult.ret = ret; // 释放 outData ___safeFree(ref outData); } else { safeCommResult.ret = ret; } } return safeCommResult; } private static NetEase.SafeCommResult safeCommIOSToServerByte(int alg, byte[] inputData, NetEase.SafeCommResult safeCommResult) { if (Application.platform == RuntimePlatform.IPhonePlayer) { byte[] resultByte = null; IntPtr outData = IntPtr.Zero; int outLen = 0; int ret = ___safeCommToServerByte(alg, inputData, inputData.Length, ref outData, ref outLen); if (ret == NetEase.SafeCommResult.SC_CODE_OK) { resultByte = new byte[outLen]; Marshal.Copy(outData, resultByte, 0, outLen); safeCommResult.encBytes = resultByte; safeCommResult.ret = ret; // 释放 outData ___safeFree(ref outData); } else { safeCommResult.ret = ret; } } return safeCommResult; } private static NetEase.SafeCommResult safeCommIOSFromServer(int alg, int timeout, string inputData, NetEase.SafeCommResult safeCommResult) { if (Application.platform == RuntimePlatform.IPhonePlayer) { byte[] decResult = null; IntPtr outData = IntPtr.Zero; int outLen = 0; int ret = ___safeCommFromServer(alg, timeout, inputData, inputData.Length, ref outData, ref outLen); if (ret == 0) { decResult = new byte[outLen]; Marshal.Copy(outData, decResult, 0, outLen); safeCommResult.decResult = decResult; safeCommResult.ret = ret; ___safeFree(ref outData); } else { safeCommResult.ret = ret; } } return safeCommResult; } private static NetEase.SafeCommResult safeCommIOSFromServerByte(int alg, int timeout, byte[] inputData, NetEase.SafeCommResult safeCommResult) { if (Application.platform == RuntimePlatform.IPhonePlayer) { byte[] decResult = null; IntPtr outData = IntPtr.Zero; int outLen = 0; int ret = ___safeCommFromServerByte(alg, timeout, inputData, inputData.Length, ref outData, ref outLen); if (ret == 0) { decResult = new byte[outLen]; Marshal.Copy(outData, decResult, 0, outLen); safeCommResult.decResult = decResult; safeCommResult.ret = ret; ___safeFree(ref outData); } else { safeCommResult.ret = ret; } } return safeCommResult; } #endif public static NetEase.SafeCommResult safeCommFromServer(int alg, int timeout, string inputData) { NetEase.SafeCommResult safeCommResult = new NetEase.SafeCommResult(); if (!isInitialized) { safeCommResult.ret = NetEase.SafeCommResult.SC_NOT_INIT; return safeCommResult; } if (inputData == null || inputData.Length == 0) { safeCommResult.ret = NetEase.SafeCommResult.SC_PARAM_ERROR; return safeCommResult; } #if UNITY_IPHONE || UNITY_IOS safeCommResult = safeCommIOSFromServer(alg,timeout,inputData,safeCommResult); #endif #if UNITY_ANDROID try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject scClass = HTPClass.CallStatic("safeCommFromServerCSharp", alg, 0, inputData); int ret = scClass.Get("ret"); safeCommResult.ret = ret; if (ret == NetEase.SafeCommResult.SC_CODE_OK) { string encResult = scClass.Get("encResult"); safeCommResult.decResult = Convert.FromBase64String(encResult); safeCommResult.ret = ret; } } } } catch (System.Exception e) { Debug.LogError("safeCommFromServer" + e.ToString()); } #endif return safeCommResult; } public static NetEase.SafeCommResult safeCommFromServerByte(int alg, int timeout, byte[] inputData) { NetEase.SafeCommResult safeCommResult = new NetEase.SafeCommResult(); if (!isInitialized) { safeCommResult.ret = NetEase.SafeCommResult.SC_NOT_INIT; return safeCommResult; } if (inputData == null || inputData.Length == 0) { safeCommResult.ret = NetEase.SafeCommResult.SC_PARAM_ERROR; return safeCommResult; } #if UNITY_IPHONE || UNITY_IOS safeCommResult = safeCommIOSFromServerByte(alg,timeout,inputData,safeCommResult); #endif #if UNITY_ANDROID try { string inputString = Convert.ToBase64String(inputData); using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject scClass = HTPClass.CallStatic("safeCommFromServerCSharp", alg, 0, inputString); int ret = scClass.Get("ret"); safeCommResult.ret = ret; if (ret == NetEase.SafeCommResult.SC_CODE_OK) { string encResult = scClass.Get("encResult"); safeCommResult.decResult = Convert.FromBase64String(encResult); safeCommResult.ret = ret; } } } } catch (System.Exception e) { Debug.LogError("safeCommToServer" + e.ToString()); } #endif return safeCommResult; } public static string safeComm(string inputData, int algType, bool dec) { string ret = ""; #if UNITY_ANDROID if (!isInitialized) { return ret; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { ret = HTPClass.CallStatic("safeComm", inputData, algType, dec); } } } catch (System.Exception e) { Debug.LogError("htpIoctl" + e.ToString()); } #endif return ret; } public static bool isHtpExist() { #if UNITY_ANDROID try { AndroidJavaClass aClass = new AndroidJavaClass("com.netease.htprotect.poly.a"); if (aClass != null) { bool value = aClass.GetStatic("a"); return value; } } catch (System.Exception e) { Debug.LogError("htpIoctl : " + e.ToString()); } return false; #else return false; #endif } public static NetEase.AntiCheatResult getToken(int timeout, string businessId) { #if UNITY_ANDROID if (!isInitialized) { return new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject gtClass = HTPClass.CallStatic("getToken", timeout, businessId); NetEase.AntiCheatResult acResult = new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); acResult.code = gtClass.Get("code"); acResult.codeStr = gtClass.Get("codeStr"); acResult.token = gtClass.Get("token"); acResult.businessId = businessId; return acResult; } } } catch (System.Exception e) { Debug.LogError("getToken : " + e.ToString()); } #endif #if UNITY_IPHONE || UNITY_IOS if (Application.platform == RuntimePlatform.IPhonePlayer) { IntPtr outPtr = IntPtr.Zero; IntPtr codeStrPtr = IntPtr.Zero; string token = null; string codeStr = null; int tokenOutLen = 0; int codeStrOutLen = 0; int ret = ___getToken(businessId, 3000, ref outPtr, ref tokenOutLen, ref codeStrPtr, ref codeStrOutLen); byte[] cc = new byte[tokenOutLen]; Marshal.Copy(outPtr, cc, 0, tokenOutLen); token = Encoding.ASCII.GetString(cc); ___safeFree(ref outPtr); byte[] codeStrBytes = new byte[codeStrOutLen]; Marshal.Copy(codeStrPtr, codeStrBytes, 0, codeStrOutLen); codeStr = Encoding.ASCII.GetString(codeStrBytes); ___safeFree(ref codeStrPtr); NetEase.AntiCheatResult acResult = new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); acResult.code = ret; acResult.codeStr = codeStr; acResult.token = token; acResult.businessId = businessId; return acResult; } #endif return new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); } public static void getTokenAsync(int timeout, string businessId, NetEase.GetTokenCallback callback) { #if UNITY_ANDROID if (!isInitialized) { if (callback != null) { AntiCheatResult acr = new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); callback.onResult(acr); } return ; } try { using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { NetEase.InnerGetTokenCallback myCallback = new NetEase.InnerGetTokenCallback(); myCallback.SetCallBack(callback); HTPClass.CallStatic("getTokenAsync", timeout, businessId, myCallback); } } } catch (System.Exception e) { Debug.LogError("getToken : " + e.ToString()); if (callback != null) { AntiCheatResult acr = new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_GEN_TOKEN, NetEase.AntiCheatResult.ERROR_GEN_TOKEN_STR, ""); callback.onResult(acr); } } #endif #if UNITY_IPHONE || UNITY_IOS TokenBlockCallbackWithIOS tokenCallback = new TokenBlockCallbackWithIOS(getTokenAction); iosTokencallback = callback; ___getTokenAsync(businessId, timeout, tokenCallback); #endif } #if UNITY_IPHONE || UNITY_IOS [MonoPInvokeCallback(typeof(TokenBlockCallbackWithIOS))] public static void getTokenAction(string token, int code, string message, string businessId) { if (iosTokencallback == null) { return; } NetEase.AntiCheatResult acResult = new NetEase.AntiCheatResult(NetEase.AntiCheatResult.ERROR_NOT_INIT, NetEase.AntiCheatResult.ERROR_NOT_INIT_STR, ""); acResult.code = code; acResult.codeStr = message; acResult.token = token; acResult.businessId = businessId; MethodInfo sellMethodInfo = typeof(NetEase.GetTokenCallback).GetMethod("onResult"); sellMethodInfo.Invoke(iosTokencallback, new object[] {acResult}); } #endif public static NetEase.SafeCommResult htpSign(int alg, int version, byte[] inputData) { NetEase.SafeCommResult safeCommResult = new NetEase.SafeCommResult(); if (inputData == null || inputData.Length == 0) { safeCommResult.ret = NetEase.SafeCommResult.SC_PARAM_ERROR; return safeCommResult; } #if UNITY_ANDROID try { string inputString = Convert.ToBase64String(inputData); using (var actClass = new AndroidJavaClass(strUUU)) { AndroidJavaClass HTPClass = new AndroidJavaClass(strHHH); if (HTPClass != null) { AndroidJavaObject scClass = HTPClass.CallStatic("htpSignCSharp", version, alg, inputString); int ret = scClass.Get("ret"); safeCommResult.ret = ret; if (ret == NetEase.SafeCommResult.SC_CODE_OK) { safeCommResult.signResult = scClass.Get("signResult"); safeCommResult.ret = ret; } } } } catch (System.Exception e) { Debug.LogError("htpSign" + e.ToString()); } #endif return safeCommResult; } private static void InitDaemonThread() { #if UNITY_ANDROID Debug.Log(" ic = " + HTProtectConfig.ic + " ie = " + HTProtectConfig.ie + " isec = " + HTProtectConfig.isec); AndroidJNI.AttachCurrentThread(); Thread.Sleep(HTProtectConfig.isec * 1000); // 线程暂停60秒,单位毫秒 bool exist = isHtpExist(); AndroidJNI.DetachCurrentThread(); Debug.Log("exist = " + exist); if (exist) { return; } if (HTProtectConfig.ic) { UnityEngine.Diagnostics.Utils.ForceCrash(UnityEngine.Diagnostics.ForcedCrashCategory.AccessViolation); } if (HTProtectConfig.ie) { Application.Quit(); } #endif } #if UNITY_IPHONE || UNITY_IOS [DllImport("__Internal")] private static extern void ___initWithProductId(string productId, InitCallback callback); [DllImport("__Internal")] private static extern int ___setRoleInfo(string businessId, string roleId, string roleName, string roleAccount, string roleServer, int serverid, string gameJson); [DllImport("__Internal")] private static extern int ___getToken(string bussinessId, int timeout, ref IntPtr outData, ref int outLen, ref IntPtr codeStr, ref int codeStrOutLen); [DllImport("__Internal")] private static extern void ___getTokenAsync(string bussinessId, int timeout, TokenBlockCallbackWithIOS callback); [DllImport("__Internal")] private static extern void ___logOut(); [DllImport("__Internal")] private static extern string ___ioctl(RequestCmdID request, string data); [DllImport("__Internal")] private static extern void ___setServerType(int type); [DllImport("__Internal")] private static extern void ___setChannel(string channel); [DllImport("__Internal")] private static extern void ___setExtraData(string value, string key); [DllImport("__Internal")] private static extern void ___setHost(string host); [DllImport("__Internal")] public static extern int ___safeCommToServer(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen); [DllImport("__Internal")] public static extern int ___safeCommToServerByte(int alg, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen); [DllImport("__Internal")] public static extern int ___safeCommFromServer(int alg, int timeout, string inputData, int dataSize, ref IntPtr outData, ref int outLen); [DllImport("__Internal")] public static extern int ___safeCommFromServerByte(int alg, int timeout, byte[] inputData, int dataSize, ref IntPtr outData, ref int outLen); [DllImport("__Internal")] public static extern void ___registerTouchEvent(ulong gameplayId, ulong sceneId); [DllImport("__Internal")] public static extern void ___unregisterTouchEvent(); [DllImport("__Internal")] public static extern void ___safeFree(ref IntPtr outData); #endif } }