Minecraft world importer for Gamecraft.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
6.1KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Threading.Tasks;
  5. using GamecraftModdingAPI;
  6. using GamecraftModdingAPI.Blocks;
  7. using GamecraftModdingAPI.Engines;
  8. using GamecraftModdingAPI.Utility;
  9. using Newtonsoft.Json;
  10. using RobocraftX.Common;
  11. using Svelto.ECS;
  12. using Unity.Mathematics;
  13. using uREPL;
  14. namespace GCMC
  15. {
  16. public class CubePlacerEngine : IApiEngine
  17. {
  18. public void Ready()
  19. {
  20. RuntimeCommands.Register<string>("importWorld", ImportWorld, "Imports a Minecraft world.");
  21. _serializer.TraceWriter = _traceWriter;
  22. }
  23. public EntitiesDB entitiesDB { get; set; }
  24. private readonly Dictionary<string, BlockType> mapping = new Dictionary<string, BlockType>(10);
  25. private JsonSerializer _serializer = JsonSerializer.Create();
  26. private JsonTraceWriter _traceWriter = new JsonTraceWriter();
  27. private async void ImportWorld(string name)
  28. {
  29. try
  30. {
  31. Log.Output("Reading block mappings...");
  32. var parser = new IniParser.FileIniDataParser();
  33. var ini = parser.ReadFile("BlockTypes.ini");
  34. mapping.Clear();
  35. foreach (var section in ini.Sections)
  36. {
  37. var mcblocks = section.SectionName.Split(',');
  38. BlockIDs type;
  39. if (section.Keys["type"] == null)
  40. {
  41. if (section.Keys["ignore"] != "true")
  42. {
  43. Log.Warn("Block type not specified for " + section.SectionName);
  44. continue;
  45. }
  46. type = BlockIDs.Invalid;
  47. }
  48. else if (!Enum.TryParse(section.Keys["type"], out type))
  49. {
  50. Log.Warn("Block type specified in ini not found: " + section.Keys["type"]);
  51. continue;
  52. }
  53. BlockColors color;
  54. if (section.Keys["color"] == null)
  55. color = BlockColors.Default;
  56. else if (!Enum.TryParse(section.Keys["color"], out color))
  57. {
  58. Log.Warn("Block color specified in ini not found: " + section.Keys["color"]);
  59. continue;
  60. }
  61. byte darkness;
  62. if (section.Keys["darkness"] == null)
  63. darkness = 0;
  64. else if (!byte.TryParse(section.Keys["darkness"], out darkness) || darkness > 9)
  65. {
  66. Log.Warn("Block darkness specified in ini isn't a number between 0 and 9: " +
  67. section.Keys["darkness"]);
  68. continue;
  69. }
  70. foreach (var mcblock in mcblocks)
  71. {
  72. mapping.Add(mcblock.ToUpper(), new BlockType
  73. {
  74. Material = mcblock.ToUpper(),
  75. Type = type,
  76. Color = new BlockColor {Color = color, Darkness = darkness}
  77. });
  78. }
  79. }
  80. Log.Output("Reading file...");
  81. Blocks[] blocksArray = null;
  82. //Console.WriteLine("Outside thread: " + Thread.CurrentThread.ManagedThreadId);
  83. //Console.WriteLine("Outside context: " + SynchronizationContext.Current);
  84. await Task.Run(() =>
  85. {
  86. //Console.WriteLine("Inside thread: " + Thread.CurrentThread.Name);
  87. var fs = File.OpenText(name);
  88. _traceWriter.FileLength = ((FileStream) fs.BaseStream).Length;
  89. blocksArray = _serializer.Deserialize<Blocks[]>(new JsonTextReader(fs));
  90. });
  91. //Console.WriteLine("After thread: " + Thread.CurrentThread.ManagedThreadId);
  92. Log.Output("Placing blocks...");
  93. int i;
  94. uint start = BlockIdentifiers.LatestBlockID + 1;
  95. uint end = start;
  96. for (i = 0; i < blocksArray.Length; i++)
  97. {
  98. //if (i % 5000 == 0) await AsyncUtils.WaitForSubmission();
  99. var blocks = blocksArray[i];
  100. if (!mapping.TryGetValue(blocks.Material, out var type))
  101. {
  102. Console.WriteLine("Unknown block: " + blocks.Material);
  103. continue;
  104. }
  105. if (type.Type == BlockIDs.Invalid) continue;
  106. end = Block.PlaceNew(type.Type, (blocks.Start + blocks.End) / 10 * 3, color: type.Color.Color,
  107. darkness: type.Color.Darkness, scale: (blocks.End - blocks.Start + 1) * 3,
  108. rotation: float3.zero).Id.entityID;
  109. }
  110. await AsyncUtils.WaitForSubmission();
  111. var conns = entitiesDB.QueryEntities<GridConnectionsEntityStruct>(CommonExclusiveGroups
  112. .OWNED_BLOCKS_GROUP);
  113. Log.Output("Start: " + start + " - End: " + end);
  114. Log.Output("conn: " + conns[start].isIsolator + " " + conns[start].isProcessed + " " +
  115. conns[start].areConnectionsAssigned + " " + conns[start].ID + " " +
  116. conns[start].machineRigidBodyId);
  117. for (uint j = start; j <= end; j++)
  118. {
  119. conns[j].isProcessed = false;
  120. conns[j].areConnectionsAssigned = false;
  121. conns[j].isIsolator = false;
  122. }
  123. Log.Output(i + " blocks placed.");
  124. }
  125. catch (Exception e)
  126. {
  127. Console.WriteLine(e);
  128. Log.Error(e.Message);
  129. }
  130. }
  131. public void Dispose()
  132. {
  133. }
  134. public string Name { get; } = "GCMCCubePlacerEngine";
  135. public bool isRemovable { get; } = false;
  136. }
  137. }