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.

159 lines
5.8KB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Threading.Tasks;
  7. using IllusionPlugin;
  8. using Newtonsoft.Json;
  9. using Svelto.Tasks.ExtraLean;
  10. using TechbloxModdingAPI;
  11. using TechbloxModdingAPI.App;
  12. using TechbloxModdingAPI.Blocks;
  13. using TechbloxModdingAPI.Commands;
  14. using TechbloxModdingAPI.Tasks;
  15. using Unity.Mathematics;
  16. using UnityEngine;
  17. using uREPL;
  18. namespace GCMC
  19. {
  20. public class GCMCPlugin : IEnhancedPlugin
  21. {
  22. public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;
  23. public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();
  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, darkness)
  77. });
  78. }
  79. }
  80. Log.Output("Reading file...");
  81. Blocks[] blocksArray = null;
  82. await Task.Run(() =>
  83. {
  84. var fs = File.OpenText(name);
  85. _traceWriter.FileLength = ((FileStream) fs.BaseStream).Length;
  86. blocksArray = _serializer.Deserialize<Blocks[]>(new JsonTextReader(fs));
  87. });
  88. Log.Output("Placing blocks...");
  89. int i;
  90. Block lastBlock = null;
  91. for (i = 0; i < blocksArray.Length; i++)
  92. {
  93. var blocks = blocksArray[i];
  94. if (!mapping.TryGetValue(blocks.Material, out var type))
  95. {
  96. Console.WriteLine("Unknown block: " + blocks.Material);
  97. continue;
  98. }
  99. if (type.Type == BlockIDs.Invalid) continue;
  100. var block = new Block(type.Type, (blocks.Start + blocks.End) / 10 * 3 + new float3(5000, 0, 5000))
  101. {
  102. Color = type.Color,
  103. //Scale = (blocks.End - blocks.Start + 1) * 3
  104. };
  105. Console.WriteLine("Placed block at " + block.Position);
  106. lastBlock = block;
  107. }
  108. if (lastBlock != null)
  109. Game.Simulate += (sender, args) => OnSimulationStarted(lastBlock).RunOn(Scheduler.extraLeanRunner);
  110. Log.Output(i + " blocks placed.");
  111. }
  112. catch (Exception e)
  113. {
  114. Console.WriteLine(e);
  115. Log.Error(e.Message);
  116. }
  117. }
  118. private IEnumerator OnSimulationStarted(Block lastBlock)
  119. {
  120. SimBody body;
  121. int C = 0;
  122. while ((body = lastBlock.GetSimBody()) == null)
  123. {
  124. C++;
  125. yield return null;
  126. }
  127. Console.WriteLine($"Body position: {body.Position} ({C})");
  128. }
  129. public override void OnApplicationStart()
  130. {
  131. TechbloxModdingAPI.Main.Init();
  132. CommandBuilder.Builder("importWorld", "Imports a Minecraft world.")
  133. .Action<string>(ImportWorld).Build();
  134. //_serializer.TraceWriter = _traceWriter;
  135. Debug.Log("GCMC loaded");
  136. }
  137. public override void OnApplicationQuit()
  138. {
  139. TechbloxModdingAPI.Main.Shutdown();
  140. }
  141. }
  142. }