SceneDataLoader.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using CommonAI.Zone.ZoneEditor;
  2. using CommonLang.IO;
  3. using ET;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. public class SceneDataLoader : ISceneDataLoader
  8. {
  9. public struct FileOffset
  10. {
  11. internal int position;
  12. internal int len;
  13. }
  14. static SceneData LoadFromStream(Stream stream, bool client_data, IExternalizableFactory factory)
  15. {
  16. var input = new InputStream(stream, factory);
  17. int typeID = input.GetS32();
  18. Type type = factory.GetType(typeID);
  19. if (typeof(SceneData).Equals(type))
  20. {
  21. var info = new SceneData();
  22. if (client_data)
  23. {
  24. info.ReadExternalByClient(input);
  25. }
  26. else
  27. {
  28. info.ReadExternal(input);
  29. }
  30. return info;
  31. }
  32. else
  33. {
  34. Log.Error($"scene ex data read type({type}) error");
  35. }
  36. return null;
  37. }
  38. private readonly MemoryStream binDataStream;
  39. private readonly Dictionary<string, FileOffset> filesDic;
  40. public SceneDataLoader(byte[] binData)
  41. {
  42. if (binData == null)
  43. {
  44. binDataStream = null;
  45. return;
  46. }
  47. binDataStream = new MemoryStream(binData);
  48. filesDic = new Dictionary<string, FileOffset>();
  49. var br = new BinaryReader(binDataStream);
  50. var count = br.ReadInt32();
  51. var names = new string[count];
  52. var sizes = new int[count];
  53. for (int i = 0; i < count; i++)
  54. {
  55. names[i] = br.ReadString();
  56. sizes[i] = br.ReadInt32();
  57. }
  58. var offset = (int)binDataStream.Position;
  59. for (int i = 0; i < count; i++)
  60. {
  61. filesDic[names[i]] = new FileOffset() { position = offset, len = sizes[i] };
  62. offset += sizes[i];
  63. }
  64. }
  65. private readonly MemoryStream msSceneDataCache = new MemoryStream();
  66. private int preSceneDataId = 0;
  67. //战斗服推过来的场景切换消息.
  68. public SceneData Load(int sceneId, bool client_data, IExternalizableFactory factory)
  69. {
  70. if (binDataStream == null)
  71. {
  72. return null;
  73. }
  74. if (sceneId != preSceneDataId)
  75. {
  76. FileOffset fileOffset;
  77. if (!filesDic.TryGetValue(sceneId.ToString(), out fileOffset))
  78. {
  79. return null;
  80. }
  81. binDataStream.Position = fileOffset.position;
  82. msSceneDataCache.Position = 0;
  83. //LZMAHelper.Decompress(binDataStream, fileOffset.len, msSceneDataCache);
  84. binDataStream.CopyTo(msSceneDataCache, fileOffset.len);
  85. preSceneDataId = sceneId;
  86. }
  87. msSceneDataCache.Position = 0;
  88. var sd = LoadFromStream(msSceneDataCache, client_data, factory);
  89. return sd;
  90. }
  91. }