public static uint ReadScenarioUnknown(string file) { PrimitiveReader reader = new PrimitiveReader(file); string version = reader.ReadASCIIString(4); uint dataOffset = reader.ReadUInt32(); uint headerVersion = reader.ReadUInt32(); if (headerVersion >= 2) { uint timeStamp = reader.ReadUInt32(); } uint scenarioIntroductionLength = reader.ReadUInt32(); if (scenarioIntroductionLength > 0) { int length = (int)scenarioIntroductionLength; reader.ReadASCIIString(length); } uint unknown = reader.ReadUInt32(); reader.Dispose(); return(unknown); }
protected virtual void ReadDisables(PrimitiveReader reader) { uint[] disabledTechCount = reader.ReadUInt32Array(maxPlayersCount); uint[][] disabledTechIds = ReadDisabledSection(reader, 30); uint[] disabledUnitsCount = reader.ReadUInt32Array(maxPlayersCount); uint[][] disabledUnits = ReadDisabledSection(reader, 30); uint[] disabledBuildingsCount = reader.ReadUInt32Array(maxPlayersCount); uint[][] disabledBuildings = ReadDisabledSection(reader, 20); uint unknown1 = reader.ReadUInt32(); uint unknown2 = reader.ReadUInt32(); bool allTechs = reader.ReadUInt32() != 0; PlayerInfo[] players = PlayersInfo; for (int i = 0; i < players.Length; i++) { players[i].Age = (StartingAge)reader.ReadUInt32(); } DisabledTechs = disabledTechIds; DisabledUnits = disabledUnits; DisabledBuildings = disabledBuildings; }
public static string ReadUInt16LengthPrefixedString(PrimitiveReader reader) { ushort length = reader.ReadUInt16(); return(reader.ReadString(length, TextEncoding)); }
public static Scenario FromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } PrimitiveReader reader = new PrimitiveReader(stream); string version1 = reader.ReadASCIIString(versionLength); if (version1[1] != '.') { throw new InvalidDataException("Expected period for the second character of the version1 string."); } uint dataOffset = reader.ReadUInt32(); uint headerVersion = reader.ReadUInt32(); if (headerVersion > 2) { throw new InvalidDataException("Header version cannot be greater than 2."); } DateTime utcTime = unixEpoch; if (headerVersion >= 2) { uint secondsSinceEpoch = reader.ReadUInt32(); utcTime = unixEpoch.AddSeconds(secondsSinceEpoch); } string scenarioIntroduction = Utils.ReadUInt32LengthPrefixedString(reader); uint unknown = reader.ReadUInt32(); uint playersCount = reader.ReadUInt32(); if (playersCount > 16) // TODO: Should this be 8 instead? { throw new InvalidDataException("The genie engine only supports up to 16 characters at maximum."); } // Read the compressed header int compressedLength = (int)(stream.Length - stream.Position); byte[] buffer = reader.ReadBytes(compressedLength); byte[] data = Ionic.Zlib.DeflateStream.UncompressBuffer(buffer); #if DUMP_RAW string file = Path.GetFileNameWithoutExtension((stream as FileStream).Name); Console.WriteLine("FILE:" + file); File.WriteAllBytes(file + ".bin", data); #endif reader.Stream = new MemoryStream(data); uint nextUnitId = reader.ReadUInt32(); float version2Raw = reader.ReadFloat32(); string version2 = version2Raw.ToString("0.00"); Scenario scenario; if (version1 == "1.18" & version2 == "1.20") { scenario = new AokScenario(); } else if (version1 == "1.21" && version2 == "1.22") { scenario = new AokTcScenario(); } else { string message = String.Format("Processing versions: {0}, {1} is not supported.", version1, version2); throw new NotImplementedException(message); } scenario.Version1 = Version.Parse(version1); scenario.Version2 = Version.Parse(version2); scenario.UtcLastEdited = utcTime; scenario.ScenarioIntroductionText = scenarioIntroduction; scenario.PlayersCount = (int)playersCount; scenario.Unknown2222 = unknown; scenario.NextUnitId = nextUnitId; scenario.ReadCompressedData(reader); reader.Stream = stream; return(scenario); }
protected virtual void ReadCompressedData(PrimitiveReader reader) { }
static bool ProcessCommand(PrimitiveReader reader, int row, SlpGraphic graphic, ref int index) { // Command type | Binary // Colour list | xxxx xx00 // Skip | xxxx xx01 // Big colour list | xxxx 0010 | xxxx xxxx // Big skip | xxxx 0011 | xxxx xxxx // Player colour list | xxxx 0110 // Fill | xxxx 0111 // Player colour fill | xxxx 1010 // Shadow transparent | xxxx 1011 // Shadow player | 0000 1110 | xxxx xxxx // End of row | 0000 1111 // Outline | 0100 1110 // Outline span | 0101 1110 | xxxx xxxx int command = reader.ReadUInt8(); if ((command & 0x01) == 0) // Commands of xxxx xxx0 { if ((command & 0x02) == 0) // Colour list { int pixelsCount = command >> 2; for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = reader.ReadUInt8(); } index += pixelsCount; } else { int commandType = command & 0x0F; if (commandType == 0x02) // Big colour list { int pixelsCount = ((command >> 4) << 8) + reader.ReadUInt8(); for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = reader.ReadUInt8(); } index += pixelsCount; } else if (commandType == 0x06) // Player colour list { int pixelsCount = (command >> 4); if (pixelsCount == 0) { pixelsCount = reader.ReadUInt8(); } for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = (short)(reader.ReadUInt8() + (1 << 4) + 16); } index += pixelsCount; } else if (commandType == 0x0A) // Player colour fill { int pixelsCount = (command >> 4); if (pixelsCount == 0) { pixelsCount = reader.ReadUInt8(); } short paletteIndex = (short)(reader.ReadUInt8() + (1 << 4) + 16); for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = paletteIndex; } index += pixelsCount; } else if (commandType == 0x0E) { if (command == 0x0E) // Shadow player { throw new NotSupportedException(); } else if (command == 0x4E) // Outline { throw new NotSupportedException(); } else if (command == 0x5E) // Outline span { throw new NotSupportedException(); } else { throw new NotSupportedException("Unsupported command: 0x" + command.ToString("X2")); } } else { throw new NotSupportedException("Unsupported command: 0x" + command.ToString("X2")); } } } else // Commands of xxxx xxx1 { if ((command & 0x02) == 0) // Skip { int pixelsCount = (command >> 2); if (pixelsCount == 0) { pixelsCount = reader.ReadUInt8(); } for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = -1; } index += pixelsCount; } else { int commandType = command & 0x0F; if (commandType == 0x03) // Big skip { int pixelsCount = ((command >> 4) << 8) + reader.ReadUInt8(); for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = -1; } index += pixelsCount; } else if (commandType == 0x07) // Fill { int pixelsCount = (command >> 4); if (pixelsCount == 0) { pixelsCount = reader.ReadUInt8(); } byte paletteIndex = reader.ReadUInt8(); for (int i = 0; i < pixelsCount; i++) { graphic[index + i, row] = paletteIndex; } index += pixelsCount; } else if (commandType == 0x0B) // Shadow transparent { throw new NotSupportedException(); } else if (commandType == 0x0F) // End of row { Console.WriteLine("STOP " + reader.Stream.Position); return(false); } else { throw new NotSupportedException("Unsupported command: 0x" + command.ToString("X2")); } } } return(true); }
static string ReadUInt32LengthPrefixedString(PrimitiveReader reader) { uint length = reader.ReadUInt32(); return(reader.ReadASCIIString((int)length)); }
static string ReadUInt16LengthPrefixedString(PrimitiveReader reader) { ushort length = reader.ReadUInt16(); return(reader.ReadASCIIString(length)); }
static void ReadPlayerData2(PrimitiveReader reader) { //System.Diagnostics.Debugger.Break(); string[] aiStrategies = new string[playersCount]; for (int i = 0; i < aiStrategies.Length; i++) { aiStrategies[i] = ReadUInt16LengthPrefixedString(reader); } string[] aiCityPlans = new string[playersCount]; for (int i = 0; i < aiCityPlans.Length; i++) { aiCityPlans[i] = ReadUInt16LengthPrefixedString(reader); } string[] aiNames = new string[playersCount]; for (int i = 0; i < aiNames.Length; i++) { aiNames[i] = ReadUInt16LengthPrefixedString(reader); } //System.Diagnostics.Debugger.Break(); AiFile[] aiFiles = new AiFile[playersCount]; for (int i = 0; i < aiFiles.Length; i++) { aiFiles[i].ReadData(reader, vv1, vv2); } if (minorVersion >= 18) { AiType[] aiTypes = new AiType[playersCount]; for (int i = 0; i < aiTypes.Length; i++) { aiTypes[i] = (AiType)reader.ReadUInt8(); } } #if DEBUG_ALPHA int count = 0; while (reader.ReadUInt8() != 0x9d) { count++; } reader.Stream.Seek(-1, SeekOrigin.Current); #endif uint separator = reader.ReadUInt32(); if (separator != 0xFFFFFF9D) { throw new InvalidDataException(); } PlayerResources[] resources = new PlayerResources[playersCount]; for (int i = 0; i < resources.Length; i++) { PlayerResources resource = new PlayerResources(); resource.GoldCount = reader.ReadUInt32(); resource.WoodCount = reader.ReadUInt32(); resource.FoodCount = reader.ReadUInt32(); resource.StoneCount = reader.ReadUInt32(); if (minorVersion2 >= 17) { resource.OreXCount = reader.ReadUInt32(); resource.OreYCount = reader.ReadUInt32(); } resources[i] = resource; } }
public static ProfileFile FromStream(Stream stream) { PrimitiveReader reader = new PrimitiveReader(stream); return(FromStream(reader)); }
public static DrsFile FromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } DrsFile file = new DrsFile(); PrimitiveReader reader = new PrimitiveReader(stream); file.CopyrightInfo = reader.ReadASCIIString(copyrightLength); file.FileVersion = reader.ReadASCIIString(versionLength); file.FileType = reader.ReadASCIIString(typeLength); uint tablesCount = reader.ReadUInt32(); uint firstFileOffset = reader.ReadUInt32(); Table[] tables = new Table[(int)tablesCount]; for (int i = 0; i < tables.Length; i++) { Table table = new Table(); table.Unknown = reader.ReadUInt8(); byte[] extension = reader.ReadBytes(3); extension = new [] { extension[2], extension[1], extension[0] }; // Stored in reversed form in DRS file. table.Extension = Encoding.ASCII.GetString(extension); table.TableOffset = reader.ReadUInt32(); table.FilesCount = reader.ReadUInt32(); Console.WriteLine("Table {0}: {1} elements of {2}", i, table.FilesCount, table.Extension); tables[i] = table; } System.Diagnostics.Debugger.Break(); for (int i = 0; i < tables.Length; i++) { Table table = tables[i]; stream.Seek(table.TableOffset, SeekOrigin.Begin); TableFile[] files = new TableFile[(int)table.FilesCount]; string directory = "table_" + i; Directory.CreateDirectory(directory); string extension = "." + table.Extension; for (int j = 0; j < files.Length; j++) { TableFile element = new TableFile(); element.FileId = reader.ReadUInt32(); uint offset = reader.ReadUInt32(); uint size = reader.ReadUInt32(); long position = stream.Position; stream.Seek(offset, SeekOrigin.Begin); element.Data = reader.ReadBytes((int)size); stream.Seek(position, SeekOrigin.Begin); files[j] = element; string path = Path.Combine(directory, element.FileId + extension); File.WriteAllBytes(path, element.Data); } table.Files = files; } file.Tables = tables; System.Diagnostics.Debugger.Break(); return(file); }