/// <summary> /// Reads game includes from GM file. /// </summary> private GMInclude[] ReadIncludes() { // Get version. int version = ReadInt(); // Check version. if (version != 430 && version != 600 && version != 620 && version != 800) throw new Exception("Unsupported Pre-Includes object version."); // Create a new array of includes. GMInclude[] includes = new GMInclude[ReadInt()]; // Iterate through includes. for (int i = 0; i < includes.Length; i++) { // Create a new include object. GMInclude include = new GMInclude(); // If version is 8.0, get last changed. if (version == 800) include.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 620 && version != 800) throw new Exception("Unsupported Includes object version."); // Read include data. include.FileName = ReadString(); include.FilePath = ReadString(); include.OriginalFileChosen = ReadBool(); include.OriginalFileSize = ReadInt(); include.StoreInEditableGMKFile = ReadBool(); // If the include file will be stored within the executable, read data. if (include.StoreInEditableGMKFile == true) include.Data = ReadBytes(ReadInt()); // Read include data. include.ExportMode = (ExportType)(ReadInt()); include.FolderToExport = ReadInt(); include.OverwriteIfExists = ReadBool(); include.FreeMemoryAfterExport = ReadBool(); include.RemoveAtGameEnd = ReadBool(); // Set include object. includes[i] = include; } // Return include objects. return includes; }
/// <summary> /// Reads a Game Maker project file /// </summary> public void ReadProject(string file) { // If the file does not exist, throw exception if (File.Exists(file) == false) { throw new Exception("The Game Maker project file does not exist."); } // Get file extension string ext = file.Substring(file.LastIndexOf('.')).ToLower(); // If a GMS project file if (ext == ".gmx") { // Read in the project as a Game Maker Studio project and return ReadProjectGMS(file); return; } // Get file size FileInfo info = new FileInfo(file); long length = info.Length; // Create a new GM file reader using (GMFileReader reader = new GMFileReader(new FileStream(file, FileMode.Open, FileAccess.Read))) { // Progress event ProgressChanged("Starting project read...", reader.BaseStream.Position, length); // Read the magic number int id = reader.ReadGMInt(); // If the magic number was incorrect, not a Game Maker project file if (id != 1234321) { throw new Exception("Not a valid Game Maker project file."); } // Get Game Maker project file version int version = reader.ReadGMInt(); // Check version switch (version) { case 500: this.GameMakerVersion = GMVersionType.GameMaker50; break; case 510: this.GameMakerVersion = GMVersionType.GameMaker51; break; case 520: this.GameMakerVersion = GMVersionType.GameMaker52; break; case 530: this.GameMakerVersion = GMVersionType.GameMaker53; break; case 600: this.GameMakerVersion = GMVersionType.GameMaker60; break; case 701: this.GameMakerVersion = GMVersionType.GameMaker70; break; case 800: this.GameMakerVersion = GMVersionType.GameMaker80; break; case 810: this.GameMakerVersion = GMVersionType.GameMaker81; break; } // Skip over reserved bytes if (version < 600) { reader.ReadGMBytes(4); } // Game Maker 7 project file encryption if (version == 701) { // Bill and Fred, psssttt they like each other ;) int bill = reader.ReadGMInt(); int fred = reader.ReadGMInt(); // Skip bytes to treasure. reader.ReadGMBytes(bill * 4); // Get the seed for swap table int seed = reader.ReadGMInt(); // Skip bytes to get out of the junk yard reader.ReadGMBytes(fred * 4); // Read first byte of Game id (Not encrypted) byte b = reader.ReadByte(); // Set the seed reader.SetSeed(seed); // Read game id id = reader.ReadGMInt(b); } else // Read game id normally { id = reader.ReadGMInt(); } // Skip unknown bytes reader.ReadGMBytes(16); // Read settings ProgressChanged("Reading Settings...", reader.BaseStream.Position, length); // Read main project objects this.Settings = GMSettings.ReadSettings(reader); this.Settings.GameIdentifier = id; // If the version is greater than Game Maker 7.0 if (version > 701) { // Read triggers and constants. this.Triggers = GMTrigger.ReadTriggers(reader); this.Settings.Constants = GMConstant.ReadConstants(reader); } // Read sounds ProgressChanged("Reading Sounds...", reader.BaseStream.Position, length); this.Sounds = GMSound.ReadSounds(reader); // Read sprites ProgressChanged("Reading Sprites...", reader.BaseStream.Position, length); this.Sprites = GMSprite.ReadSprites(reader); // Read backgrounds ProgressChanged("Reading Backgrounds...", reader.BaseStream.Position, length); this.Backgrounds = GMBackground.ReadBackgrounds(reader); // Read paths ProgressChanged("Reading Paths...", reader.BaseStream.Position, length); this.Paths = GMPath.ReadPaths(reader); // Read scripts ProgressChanged("Reading Scripts...", reader.BaseStream.Position, length); this.Scripts = GMScript.ReadScripts(reader); // Get version int version2 = reader.ReadGMInt(); // Check version if (version2 != 440 && version2 != 540 && version2 != 800) { throw new Exception("Unsupported Pre-Font/Pre-Data File object version."); } // If version is old, read data files else, read fonts. if (version2 == 440) { // Read data files ProgressChanged("Reading Data Files...", reader.BaseStream.Position, length); this.DataFiles = GMDataFile.ReadDataFiles(reader); } else { // Read fonts ProgressChanged("Reading Fonts...", reader.BaseStream.Position, length); this.Fonts = GMFont.ReadFonts(version2, reader); } // Read timelines ProgressChanged("Reading Timelines...", reader.BaseStream.Position, length); this.Timelines = GMTimeline.ReadTimelines(reader); // Read objects ProgressChanged("Reading Objects...", reader.BaseStream.Position, length); this.Objects = GMObject.ReadObjects(reader); // Read rooms ProgressChanged("Reading Rooms...", reader.BaseStream.Position, length); this.Rooms = GMRoom.ReadRooms(this.Objects, reader); // Read last ids for instances and tiles this.LastInstanceId = reader.ReadGMInt(); this.LastTileId = reader.ReadGMInt(); // If the version is above 6.1, read include files and packages if (version >= 700) { // Read includes ProgressChanged("Reading Includes...", reader.BaseStream.Position, length); this.Settings.Includes = GMInclude.ReadIncludes(reader); // Read packages ProgressChanged("Reading Packages...", reader.BaseStream.Position, length); this.Packages.AddRange(GMPackage.ReadPackages(reader)); } // Read game information ProgressChanged("Reading Game Information...", reader.BaseStream.Position, length); this.GameInformation = GMGameInformation.ReadGameInformation(reader); // Get version version = reader.ReadGMInt(); // Check version if (version != 500) { throw new Exception("Unsupported Post-Game Information object version."); } // Read libraries ProgressChanged("Reading Libraries...", reader.BaseStream.Position, length); this.Libraries = GMLibrary.ReadLibraries(reader); // Read project tree ProgressChanged("Reading Project Tree...", reader.BaseStream.Position, length); this.ProjectTree = GMNode.ReadTree(file.Substring(file.LastIndexOf(@"\") + 1), reader); // Progress event ProgressChanged("Finished Reading Project.", reader.BaseStream.Position, length); } }
/// <summary> /// Writes includes from Game Maker project. /// </summary> private void WriteIncludes(GMInclude[] includes, GMVersionType version) { // Write the amount of includes. WriteInt(includes.Length); // Iterate through includes. for (int i = 0; i < includes.Length; i++) { // If version is 8.0, write last changed. if (version == GMVersionType.GameMaker80) WriteDouble(includes[i].LastChanged); // Write version number. if (version < GMVersionType.GameMaker80) WriteInt(620); else WriteInt(800); // Write include data. WriteString(includes[i].FileName); WriteString(includes[i].FilePath); WriteBool(includes[i].OriginalFileChosen); WriteInt(includes[i].OriginalFileSize); WriteBool(includes[i].StoreInEditableGMKFile); // If the include file will be stored within the executable, write data. if (includes[i].StoreInEditableGMKFile == true) WriteBytes(includes[i].Data); // Write include data. WriteInt((int)includes[i].ExportMode); WriteInt(includes[i].FolderToExport); WriteBool(includes[i].OverwriteIfExists); WriteBool(includes[i].FreeMemoryAfterExport); WriteBool(includes[i].RemoveAtGameEnd); } }