示例#1
0
        public void Dispose()
        {
            lock ( _threadStreams )
            {
                foreach (var stream in _threadStreams)
                {
                    stream.Dispose();
                }

                _threadStreams.Clear();
            }

            PakFile.Dispose();
        }
        /// <summary>
        ///		Used as an entry point for the project building thread.
        /// </summary>
        private void BuildProjectThread()
        {
            // Work out script compiling options
            _compileFlags = _compileInDebugMode == true ? CompileFlags.Debug : 0;
            if (_treatMessagesAsErrors)
            {
                _compileFlags |= CompileFlags.TreatMessagesAsErrors;
            }
            if (_treatWarningsAsErrors)
            {
                _compileFlags |= CompileFlags.TreatWarningsAsErrors;
            }

            // Split up the script defines string.
            string[] defines = _scriptDefines.Split(new char[1] {
                ','
            });
            _scriptDefineList = new Define[defines.Length + 1];
            for (int i = 0; i < defines.Length; i++)
            {
                if (defines[i].IndexOf('=') >= 0)
                {
                    string[] splitList = defines[i].Split(new char[1] {
                        '='
                    });
                    _scriptDefineList[i] = new Define(splitList[0], splitList[1], TokenID.TypeIdentifier);
                }
                else
                {
                    _scriptDefineList[i] = new Define(defines[i], "", TokenID.TypeIdentifier);
                }
            }
            _scriptDefineList[_scriptDefineList.Length - 1] = new Define(_compileInDebugMode ? "__DEBUG__" : "__RELEASE__", "", TokenID.TypeBoolean);

            // Set the include path list to include the script library path.
            _scriptIncludePathList = new string[] { Environment.CurrentDirectory + "\\" + Editor.GlobalInstance.ScriptLibraryPath, Editor.GlobalInstance.GlobalScriptLibraryPath };

            // Work out a directory that we can build to.
            _buildBasePath  = _buildDirectory;
            _buildDirectory = _buildBasePath + "\\" + DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year + " " + DateTime.Now.Hour + "-" + DateTime.Now.Minute + "-" + DateTime.Now.Second;
            int buildIndex = 2;

            if (Directory.Exists(_buildBasePath) == false)
            {
                Directory.CreateDirectory(_buildBasePath);
            }

            while (Directory.Exists(_buildDirectory) == true)
            {
                _buildDirectory = _buildBasePath + "\\" + DateTime.Now.Day + "-" + DateTime.Now.Month + "-" + DateTime.Now.Year + " " + DateTime.Now.Hour + "-" + DateTime.Now.Minute + "-" + DateTime.Now.Second + (buildIndex++).ToString().PadLeft(4, '0');
            }

            // Create the build directory.
            Directory.CreateDirectory(_buildDirectory);

            // Open the game configuration file, change the pak file settings and save it into
            // the new build folder.
            XmlConfigFile configFile = new XmlConfigFile(Editor.GlobalInstance.GameName + ".xml");

            configFile.SetSetting("path:resources:usepakfiles", _compilePakFiles == true || _buildStandAlone == true ? "1" : "0");
            if (_buildStandAlone == false)
            {
                configFile.Save(_buildDirectory + "\\" + Editor.GlobalInstance.GameName + ".xml");
            }

            // Copy the configuration directory into the build directory.
            //IOMethods.CopyDirectory(Editor.GlobalInstance.ConfigPath, _buildDirectory + "\\" + Editor.GlobalInstance.ConfigPath);

            // Copy the language directory into the build directory.
            //IOMethods.CopyDirectory(Editor.GlobalInstance.LanguagePath, _buildDirectory + "\\" + Editor.GlobalInstance.LanguagePath);

            // Copy the saves file if we have been told to.
            if (_copySaves == true && Directory.GetFiles(Editor.GlobalInstance.SavePath).Length != 0)
            {
                IOMethods.CopyDirectory(Editor.GlobalInstance.SavePath, _buildDirectory + "\\" + Editor.GlobalInstance.SavePath);
            }

            // Create a plugins folder.
            //IOMethods.CopyDirectory(Editor.GlobalInstance.GamePluginPath, _buildDirectory + "\\" + Editor.GlobalInstance.GamePluginPath);

            // Copy the icon.
            if (_buildStandAlone == false && File.Exists(Editor.GlobalInstance.GamePath + "\\icon.ico"))
            {
                File.Copy(Editor.GlobalInstance.GamePath + "\\icon.ico", _buildDirectory + "\\icon.ico");
            }

            // Compile the pak files or copy the media directory if we are not using pak files.
            if (_buildStandAlone == true)
            {
                _taskProgress = 0;
                _task         = "Packing files";
                _logStack.Push(_task);

                // Work out the game ID code.
                long gameIDCode = DateTime.Now.Ticks ^ (long)configFile["title", "engine"].GetHashCode();

                // Create the pak file to save resources to.
                _pakFile            = new PakFile();
                _pakFileIndex       = 0;
                _pakFileSize        = 0;
                _pakFileMaximumSize = 0;

                // Compile the media directory to the pak file.
                CompileDirectoryToPak(Editor.GlobalInstance.MediaPath);
                CompileDirectoryToPak(Editor.GlobalInstance.ConfigPath);
                CompileDirectoryToPak(Editor.GlobalInstance.LanguagePath);

                // Work out game files that we need.
                ArrayList gameFiles = new ArrayList();
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "fusion.exe");
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "graphics.dll");
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "runtime.dll");
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "input.dll");
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "audio.dll");
                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + "engine.dll");

                // Copy plugins.
                string[] requiredPlugins = Editor.GlobalInstance.GameConfigFile.GetSettings("requirements");
                if (requiredPlugins != null)
                {
                    foreach (string requirement in requiredPlugins)
                    {
                        string[] pathSplit = requirement.Split(new char[] { ':' });
                        string   name      = pathSplit[pathSplit.Length - 1];
                        string   value     = Editor.GlobalInstance.GameConfigFile[requirement, ""];
                        switch (name.ToLower())
                        {
                        case "plugin":
                            if (File.Exists(Editor.GlobalInstance.PluginPath + "\\" + value))
                            {
                                //if (Directory.Exists(_buildDirectory + "\\" + Editor.GlobalInstance.PluginPath) == false)
                                //    Directory.CreateDirectory(_buildDirectory + "\\" + Editor.GlobalInstance.PluginPath);
                                //File.Copy(Editor.GlobalInstance.PluginPath + "\\" + value, _buildDirectory + "\\" + Editor.GlobalInstance.PluginPath + value);
                                gameFiles.Add(AppDomain.CurrentDomain.BaseDirectory + Editor.GlobalInstance.PluginPath + "\\" + value);
                            }
                            break;
                        }
                    }
                }

                // Copy all!
                else
                {
                    if (Directory.Exists(Editor.GlobalInstance.PluginPath))
                    {
                        foreach (string file in Directory.GetFiles(Editor.GlobalInstance.PluginPath))
                        {
                            if (Path.GetExtension(file).ToLower() != ".dll")
                            {
                                continue;
                            }
                            gameFiles.Add(file);
                        }
                    }

                    // Game plugins as well.
                    // TODO
                }

                _taskProgress = 50;
                _task         = "Building executable";

                // Create the sub that we are going to add the files into.
                string stubFile = _buildDirectory + "\\" + string.Join("", configFile["title", "engine"].Split(new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|' }, StringSplitOptions.None)) + ".exe";
                File.Copy(AppDomain.CurrentDomain.BaseDirectory + "Stand Alone Stub.exe", stubFile);

                // Open up the stub.
                Stream       stubStream = StreamFactory.RequestStream(stubFile, StreamMode.Append);
                BinaryWriter stubWriter = new BinaryWriter(stubStream);

                // Grab the offset.
                long offset = stubStream.Position;
                stubWriter.Write(gameFiles.Count + 3);
                foreach (string gameFilePath in gameFiles)
                {
                    Stream fileStream = null;
                    fileStream = StreamFactory.RequestStream(gameFilePath, StreamMode.Open);
                    if (fileStream == null)
                    {
                        string tmpFile = Path.GetTempFileName();
                        File.Delete(tmpFile);
                        File.Copy(gameFilePath, tmpFile);
                        fileStream = StreamFactory.RequestStream(tmpFile, StreamMode.Open);
                    }
                    byte[] buffer = new byte[fileStream.Length];
                    fileStream.Read(buffer, 0, (int)fileStream.Length);

                    string url = gameFilePath;
                    if (url.ToLower().StartsWith(AppDomain.CurrentDomain.BaseDirectory.ToLower()))
                    {
                        url = url.Substring(AppDomain.CurrentDomain.BaseDirectory.Length);
                    }

                    stubWriter.Write(url);
                    stubWriter.Write(buffer.Length);
                    stubWriter.Write(buffer, 0, buffer.Length);
                }

                stubStream.Flush();
                GC.Collect();

                // Write the pak file into a memory stream.
                MemoryStream engineMemStream = new MemoryStream();
                BinaryWriter engineMemWriter = new BinaryWriter(engineMemStream);

                XmlConfigFile engineConfigFile = new XmlConfigFile(AppDomain.CurrentDomain.BaseDirectory + "fusion.xml");
                engineConfigFile.SetSetting("standalone", _buildStandAlone == true ? "1" : "0");
                engineConfigFile.Save(engineMemWriter);

                GC.Collect();

                // Write the game config file.
                stubWriter.Write("fusion.xml");
                stubWriter.Write((int)engineMemStream.Length);
                engineMemStream.WriteTo(stubStream);



                // Write the pak file into a memory stream.
                MemoryStream gameMemStream = new MemoryStream();
                BinaryWriter gameMemWriter = new BinaryWriter(gameMemStream);
                configFile.Save(gameMemWriter);
                GC.Collect();

                // Write the game config file.
                stubWriter.Write("standalone.xml");
                stubWriter.Write((int)gameMemStream.Length);
                gameMemStream.WriteTo(stubStream);



                // Write the pak file into a memory stream.
                MemoryStream memStream = new MemoryStream();
                BinaryWriter memWriter = new BinaryWriter(memStream);
                _pakFile.Save(memWriter);
                _pakFile.Resources.Clear();
                GC.Collect();

                // Write in the pak file.
                stubWriter.Write("data.pk");
                stubWriter.Write((int)memStream.Length);
                memStream.WriteTo(stubStream);



                // Write in the offset footer
                stubWriter.Write(gameIDCode);
                stubWriter.Write(offset);

                // Write the data into the stub.
                stubWriter.Close();
                stubStream.Close();
            }
            else
            {
                if (_compilePakFiles == true)
                {
                    _taskProgress = 0;
                    _task         = "Compiling pak files";
                    _logStack.Push(_task);

                    // Create the pak file to save resources to.
                    _pakFile      = new PakFile();
                    _pakFileIndex = 0;
                    _pakFileSize  = 0;

                    // Compile the media directory to the pak file.
                    CompileDirectoryToPak(Editor.GlobalInstance.MediaPath);
                    CompileDirectoryToPak(Editor.GlobalInstance.ConfigPath);
                    CompileDirectoryToPak(Editor.GlobalInstance.LanguagePath);

                    // Save the pak file to the hard drive.
                    if (_pakFile.Resources.Count != 0)
                    {
                        string filePath = _buildDirectory + "\\" + _pakFilePrefix.Replace("#", _pakFileIndex.ToString()) + ".pk";
                        int    index    = 0;
                        while (File.Exists(filePath) == true)
                        {
                            filePath = _buildDirectory + "\\" + _pakFilePrefix.Replace("#", _pakFileIndex.ToString()) + (index++) + ".pk";
                        }
                        _pakFile.Save(filePath);
                        _pakFile.Dispose();
                    }
                }
                else
                {
                    _taskProgress = 0;
                    _task         = "Copying media";
                    _logStack.Push(_task);
                    CopyDirectoryWithProgress(Editor.GlobalInstance.MediaPath, _buildDirectory + "\\" + Editor.GlobalInstance.MediaPath);
                    CopyDirectoryWithProgress(Editor.GlobalInstance.ConfigPath, _buildDirectory + "\\" + Editor.GlobalInstance.ConfigPath);
                    CopyDirectoryWithProgress(Editor.GlobalInstance.LanguagePath, _buildDirectory + "\\" + Editor.GlobalInstance.LanguagePath);
                }

                // If we are building an FGE distrubutable file then copy the icon file and copile all to pak file.
                if (_buildFGE)
                {
                    _taskProgress = 0;
                    _task         = "Compiling FGE files";
                    _logStack.Push(_task);

                    // Create the pak file to save resources to.
                    _pakFile            = new PakFile();
                    _pakFileIndex       = 0;
                    _pakFileSize        = 0;
                    _pakFileMaximumSize = 0;

                    // Pak the build directory.
                    string oldDirectory = Directory.GetCurrentDirectory();

                    Directory.SetCurrentDirectory(_buildDirectory);
                    CompileDirectoryToPak(Directory.GetCurrentDirectory());

                    // Save the pak file.
                    _pakFile.Save(Editor.GlobalInstance.GameName + ".pk");
                    _pakFile.Dispose();

                    Directory.SetCurrentDirectory(oldDirectory);

                    // Delete folder.
                    if (_copySaves == true && Directory.GetFiles(Editor.GlobalInstance.SavePath).Length != 0)
                    {
                        Directory.Delete(_buildDirectory + "\\" + Editor.GlobalInstance.SavePath);
                    }

                    // Delete all files and folders.
                    File.Delete(_buildDirectory + "\\" + Editor.GlobalInstance.GameName + ".xml");
                    if (Directory.Exists(_buildDirectory + "\\" + Editor.GlobalInstance.MediaPath))
                    {
                        Directory.Delete(_buildDirectory + "\\" + Editor.GlobalInstance.MediaPath, true);
                    }
                    if (Directory.Exists(_buildDirectory + "\\" + Editor.GlobalInstance.ConfigPath))
                    {
                        Directory.Delete(_buildDirectory + "\\" + Editor.GlobalInstance.ConfigPath, true);
                    }
                    if (Directory.Exists(_buildDirectory + "\\" + Editor.GlobalInstance.LanguagePath))
                    {
                        Directory.Delete(_buildDirectory + "\\" + Editor.GlobalInstance.LanguagePath, true);
                    }
                }
            }
        }