diff --git a/ModifyBH.csproj b/ModifyBH.csproj new file mode 100644 index 0000000..b92f669 --- /dev/null +++ b/ModifyBH.csproj @@ -0,0 +1,13 @@ + + + + Exe + netcoreapp2.2 + + + + .\lib\UnityAssetBundleTool.dll + + + + diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..0377263 --- /dev/null +++ b/Program.cs @@ -0,0 +1,487 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Net; +using System.Security.Cryptography; +using System.Text.RegularExpressions; +using UABT; +using bh3tool; +using System.Threading; +using System.Diagnostics; + +namespace ModifyBH +{ + class Program + { + public static DateTime oldTime; + public static bool firstUpdate_a = true; + public static bool firstUpdate_i = true; + Dictionary mod_servers = new Dictionary + { + { "android01", new Server_modinfo(Gameserver.android01) }, + { "bb01", new Server_modinfo(Gameserver.bb01) }, + { "hun01", new Server_modinfo(Gameserver.hun01) }, + { "hun02", new Server_modinfo(Gameserver.hun02) }, + { "ios01", new Server_modinfo(Gameserver.ios01) }, + { "yyb01", new Server_modinfo(Gameserver.yyb01) } + }; + + static void Main(string[] args) + { + Console.WriteLine("bh3tool is running"); + oldTime = DateTime.Now; + + Timer timer = new Timer(new TimerCallback((o) => { + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] It is time to update"); + ModFile(true, false); + GC.Collect(); + ModFile(true, true); + GC.Collect(); + }), null, 0, 900 * 1000); + while (true) + { + string s = Console.ReadLine(); + if (s == "exit") + { + return; + } + if (s == "update") + { + ModFile(true, false); + GC.Collect(); + ModFile(true, true); + GC.Collect(); + } + } + } + + public static void Update () + { + + + } + bool Getseverinfo(string se) + { + //用于匹配数据的正则 + Regex reg_serverurl = new Regex("(dispatch_url\":\")(.*?)\""); + Regex reg_gameserver = new Regex("(gameserver\":)(\\{.*?\\})"); + Regex reg_geteway = new Regex("(gateway\":)(\\{.*?\\})"); + Regex reg_oaserver = new Regex("(oaserver_url\":)(\".*?\")"); + + WebClient client = new WebClient(); + try + { + //note version number + string version = "?version=3.3.0_" + GetserverStr(mod_servers[se].server); + string globaleDispatchUrl = "http://global1.bh3.com/query_dispatch" + version; + + string rsp = client.DownloadString(globaleDispatchUrl); + //get dispatch_url + string dispatch_url = reg_serverurl.Match(rsp).Groups[2].Value; + + string qserverurl = dispatch_url + version; + //get server rsponse + string qrsp = client.DownloadString(qserverurl); + //match server ip + string gameserver = reg_gameserver.Match(qrsp).Groups[2].Value; + string getway = reg_geteway.Match(qrsp).Groups[2].Value; + string oa = reg_oaserver.Match(qrsp).Groups[2].Value; + + mod_servers[se].gameserver_url = dispatch_url; + mod_servers[se].gameserver_rsp = qrsp; + mod_servers[se].server_ip = gameserver; + mod_servers[se].getway_ip = getway; + mod_servers[se].oa_ip = oa; + //Replace "https" with "http" + mod_servers[se].mod_gameserver_rsp = qrsp.Replace("https://bundle.bh3.com", "http://bundle.bh3.com"); + } + catch + { + return false; + } + return true; + } + string GetserverStr(Gameserver server) + { + switch (server) + { + case Gameserver.android01: return "gf_android"; + case Gameserver.bb01: return "bilibili"; + case Gameserver.hun01: return "oppo"; + case Gameserver.hun02: return "xiaomi"; + case Gameserver.ios01: return "gf_ios"; + case Gameserver.yyb01: return "tencent"; + default: return "gf_android"; + } + + } + public static void ModFile(bool forceUpdate, bool isIOS) + { + if (firstUpdate_a) + { + forceUpdate = true; + firstUpdate_a = false; + } else + { + if (firstUpdate_i) + { + forceUpdate = true; + firstUpdate_i = false; + } + } + Console.WriteLine("--------------------------------------------------------"); + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] Updating " + (isIOS ? "IOS" : "Android")); + //file url + string baseurl = isIOS ? "https://bundle.bh3.com/asset_bundle/ios01/1.0" : "https://bundle.bh3.com/asset_bundle/android01/1.0"; + string settingurl = isIOS ? "/data/iphone_compressed/data/setting_" : "/data/android_compressed/data/setting_"; + string excelurl = isIOS ? "/data/iphone_compressed/data/excel_output_" : "/data/android_compressed/data/excel_output_"; + string dataurl = isIOS ? "/data/iphone_compressed/DataVersion.unity3d" : "/data/android_compressed/DataVersion.unity3d"; + + string RSAkey = @"rXoKWm82JSX4UYihkt2FSjrp3pZqTxt6AyJ0ZexHssStYesCFuUOmDBrk0nxPTY2r7oB4ZC9tDhHzmA66Me56wkD47Z3fCEBfLFxmEVdUCvM1RIFdQxQCB7CMaFWXHoVfBhNcD60OtXD71vFusBLioa6HDHbKk8LdgWdV10OWaE=EQ==

16GiwrgCGvcYbgSZOBJRx4G9kioGgexLSyW62iK4EuT0Xu9xyflBDaC4yooFkxrflqEAIiEfTqNGlYeJks+5qw==

zfQY4dWi/Dlo38y6xvX4pUEAj1hbeFo/Qiy7H00P089W0KC6Mdi+GY4UuRGJtgX7UZfGQdHRj8mBjijFyhUl4w==cihlOejyDkaUdnrntEXvD0Svp7vlU9dzJ8iuNz+OoJdUMkKHiQt8yvq8Lv3Gt0p2Xs20xsY9wDhSi2Xfa9diSw==GDrVwDdAWeii7SclCFksT61LXCiDO1XpUxRSP+ryzZ/sGIthMwpwt7ZcynqIrAC0J7eAvHMJmHIPPeat24oEdQ==P4/vgq1XF77N8K/OxTbcjWFCC1d+v3W5xWQJbmU3KfVF2wOStZeILT2X12s7AHD+uUfN9O/xdEBIeqcSLVxWjw==o0WvZCxvMgWeatrybBvIvlWQ0X6CLFYYe2u42GXpILkbp3PFuzHvnkuwip/yG35RllS2efGjfHE0hgA3cazrNgM6gBDcFa7iznviIiQTySxFuzy3mXpjSQFaGgdvmuUQLgg5qahcdGgT455Fzo5GSu+IyTpD+dNoKy79NLTbvjE=
"; + + WebClient client = new WebClient(); + //Download DataVersion.unity3d. + byte[] dataversion = client.DownloadData(baseurl + dataurl); + string[] key = client.ResponseHeaders.AllKeys; + //Check Last-Modified time. + DateTime time = new DateTime(0); + for (int i = 0; i < key.Length; i++) + { + if (key[i] == "Last-Modified") + { + time = DateTime.Parse(client.ResponseHeaders.Get(i)); + } + } + if (!forceUpdate) + { + bool a = DateTime.Compare(oldTime, time) >= 0; + if (a) + { + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] No update"); + return; + } + } + + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] Start update"); + + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] edit dataversion.unity3d"); + + //Decrypt DataVersion.unity3d + for (int i = 0; i < dataversion.Length; i++) dataversion[i] = (byte)(dataversion[i] ^ 0xA5); + //load bundle asset + BundleFile dataversionBundle = new BundleFile(dataversion); + SerializedFile dataversionFile = new SerializedFile("dataversion", new EndianBinaryReader(dataversionBundle.fileList[0].stream)); + //get textasset bytes + long Pid = dataversionFile.GetPathIDByName("packageversion.txt"); + var packageversion = dataversionFile.m_Objects.Find(x => x.m_PathID == Pid); + //load textasset + Textasset textasset = new Textasset(packageversion.data); + + string[] versiontext = textasset.text.Split('\n'); + //Get AES key IV and HMACSHA1 key + var rsa = RSA.Create(); + rsa.FromXmlStringA(RSAkey); + byte[] AES_SHA = rsa.Decrypt(Hex2bytes(versiontext[0]), RSAEncryptionPadding.Pkcs1); + //AES_SHA 56 bytes, AES key 32 bytes|AES IV 16 bytes|HMACSHA1 8 bytes + byte[] AESkey = AES_SHA.Take(32).ToArray(); + byte[] AESIV = AES_SHA.Skip(32).Take(16).ToArray(); + byte[] SHA = AES_SHA.Skip(48).Take(8).ToArray(); + + Regex regexCS = new Regex("(CS\":\")([1-9]\\d*)"); + Regex regexCRC = new Regex("(CRC\":\")([0-9A-Z]*)"); + + string settingCRC; + string excelCRC; + int settingindex; + int excelindex; + //Get File CRC + if (versiontext[1].Contains("excel_output")) + { + excelindex = 1; + settingindex = 2; + } + else + { + excelindex = 2; + settingindex = 1; + } + excelCRC = regexCRC.Match(versiontext[excelindex]).Groups[2].Value; + settingCRC = regexCRC.Match(versiontext[settingindex]).Groups[2].Value; + + + //Download setting.unity3d and excel_output.unity3d + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] download setting"); + byte[] settingbytes = client.DownloadData(baseurl + settingurl + settingCRC); + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] download excel_output"); + byte[] excelbytes = client.DownloadData(baseurl + excelurl + excelCRC); + client.Dispose(); + + GC.Collect(); + + //Decrypt File + Aes Aes = Aes.Create(); + var AES_Encryptor = Aes.CreateEncryptor(AESkey, AESIV); + + var AES_Decryptor = Aes.CreateDecryptor(AESkey, AESIV); + settingbytes = AES_Decryptor.TransformFinalBlock(settingbytes, 0, settingbytes.Length); + + AES_Decryptor = Aes.CreateDecryptor(AESkey, AESIV); + excelbytes = AES_Decryptor.TransformFinalBlock(excelbytes, 0, excelbytes.Length); + + #region Modify setting.unity3d + + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] edit setting"); + + BundleFile settingBundle = new BundleFile(settingbytes); + SerializedFile setting = new SerializedFile("setting", new EndianBinaryReader(settingBundle.fileList[0].stream)); + + #region Edit miscdata.txt + //Get miscdata.txt from bundle + long miscid = setting.GetPathIDByName("miscdata.txt"); + var misc = setting.m_Objects.Find(x => x.m_PathID == miscid); + Textasset miscasset = new Textasset(misc.data); + //Enable All BodyPort Touch + Regex regexMISC = new Regex("(Face|Chest|Private|Arm|Leg)(\" *\t*: )(false)"); + miscasset.text = regexMISC.Replace(miscasset.text, "$1$2true"); + misc.data = miscasset.GetBytes(); + #endregion + + #region Edit uiluadesign_x_x.lua.txt + //version number + long uiluaid = setting.GetPathIDByName("uiluadesign_3_3.lua.txt"); + var uilua = setting.m_Objects.Find(x => x.m_PathID == uiluaid); + Textasset uiluaasset = new Textasset(uilua.data); + //insert Lua code to function UITable.ModuleEndHandlePacket + List list = new List(uiluaasset.text.Split('\n')); + int index = list.FindIndex(x => x.Contains("UITable.ModuleEndHandlePacket")); + //Handle NetPacketV1 for GalTouchModule,and set GalTouchModule._canGalTouch to true + string insertStr = "\tif moduleName == \"GalTouchModule\" and packet:getCmdId() == 111 then\n\t\tlocal gal = __singletonManagerType.GetSingletonInstance(\"MoleMole.GalTouchModule\")\n\t\tif gal == nil then\n\t\t\treturn\n\t\tend\n\t\tgal._canGalTouch = true\n\tend\n"; + list.Insert(index + 1, insertStr); + uiluaasset.text = String.Join("\n", list); + uilua.data = uiluaasset.GetBytes(); + #endregion + + #region Edit luahackconfig.txt + //Add "GalTouchModule" to "UILuaPatchModuleList" + long luahackpid = setting.GetPathIDByName("luahackconfig.txt"); + var luahack = setting.m_Objects.Find(x => x.m_PathID == luahackpid); + Textasset hack = new Textasset(luahack.data); + string inserthack = " \"GalTouchModule\","; + list = new List(hack.text.Split('\n')); + index = list.FindIndex(x => x.Contains("UILuaPatchModuleList")); + list.Insert(index + 2, inserthack); + hack.text = string.Join("\n", list); + luahack.data = hack.GetBytes(); + #endregion + + //pack to assetbundle + misc.data = miscasset.GetBytes(); + settingBundle.fileList[0].stream = new MemoryStream(setting.Pack()); + settingbytes = settingBundle.RePack(); + //ENCRYPT + settingbytes = AES_Encryptor.TransformFinalBlock(settingbytes, 0, settingbytes.Length); + #endregion + + GC.Collect(); + + #region Edit excel_output.unity3d + // + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] edit excel"); + + BundleFile excelBundle = new BundleFile(excelbytes); + SerializedFile excel = new SerializedFile("excel", new EndianBinaryReader(excelBundle.fileList[0].stream)); + //Edit touch buff + long touchbuffid = excel.GetPathIDByName("touchbuffdata.asset"); + var bf = excel.m_Objects.Find(x => x.m_PathID == touchbuffid); + bf.data = TouchBuff.GetNew(bf.data); + excelBundle.fileList[0].stream = new MemoryStream(excel.Pack()); + excelbytes = excelBundle.RePack(); + //Encrypt excel_output.unity3d + AES_Encryptor = Aes.CreateEncryptor(AESkey, AESIV); + excelbytes = AES_Encryptor.TransformFinalBlock(excelbytes, 0, excelbytes.Length); + #endregion + + GC.Collect(); + + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] edit dataversion"); + + //compute new CRC(hmac-SHA1) + HMACSHA1 hMACSHA1 = new HMACSHA1(SHA); + settingCRC = BitConverter.ToString(hMACSHA1.ComputeHash(settingbytes)).Replace("-", ""); + excelCRC = BitConverter.ToString(hMACSHA1.ComputeHash(excelbytes)).Replace("-", ""); + + //Replace fileSize("CS") and SHA1("CRC") + versiontext[excelindex] = regexCRC.Replace(versiontext[1], "CRC\":\"" + excelCRC); + versiontext[excelindex] = regexCS.Replace(versiontext[1], "CS\":\"" + excelbytes.Length.ToString()); + versiontext[settingindex] = regexCRC.Replace(versiontext[2], "CRC\":\"" + settingCRC); + versiontext[settingindex] = regexCS.Replace(versiontext[2], "CS\":\"" + settingbytes.Length.ToString()); + + //string[] to string + textasset.text = string.Join("\n", versiontext); + //get textasset bytes + packageversion.data = textasset.GetBytes(); + //pack + dataversionBundle.fileList[0].stream = new MemoryStream(dataversionFile.Pack()); + byte[] dz = dataversionBundle.RePack(); + //encrypt dataversion.unity3d + for (int i = 0; i < dz.Length; i++) dz[i] = (byte)(dz[i] ^ 0xA5); + Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "[FileUpdate] Update file success"); + ByteToFile(dz, isIOS ? "i_DataVersion.unity3d" : "a_DataVersion.unity3d"); + ByteToFile(excelbytes, isIOS ? "i_excel_output.unity3d" : "a_excel_output.unity3d"); + ByteToFile(settingbytes, isIOS ? "i_setting.unity3d" : "a_setting.unity3d"); + GC.Collect(); + } + + /// + /// HEX string to byte[] + /// + /// + /// + private static byte[] Hex2bytes(string hex) + { + int ver = hex.Length / 2; + byte[] data = new byte[ver]; + for (int i = 0; i < ver; i++) + { + data[i] = (byte)Convert.ToInt32(hex.Substring(i * 2, 2), 16); + } + return data; + } + + public static bool ByteToFile(byte[] byteArray, string fileName) + { + bool result = false; + try + { + using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write)) + { + fs.Write(byteArray, 0, byteArray.Length); + result = true; + } + } + catch + { + result = false; + } + return result; + } + } + /// + /// edit touch buff + /// + class TouchBuff + { + static readonly int buffId = 6; + static string effect = "EmotionBuff_01"; + static string buffDetail = "TouchBuff_SKL_CHG"; + static float param1 = 0.0299999993f; + static float param1Add = 0.00999999978f; + + static public byte[] GetNew(byte[] data) + { + MemoryStream stream = new MemoryStream(data); + BinaryReader reader = new BinaryReader(stream); + reader.BaseStream.Position = 0x30; + int count = reader.ReadInt32(); + EndianBinaryWriter writer = new EndianBinaryWriter(new MemoryStream(), EndianType.LittleEndian); + reader.BaseStream.Position = 0; + byte[] header = new byte[0x34]; + reader.BaseStream.Read(header, 0, header.Length); + writer.Write(header); + for (int i = 0; i < count; i++) + { + writer.Write(buffId); + writer.WriteAlignedString(effect); + writer.WriteAlignedString(buffDetail); + writer.Write(param1); + writer.Write(0); + writer.Write(0); + writer.Write(param1Add); + writer.Write(0); + writer.Write(0); + } + byte[] output = new byte[writer.BaseStream.Length]; + writer.BaseStream.Position = 0; + writer.BaseStream.Read(output, 0, output.Length); + return output; + } + } + + /// + /// unity TextAsset + /// + class Textasset + { + public string name; + public string text; + /// + /// TextAsset + /// + /// + public Textasset(byte[] data) + { + EndianBinaryReader reader = new EndianBinaryReader(new MemoryStream(data), EndianType.LittleEndian); + name = reader.ReadAlignedString(); + text = reader.ReadAlignedString(); + } + /// + /// TextAsset to byte[] + /// + /// + public byte[] GetBytes() + { + EndianBinaryWriter writer = new EndianBinaryWriter(new MemoryStream(), EndianType.LittleEndian); + writer.WriteAlignedString(name); + writer.WriteAlignedString(text); + writer.Position = 0; + byte[] data = new byte[writer.BaseStream.Length]; + writer.BaseStream.Read(data, 0, data.Length); + return data; + } + } + + /// + /// serverinfo + /// + public class Server_modinfo + { + /// + /// Server + /// + public Gameserver server; + /// + /// Enable? + /// + public bool Enabletouch; + public string gameserver_url; + public string gameserver_rsp; + public string server_ip; + public string getway_ip; + public string oa_ip; + /// + /// modified response + /// + public string mod_gameserver_rsp; + + public Server_modinfo(Gameserver sser) + { + server = sser; + } + } + + /// + /// Server + /// + public enum Gameserver + { + android01, + ios01, + hun01, + hun02, + bb01, + yyb01 + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..56526dd --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# ModifyBH + +本文按照原生系统来编写,非原生请自行摸索 +需要安装证书,Android 7或以上需要root(小米不能用自带的root) + +## 大致流程 +1. 设置代理 +2. 安装证书 +3. 进入游戏更新配置 + +## 代理设置 +### Wi-Fi +1. 打开设置,进入Wi-Fi +2. 长按当前Wi-Fi,点击修改(Pie以上点击当前Wi-Fi,然后点右上角的小笔) +3. 代理方式选择手动,写上代理地址和端口 +4. 保存退出 +### 流量(不推荐) +1. 打开设置,进入移动网络 +2. 展开高级菜单,进入接入点名称(APN) +3. 记住你当前的APN,然后点击右上角的加号添加APN +4. 名称随便,APN填上之前的,写上代理和端口 +5. 保存退出 + +## 安装证书 +### Android 6或以下安装方法: +1. 下载证书 +原生系统只需第2步即可,国内rom跳到第3步 +2. 直接点击下载的证书安装,证书名字随便输,用途默认 +3. 在设置中搜索“从SD卡安装”(安全/凭据储存) +4. 选择下载的证书安装,证书名字随便输,用途默认 + +### Android 7或以上安装方法(小米不能用自带的root): +1. 下载证书 +2. 重命名为 8208f87d.0 +3. 复制到 /system/etc/security/cacerts/ + +如果有Xposed的话JustTrustMe应该可以不用安装证书 + +有终端的小伙伴可以执行下面的命令来安装证书(记得mount system) +mv /sdcard/Download/rootCA.crt /system/etc/security/cacerts/8208f87d.0 diff --git a/Rsa.cs b/Rsa.cs new file mode 100644 index 0000000..47e5081 --- /dev/null +++ b/Rsa.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Xml; + +namespace bh3tool +{ + public static class RsaExtention + { + + public static void FromXmlStringA(this RSA rsa, string xmlString) + { + RSAParameters parameters = new RSAParameters(); + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(xmlString); + if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue")) + { + foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes) + { + switch (node.Name) + { + case "Modulus": parameters.Modulus = Convert.FromBase64String(node.InnerText); break; + case "Exponent": parameters.Exponent = Convert.FromBase64String(node.InnerText); break; + case "P": parameters.P = Convert.FromBase64String(node.InnerText); break; + case "Q": parameters.Q = Convert.FromBase64String(node.InnerText); break; + case "DP": parameters.DP = Convert.FromBase64String(node.InnerText); break; + case "DQ": parameters.DQ = Convert.FromBase64String(node.InnerText); break; + case "InverseQ": parameters.InverseQ = Convert.FromBase64String(node.InnerText); break; + case "D": parameters.D = Convert.FromBase64String(node.InnerText); break; + } + } + } + else + { + throw new Exception("Invalid XML RSA key."); + } + + rsa.ImportParameters(parameters); + } + + public static string ToXmlString(this RSA rsa, bool includePrivateParameters) + { + RSAParameters parameters = rsa.ExportParameters(includePrivateParameters); + + if (includePrivateParameters) + { + return string.Format("{0}{1}

{2}

{3}{4}{5}{6}{7}
", + Convert.ToBase64String(parameters.Modulus), + Convert.ToBase64String(parameters.Exponent), + Convert.ToBase64String(parameters.P), + Convert.ToBase64String(parameters.Q), + Convert.ToBase64String(parameters.DP), + Convert.ToBase64String(parameters.DQ), + Convert.ToBase64String(parameters.InverseQ), + Convert.ToBase64String(parameters.D)); + } + return string.Format("{0}{1}", + Convert.ToBase64String(parameters.Modulus), + Convert.ToBase64String(parameters.Exponent)); + } + + } +} \ No newline at end of file diff --git a/lib/UnityAssetBundleTool.dll b/lib/UnityAssetBundleTool.dll new file mode 100644 index 0000000..0c55c99 Binary files /dev/null and b/lib/UnityAssetBundleTool.dll differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..056cb24 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "modifybh", + "version": "1.0.0", + "description": "", + "main": "anyproxy -i -r rule.js", + "directories": { + "lib": "lib" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/heqyoufree/ModifyBH.git" + }, + "author": "heqyou_free", + "license": "MIT", + "bugs": { + "url": "https://github.com/heqyoufree/ModifyBH/issues" + }, + "homepage": "https://github.com/heqyoufree/ModifyBH#readme" +} diff --git a/rule.js b/rule.js new file mode 100644 index 0000000..f3fe4e3 --- /dev/null +++ b/rule.js @@ -0,0 +1,60 @@ +const fs = require('fs') +// 免安装证书,需要合法ssl证书 +// var sslServer = '' +module.exports = { + summary: 'ModifyBH by heqyou_free', + * beforeSendRequest (requestDetail) { + if (requestDetail.url.indexOf('_compressed/DataVersion.unity3d') > -1) { + if (requestDetail.url.indexOf('android') > -1) { + return returnFileAsResponse('a_DataVersion.unity3d') + } + if (requestDetail.url.indexOf('iphone') > -1) { + return returnFileAsResponse('i_DataVersion.unity3d') + } + } + if (requestDetail.url.indexOf('excel_output_') > -1) { + if (requestDetail.url.indexOf('android') > -1) { + return returnFileAsResponse('a_excel_output.unity3d') + } + if (requestDetail.url.indexOf('iphone') > -1) { + return returnFileAsResponse('i_excel_output.unity3d') + } + } + if (requestDetail.url.indexOf('setting_') > -1) { + if (requestDetail.url.indexOf('android') > -1) { + return returnFileAsResponse('a_setting.unity3d') + } + if (requestDetail.url.indexOf('iphone') > -1) { + return returnFileAsResponse('i_setting.unity3d') + } + } + }, + * beforeSendResponse (requestDetail, responseDetail) { + // 免安装证书,要把beforeSendRequest注释掉 + // if (requestDetail.url.indexOf('query_gameserver') > -1) { + // console.log('requested gameserver') + // var newResponse = Object.assign({}, responseDetail.response) + // var json = JSON.parse(newResponse.body) + // json.asset_boundle_url = json.asset_boundle_url.replace('bundle.bh3.com', sslServer) + // var str = JSON.stringify(json) + // newResponse.body = str + // return { + // response: newResponse + // } + // } + } +} +function returnFileAsResponse (name) { + console.log(`requested ${name}`) + var resp = fs.readFileSync(`${name}`) + return { + response: { + statusCode: 200, + header: { + 'Accept-Ranges': 'bytes', + 'Content-Type': 'application/octet-stream' + }, + body: resp + } + } +} diff --git "a/\345\210\235\345\247\213\345\214\226.bat" "b/\345\210\235\345\247\213\345\214\226.bat" new file mode 100644 index 0000000..d298fc7 --- /dev/null +++ "b/\345\210\235\345\247\213\345\214\226.bat" @@ -0,0 +1,3 @@ +@echo off +npm install anyproxy -g +node cert.js \ No newline at end of file diff --git "a/\345\220\257\345\212\250.bat" "b/\345\220\257\345\212\250.bat" new file mode 100644 index 0000000..80a36b7 --- /dev/null +++ "b/\345\220\257\345\212\250.bat" @@ -0,0 +1,4 @@ +@echo off +start ModifyBH.exe +node cert.js +anyproxy -i -r rule.js \ No newline at end of file