/// <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); } } }
/// <summary> /// Updates all the software owned by this user and out of date. /// </summary> private void UpdateSoftware() { if (Updater.GlobalInstance.CreateUpdate == false) // Install an update. { // Load the pak file. PakFile pakFile = new PakFile(Updater.GlobalInstance.UpdateFile); // Output to the correct folder. int resourceIndex = 0; foreach (PakResource resource in pakFile.Resources) { if (Path.GetDirectoryName(resource.URL as string) != "" && !Directory.Exists(Path.GetDirectoryName(resource.URL as string))) Directory.CreateDirectory(Path.GetDirectoryName(resource.URL as string)); installLabel.Text = "Unpacking \"" + (resource.URL as string) + "\"..."; installProgressBar.Value = (int)((100.0f / pakFile.Resources.Count) * resourceIndex); resourceIndex++; this.Refresh(); Stream resourceStream = resource.RequestResourceStream(); if (File.Exists(resource.URL as string) == false) File.Create(resource.URL as string); Stream resourceFileStream = new FileStream(resource.URL as string, FileMode.Truncate, FileAccess.Write); byte[] data = new byte[resourceStream.Length]; resourceStream.Read(data, 0, (int)resourceStream.Length); resourceFileStream.Write(data, 0, data.Length); resourceFileStream.Close(); resourceStream.Close(); } // We're done, so allow the user to quit. installLabel.Text = "Installation complete"; stepNameLabel.Text = "Updated"; stepDescriptionLabel.Text = "The Fusion Game Engine has been updated."; finishButton.Enabled = true; } else // Create an update. { // Tell the we are creating one!. installLabel.Text = "Creating update"; stepNameLabel.Text = "Creating Update"; stepDescriptionLabel.Text = "A new update file for the Fusion engine is being built."; // Create a pak file to put everything into. _pakFile = new PakFile(); // Add the system files. PakFile("Fusion.exe"); if (Updater.GlobalInstance.BuildSDK == true) PakFile("Editor.exe"); if (Updater.GlobalInstance.BuildSDK == true) PakFile("Stand Alone Stub.exe"); PakFile("Graphics.dll"); PakFile("Audio.dll"); PakFile("Input.dll"); PakFile("Engine.dll"); PakFile("Runtime.dll"); PakFile("Fusion.xml"); // Pak the plugin folder. string[] files = Directory.GetFiles(Updater.GlobalInstance.EngineConfigFile["paths:pluginpath", ""], "*.*", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) PakFile(files[i]); // Update status. installLabel.Text = "Saving update"; installProgressBar.Value = 50; // Save update. _pakFile.Save(Updater.GlobalInstance.UpdateFile); } // We be done! installProgressBar.Value = 100; installLabel.Text = "Completed"; finishButton.Enabled = true; }