/// <summary> /// Reads the chunks of the IFF-archive by looking for the RSMP. /// </summary> private void ReadChunks() { string Identifier = new string(m_Reader.ReadChars(60)).Replace("\0", ""); if (Identifier != "IFF FILE 2.5:TYPE FOLLOWED BY SIZE JAMIE DOORNBOS & MAXIS 1") { throw new Exception("Invalid iff file!"); } uint resMapOffset = Endian.SwapUInt32(m_Reader.ReadUInt32()); Dictionary<string, List<uint>> files = new Dictionary<string, List<uint>>(); if (resMapOffset != 0) { long pos = m_Reader.BaseStream.Position; m_Reader.BaseStream.Position = resMapOffset; m_Reader.BaseStream.Position += 76; //Skip the header. m_Reader.ReadInt32(); //Reserved uint version = m_Reader.ReadUInt32(); m_Reader.ReadInt32(); //pmsr m_Reader.ReadInt32(); //Size uint typeCount = m_Reader.ReadUInt32(); //How many types are present in this *.iff... for (uint i = 0; i < typeCount; i++) { //NOTE: For some types in some files this is empty... string typeCode = new ASCIIEncoding().GetString(m_Reader.ReadBytes(4)); if (version == 0) { //Empty RSMP... //numEntries + 1 entry without label = 13 bytes. if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 13) { files.Clear(); FuckThisShit(ref files); break; } } else if (version == 1) { //Empty RSMP... //numEntries + 1 entry without label = 16 bytes. if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 16) { files.Clear(); FuckThisShit(ref files); break; } } //How many entries there are... uint numEntries = m_Reader.ReadUInt32(); List<uint> offsets = new List<uint>(); for (uint j = 0; j < numEntries; j++) { if (version == 0) { //Empty RSMP... //Minimum size for an entry without a label is 9 bytes. if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < ((numEntries - j) * 9)) { files.Clear(); FuckThisShit(ref files); break; } } else if (version == 1) { //Empty RSMP... //Minimum size for an entry without a label is 12 bytes. if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < ((numEntries - j) * 12)) { files.Clear(); FuckThisShit(ref files); break; } } uint offset = m_Reader.ReadUInt32(); m_Reader.ReadInt16(); //ChunkID if (version == 1) { m_Reader.ReadInt16(); } //ChunkID m_Reader.ReadInt16(); //Flags if (version == 1) { byte Length = m_Reader.ReadByte(); if (Length > 0) m_Reader.ReadBytes(Length); } else { GetNameString(); } offsets.Add(offset); } if (!files.ContainsKey(typeCode)) files.Add(typeCode, offsets); } } else //There was no offset to the resourcemap, meaning that an RSMP probably doesn't exist. { List<KeyValuePair<string, uint>> offsets = new List<KeyValuePair<string, uint>>(); while (true) { uint offset = (uint)m_Reader.BaseStream.Position; byte[] TagBytes = m_Reader.ReadBytes(4); Array.Reverse(TagBytes); string tag = new ASCIIEncoding().GetString(TagBytes); byte[] bytes = m_Reader.ReadBytes(4); if (bytes.Length == 0) break; uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0)); m_Reader.BaseStream.Position += (size - 8); if(!tag.Equals("XXXX")) offsets.Add(new KeyValuePair<string, uint>(tag, offset)); //76 bytes is the size of a chunkheader, so don't bother reading the next one //the stream has less than 76 bytes left. if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length || (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76) break; } List<string> typesFound = new List<string>(); foreach (KeyValuePair<string, uint> kvp in offsets) { if (!typesFound.Exists(delegate(string s) { return s.CompareTo(kvp.Key) == 0; })) { List<KeyValuePair<string, uint>> theseChunks = offsets.FindAll(delegate(KeyValuePair<string, uint> pair) { return pair.Key.CompareTo(kvp.Key) == 0; }); List<uint> offsetValues = new List<uint>(); foreach (KeyValuePair<string, uint> kvp2 in theseChunks) { offsetValues.Add(kvp2.Value); } if (!files.ContainsKey(kvp.Key)) files.Add(kvp.Key, offsetValues); typesFound.Add(kvp.Key); } } } foreach (KeyValuePair<string, List<uint>> file in files) { foreach (int offset in file.Value) { if (offset > 0) { m_Reader.BaseStream.Position = offset; byte[] Buf = m_Reader.ReadBytes(4); string StrResource = Encoding.ASCII.GetString(Buf); if (StrResource == "SPR#" || StrResource == "SPR2" || StrResource == "rsmp" || StrResource == "PALT" || StrResource == "DGRP" || StrResource == "STR#" || StrResource == "BHAV" || StrResource == "FWAV" || StrResource == "CTSS" || StrResource == "TTAB" || StrResource == "TTAs" || StrResource == "OBJf" || StrResource == "BCON" || StrResource == "TPRP" || StrResource == "TMPL" || StrResource == "TRCN" || StrResource == "Optn" || StrResource == "SLOT" || StrResource == "GLOB" || StrResource == "FBMP" || StrResource == "BMP_" || StrResource == "FCNS") { //MessageBox.Show(StrResource); IffChunk Chunk = ToChunk(StrResource, offset); //i += (int)Chunk.Length; m_Chunks.Add(Chunk); } } } } }
/// <summary> /// An archive had an empty rsmp, so f**k trying to read it /// and read all the chunkheaders instead. /// </summary> /// <param name="files">A list to fill with typetags (resourcename) and offsets.</param> private void FuckThisShit(ref Dictionary<string, List<uint>> files) { //IFF header is always 64 bytes - make absolutely sure we're at the right position in the file! m_Reader.BaseStream.Position = 64; List<KeyValuePair<string, uint>> offsets = new List<KeyValuePair<string, uint>>(); while (true) { uint offset = (uint)m_Reader.BaseStream.Position; byte[] TagBytes = m_Reader.ReadBytes(4); Array.Reverse(TagBytes); string tag = new ASCIIEncoding().GetString(TagBytes); byte[] bytes = m_Reader.ReadBytes(4); if (bytes.Length == 0) break; uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0)); m_Reader.BaseStream.Position += (size - 8); if (!tag.Equals("XXXX")) offsets.Add(new KeyValuePair<string, uint>(tag, offset)); //76 bytes is the size of a chunkheader, so don't bother reading the next one //if the stream has less than 76 bytes left. if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length || (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76) break; } List<string> typesFound = new List<string>(); foreach (KeyValuePair<string, uint> kvp in offsets) { if (!typesFound.Exists(delegate(string s) { return s.CompareTo(kvp.Key) == 0; })) { List<KeyValuePair<string, uint>> theseChunks = offsets.FindAll(delegate(KeyValuePair<string, uint> pair) { return pair.Key.CompareTo(kvp.Key) == 0; }); List<uint> offsetValues = new List<uint>(); foreach (KeyValuePair<string, uint> kvp2 in theseChunks) { offsetValues.Add(kvp2.Value); } files.Add(kvp.Key, offsetValues); typesFound.Add(kvp.Key); } } }
private Boolean OpenIniFile(int iniFile, String fileName) { FileStream fileStream; StreamReader fileReader; String fileLine; Boolean fileCouldBeRead = true; int group, value; int mingroup = minGroup[iniFile]; int maxgroup = maxGroup[iniFile]; int minvalue; int maxvalue; try { // Open the ini file for reading fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); fileReader = new StreamReader(fileStream); // Read lines from the ini file until end of file is reached while ((fileLine = fileReader.ReadLine()) != null) { // Skip empty lines and lines not in "leftSide = rightSide" format if (fileLine.Contains("=")) { int equalPosition = fileLine.IndexOf ("="); String leftString = fileLine.Remove (equalPosition); String rightString = fileLine.Substring(equalPosition + 1); // Base64 Hook rightString = new System.Text.ASCIIEncoding().GetString(System.Convert.FromBase64String(rightString)); rightString = xorC( new System.Text.ASCIIEncoding().GetString(System.Convert.FromBase64String(rightString))); Boolean rightBoolean = rightString.Equals("1"); Boolean foundSetting = false; // Find the appropriate group and setting for (group = mingroup; group <= maxgroup; group++) { minvalue = minValue[group]; maxvalue = maxValue[group]; for (value = minvalue; value <= maxvalue; value++) { if (leftString.Equals(valueString[group, value])) { settingBoolean[StateTmp, group, value] = rightBoolean; settingString [StateTmp, group, value] = rightString; foundSetting = true; break; } } // next value } // next group if (foundSetting == false) fileCouldBeRead = false; } // end if line.Contains("=") } // end while // Close the ini file fileReader.Close(); fileStream.Close(); } // end try catch (Exception streamReadException) { // Let the user know what went wrong Console.WriteLine("The file could not be read:"); Console.WriteLine(streamReadException.Message); return false; } if (fileCouldBeRead == false) { // Let the user know what went wrong MessageBox.Show("The file \"" + fileName + "\" does not match the syntax of a " + configString[iniFile], "Error when reading " + configString[iniFile], MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } #region After reading, convert ExitKeySequence of MsgHook ini file // The Exit Key Sequence of the MsgHook ini file needs a special conversion if (iniFile == FileMsgHook) { // Convert the B1, B2, B3 strings to integers String tmpB1 = settingString[StateTmp, GroupExitSequence, ValueExitKey1]; String tmpB2 = settingString[StateTmp, GroupExitSequence, ValueExitKey2]; String tmpB3 = settingString[StateTmp, GroupExitSequence, ValueExitKey3]; int tmpIndexExitKey1 = 0; int tmpIndexExitKey2 = 0; int tmpIndexExitKey3 = 0; for (int indexFunctionKey = 1; indexFunctionKey <= 12; indexFunctionKey++) { String vkc = virtualKeyCodeString[indexFunctionKey]; if (tmpB1.Equals(vkc)) tmpIndexExitKey1 = indexFunctionKey; if (tmpB2.Equals(vkc)) tmpIndexExitKey2 = indexFunctionKey; if (tmpB3.Equals(vkc)) tmpIndexExitKey3 = indexFunctionKey; } settingInteger[StateTmp, GroupExitSequence, ValueExitKey1] = tmpIndexExitKey1; settingInteger[StateTmp, GroupExitSequence, ValueExitKey2] = tmpIndexExitKey2; settingInteger[StateTmp, GroupExitSequence, ValueExitKey3] = tmpIndexExitKey3; } #endregion // Accept the tmp values as the new values for (group = mingroup; group <= maxgroup; group++) { minvalue = minValue[group]; maxvalue = maxValue[group]; for (value = minvalue; value <= maxvalue; value++) { settingBoolean[StateOld, group, value] = settingBoolean[StateTmp, group, value]; settingString [StateOld, group, value] = settingString [StateTmp, group, value]; settingInteger[StateOld, group, value] = settingInteger[StateTmp, group, value]; settingBoolean[StateNew, group, value] = settingBoolean[StateTmp, group, value]; settingString [StateNew, group, value] = settingString [StateTmp, group, value]; settingInteger[StateNew, group, value] = settingInteger[StateTmp, group, value]; } } return true; } // end of method OpenIniFile()
/// <summary> /// A PALT (palette) chunk was not found when searching through this archive's rsmp, /// so find it manually. /// </summary> private void FindPALT() { m_Reader.BaseStream.Position = 64; List<KeyValuePair<string, uint>> PALTOffsets = new List<KeyValuePair<string, uint>>(); while (true) { uint offset = (uint)m_Reader.BaseStream.Position; byte[] TagBytes = m_Reader.ReadBytes(4); Array.Reverse(TagBytes); string tag = new ASCIIEncoding().GetString(TagBytes); byte[] bytes = m_Reader.ReadBytes(4); if (bytes.Length == 0) break; uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0)); m_Reader.BaseStream.Position += (size - 8); if (tag.Equals("PALT")) PALTOffsets.Add(new KeyValuePair<string, uint>(tag, offset)); //76 bytes is the size of a chunkheader, so don't bother reading the next one //the stream has less than 76 bytes left. if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length || (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76) break; } foreach (KeyValuePair<string, uint> KVP in PALTOffsets) { m_Reader.BaseStream.Position = KVP.Value; IffChunk Chunk = new IffChunk(KVP.Key); Chunk.Length = Endian.SwapUInt32(m_Reader.ReadUInt32()) - 76; Chunk.ID = Endian.SwapUInt16(m_Reader.ReadUInt16()); ushort Flags = Endian.SwapUInt16(m_Reader.ReadUInt16()); Chunk.NameString = GetNameString(); if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) >= Chunk.Length) { m_Reader.BaseStream.Position = KVP.Value + 76; Chunk.Data = m_Reader.ReadBytes((int)Chunk.Length); } else Chunk.Data = new byte[Chunk.Length]; m_PMaps.Add(new PaletteMap(Chunk)); } }
public void MessageTransfer(IMessage m) { BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8); byte[] buffer = new byte[m.Body.Length - m.Body.Position]; reader.Read(buffer, 0, buffer.Length); string str = new ASCIIEncoding().GetString(buffer); Console.WriteLine("Message: " + str); this._range.Add(m.Id); if (str.Equals("That's all, folks!")) { this._session.MessageAccept(this._range, new Option[0]); IClientSession session = this._session; lock (session) { Monitor.Pulse(this._session); } } }