Beispiel #1
0
        public World(PackReader pack)
        {
            this.Regions = new List <Region>();

            Dictionary <int, PropClass> propClasses;

            using (var ms = pack.GetEntry(@"db\propdb.xml").GetDataAsStream())
                propClasses = PropClass.ReadFromXml(ms);

            FeaturesFile features;

            using (var ms = pack.GetEntry(@"features.xml.compiled").GetDataAsStream())
                features = new FeaturesFile(ms, "Regular, USA");

            using (var ms = pack.GetEntry(@"world\world.trn").GetDataAsStream())
                using (var trnReader = XmlReader.Create(ms))
                {
                    if (!trnReader.ReadToDescendant("regions"))
                    {
                        return;
                    }

                    using (var trnRegionsReader = trnReader.ReadSubtree())
                    {
                        var i = 1;
                        while (trnRegionsReader.ReadToFollowing("region"))
                        {
                            var workDir  = trnRegionsReader.GetAttribute("workdir");
                            var fileName = trnReader.GetAttribute("name");

                            Console.Write("\r".PadRight(70) + "\r");
                            Console.Write("Reading {0}: {1}...", i++, fileName);

                            var region = new Region(pack, workDir, fileName, propClasses, features);
                            this.Regions.Add(region);
                        }

                        Console.WriteLine("\r".PadRight(70) + "\r");
                    }
                }

            Regions = Regions.OrderBy(a => a.RegionId).ToList();
            Regions.ForEach(region =>
            {
                region.Areas = region.Areas.ToList();
                region.Areas.ForEach(area =>
                {
                    area.Props  = area.Props.OrderBy(prop => prop.PropId).ToList();
                    area.Events = area.Events.OrderBy(ev => ev.EventId).ToList();
                });
            });
        }
Beispiel #2
0
        public Region(PackReader pack, string workDir, string fileName, Dictionary <int, PropClass> propClasses, FeaturesFile features)
        {
            this.Areas = new List <Area>();

            var regionFilePath = Path.Combine("world", workDir, fileName + ".rgn");

            using (var ms = pack.GetEntry(regionFilePath).GetDataAsStream())
                using (var br = new BinaryReader(ms))
                {
                    Version = br.ReadInt32();
                    br.ReadInt32();             // Unk
                    RegionId   = br.ReadInt32();
                    GroupId    = br.ReadInt32();
                    ClientName = br.ReadUnicodeString();
                    CellSize   = br.ReadInt32();
                    Sight      = br.ReadByte();
                    var areaCount = br.ReadInt32();
                    br.Skip(0x34);             // Unk
                    AreaType   = br.ReadInt32();
                    IndoorType = br.ReadInt32();
                    br.Skip(0x4);             // Unk
                    Scene = br.ReadUnicodeString();
                    br.Skip(0x2D);            // Unk
                    Camera = br.ReadUnicodeString();
                    Light  = br.ReadUnicodeString();
                    br.Skip(0x0C);             // Unk

                    if (IndoorType != 100 && IndoorType != 200)
                    {
                        throw new Exception("Unknown indoor type.");
                    }

                    for (int i = 0; i < areaCount; ++i)
                    {
                        var areaName = br.ReadUnicodeString();
                        var area     = new Area(pack, workDir, areaName, propClasses, features);
                        Areas.Add(area);
                    }

                    br.Skip(0x1B);             // Unk
                    XML = br.ReadUnicodeString();
                }

            Name = ClientName;
            //Name = Name.Replace("Tin_Beginner_Tutorial", "tir_beginner");
            //Name = Name.Replace("Uladh_Cobh_to_Belfast", "cobh_to_belfast");
            //Name = Name.Replace("Uladh_Belfast_to_Cobh", "belfast_to_cobh");
            //Name = Name.Replace("Cobh_to_Belfast", "cobh_to_belfast_ocean");
            //Name = Name.Replace("Belfast_to_Cobh", "belfast_to_cobh_ocean");
            //Name = Name.Replace("MonsterRegion", "monster_region");
            //Name = Name.Replace("Uladh_main", "tir");
            //Name = Name.Replace("Uladh_TirCho_", "tir_");
            //Name = Name.Replace("Uladh_Dunbarton", "dunbarton");
            //Name = Name.Replace("Uladh_Dun_to_Tircho", "dugald_aisle");
            //Name = Name.Replace("Ula_Tirnanog", "tnn");
            //Name = Name.Replace("Ula_DgnHall_Dunbarton_before1", "rabbie_altar");
            //Name = Name.Replace("Ula_DgnHall_Dunbarton_before2", "math_altar");
            //Name = Name.Replace("MiscShop", "general");
            //Name = Name.Replace("tir_ChiefHouse", "tir_duncan");
            //Name = Name.Replace("Uladh_Dungeon_Black_Wolfs_Hall1", "ciar_altar");
            //Name = Name.Replace("Uladh_Dungeon_Black_Wolfs_Hall2", "ciar_entrance");
            //Name = Name.Replace("Uladh_Dungeon_Beginners_Hall1", "alby_altar");
            //Name = Name.Replace("Uladh_Cobh_harbor", "cobh");
            //Name = Name.Replace("Ula_DgnHall_Dunbarton_after", "rabbie_entrance");
            //Name = Name.Replace("Ula_hardmode_DgnHall_TirChonaill_before", "alby_hard_altar");
            //Name = Name.Replace("Ula_DgnArena_Tircho_Lobby", "alby_arena_lobby");
            //Name = Name.Replace("Ula_DgnArena_Tircho_Arena", "alby_arena");
            //Name = Name.Replace("Ula_Dun_to_Bangor", "gairech");
            //Name = Name.Replace("Ula_Bangor", "bangor");
            //Name = Name.Replace("Ula_DgnHall_Bangor_before1", "barri_altar");
            //Name = Name.Replace("Ula_DgnHall_Bangor_before2", "barri_entrance_test");
            //Name = Name.Replace("Ula_DgnHall_Bangor_after", "barri_entrance");
            //Name = Name.Replace("tnn_ChiefHouse", "tnn_duncan");
            //Name = Name.Replace("Ula_DgnHall_Tirnanog_before1", "albey_altar");
            //Name = Name.Replace("Ula_DgnHall_Tirnanog_before2", "albey_altar_test");
            //Name = Name.Replace("Ula_DgnHall_Tirnanog_after", "albey_altar_entrance");
            //Name = Name.Replace("Sidhe_Sneachta_S", "sidhe_north");
            //Name = Name.Replace("Sidhe_Sneachta_N", "sidhe_south");
            //Name = Name.Replace("Ula_DgnHall_Danu_before", "fiodh_altar");
            //Name = Name.Replace("Ula_DgnHall_Danu_after", "fiodh_entrance");
            //Name = Name.Replace("Ula_", "");
            //Name = Name.Replace("Emainmacha", "emain_macha");
            //Name = Name.Replace("DgnHall_Coill_before", "coill_altar");
            //Name = Name.Replace("DgnHall_Coill_after", "coill_entrance");
            //Name = Name.Replace("emain_macha_Ceo", "ceo");
            //Name = Name.Replace("DgnHall_Runda_before", "rundal_altar");
            //Name = Name.Replace("DgnHall_Runda_after", "rundal_entrance");
            //Name = Name.Replace("emain_macha_OidTobar_Hall", "ceo_cellar");
            //Name = Name.Replace("Studio_Runda", "studio_rundal_boss");
            //Name = Name.Replace("dunbarton_SchoolHall_before", "dunbarton_school_altar");
            //Name = Name.Replace("dunbarton_School_LectureRoom", "dunbarton_school_library");
            //Name = Name.Replace("Dgnhall_Peaca_before", "peaca_altar");
            //Name = Name.Replace("Dgnhall_Peaca_after", "peaca_entrance");
            //Name = Name.Replace("DgnHall_Tirnanog_G3_before", "baol_altar");
            //Name = Name.Replace("DgnHall_Tirnanog_G3_after", "baol_entrance");
            //Name = Name.Replace("Private_Wedding_waitingroom", "emain_macha_wedding_waiting");
            //Name = Name.Replace("Private_Wedding_ceremonialhall", "emain_macha_wedding_ceremony");
            //Name = Name.Replace("Dugald_Aisle_UserHouse", "dugald_userhouse");
            //Name = Name.Replace("tnn_G3_Gairech_Hill", "tnn_gairech");
            //Name = Name.Replace("Dugald_Aisle_UserCastleTest1", "user_castle_test_1");
            //Name = Name.Replace("Dugald_Aisle_UserCastleTest2", "user_castle_test_2");
            //Name = Name.Replace("tnn_G3", "tnn_bangor");
            //Name = Regex.Replace(Name, "_TestRegion([0-9]+)", "test_region_$1");
            //Name = Regex.Replace(Name, "dugald_userhouse_int_([0-9]+)", "user_house_int_$1");
            //Name = Name.Replace("Dugald_Aisle_UserCastle_", "user_castle_");
            //Name = Name.Replace("Dugald_Aisle_ModelHouse", "model_house");
            //Name = Name.Replace("DgnArena_Dunbarton_Arena", "rabbie_battle_arena");
            //Name = Name.Replace("DgnArena_Dunbarton_Lobby", "rabbie_battle_arena_lobby");
            //Name = Name.Replace("DgnArena_Dunbarton_waitingroom", "rabbie_battle_arena_waiting");
            //Name = Name.Replace("Iria_Harbor_01", "iria_harbor");
            //Name = Name.Replace("Iria_SW_ruins_DG_before", "rano_ruins_altar");
            //Name = Name.Replace("Iria_SW_ruins_DG_after", "rano_ruins_entrance");
            //Name = Name.Replace("ArenaTest0", "arena_test_0");
            //Name = Name.Replace("Loginstage_0", "login_stage_0");
            //Name = Name.Replace("Iria_NN_dragoncave01", "renes");
            //Name = Name.Replace("hardmode_DgnHall_TirChonaill_after", "alby_hard_entrance");
            //Name = Name.Replace("hardmode_DgnHall_Ciar_before", "ciar_hard_altar");
            //Name = Name.Replace("hardmode_DgnHall_Ciar_after", "ciar_hard_entrance");
            //Name = Name.Replace("hardmode_rundal_altar", "rundal_hard_altar");
            //Name = Name.Replace("hardmode_rundal_entrance", "rundal_hard_entrance");
            //Name = Name.Replace("Uladh_Cobh", "cobh");
            //Name = Name.Replace("Dunbarton_LectureRoom", "dunbarton_school_library");
            //Name = Name.Replace("OidTobar_Hall", "ceo_cellar");
            //Name = Name.Replace("Dugald_Aisle_Town", "dugald_residential");
            //Name = Name.Replace("_Keep", "_castle_entrance");
            //Name = Name.Replace("Dugald_Aisle", "dugald");
            //Name = Name.Replace("keep_DgnHall_after", "dungeon_altar");
            //Name = Name.Replace("keep_DgnHall_before", "dungeon_entrance");
            //Name = Name.Replace("Studio_keep_DG", "studio_residential");
            //Name = Name.Replace("Housing_CharDummyStage", "housing_dummy");
            //Name = Name.Replace("Private_giant_Wedding_ceremonialhall", "vales_wedding_ceremony");
            //Name = Name.Replace("Private_giant_Wedding_waitingroom", "vales_wedding_waiting");
            //Name = Name.Replace("Private_Promotion_testRoom_waiting", "advancement_test_waiting");
            //Name = Name.Replace("Private_Promotion_testRoom", "advancement_test");
            //Name = Regex.Replace(Name, "_town$", "_residential");
            //Name = Name.Replace("Soulstream", "soul_stream");
            //Name = Name.Replace("soul_stream_region", "soul_stream_battle");
            //Name = Name.Replace("taillteann_main_field", "taillteann");
            //Name = Name.Replace("Taillteann_E_field", "sliab_cuilin");
            //Name = Name.Replace("Taillteann_SE_field", "abb_neagh");
            //Name = Name.Replace("Tara_N_Field", "comb_valley");
            //Name = Name.Replace("Tara_main_field", "tara");
            //Name = Name.Replace("Tara_SE_Field", "blago_prairie");
            //Name = Name.Replace("Tara_tournament_field", "tara_jousting");
            //Name = Name.Replace("Tara_cloth", "tara_clothing");
            //Name = Regex.Replace(Name, "_misc$", "_general");
            //Name = Name.Replace("Falias_main_field", "falias");
            //Name = Name.Replace("Avon_main_field", "avon");
            //Name = Name.Replace("JP_Nekojima_islet", "nekojima");
            //Name = Name.Replace("JP_Nekojima_dungeon_hall_after", "nekojima_dungeon_entrance");
            //Name = Name.Replace("JP_Nekojima", "nekojima");
            //Name = Name.Replace("TirnanogDG", "Tirnanog_DG");
            //Name = Name.Replace("Tirnanog", "tnn");
            //Name = Name.Replace("Nao_tutorial", "soul_stream");
            //Name = Name.Replace("G1_GoddessStage", "morrighan");
            //Name = Name.Replace("Event_moonsurface", "event_moon");
            //Name = Name.Replace("pvp_event", "event_pvp");
            //Name = Name.Replace("Event", "event");
            //Name = Name.Replace("event_impdream", "event_imp_dream");
            //Name = Name.Replace("Iria_SW_main_field", "rano");
            //Name = Name.Replace("Iria_Uladh_Ocean_fishingboat_float", "rano_fishing_boat");
            //Name = Name.Replace("Iria_to_fishingboat", "rano_to_fishingboat");
            //Name = Name.Replace("fishingboat_to_Iria", "fishingboat_to_rano");
            //Name = Name.Replace("Iria_SE_main_field", "connous");
            //Name = Name.Replace("Iria_SE_Desert_underground", "ant_tunnel");
            //Name = Name.Replace("Iria_SE", "filia");
            //Name = Name.Replace("Iria_NW", "physis");
            //Name = Name.Replace("Iria_SW", "rano");
            //Name = Name.Replace("MineField", "mine_field");
            //Name = Name.Replace("monsterraid01", "monster_raid");
            //Name = Name.Replace("ElfArena", "arena");
            //Name = Name.Replace("Iria_Elf", "elf");
            //Name = Name.Replace("physis_main_field", "physis");
            //Name = Name.Replace("physis_tunnel_S", "physis_tunnel_south");
            //Name = Name.Replace("physis_tunnel_N", "physis_tunnel_north");
            //Name = Name.Replace("physis_tunnel_Outside", "solea");
            //Name = Name.Replace("physis_Tutorial", "giant_tutorial");
            //Name = Name.Replace("Studio", "studio");
            //Name = Name.Replace("_mineB", "_mine_B");
            //Name = Name.Replace("Iria_C", "courcle");
            //Name = Name.Replace("Iria_NN", "zardine");
            //Name = Name.Replace("_main_field", "");
            //Name = Name.Replace("Belfast_human", "belfast");
            //Name = Name.Replace("Qwest", "quest");
            //Name = Name.Replace("Belfast_Skatha", "scathach");
            //Name = Name.Replace("physis_glacier01_DG", "par");
            //Name = Name.Replace("par_after", "par_altar");
            //Name = Name.Replace("par_before", "par_entrance");
            //Name = Name.Replace("Test01", "test_01");
            //Name = Name.Replace("Test02", "test_02");
            //Name = Name.Replace("Tara_keep_RG", "tara_castle");
            //Name = Name.Replace("Tara_town_RG", "tara_residential");
            //Name = Name.Replace("_TestRegion", "gm_island");
            //Name = Regex.Replace(Name, "_Cloth$", "_clothing");
            //Name = Name.Replace("filia_Desert_01_DG_after", "longa_altar");
            //Name = Name.Replace("filia_Desert_01_DG_before", "longa_entrance");
            //Name = Name.Replace("Private_igloo_01", "igloo");
            //Name = Name.Replace("BlockRegion", "block_region");
            //Name = Name.Replace("soul_stream_past_region", "soul_stream_past");
            //Name = Name.Replace("soul_stream_future_region", "soul_stream_future");
            //Name = Name.Replace("RE_Nekojima_islet", "doki_doki_island");
            //Name = Name.Replace("DramaIriaS2", "drama_iria_s2");

            //Name = Name.ToLower();
        }
Beispiel #3
0
        public Area(PackReader pack, string workDir, string fileName, Dictionary <int, PropClass> propClasses, FeaturesFile features)
        {
            this.Props  = new List <Prop>();
            this.Events = new List <Event>();

            var areaFilePath = Path.Combine("world", workDir, fileName + ".area");

            using (var ms = pack.GetEntry(areaFilePath).GetDataAsStream())
                using (var br = new BinaryReader(ms))
                {
                    Version = br.ReadInt16();
                    if (Version < 202)
                    {
                        throw new Exception("Invalid file version.");
                    }

                    br.Skip(0x02);                 // Unk
                    br.Skip(0x04);                 // Unk
                    AreaId = br.ReadInt16();
                    var regionId = br.ReadInt16(); // Unk
                    Server = br.ReadUnicodeString();
                    Name   = br.ReadUnicodeString();
                    br.Skip(0x10);             // Unk
                    var eventCount = br.ReadInt32();
                    var propCount  = br.ReadInt32();
                    br.Skip(0x14);             // Unk
                    X1 = br.ReadSingle();
                    br.Skip(0x04);             // Unk
                    Y1 = br.ReadSingle();
                    br.Skip(0x0C);             // Unk
                    X2 = br.ReadSingle();
                    br.Skip(0x04);             // Unk
                    Y2 = br.ReadSingle();
                    br.Skip(0x0C);             // Unk
                    if (Version == 203)
                    {
                        br.Skip(0x04);                 // Unk
                    }
                    var ver = br.ReadInt16();
                    br.Skip(0x02);             // Unk
                    var propCountCheck = br.ReadInt32();
                    if (ver < 202 || propCount != propCountCheck)
                    {
                        throw new Exception("Reading error.");
                    }

                    for (int i = 0; i < propCount; ++i)
                    {
                        var prop = this.ReadProp(br);

                        // Get prop data for features check
                        PropClass cls;
                        if (!propClasses.TryGetValue(prop.ClassId, out cls))
                        {
                            throw new Exception("Unknown prop class.");
                        }

                        //if (prop.ClassId == 44824)
                        //	Console.WriteLine("asd");

                        // Check feature
                        var feature = cls.GetExtra("feature");
                        var enabled = true;
                        if (!string.IsNullOrWhiteSpace(feature))
                        {
                            var found = false;

                            // Check for features that aren't in the features file
                            foreach (var nf in new string[] { "bossrush", "dungeonrenewal", "partyboard" })
                            {
                                if (feature == "-" + nf)
                                {
                                    enabled = false;
                                    found   = true;
                                    break;
                                }
                                else if (feature == nf)
                                {
                                    enabled = true;
                                    found   = true;
                                    break;
                                }
                            }

                            if (!found)
                            {
                                enabled = features.IsEnabled(feature);
                            }
                        }

                        // Even with the feature check a few props slip through,
                        // it's unknown how the client decides not to load those.
                        // However, those I found so far all had the /event/ tag
                        // and UsedServer.
                        //
                        // South Tir Chonaill
                        //   41146, scene_prop_mapletree_01
                        //   41963, scene_prop_memory_tree_01
                        //   41288, scene_prop_cherrytree_01
                        //   42340, scene_prop_balloon_01
                        //
                        // Dunbarton Square
                        //   41625, scene_prop_christmas_2008_light_03
                        //
                        // I don't know why the area files would contain props
                        // that are never loaded and expected to come from the
                        // server, but for now the following check seems to work
                        // fine.
                        //
                        // As of the time of this comment 120 props are excluded
                        // via feature check, plus 76 by the event check.
                        if (cls.StringID.Contains("/event/") && cls.UsedServer)
                        {
                            enabled = false;
                        }

                        if (!enabled)
                        {
                            //File.AppendAllText("test.txt", cls.ClassID + ", " + cls.ClassName + ", " + cls.StringID + ", " + cls.UsedServer + Environment.NewLine);
                            continue;
                        }

                        this.Props.Add(prop);
                    }

                    for (int i = 0; i < eventCount; ++i)
                    {
                        var ev = new Event();
                        this.Events.Add(ev);

                        ev.EventId = br.ReadInt64();
                        ev.Name    = br.ReadUnicodeString();
                        ev.X       = br.ReadSingle();
                        ev.Y       = br.ReadSingle();
                        br.Skip(0x04);                 // Unk (Z?)
                        var shapeCount = br.ReadByte();
                        br.Skip(0x04);                 // Unk

                        for (int j = 0; j < shapeCount; ++j)
                        {
                            var shape = new Shape();
                            shape.DirX1 = br.ReadSingle();
                            shape.DirX2 = br.ReadSingle();
                            shape.DirY1 = br.ReadSingle();
                            shape.DirY2 = br.ReadSingle();
                            shape.LenX  = br.ReadSingle();
                            shape.LenY  = br.ReadSingle();
                            var shapeType = br.ReadInt32();
                            shape.PosX = br.ReadSingle();
                            shape.PosY = br.ReadSingle();
                            br.Skip(0x10);                     // Unk

                            ev.Shapes.Add(shape);
                        }

                        ev.EventType = br.ReadInt32();
                        var parameterCount = br.ReadByte();
                        for (int k = 0; k < parameterCount; ++k)
                        {
                            var def        = br.ReadByte();
                            var eventType  = br.ReadInt32();
                            var signalType = br.ReadInt32();
                            var name       = br.ReadUnicodeString();
                            var xml        = br.ReadUnicodeString();

                            ev.Parameters.Add(new PropParameter(eventType, signalType, name, xml));
                        }
                    }
                }
        }