Hotfix.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Reflection;
  5. using UnityEngine;
  6. namespace Model
  7. {
  8. public sealed class Hotfix : Object
  9. {
  10. public Assembly HotfixAssembly;
  11. public ILRuntime.Runtime.Enviorment.AppDomain AppDomain;
  12. private readonly IStaticMethod start;
  13. public Action Update;
  14. public Action LateUpdate;
  15. public Action OnApplicationQuit;
  16. public Hotfix()
  17. {
  18. Game.Scene.GetComponent<ResourcesComponent>().LoadBundle($"code.unity3d");
  19. this.LoadHotfixAssembly();
  20. Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle($"code.unity3d");
  21. #if ILRuntime
  22. this.start = new ILStaticMethod(this.AppDomain, "Hotfix.Init", "Start", 0);
  23. #else
  24. Type hotfixInit = this.HotfixAssembly.GetType("Hotfix.Init");
  25. this.start = new MonoStaticMethod(hotfixInit, "Start");
  26. #endif
  27. }
  28. public void GotoHotfix()
  29. {
  30. #if ILRuntime
  31. ILHelper.InitILRuntime();
  32. #endif
  33. this.start.Run();
  34. }
  35. public Type[] GetHotfixTypes()
  36. {
  37. #if ILRuntime
  38. if (this.AppDomain == null)
  39. {
  40. return new Type[0];
  41. }
  42. return this.AppDomain.LoadedTypes.Values.Select(x => x.ReflectionType).ToArray();
  43. #else
  44. if (this.HotfixAssembly == null)
  45. {
  46. return new Type[0];
  47. }
  48. return this.HotfixAssembly.GetTypes();
  49. #endif
  50. }
  51. public void LoadHotfixAssembly()
  52. {
  53. #if ILRuntime
  54. this.AppDomain = new ILRuntime.Runtime.Enviorment.AppDomain();
  55. GameObject code = Game.Scene.GetComponent<ResourcesComponent>().GetAsset<GameObject>("code.unity3d", "Code");
  56. byte[] assBytes = code.Get<TextAsset>("Hotfix.dll").bytes;
  57. byte[] mdbBytes = code.Get<TextAsset>("Hotfix.pdb").bytes;
  58. using (MemoryStream fs = new MemoryStream(assBytes))
  59. using (MemoryStream p = new MemoryStream(mdbBytes))
  60. {
  61. this.AppDomain.LoadAssembly(fs, p, new Mono.Cecil.Pdb.PdbReaderProvider());
  62. }
  63. #else
  64. GameObject code = Game.Scene.GetComponent<ResourcesComponent>().GetAsset<GameObject>("code.unity3d", "Code");
  65. byte[] assBytes = code.Get<TextAsset>("Hotfix.dll").bytes;
  66. byte[] mdbBytes = code.Get<TextAsset>("Hotfix.mdb").bytes;
  67. Assembly assembly = Assembly.Load(assBytes, mdbBytes);
  68. this.HotfixAssembly = assembly;
  69. #endif
  70. }
  71. }
  72. }