示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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));
        }
示例#4
0
        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));
        }
示例#5
0
        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));
        }
示例#6
0
        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);
            }
        }
示例#7
0
        //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));
        }
示例#8
0
 public static void WriteEncryptedCString(this BinaryWriter writer, string text)
 {
     byte[] buffer = AGSEncryption.EncryptAvis(text);
     writer.Write((Int32)buffer.Length);
     writer.Write((byte[])buffer);
 }