ユニティバグ修正アーティファクトのためのテンセントの公式オープンソースプロジェクトInjectFix

InjectFixテンセントは、新しいバージョン反復せずに、あなたはすぐにゲームをオンラインのバグを修正することができ、外部の熱リハビリテーション・プログラム・コード・ロジックの最新のオープンソースUnityがユニティオンラインクライアントで実現することが可能です。

私はいくつかのハイライトについてお話しましょう:

  1. C#が直接ユニティを更新するためのプロジェクトを修正、古いプロジェクトで動作するように元のコードを変更せずに、
  2. 熱のアップル更新された用語に沿って、より多くの。
  3. 各ゲーム形式のプライベートパッチ、セキュリティより安全。

テンセント内部アプリケーションのフィードバックによるInjectFix複数のプロジェクトでは、効果的に日々の開発の効率を向上させることができ、オンラインバグを解決するのが、このプロジェクトの下で過去の生活について話を聞かせするだけでなく、非常に良いです。

加熱複数のプログラムスマッシュブラザーズ

すべてのサポートのiOSは、より多くのプログラムが一つの共通点を持っている熱:更新コードが実行を解析された後。アップデート前に実行する決意は、2つのカテゴリに分けることができた場合:

一つは、特定のモジュール、あるいは全体のゲームで、実行解決されています。これは、現在使用可能なすべての主流プログラム(xLua、slua、tolua、ILRuntime、JSBなど)は、この方法でサポートされている最も伝統的な方法です。このモードの特徴:

  1. いくつか多かれ少なかれ侵襲:ILRuntime解像度はこれらのプログラムの最小侵襲性が内部であってもよい、C#コンパイラの組み立て後に行われるが、それはまた、別個のアセンブリに論理分割を更新するために、コードを再構成する必要があります。非侵襲性の最大の様々なC#のスクリプトは、書き換え純粋なC#の手段を使用するプロジェクトを完了しました。

PS:アイデアを持っているが、C#のターンXXのスクリプトツール、分析の実行を通じて、C#のコード化を達成することですが、あなたがしている場合は、既存のプロジェクトは、あなたがこの方法を使用して起動しない限り、それは、失敗の大きな確率、周りに回転したいと思います必ずしも正確に同じ開発で、ピット間避けるために、このようなプログラムは、多くの場合、すべての文法を完全にサポートされないため、構文がサポートされています。

  1. こうした利便性に基づく、一般的なゲームとしての性能、実装上の考慮事項ネイティブな方法で実行するためのいくつかの場所、このようにバグを実行するために、これらのネイティブコードは無力です。
  2. スクリプトは動的型付け言語を使用している場合は、コードの保守が困難な問題をもたらすでしょう。
  3. 利点は、あなたが機能を追加することができ、いくつかのゲームもダウンロードを行うことができ、全体のパッケージのアップデートに従わないです。しかし、Appleは見ることができ、セクションの用語の分析は、これは必ずしも良いことではありません。

、ロジックの実行を解析し、新しい論理にリダイレクトバグ場合は、別のクラスには、ネイティブに実行されます。このモードの特徴:

  1. 侵襲的な低、事後にも使用することができます。
  2. 通常のロジックネイティブ実行では、部分的にしかハンドオーバ実行、より良いパフォーマンスを解決する問題があります。
  3. 原因は、注入さに比例したクラスの数を増加させる、コードセグメントを増加させました。
  4. このように新はしばしば困難です。

第二の方法は、私たちはこの後に参加したtolua番号、使用の2年後、徐々に受け入れられてきた、プログラムの最も初期の成熟度がxLuaを提供することであり、「ホットフィックス」ホットフィックスを呼び出す便宜のために、以下の議論の焦点であります機能、ILRuntimeベースの一部のユーザーがあるホット修復を持っていました。

何がそれをInjectFix?

ホットフィックスが達成されるInjectFix。これと他のホットフィックスソリューションは、それがどのような違いを生むだろうか?

、我々はコードの1000行の機能を持って、問題がある行があるように場面を想像してみて、我々はそれを修正する必要があります。

xLua場合は、LUAは、再び重いワークロードを、この関数を再実装する必要があります。そのパッチの別の集合体であるため、コードの999行は、一般的に、通常は直接使用することができないように、とのホットフィックスILRuntime上で、それが直接、修正するために行われるためのより多くのニーズを元のクラスのprivateメンバにアクセスすることはできません。

InjectFixは、LUAを使用する必要がある、あなたはそれを達成するためのロジック重量の1000行を構築するための別のプロジェクトとしてILRuntimeホットフィックスを好きにする必要はありませんありません。ただ、ユニティ元のプロジェクトに直接コード行を取り除くために必要があり、この機能のノートを更新することができます。

他の利点があるだけでなくInjectFix、ということ:

  • 非常に小さな操作は、たったの約100K、各プログラムLUA比べ、ILRuntimeははるかに小さくすることが、およびサードパーティのライブラリ、純粋なC#実装に依存しません。
  • 各ゲームには、サポート専用のパッチ形式、民間の命令の定義を生成します。そのようなコードは、元のユニバーサルLUA、LUAバイトコードと比較され、CLRアセンブリは安全です。
  • 組立-CSharp.dll外のdllを修復するためにサポート。
  • 無料コード生成、クリーナー。

それは、その欠点を持って、新しいクラスをサポートしていません。また、既存のクラス、修理のバグ、または十分に新しいフィールドをサポートしていないが、ゲームはホットな新機能を通過することはより困難です。純粋なバグ修復ツールにInjectFix。

ブラック&

繰り返しによる負荷InjectFixサポートパッチに、新しいパッチが自動的に表紙にロードされます、この機能は、リアルタイムで変更本物のマシンコードのロジックを達成するために使用することができます。

(ビデオのアドレス:https://v.qq.com/x/page/v09240mo6ai.html?&ptag=4_7.2.5.22206_copy

アップルのポリシー準拠

各のよく寄せられる質問の一つは、より多くのプログラムグループを加熱:私のゲームをリードしません。このプログラムは、アップルによってレビューされていません。

のは、Appleのホット更新条項を見てみましょう。

あなたがダウンロードコード分析の実行を許可する最新の規定を見ることができますが、前提は、プログラム変更に新機能を通じてではありませんでした認識を越えて(および監査と比較して)。通常の文章でガイドライン2.5.2に拒絶理由を見てください:

アプリ、拡張機能、またはリンクされたフレームワークは、アプリのレビューの承認後にアプリの動作や機能を変更する機能を明示的に設計されたコードが含まれているように見えます。

「新機能、」の「の認識を超えて変更」する能力を持って恥ずかしホット更新プログラムの能力があります。ビューの(唯一の既存の機能を変更する)ポイントを提供する能力からInjectFixは、もともとここの弱点だった「新機能と機能は、」適合性の保証となっている能力を持っていません。

基本的な

InjectFix研究開発プロジェクトはかなり曲がりくねりました。この記事の著者はInjectFixとxLuaは、同じ著者である、そしてxLuaオープンソースの後に、言及されたLUAのC#のターンのためのツールを提供したいし続け、かつ綿密に研究は、仮想マシンのワークロードのILも小さく、これは、LUAを回避することを実現するためにいくつかのGCの問題。

决定要做il虚拟机后,也曾想过直接使用ILRuntime,评估后觉得不太符合我们的使用场景:ILRuntime并不能实现和原生代码的函数级别配合,这是我们能实现原工程直接改Bug的关键;ILRuntime运行时部分依赖cecil,除了资源占用大之外,还容易和unity自带或者某些插件的cecil冲突;加载的是标准的程序集在安全性方面也比较堪忧。虽说这些都可以改,但修改的工作量也挺大的,还不如自己写一个。

InjectFix实现bug修复主要靠这两部分:虚拟机负责新逻辑的解析执行;注入代码负责把调用重定向到虚拟机;下面我们结合最简单的例子介绍下这两部分。

虚拟机

关键部分用几行伪码就可以描述清楚:

导读

  1. pc指向的是函数的第一条指令;
  2. argumentBase指向的是第一个参数;
  3. while+switch一条条指令往下执行,具体指令的操作在case那;

argumentBase指向的是求值栈该函数的栈帧,栈帧是这么安排的:

先放参数(如果有的话),再放本地变量(如果有的话),接着是临时区域,当函数返回时弹掉所有东西,如果有返回值就放到栈顶(函数执行前参数0的位置)。

用如下一个静态方法来演示下虚拟机怎么运行:

public static float Add(float a, float b)
{
    return a - b;
}

这函数编译后是这四条指令

http://km.oa.com/files/photos/pictures/201803/1520994863_7_w145_h75.png

Add函数的执行过程

  1. 指令1把参数0 Push到栈顶;
  2. 指令2把参数1 Push到栈顶;
  3. 指令3把两个栈顶元素弹出(Pop)并相加,结果Push到栈顶;
  4. 指令4把栈顶拷贝到参数0的位置,清理栈,退出循环,Execute函数执行结束。

代码注入

上面的Add函数注入后是这样的

public static float Add(float a, float b)
{
    if (WrappersManagerImpl.IsPatched(92))
    {
        return WrappersManagerImpl.GetPatch(92).__Gen_Wrap_25(a, b);
    }
    return a - b;
}

比较简单,发现这函数有patch的话,就重定向到虚拟机。

而__Gen_Wrap_25是个适配器函数,赋值把参数压栈,调用虚拟机的Execute函数,并把结果返回。__Gen_Wrap_25的实现如下:

public float __Gen_Wrap_25(float P0, float P1)
{
    Call call = Call.Begin();
    call.PushSingle(P0);
    call.PushSingle(P1);
    this.virtualMachine.Execute(this.methodId, ref call, 2, 0);
    return call.GetSingle(0);
}

PS:我们的例子仅有三种指令,和这几条指令无关的代码全部简化了,真正复杂得多,有兴趣可以看源码了解。

总结

InjectFix使用简单,小巧,合规且安全。即使你不打算用它来更新线上版本,只要你程序有原生部分,接入也能一定程度上提高开发效率,没什么拒绝它的理由,是吧?

おすすめ

転載: www.oschina.net/news/109803/injectfix-opensource