/// <inheritdoc />
        public override void Run(MappingDatabase mappingDatabase)
        {
            if (Args == null)
            {
                PrintErrorUsage();
                return;
            }

            if (Args.EndsWith(".tiny"))
            {
                if (!File.Exists(Args))
                {
                    Lumberjack.Error($"Mapping file \"{Args}\" could not be found!");
                    return;
                }

                mappingDatabase.UseLocalFile(Args);

                Lumberjack.Log($"Using mappings from \"{Args}\"");
            }
            else
            {
                LoadRemoteMappings(mappingDatabase, Args);
            }
        }
        public static void Run()
        {
            // Load local mapping database
            Lumberjack.Log("Loading mapping database...");
            _mappingDatabase = new MappingDatabase(Path.Combine(Program.BaseDirConfig, "mappings.db"));

            var assy = Assembly.GetExecutingAssembly().GetName();

            Lumberjack.Info("Fabric Lightweight Obfuscation Remapping Assistant (FLORA)");
            Lumberjack.Info($"Version {assy.Version} - parzivail");
            Lumberjack.Info($"Source, issues and discussion: {"https://github.com/Parzivail-Modding-Team/FLORA".Pastel(Color.RoyalBlue)}");
            Lumberjack.Info("Interactive Mode - \"help\" for commands, \"exit\" to quit.");

            // Enter read-eval-print loop
            InteractiveCommand command;

            do
            {
                command = GetCommand();
                if (command == null)
                {
                    Lumberjack.Error("Unknown command");
                }
                else
                {
                    command.Run(_mappingDatabase);
                }
            } while (!(command is ExitCommand));
        }
示例#3
0
        public static string[] GetYarnMappings(YarnVersion version)
        {
            try
            {
                var lines = new List <string>();

                var mappingsTarball =
                    $"https://maven.fabricmc.net/net/fabricmc/yarn/{version.Version}/yarn-{version.Version}-tiny.gz";
                using (var client = new WebClient())
                    using (var fileStream = new MemoryStream(client.DownloadData(mappingsTarball)))
                        using (var gzStream = new GZipStream(fileStream, CompressionMode.Decompress))
                            using (var sr = new StreamReader(gzStream))
                            {
                                sr.ReadLine();

                                string line;
                                while ((line = sr.ReadLine()) != null)
                                {
                                    lines.Add(line);
                                }
                            }

                return(lines.ToArray());
            }
            catch (WebException e)
            {
                Lumberjack.Error($"Could not retrieve remote Yarn mappings: {e.Message}");
                return(null);
            }
            catch (Exception e)
            {
                Lumberjack.Error($"Could not load remote Yarn mappings: {e.Message}! Please report this to the developer.");
                return(null);
            }
        }
        /// <inheritdoc />
        public override void Run(MappingDatabase mappingDatabase)
        {
            var args = GetUnquotedArgs();

            if (args.Length < 1 || args.Length > 2)
            {
                PrintErrorUsage();
                return;
            }

            var input  = args[0];
            var output = args.Length == 1 ? $"{Path.GetFileNameWithoutExtension(input)}-mapped" : args[1];

            if (!File.Exists(input))
            {
                Lumberjack.Error($"Input file \"{input}\" does not exist!");
                return;
            }

            var mappingSource = InteractiveMapper.GetSelectedMappingSource();

            if (mappingSource == null)
            {
                return;
            }

            Mapper.MapArchive(mappingSource, input, output);
        }
示例#5
0
        private void LoadScript(string filename)
        {
            var fs = WaitForFile(filename, FileMode.Open, FileAccess.Read, FileShare.Read);

            if (fs == null)
            {
                Lumberjack.Error("Failed to gain exclusive lock to read script!");
                return;
            }

            string scriptCode;

            using (var reader = new StreamReader(fs))
            {
                scriptCode = reader.ReadToEnd();
            }

            if (scriptCode.GetHashCode() == _stringHash)
            {
                return;
            }

            _stringHash = scriptCode.GetHashCode();

            OnFileChanged(new ScriptChangedEventArgs
            {
                ScriptCode = scriptCode,
                Filename   = filename
            });
        }
示例#6
0
 protected void Log(string msg)
 {
     msg = msg.Trim();
     if (msg.Length > 0)
     {
         Lumberjack.Error("GLSL", msg);
     }
 }
 public static IMappingSource GetSelectedMappingSource()
 {
     if (_mappingDatabase.IsUsingLocalFile)
     {
         return(_mappingDatabase.GetMappingSet(null));
     }
     if (_selectedMappingSource == null)
     {
         Lumberjack.Error("No mapping source defined! Select one with \"mapsrc\"");
     }
     return(_selectedMappingSource);
 }
        private static void LoadRemoteMappings(MappingDatabase mappingDatabase, string version)
        {
            Lumberjack.Log("Fetching mapping versions from remote...");
            var yarnVersions = YarnUtil.GetYarnVersions();

            if (yarnVersions == null)
            {
                // If we couldn't get them, try to use the ones we've already cached

                Lumberjack.Warn("Working in offline mode. Only local Yarn mappings will be available.");
                yarnVersions = mappingDatabase.GetYarnVersions();
            }

            if (yarnVersions.All(mapping => mapping.Version != version))
            {
                // If a specific mapping version was specified that doesn't exist in the version listing, fail

                Lumberjack.Error($"Could not find mapping version {version}!");
                return;
            }

            var mappingVersion = yarnVersions.First(mapping => mapping.Version == version);

            if (!mappingDatabase.HasMappingSet(mappingVersion))
            {
                // If we don't have those mappings cached, download them and cache them

                Lumberjack.Log("Fetching mappings from remote...");
                var mappings = YarnUtil.GetYarnMappings(mappingVersion);

                if (mappings != null)
                {
                    Lumberjack.Log("Updating database...");
                    mappingDatabase.CreateMappingSet(mappingVersion, mappings);
                }
                else
                {
                    Lumberjack.Error($"Failed to load requested mappings {mappingVersion.Version}");
                    Environment.Exit((int)ExitConditions.MappingVersionNotFound);
                }
            }
            else
            {
                Lumberjack.Log("Local database contains required mappings.");
            }

            InteractiveMapper.SetYarnVersion(mappingVersion);

            Lumberjack.Log($"Using mappings from yarn {version}");
        }
示例#9
0
 public static YarnVersion[] GetYarnVersions()
 {
     try
     {
         using (var wc = new WebClient())
             return(wc.DownloadString("https://meta.fabricmc.net/v2/versions/yarn").ParseJson <YarnVersion[]>());
     }
     catch (WebException e)
     {
         Lumberjack.Error($"Could not retrieve remote Yarn versions: {e.Message}");
         return(null);
     }
     catch (Exception e)
     {
         Lumberjack.Error($"Could not load remote Yarn versions: {e.Message}! Please report this to the developer.");
         return(null);
     }
 }
示例#10
0
        public void InitializeVbo(Vector3[] vertices, Vector3[] vertexNormals, Vector2[] vertexUVs, int[] indices)
        {
            if (vertices == null)
            {
                return;
            }
            if (indices == null)
            {
                return;
            }

            Vector3[] tangents  = null;
            Vector3[] binormals = null;

            if (vertexNormals != null)
            {
                tangents  = new Vector3[vertices.Length];
                binormals = new Vector3[vertices.Length];

                for (var a = 0; a < indices.Length / 6 - 2; a++)
                {
                    var i1 = indices[a * 6 + 0];
                    var i2 = indices[a * 6 + 1];
                    var i3 = indices[a * 6 + 2];

                    var v1 = vertices[i1];
                    var v2 = vertices[i2];
                    var v3 = vertices[i3];

                    var w1 = vertexUVs[i1];
                    var w2 = vertexUVs[i2];
                    var w3 = vertexUVs[i3];

                    var x1 = v2.X - v1.X;
                    var x2 = v3.X - v1.X;
                    var y1 = v2.Y - v1.Y;
                    var y2 = v3.Y - v1.Y;
                    var z1 = v2.Z - v1.Z;
                    var z2 = v3.Z - v1.Z;

                    var s1 = w2.X - w1.X;
                    var s2 = w3.X - w1.X;
                    var t1 = w2.Y - w1.Y;
                    var t2 = w3.Y - w1.Y;

                    var coef    = 1 / (s1 * t1 - s2 * t2);
                    var tangent = new Vector3(coef * ((x1 * t2) + (x2 * -t1)), coef * ((y1 * t2) + (y2 * -t1)), coef * ((z1 * t2) + (z2 * -t1)));

                    tangents[a + 0] = tangent;
                    tangents[a + 1] = tangent;
                    tangents[a + 2] = tangent;

                    binormals[a + 0] = Vector3.Cross(vertexNormals[i1], tangent);
                    binormals[a + 1] = Vector3.Cross(vertexNormals[i2], tangent);
                    binormals[a + 2] = Vector3.Cross(vertexNormals[i3], tangent);
                }
            }

            try
            {
                // UV Array Buffer
                if (vertexUVs != null)
                {
                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out UvBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, UvBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexUVs.Length * Vector2.SizeInBytes), vertexUVs,
                                  BufferUsageHint.StaticDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int bufferSize);
                    if (vertexUVs.Length * Vector2.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Vertex UV array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Normal Array Buffer
                if (vertexNormals != null)
                {
                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out NormalBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, NormalBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertexNormals.Length * Vector3.SizeInBytes),
                                  vertexNormals, BufferUsageHint.StaticDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int bufferSize);
                    if (vertexNormals.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Normal array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    /*
                     * Tangents
                     */

                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out TangentBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, TangentBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(tangents.Length * Vector3.SizeInBytes),
                                  tangents, BufferUsageHint.StaticDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                    if (tangents.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Tangent array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    /*
                     * Binormals
                     */

                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out BinormalBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, BinormalBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(binormals.Length * Vector3.SizeInBytes),
                                  binormals, BufferUsageHint.StaticDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out bufferSize);
                    if (binormals.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Binormal array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Vertex Array Buffer
                {
                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out VertexBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Vector3.SizeInBytes), vertices,
                                  BufferUsageHint.DynamicDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out int bufferSize);
                    if (vertices.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Vertex array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Element Array Buffer
                {
                    // Generate Array Buffer Id
                    GL.GenBuffers(1, out ElementBufferId);

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(int)), indices,
                                  BufferUsageHint.StreamDraw);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize,
                                          out int bufferSize);
                    if (indices.Length * sizeof(int) != bufferSize)
                    {
                        throw new ApplicationException("Element array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
                }
            }
            catch (ApplicationException ex)
            {
                Lumberjack.Error($"{ex.Message}. Try re-rendering.");
            }

            // Store the number of elements for the DrawElements call
            NumElements = indices.Length;
        }
        public virtual void PrintErrorUsage()
        {
            var commandDescription = GetCommandDescription();

            Lumberjack.Error($"Invalid arguments! Usage: {commandDescription.Usage}");
        }
示例#12
0
        public void InitializeVbo(ChunkBuffer buffer)
        {
            lock (buffer.LockHandle)
            {
                try
                {
                    // Color Buffer
                    {
                        // Generate Array Buffer Id
                        if (ColorBufferId == -1)
                        {
                            GL.GenBuffers(1, out ColorBufferId);
                        }

                        // Bind current context to Array Buffer ID
                        GL.BindBuffer(BufferTarget.ArrayBuffer, ColorBufferId);

                        // Send data to buffer
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(buffer.Length * sizeof(int)),
                                      buffer.ColorBuffer,
                                      BufferUsageHint.StaticDraw);

                        // Validate that the buffer is the correct size
                        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                              out int bufferSize);
                        if (buffer.Length * sizeof(int) != bufferSize)
                        {
                            throw new ApplicationException("Vertex color array not uploaded correctly");
                        }

                        // Clear the buffer Binding
                        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                    }

                    // Normal Array Buffer
                    {
                        // Generate Array Buffer Id
                        if (NormalBufferId == -1)
                        {
                            GL.GenBuffers(1, out NormalBufferId);
                        }

                        // Bind current context to Array Buffer ID
                        GL.BindBuffer(BufferTarget.ArrayBuffer, NormalBufferId);

                        // Send data to buffer
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(buffer.Length * SmallVertex.Size),
                                      buffer.NormalBuffer, BufferUsageHint.StaticDraw);

                        // Validate that the buffer is the correct size
                        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                              out int bufferSize);
                        if (buffer.Length * SmallVertex.Size != bufferSize)
                        {
                            throw new ApplicationException("Normal array not uploaded correctly");
                        }

                        // Clear the buffer Binding
                        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                    }

                    // Vertex Array Buffer
                    {
                        // Generate Array Buffer Id
                        if (VertexBufferId == -1)
                        {
                            GL.GenBuffers(1, out VertexBufferId);
                        }

                        // Bind current context to Array Buffer ID
                        GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferId);

                        // Send data to buffer
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(buffer.Length * Vertex.Size),
                                      buffer.VertexBuffer,
                                      BufferUsageHint.DynamicDraw);

                        // Validate that the buffer is the correct size
                        GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                              out int bufferSize);
                        if (buffer.Length * Vertex.Size != bufferSize)
                        {
                            throw new ApplicationException("Vertex array not uploaded correctly");
                        }

                        // Clear the buffer Binding
                        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                    }

                    // Element Array Buffer
                    {
                        // Generate Array Buffer Id
                        if (ElementBufferId == -1)
                        {
                            GL.GenBuffers(1, out ElementBufferId);
                        }

                        // Bind current context to Array Buffer ID
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferId);

                        // Send data to buffer
                        GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(buffer.Length * sizeof(short)),
                                      buffer.IndexBuffer,
                                      BufferUsageHint.StreamDraw);

                        // Validate that the buffer is the correct size
                        GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize,
                                              out int bufferSize);
                        if (buffer.Length * sizeof(short) != bufferSize)
                        {
                            throw new ApplicationException("Element array not uploaded correctly");
                        }

                        // Clear the buffer Binding
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
                    }

                    Initialized = true;
                }
                catch (ApplicationException ex)
                {
                    Lumberjack.Error($"{ex.Message}. Try re-rendering.");
                }
                finally
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Store the number of elements for the DrawElements call
                NumElements = buffer.Length;
            }
        }
示例#13
0
        public void InitializeVbo(Vector3[] vertices, Vector3[] normals, Vector2[] texCoords, uint[] elements)
        {
            try
            {
                if (VaoId == -1)
                {
                    GL.GenVertexArrays(1, out VaoId);
                }
                GL.BindVertexArray(VaoId);

                // Normal Array Buffer
                {
                    // Generate Array Buffer Id
                    if (NormalBufferId == -1)
                    {
                        GL.GenBuffers(1, out NormalBufferId);
                    }

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, NormalBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(normals.Length * Vector3.SizeInBytes),
                                  normals,
                                  _hint);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                          out int bufferSize);
                    if (normals.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Normal array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Uv Array Buffer
                {
                    // Generate Array Buffer Id
                    if (TexCoordBufferId == -1)
                    {
                        GL.GenBuffers(1, out TexCoordBufferId);
                    }

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, TexCoordBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(texCoords.Length * Vector2.SizeInBytes),
                                  texCoords,
                                  _hint);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                          out int bufferSize);
                    if (texCoords.Length * Vector2.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Uv array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Vertex Array Buffer
                {
                    // Generate Array Buffer Id
                    if (VertexBufferId == -1)
                    {
                        GL.GenBuffers(1, out VertexBufferId);
                    }

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Vector3.SizeInBytes),
                                  vertices,
                                  _hint);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize,
                                          out int bufferSize);
                    if (vertices.Length * Vector3.SizeInBytes != bufferSize)
                    {
                        throw new ApplicationException("Vertex array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }

                // Element Array Buffer
                {
                    // Generate Array Buffer Id
                    if (ElementBufferId == -1)
                    {
                        GL.GenBuffers(1, out ElementBufferId);
                    }

                    // Bind current context to Array Buffer ID
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferId);

                    // Send data to buffer
                    GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(elements.Length * sizeof(uint)),
                                  elements,
                                  _hint);

                    // Validate that the buffer is the correct size
                    GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize,
                                          out int bufferSize);
                    if (elements.Length * sizeof(int) != bufferSize)
                    {
                        throw new ApplicationException("Element array not uploaded correctly");
                    }

                    // Clear the buffer Binding
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
                }

                GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferId);
                GL.EnableVertexAttribArray(0);
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);

                GL.BindBuffer(BufferTarget.ArrayBuffer, NormalBufferId);
                GL.EnableVertexAttribArray(1);
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);

                GL.BindBuffer(BufferTarget.ArrayBuffer, TexCoordBufferId);
                GL.EnableVertexAttribArray(2);
                GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 0, 0);

                GL.BindVertexArray(0);

                Initialized = true;
            }
            catch (ApplicationException ex)
            {
                Lumberjack.Error($"VertexBuffer/{VaoId}", $"{ex.Message}");
            }
            finally
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            }

            // Store the number of elements for the DrawElements call
            NumElements = elements.Length;
        }
示例#14
0
        public bool LoadScript(string code)
        {
            var codeDomProvider = CodeDomProvider.CreateProvider("CSharp");

            var compilerParameters = new CompilerParameters();

            compilerParameters.ReferencedAssemblies.Add("system.dll");
            compilerParameters.ReferencedAssemblies.Add("TerrainGenCore.dll");

            compilerParameters.GenerateExecutable = false;
            compilerParameters.GenerateInMemory   = true;

            var compilerResults = codeDomProvider.CompileAssemblyFromSource(compilerParameters, code);

            if (compilerResults.Errors.HasErrors)
            {
                var errorMessage = "Compilation failed.\r\n";
                foreach (var error in compilerResults.Output)
                {
                    errorMessage += error + "\r\n";
                }

                Lumberjack.Error(errorMessage);
                return(false);
            }

            var compiledAssembly = compilerResults.CompiledAssembly;

            try
            {
                var types = compiledAssembly.DefinedTypes;
                foreach (var type in types)
                {
                    if (type.FullName is null || !type.IsDefined(typeof(TerrainProviderAttribute)))
                    {
                        continue;
                    }

                    _generatorInstance = compiledAssembly.CreateInstance(type.FullName);
                    Lumberjack.Log($"Creating instance of {type.FullName}");
                    break;
                }

                if (_generatorInstance is null)
                {
                    Lumberjack.Log("No classes found in assembly with the TerrainProvider attribute");
                    return(false);
                }

                var typeInfo = _generatorInstance.GetType();
                var methods  = typeInfo.GetMethods();

                foreach (var requiredMethod in RequiredMethods)
                {
                    if (methods.All(method => method.Name != requiredMethod.Name))
                    {
                        Lumberjack.Error($"Required method {requiredMethod.Name} not found in instantiated class");
                        return(false);
                    }

                    var foundMethod = typeInfo.GetMethod(requiredMethod.Name, requiredMethod.ParameterTypes);

                    if (foundMethod is null)
                    {
                        Lumberjack.Error($"Required method {requiredMethod.Name} does not have required signature {string.Join(", ", requiredMethod.ParameterTypes.Select(type => type.Name))}");
                        return(false);
                    }

                    if (foundMethod.ReturnType != requiredMethod.ReturnType)
                    {
                        Lumberjack.Error($"Required method {requiredMethod.Name} does not have required return type {requiredMethod.ReturnType.Name}");
                        return(false);
                    }
                }

                _methodGetValue      = typeInfo.GetMethod("GetTerrain");
                _methodGetWaterLevel = typeInfo.GetMethod("GetWaterLevel");
            }
            catch (Exception e)
            {
                Lumberjack.Error(e.Message);
                return(false);
            }

            return(true);
        }