InjectFix 热更新解决方案
简介
今天来谈一谈,项目种的客户端热更新解决方案。InjectFix是腾讯xlua团队出品的一种用于Unity中C#代码热更新热修复的解决方案。支持Unity全系列,全平台。与xlua的思路类似,InjectFix解决的痛点主要在于Unity中C#代码写的逻辑在发包之后无法更新,导致出现了严重的逻辑问题只能通过配置关闭功能或者利用资源更新来绕过bug这类问题。
相比较lua虚拟机热更的优点
相较于一般使用lua这种接入C#来进行热更新的如ulua之类的方案,InjectFix直接修改C#即可使用,老项目也可以使用,只要简单的接入相应的库,并依照补丁流程进行相应的操作即可。减少了额外学习一门语言的开销。
使用
官方链接:https://github.com/Tencent/InjectFix
1.注入(DLL插桩)
【InjectFix】-【Inject】来对我们的DLL进行自动插桩,需要在编辑器页面。
运行这个菜单工具后,这时IFix会根据我们提供的Config文件去给这些注册的类里面的每个方法插桩,它会直接修改 \Library\ScriptAssemblies\Assembly-CSharp.dll 这个文件,正常注入后即可得到一个拥有热更新能力的DLL文件。
所以我们需要在Editor目录下配置config文件添加需要热更的类。
原理如下。在.NET的CLR生成MSIL中间层语言时,在il代码中增加了一些跳转操作,如果检测到补丁就会执行相应的函数,本质上是修改了Unity生成的dll临时文件。
图1.1 注入后会修改MSIL代码
我们可以在il中清晰地看到这些逻辑。
如果IsPatche == false, 会跳转到IL_0021,否则顺序执行。
2.标注代码(制作补丁)
当有代码需要更新的时候,需要修改相应的代码。这里InjectFix主要提供了三种修改方式。这三种方式都是通过使用Attribute来标注被修改代码的途径来实现的。详细使用方式可以查看官方文档。这里说一下大概都是干什么的以及怎么用。
1.patch(用于修改一个函数)
比如
--- ImmortalGuideRootLogic.cs (revision 323246)
+++ ImmortalGuideRootLogic.cs (working copy)
@@ -81,6 +81,7 @@
public GameObject m_Finished;
public UIButton m_GoToGrowGuide;
public UILabel m_TipsLabel; //完成和等级不足公用一个label +
[IFix.Patch]
private void Start()
{ if (m_DayItemList.Length != GlobeVar.IMMORTALGUIDE_TASKDAYCOUNT)@@ -87,7 +88,9 @@ { return; } - + //发消息请求仙人指路任务状态 + CG_IMMORTALGUIDE_PROGRESS_REQ_PAK pak =new CG_IMMORTALGUIDE_PROGRESS_REQ_PAK();+ pak.SendPacket(); m_Instance = this; m_LeftTime.text = ""; m_ProgressBonusPanel.SetActive(false);
//---------
}
这里代码的修改主要是在Start函数中增加了一些代码。增加了之后给函数标记Patch。这样之后生成Patch的时候,就能发现这个函数并生成相应的逻辑了。
2.Interpret(用于新增一个函数或者一个字段等)
[IFix.Patch] void OnDestroy() {
+ OnDisable();
+ }
+
+ [IFix.Interpret] + void OnDisable() + { m_tabBtnController.delTabWillChange -= TabChangeCheck; m_Instance = null; GameManager.PlayerDataPool.ChargeLTea.m_DelLTDrink -= UpDataChargeTeaRedDot;@@ -72,19 +79,21 @@ GameManager.PlayerDataPool.ChargeHTea.m_DelHTDrink -= UpDataChargeTeaRedDot; }
+ [IFix.Patch] void UpdateRightBtnShow(TabIndex index, bool bShow) { if((int)index >= 0 && (int)index < (int)TabIndex.Count) + if((int)index >= 0 && (int)index < m_TabObject.Length) {- m_TabObject[(int)index].gameObject.SetActive(bShow);+ m_TabObject[(int)index].SetActive(bShow); }
}
这里主要是想把原来用在Destroy的逻辑放到OnDisable中去。因为没有办法删除函数,所以直接删除函数中的逻辑,这里去掉了原来Destroy中的逻辑。然后新增了OnDisable函数用来相应相关的逻辑。
注意OnDisable在OnDestroy中进行了一次调用。这是因为在生成patch的时候会进行函数的裁剪。如果一个函数没有使用过的话,直接就被裁剪掉了。所以这里在别的函数用用一下,避免裁剪。
3.CustomBridge(用于告诉外界,虚拟机这里有一个类可以用)
因为本质上,InjectFix的Patch实现的所有的逻辑都是运行在一个用C#编写的虚拟机中
的,其实外界并不知道虚拟机中加载了什么样的逻辑。为了通知外界这里有一个逻辑可以让外界调用,需要用这个特性标注一下。
主要是为了以下这些使用情景。
- 修复代码赋值一个闭包到一个delegate变量;
- 修复代码的Unity协程用了yield return;
- 新增一个函数,赋值到一个delegate变量;
- 新增一个类,赋值到一个原生interface变量;
- 新增函数,用了yield return;
3.生成Patch
【InjectFix】-【Fix】生成补丁
按照上述方法标注了代码之后,就可以生成Patch了。即提取标注的代码,放到一个文件里。
在Unity的Menu中点击InjectFix->FixAll按钮执行对应的生成逻辑。
之后会在Client\IFixPatch路径下生成针对PC,ios和Android的三个patch包。再根据需要热更到的底包和资源版本号修改名字,提交上到CDN。
总结
IFix的原理主要包括两个部分:
- 自动插桩,首先在代码里面插桩,进入这些的函数的时候判断是否需要热更新,如果需要则直接跳转去执行热更新补丁中的IL指令。
- 生成补丁,将需要热更新的代码生成为IL指令。
周更
项目的热更新步骤是自动的。整体的过程是取到IFixPatch路径下的patch包。根据其名字取出这个patch对应的底包及资源路径。在执行热更新脚本的过程中,将这个patch进行改名,然后放到对应的资源更新的路径中,作为周更资源的一种进行更新。
底包在放出去之后,打开进行周更的时候,会下载patch包到机器的可读写路径中。加载完资源之后会进行尝试加载patch包的操作。加载了patch包之后,如果有被替换的逻辑,就会自动执行新的逻辑了。
这里可以很显然的看出,如果是资源更新完之前的逻辑出问题,热更新是无法解决的,所以这里需要额外注意。
InjectFix 的缺点
确定注入的函数
要注入哪些函数其实也是根据配置生成的,详细可以看看官方文档。目前项目中的做法是注入了所有的Assembly-CSharp中的函数。所以在这之外的,比方说firstpass中的函数,就没有办法进行热更了。这一步会影响效率。
不能直接修改变量的值
整体的热更方案没有办法修改字段的值。所以如果修改一个变量的值,需要修改所有用到这个变量的逻辑。或者把变量改成以属性或者函数的方式来获得。
继承受限制
新增的类不可以继承外界的类。因为新的虚拟机没有实现这么多东西。
性能一般
补丁的逻辑性能很差,较外界的正常il2cpp(HybridCLR)差了大概3个数量级。所以频繁操作和复杂逻辑尽量不要热更,想办法绕过去。最好能不热更就不热更。
参考资料:https://www.jianshu.com/p/adf1cb2dbd3c
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/ca94718a7746096d572a0aae3a236717.png)
InjectFix 热更新解决方案
简介 今天来谈一谈,项目种的客户端热更新解决方案。InjectFix是腾讯xlua团队出品的一种用于Unity中C#代码热更新热修复的解决方案。支持Unity全系列,全平台。与xlua的思路类似,InjectFix解决的痛点主要在于Unity中C#代码写的逻辑在发包之后无…...
![](https://i-blog.csdnimg.cn/direct/41c38cca1b0b4a9bba82a969a6d12597.png)
PHP7.4安装使用rabbitMQ教程(windows)
(1),安装rabbitMQ客户端erlang语言 一,erlang语言安装 下载地址1—— 下载地址2——https://www.erlang.org/patches/otp-27.0 二,rabbitMQ客户端安装 https://www.rabbitmq.com/docs/install-windows (…...
![](https://i-blog.csdnimg.cn/direct/ed3b4e309ccb402e909b0b4b9d46146d.png)
分页以及tab栏切换,动态传类型
<view class"disTitle"><view class"disName">账户明细</view><view class"nav"><u-tabs lineWidth"0" :activeStyle"{color: #FD893F }" :list"navList" change"tabsChange&quo…...
![](https://i-blog.csdnimg.cn/direct/ef4fce99b88e43aaa9a586790a7fae6c.png#pic_center)
【算法】平衡二叉树
难度:简单 题目 给定一个二叉树,判断它是否是 平衡二叉树 示例: 示例1: 输入:root [3,9,20,null,null,15,7] 输出:true 示例2: 输入:root [1,2,2,3,3,null,null,4,4] 输出&…...
![](https://i-blog.csdnimg.cn/direct/5e4c33fadf8b47da99b973e3108fa5bf.png)
五、 计算机网络(考点篇)
1 网络概述和模型 计算机网络是计算机技术与通信技术相结合的产物,它实现了远程通信、远程信息处理和资源共享。计算机网络的功能:数据通信、资源共享、管理集中化、实现分布式处理、负载均衡。 网络性能指标:速率、带宽(频带宽度或传送线路…...
![](https://www.ngui.cc/images/no-images.jpg)
如何解决数据分析问题:IPython与Pandas结合
如何解决数据分析问题:IPython与Pandas结合 数据分析是现代科学研究、商业决策和技术开发中的一个重要环节。IPython和Pandas是两个强大的工具,它们可以大大简化和加速数据分析的过程。本文将为初学者详细介绍如何结合使用IPython和Pandas来解决数据分析…...
![](https://i-blog.csdnimg.cn/direct/53cdfc2ea70a412ca9a0673f904534c9.png)
如何在 Microsoft Edge 上使用开发人员工具
Microsoft Edge 提供了一套强大的开发人员工具,可帮助 Web 开发人员检查、调试和优化他们的网站或 Web 应用程序。 无论您是经验丰富的 Web 开发人员还是刚刚起步,了解如何有效地使用这些工具都可以对开发过程产生重大影响。 在本文中,我们…...
![](https://i-blog.csdnimg.cn/direct/c509b81030014413b01bfb4e2e626e40.png)
《Linux系统编程篇》认识在linux上的文件 ——基础篇
前言 Linux系统编程的文件操作如同掌握了一把魔法钥匙,打开了无尽可能性的大门。在这个世界中,你需要了解文件描述符、文件权限、文件路径等基础知识,就像探险家需要了解地图和指南针一样。而了解这些基础知识,就像学会了魔法咒语…...
![](https://i-blog.csdnimg.cn/direct/ea4f6c69b89143ed9688bb02dbb76ba2.png)
Qt:22.鼠标相关事件(实例演示——鼠标进入/离开某控件的事件、鼠标按下事件、鼠标释放事件、鼠标双击事件)
目录 1.实例演示——鼠标进入/离开某控件的事件: 2.鼠标按下事件: 3.鼠标释放事件: 4.鼠标双击事件: 1.实例演示——鼠标进入/离开某控件的事件: 首先创建一个C类文件 Label,填写好要继承的父类 QLabe…...
![](https://i-blog.csdnimg.cn/direct/99bf491d80dd4e06a916e074fc08309c.png)
笔记 4 :linux 0.11 中继续分析 0 号进程创建一号进程的 fork () 函数
(27)本条目开始, 开始分析 copy_process () 函数,其又会调用别的函数,故先分析别的函数。 get_free_page () ; 先 介绍汇编指令 scasb : 以及 指令 sstosd :…...
![](https://i-blog.csdnimg.cn/direct/406b9599dd2d410e8b80b269caa132e5.png)
Vue3 引入Vanta.js使用
能搜到这篇文章 想必一定看过demo效果图了吧 示例 Vanta.js - Animated 3D Backgrounds For Your Website (vantajs.com) 1. 引入 在根目录 index.html中引入依赖 <script src"https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></sc…...
![](https://i-blog.csdnimg.cn/direct/bb254161b24742619559b81d71ab41ba.png)
LeetCode --- 134双周赛
题目 3206. 交替组 I 3207. 与敌人战斗后的最大分数 3208. 交替组 II 3209. 子数组按位与值为 K 的数目 一、交替组 I & II 题目中问环形数组中交替组的长度为3的子数组个数,主要的问题在于它是环形的,我们要考虑首尾相接的情况,如何…...
![](https://i-blog.csdnimg.cn/direct/27785dc454a547f796bccc545eef984d.png)
快速读出linux 内核中全局变量
查问题时发现全局变量能读出来会提高效率,于是考虑从怎么读出内核态的全局变量,脚本如下 f open("/proc/kcore", rb) f.seek(4) # skip magic assert f.read(1) b\x02 # 64 位def read_number(bytes):return int.from_bytes(bytes, little,…...
![](https://i-blog.csdnimg.cn/direct/58693513d93541a8a699fad79fb239a5.png)
postman录制设置
一、前言: postman是一个很好接口调试或是测试工具,简单方便,不需要很复杂的流程与技术,并且也具备录制条件。对于接口不了解,没有明确对应的说明,但又想通过接口进行一些测试使用其录制是一个不错的办…...
![](https://i-blog.csdnimg.cn/direct/bc19d7fded664ca092f00ea8bbdc4cc9.png)
redis消息队列
redis 的list类型实现消息队列: list结构实现的优缺点: 2、pubsub模式(消息发布订阅)实现消息队列 pubsub的优缺点: 命令行实现: pub:第一次发送有两个接收,第二个只有一个接收 sub接收&#x…...
![](https://i-blog.csdnimg.cn/direct/1a498df91d0a401aa9e1f82c3ba02d41.png)
Linux vim的使用(一键安装则好用的插件_forcpp),gcc的常见编译链接操作
vim 在Linux系统上vim是个功能还比较完善的软件。但是没装插件的vim用着还是挺难受的,所以我们直接上一款插件。 我们只需要在Linux上执行这个命令就能安装(bite提供的) curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh …...
![](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=C%3A%5CUsers%5CaDMIN%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20240713150844844.png&pos_id=img-UDcJW3Ot-1720872886067)
css基础(1)
CSS CCS Syntax CSS 规则由选择器和声明块组成。 CSS选择器 CSS选择器用于查找想要设置样式的HTML元素 一般选择器分为五类 Simple selectors (select elements based on name, id, class) 简单选择器(根据名称、id、类选择元素) //页面上的所有 …...
![](https://i-blog.csdnimg.cn/direct/e3f247a8bb38412abdf00863f2ecc6c0.png)
高并发线程池设计Nginx线程池源码剖析
为什么我们需要线程池?Why? 省流: 为了解决: 1.访问磁盘速度慢 2.等待设备工作 3..... 我们使用多线程技术,在IO繁忙的时候优先处理别的任务 为了解决多线程的缺陷: 1.创建、销毁线程时间消耗大 2.创建线程太多使系统资源不足或者线程频繁切换…...
![](https://i-blog.csdnimg.cn/direct/94ee638781e147bb8884b20c0c3be4ee.jpeg)
SEO:6个避免被搜索引擎惩罚的策略-华媒舍
在当今数字时代,搜索引擎成为了绝大多数人获取信息和产品的首选工具。为了在搜索结果中获得良好的排名,许多网站采用了各种优化策略。有些策略可能会适得其反,引发搜索引擎的惩罚。以下是彭博社发稿推广的6个避免被搜索引擎惩罚的策略。 1. 内…...
STM32之六:SysTick系统滴答定时器
目录 1. SysTick简介 2. 时钟来源 3. SysTick寄存器 3.1 CTRL—SysTick控制及状态寄存器 3.2 RELOAD—SysTick重装载数值寄存器 3.3 CURRENT—SysTick当前数值寄存器 4. systick系统定时器配置 5. 延时函数实现 5.1 延时函数编写步骤 5.2 微秒级延时函数delay_us 5.…...
![](https://i-blog.csdnimg.cn/direct/02508da0900d4be2bd02fee89661be00.png)
全栈物联网项目:结合 C/C++、Python、Node.js 和 React 开发智能温控系统(附代码示例)
1. 项目概述 本文详细介绍了一个基于STM32微控制器和AWS IoT云平台的智能温控器项目。该项目旨在实现远程温度监控和控制,具有以下主要特点: 使用STM32F103微控制器作为主控芯片,负责数据采集、处理和控制逻辑采用DHT22数字温湿度传感器,精确采集环境温湿度数据通过ESP8266 W…...
![](https://i-blog.csdnimg.cn/direct/e7a5562ac8684b8d9e890816a8b3d746.png)
WPF学习(3) -- 控件模板
一、操作过程 二、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expressio…...
![](https://www.ngui.cc/images/no-images.jpg)
Netty Websocket SpringBoot Starter
netty websocket starter Quick Start Demo 项目 添加依赖 <!--添加源--> <repository><id>github</id><url>https://maven.pkg.github.com</url><snapshots><enabled>true</enabled></snapshots> </reposit…...
![](https://i-blog.csdnimg.cn/direct/798118bb4fda4ba9a34ee230cfad36a4.png)
数据结构(4.2)——朴素模式匹配算法
字符串模式匹配 在主串中找到模式串相同的子串,并返回其所在的位置。 子串和模式串的区别 子串:主串的一部分,一定存在 模式串:不一定能在主串中找到 字符串模式匹配 朴素模式匹配算法 主串长度为n,模式串长度为…...
![](https://www.ngui.cc/images/no-images.jpg)
git切换远程仓库地址
git 更换远程仓库地址三种方法总结 一、前言 由于之前项目管理使用私服的 gitlab ,现在换成了Gitea,需要修改远端仓库地址。 二、环境 windows 10git version 2.34.0.windows.1 三、帮助文档 GitHub文档 四、三种修改方法 方法一:不删除远程仓…...
![](https://www.ngui.cc/images/no-images.jpg)
同步与异步:.NET 中的 Task.WaitAll 和 Task.WhenAll
在 C# 中,异步编程通常涉及同时运行多个任务。处理多个任务的两种常见方法是 Task.WaitAll 和 Task.WhenAll。虽然它们看起来很相似,但它们的用途不同,并且用于不同的场景。本文探讨了 Task.WaitAll 和 Task.WhenAll 之间的区别,并…...
![](https://i-blog.csdnimg.cn/direct/bcc6b52baadc45a69bdf8c0afdd4c49b.png)
在Linux系统实现瑞芯微RK3588部署rknntoolkit2进行模型转换
一、首先要先安装一个虚拟的环境 安装Miniconda包 Miniconda的官网链接:Minidonda官网 下载好放在要操作的linux系统,我用的是远程服务器的linux系统,我放在whl这个文件夹里面,这个文件夹是我自己创建的 运行安装 安装的操作都是yes就可以了 检查是否安装成功,输入下面…...
![](https://i-blog.csdnimg.cn/direct/e8f2813d3f6a4f638c0d02689e7ff7e7.png)
【人工智能】Transformers之Pipeline(概述):30w+大模型极简应用
目录 一、引言 二、pipeline库 2.1 概述 2.2 使用task实例化pipeline对象 2.2.1 基于task实例化“自动语音识别” 2.2.2 task列表 2.2.3 task默认模型 2.3 使用model实例化pipeline对象 2.3.1 基于model实例化“自动语音识别” 2.3.2 查看model与task…...
![](https://i-blog.csdnimg.cn/direct/5b3ea622034a43608159cf0925ccd080.png)
Jenkins中Node节点与构建任务
目录 节点在 Jenkins 中的主要作用 1. 分布式构建 分布式处理 负载均衡 2. 提供不同的运行环境 多平台支持 特殊环境需求 3. 提高资源利用率 动态资源管理 云端集成 4. 提供隔离和安全性 任务隔离 权限控制 5. 提高可扩展性 横向扩展 高可用性 Jenkins 主服务…...
![](https://i-blog.csdnimg.cn/direct/c46a1c2c9bce4af9adb9e84a2a170417.png)
Leetcode3200. 三角形的最大高度
Every day a Leetcode 题目来源:3200. 三角形的最大高度 解法1:模拟 枚举第一行是红色还是蓝色,再按题意模拟即可。 代码: /** lc appleetcode.cn id3200 langcpp** [3200] 三角形的最大高度*/// lc codestart class Solutio…...
![](/images/no-images.jpg)
微信公众号平台网站开发/北京seo排名公司
我是站在纯技术的角度上来考虑的,微软对MFC提供了源代码,而对C#只提供了一些组件。这对这个讨论起着至关重要的作用。 MFC是用C的语法来封装Windows的API,掌握MFC的关键不是在于记住掌握它的类库的使用方法,而是要学习它的源码。虽…...
![](/images/no-images.jpg)
no.7主题wordpress/郑州网站制作公司
这篇文章主要介绍了Python autoescape标签用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下1.spaceless标签:移除html标签中的空白字符。包括空格、tab键、换行符,示例代码如下&am…...
![](/images/no-images.jpg)
邢台123网/网站优化怎么操作
很多朋友都希望读取txt文本这个功能, 请教了工程师大大,才了解到,本版手机按键已经有了插件读取文本的功能.在按键的plugin目录下有一个file.lua就是文件操作插件,内有帮助文档,同学们可以参考比如读取附件里的qq.txt,代码如下 PutAttachment "/sdcard", "qq.tx…...
![](/images/no-images.jpg)
建设网站需要哪些手续/下载百度网盘app
/***题目:旅店信息管理系统**小组成员:闫若琳 戴雨晨 马渊沐 张子飞 李闯王浩 崔以博 孙浩浩 李春普 温健成*/#include #include #include #include #define MIN 1#define MAX 30#define LEN sizeof(struct Hotel)//用LEN代替结构体的"长度"void regeist(…...
![](https://s1.51cto.com/attachment/201010/003157434.jpg)
哈尔滨做网站seo的/如何进行网站推广?网站推广的基本手段有哪些
故事是这样发生的:前几天和同事在公司吃饭,同事讲起他早年间相亲的故事。女方是某IT公司的HR,研究生学历,两人第一次见面的一段对话,觉得非常的有意思。 两人是共同的朋友介绍的,第一次见面地点商定在一家餐…...
![](https://images2015.cnblogs.com/blog/817161/201701/817161-20170114140733681-1058760194.png)
网站建设上海公司/黑帽seo工具
Linux_安装 总结: 分区-->格式化-->起一个设备文件名(逻辑分区一定从5开始)-->指定挂载点(必须是空的目录名称作为盘幅) posted 2017-01-14 14:08 douzujun 阅读(...) 评论(...) 编辑 收藏...