public void WriteSourceBlock(BinaryWriter writer, int roomVersion) { byte[] buffer = AGSStringUtils.GetASCIIBytes(SourceCode); //NOTE(adm244): not a bug, it encrypts by decrypting buffer = AGSEncryption.DecryptAvisBuffer(buffer); writer.Write((Int32)buffer.Length); writer.Write((byte[])buffer); }
public void ReadSourceBlock(BinaryReader reader, int roomVersion) { int length = reader.ReadInt32(); byte[] buffer = reader.ReadBytes(length); //NOTE(adm244): not a bug, it decrypts by encrypting buffer = AGSEncryption.EncryptAvisBuffer(buffer); SourceCode = AGSStringUtils.ConvertToString(buffer); }
public static string ReadEncryptedCString(this BinaryReader reader) { Int32 length = reader.ReadInt32(); if ((length <= 0) || (length > AGSStringUtils.MaxCStringLength)) { throw new IndexOutOfRangeException(); } //NOTE(adm244): ASCII ReadChars is not reliable in this case since it replaces bytes > 0x7F // https://referencesource.microsoft.com/#mscorlib/system/text/asciiencoding.cs,879 byte[] buffer = reader.ReadBytes(length); return(AGSEncryption.DecryptAvis(buffer)); }
private byte[] EncryptRoomPassword(byte[] buffer, int roomVersion) { if (roomVersion < 9) { byte[] bufferEncrypted = new byte[buffer.Length]; for (int i = 0; i < bufferEncrypted.Length; ++i) { bufferEncrypted[i] = (byte)(buffer[i] - (byte)60); } return(bufferEncrypted); } //NOTE(adm244): not a bug, it encrypts by decrypting return(AGSEncryption.DecryptAvisBuffer(buffer)); }
private CLibFile[] ReadCLibPre10(BinaryReader reader, int version) { CLibFile[] files = new CLibFile[1]; files[0] = new CLibFile(); files[0].Filename = RootFilename; byte salt = reader.ReadByte(); byte reserved = reader.ReadByte(); Int16 assetsCount = reader.ReadInt16(); AGSCLibAsset[] assets = new AGSCLibAsset[assetsCount]; //TODO(adm244): figure out how it's used in pre 6, ignored for now byte[] password = reader.ReadBytes(13); for (int i = 0; i < assets.Length; ++i) { assets[i] = new AGSCLibAsset(); string filename = reader.ReadFixedCString(13); assets[i].Filename = AGSEncryption.DecryptSalt(filename, salt); } for (int i = 0; i < assetsCount; ++i) { assets[i].Size = reader.ReadInt32(); } //TODO(adm244): read "flags and ratio", skipping for now reader.BaseStream.Seek(assetsCount * sizeof(Int16), SeekOrigin.Current); assets[0].Offset = reader.BaseStream.Position; for (int i = 1; i < assets.Length; ++i) { assets[i].Offset = assets[i - 1].Offset + assets[i - 1].Size; } return(BuildAssetsLists(assets, ref files)); }
public void LoadFromStream(BinaryReader r) { // verify signature char[] dta_sig = r.ReadChars(DTA_SIGNATURE.Length); string dta_sig_string = new string(dta_sig); Debug.Assert(DTA_SIGNATURE == dta_sig_string); // parse dta header Int32 dta_version = r.ReadInt32(); Int32 strlen = r.ReadInt32(); string engine_version = r.ReadFixedCString(strlen); // parse capability strings if (dta_version >= 48) // 3.4.1 { Int32 capabilities_count = r.ReadInt32(); for (int i = 0; i < capabilities_count; ++i) { string capability = r.ReadString(); } } // parse game setup struct base AGSAlignedStream ar = new AGSAlignedStream(r); setup.LoadFromStream(ar, dta_version); if (dta_version > 32) // 3.x { // parse save game info save_guid = r.ReadChars(40); save_extension = r.ReadChars(20); save_folder = r.ReadChars(50); } // parse font info if (dta_version < 50) // 3.5 { font_flags = r.ReadBytes(setup.fonts_count); font_outlines = r.ReadBytes(setup.fonts_count); if (dta_version >= 48) // 3.4.1 { for (int i = 0; i < setup.fonts_count; ++i) { Int32 font_offset_y = r.ReadInt32(); if (dta_version >= 49) // 3.4.1_2 { Int32 font_linespacing = r.ReadInt32(); } } } } else { for (int i = 0; i < setup.fonts_count; ++i) { Int32 flags = r.ReadInt32(); Int32 sizePt = r.ReadInt32(); Int32 outline = r.ReadInt32(); Int32 yOffset = r.ReadInt32(); Int32 lineSpacing = Math.Max(0, r.ReadInt32()); } } // parse sprite flags Int32 sprites_count_max = 6000; if (dta_version >= 24) // pre 2.5.6 { sprites_count_max = r.ReadInt32(); } sprite_flags = r.ReadBytes(sprites_count_max); // parse inventory items info inventoryItems = new AGSInventoryItem[setup.inventory_items_count]; AGSAlignedStream ar1 = new AGSAlignedStream(r); for (int i = 0; i < setup.inventory_items_count; ++i) { inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].LoadFromStream(ar1); //NOTE(adm244): reset aligned stream?? } // parse cursors info AGSAlignedStream ar2 = new AGSAlignedStream(r); cursors = new AGSCursorInfo[setup.cursors_count]; for (int i = 0; i < cursors.Length; ++i) { cursors[i] = new AGSCursorInfo(); cursors[i].LoadFromStream(ar2); } characters = new AGSCharacter[setup.characters_count]; if (dta_version > 32) // 3.x { // parse characters interaction scripts for (int i = 0; i < characters.Length; ++i) { characters[i] = new AGSCharacter(); characters[i].interactions.LoadFromStream(r); } // parse inventory items interaction scripts for (int i = 1; i < inventoryItems.Length; ++i) { //inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].interactions.LoadFromStream(r); } } else // 2.72 and older { for (int i = 0; i < characters.Length; ++i) { characters[i] = new AGSCharacter(); characters[i].interactions_old.LoadFromStream(r); } for (int i = 0; i < inventoryItems.Length; ++i) { //inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].interactions_old.LoadFromStream(r); } Int32 globalvars_count = r.ReadInt32(); globalvars = new AGSInteractionVariable[globalvars_count]; for (int i = 0; i < globalvars.Length; ++i) { globalvars[i] = new AGSInteractionVariable(); globalvars[i].LoadFromStream(r); } } // parse dictionary if (setup.load_dictionary != 0) { dictionary.LoadFromStream(r); } // parse global script globalScript.ReadFromStream(r); // parse dialog script if (dta_version > 37) // 3.1.0 { dialogScript.ReadFromStream(r); } // parse other scripts if (dta_version >= 31) // 2.7.0 { Int32 modules_count = r.ReadInt32(); scriptModules = new AGSScript[modules_count]; for (int i = 0; i < scriptModules.Length; ++i) { scriptModules[i] = new AGSScript(); scriptModules[i].ReadFromStream(r); } } // parse views if (dta_version > 32) // 3.x { views = new AGSView[setup.views_count]; for (int i = 0; i < views.Length; ++i) { views[i] = new AGSView(); views[i].LoadFromStream(r); } } else // 2.7.2 and older { views272 = new AGSView272[setup.views_count]; for (int i = 0; i < views272.Length; ++i) { views272[i] = new AGSView272(); views272[i].LoadFromStream(r); } } // parse characters AGSAlignedStream ar3 = new AGSAlignedStream(r); for (int i = 0; i < characters.Length; ++i) { characters[i].LoadFromStream(ar3); ar.Reset(); } if (dta_version >= 21) // 2.54 { //TODO(adm244): real parsing r.BaseStream.Seek(20 * 50, SeekOrigin.Current); } ParseGlobalMessages(r, dta_version); ParseDialogs(r); if (dta_version <= 37) // 3.0 and older { for (int i = 0; i < dialogs.Length; ++i) { dialogs[i].old_dialog_code = r.ReadBytes(dialogs[i].code_size); Int32 scriptSize = r.ReadInt32(); byte[] encodedStr = r.ReadBytes(scriptSize); dialogs[i].old_dialog_script = AGSEncryption.DecryptAvis(encodedStr); } if (dta_version <= 25) // 2.60 and older { while (true) { uint mark = r.ReadUInt32(); r.BaseStream.Seek(-sizeof(UInt32), SeekOrigin.Current); if (mark == GUI_SIGNATURE) { break; } string dialogString = r.ReadCString(); oldDialogStrings.Add(dialogString); } } else { while (true) { Int32 length = r.ReadInt32(); if ((UInt32)length == GUI_SIGNATURE) { r.BaseStream.Seek(-sizeof(UInt32), SeekOrigin.Current); break; } byte[] encodedStr = r.ReadBytes(length); oldDialogStrings.Add(AGSEncryption.DecryptAvis(encodedStr)); } } } int gui_version = ParseGUIs(r); ParseGUIControls(r, gui_version); if (dta_version >= 25) // 2.60+ { ParsePlugins(r); ParseCustomProperties(r); ParseObjectsScriptNames(r, dta_version); } if (dta_version >= 41) // 3.2.0+ { audioStorage = new AGSAudioStorage(); audioStorage.LoadFromStream(r); } if (dta_version >= 36) // 2.8 ??? { ParseRoomsDebugInfo(r); } }
//private CLibFile[] ReadCLib20(BinaryReader reader) //{ // //NOTE(adm244): assuming asset files are stored sequentially // Int32 filesCount = reader.ReadInt32(); // CLibFile[] files = new CLibFile[filesCount]; // for (int i = 0; i < files.Length; ++i) // files[i].Filename = reader.ReadCString(50); // // Int32 assetsCount = reader.ReadInt32(); // AGSCLibAsset[] assets = new AGSCLibAsset[assetsCount]; // // for (int i = 0; i < assets.Length; ++i) // { // Int16 length = reader.ReadInt16(); // length /= 5; // // byte[] jibzler = reader.ReadBytes(length); // assets[i].Filename = AGSEncryption.DecryptJibzle(jibzler); // } // // for (int i = 0; i < assets.Length; ++i) // assets[i].Offset = reader.ReadInt32(); // // for (int i = 0; i < assets.Length; ++i) // assets[i].Size = reader.ReadInt32(); // // for (int i = 0; i < assets.Length; ++i) // assets[i].AssetFileIndex = reader.ReadByte(); // // return BuildAssetsLists(assets, ref files); //} private CLibFile[] ReadCLibPre21(BinaryReader reader, int version) { Int32 filesCount = reader.ReadInt32(); CLibFile[] files = new CLibFile[filesCount]; for (int i = 0; i < files.Length; ++i) { files[i] = new CLibFile(); if (version == 20) { files[i].Filename = reader.ReadCString(50); } else { files[i].Filename = reader.ReadFixedCString(20); } } Int32 asset_count = reader.ReadInt32(); AGSCLibAsset[] assets = new AGSCLibAsset[asset_count]; for (int i = 0; i < assets.Length; ++i) { assets[i] = new AGSCLibAsset(); if (version == 20) { Int16 length = reader.ReadInt16(); length /= 5; byte[] jibzler = reader.ReadBytes(length); assets[i].Filename = AGSEncryption.DecryptJibzle(jibzler); } else if (version >= 11) { byte[] jibzler = reader.ReadBytes(25); assets[i].Filename = AGSEncryption.DecryptJibzle(jibzler); } else { assets[i].Filename = reader.ReadFixedCString(25); } } for (int i = 0; i < assets.Length; ++i) { assets[i].Offset = reader.ReadInt32(); } for (int i = 0; i < assets.Length; ++i) { assets[i].Size = reader.ReadInt32(); } for (int i = 0; i < assets.Length; ++i) { assets[i].AssetFileIndex = reader.ReadByte(); } return(BuildAssetsLists(assets, ref files)); }
public static void WriteEncryptedCString(this BinaryWriter writer, string text) { byte[] buffer = AGSEncryption.EncryptAvis(text); writer.Write((Int32)buffer.Length); writer.Write((byte[])buffer); }