Пример #1
0
        private static void LoadItems(BinaryFileReader reader,
                                      ItemEntry[] entries)
        {
            for (int i = 0; i < entries.Length; ++i)
            {
                ItemEntry entry = entries[i];
                Item      item  = (Item)entry.Object;
                if (item == null)
                {
                    continue;
                }

                reader.Seek(entry.Position, SeekOrigin.Begin);

                try {
                    m_LoadingType = entry.TypeName;
                    item.Deserialize(reader);
                } catch (Exception e) {
                    log.Error(String.Format("failed to load item {0}", item),
                              e);
                    item.Delete();
                    entries[i].Clear();
                    ++m_LoadErrors;
                    continue;
                }

                if (reader.Position != entry.Position + entry.Length)
                {
                    log.ErrorFormat("Bad deserialize on item {0}, type {1}: position={2}, should be {3}",
                                    entry.Serial, entry.TypeName,
                                    reader.Position, entry.Position + entry.Length);
                    item.Delete();
                    entries[i].Clear();
                    ++m_LoadErrors;
                }
            }
        }
Пример #2
0
        public static void Load()
        {
            if (m_Loaded)
            {
                return;
            }

            m_Loaded      = true;
            m_LoadingType = null;

            Console.Write("World: Loading...");

            Stopwatch watch = Stopwatch.StartNew();

            m_Loading = true;

            _addQueue    = new Queue <IEntity>();
            _deleteQueue = new Queue <IEntity>();

            int mobileCount = 0, itemCount = 0, guildCount = 0;

            object[] ctorArgs = new object[1];

            List <ItemEntry>   items   = new List <ItemEntry>();
            List <MobileEntry> mobiles = new List <MobileEntry>();
            List <GuildEntry>  guilds  = new List <GuildEntry>();

            if (File.Exists(MobileIndexPath) && File.Exists(MobileTypesPath))
            {
                using (FileStream idx = new FileStream(MobileIndexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryReader idxReader = new BinaryReader(idx);

                    using (FileStream tdb = new FileStream(MobileTypesPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        BinaryReader tdbReader = new BinaryReader(tdb);

                        List <object[]> types = ReadTypes(tdbReader);

                        mobileCount = idxReader.ReadInt32();

                        m_Mobiles = new Dictionary <Serial, Mobile>(mobileCount);

                        for (int i = 0; i < mobileCount; ++i)
                        {
                            int  typeID = idxReader.ReadInt32();
                            int  serial = idxReader.ReadInt32();
                            long pos    = idxReader.ReadInt64();
                            int  length = idxReader.ReadInt32();

                            object[] objs = types[typeID];

                            if (objs == null)
                            {
                                continue;
                            }

                            Mobile          m        = null;
                            ConstructorInfo ctor     = ( ConstructorInfo )objs[0];
                            string          typeName = ( string )objs[1];

                            try {
                                ctorArgs[0] = ( Serial )serial;
                                m           = ( Mobile )(ctor.Invoke(ctorArgs));
                            } catch {
                            }

                            if (m != null)
                            {
                                mobiles.Add(new MobileEntry(m, typeID, typeName, pos, length));
                                AddMobile(m);
                            }
                        }

                        tdbReader.Close();
                    }

                    idxReader.Close();
                }
            }
            else
            {
                m_Mobiles = new Dictionary <Serial, Mobile>();
            }

            if (File.Exists(ItemIndexPath) && File.Exists(ItemTypesPath))
            {
                using (FileStream idx = new FileStream(ItemIndexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryReader idxReader = new BinaryReader(idx);

                    using (FileStream tdb = new FileStream(ItemTypesPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        BinaryReader tdbReader = new BinaryReader(tdb);

                        List <object[]> types = ReadTypes(tdbReader);

                        itemCount = idxReader.ReadInt32();

                        m_Items = new Dictionary <Serial, Item>(itemCount);

                        for (int i = 0; i < itemCount; ++i)
                        {
                            int  typeID = idxReader.ReadInt32();
                            int  serial = idxReader.ReadInt32();
                            long pos    = idxReader.ReadInt64();
                            int  length = idxReader.ReadInt32();

                            object[] objs = types[typeID];

                            if (objs == null)
                            {
                                continue;
                            }

                            Item            item     = null;
                            ConstructorInfo ctor     = ( ConstructorInfo )objs[0];
                            string          typeName = ( string )objs[1];

                            try {
                                ctorArgs[0] = ( Serial )serial;
                                item        = ( Item )(ctor.Invoke(ctorArgs));
                            } catch {
                            }

                            if (item != null)
                            {
                                items.Add(new ItemEntry(item, typeID, typeName, pos, length));
                                AddItem(item);
                            }
                        }

                        tdbReader.Close();
                    }

                    idxReader.Close();
                }
            }
            else
            {
                m_Items = new Dictionary <Serial, Item>();
            }

            if (File.Exists(GuildIndexPath))
            {
                using (FileStream idx = new FileStream(GuildIndexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryReader idxReader = new BinaryReader(idx);

                    guildCount = idxReader.ReadInt32();

                    CreateGuildEventArgs createEventArgs = new CreateGuildEventArgs(-1);
                    for (int i = 0; i < guildCount; ++i)
                    {
                        idxReader.ReadInt32();                        //no typeid for guilds
                        int  id     = idxReader.ReadInt32();
                        long pos    = idxReader.ReadInt64();
                        int  length = idxReader.ReadInt32();

                        createEventArgs.Id = id;
                        EventSink.InvokeCreateGuild(createEventArgs);
                        BaseGuild guild = createEventArgs.Guild;
                        if (guild != null)
                        {
                            guilds.Add(new GuildEntry(guild, pos, length));
                        }
                    }

                    idxReader.Close();
                }
            }

            bool      failedMobiles = false, failedItems = false, failedGuilds = false;
            Type      failedType   = null;
            Serial    failedSerial = Serial.Zero;
            Exception failed       = null;
            int       failedTypeID = 0;

            if (File.Exists(MobileDataPath))
            {
                using (FileStream bin = new FileStream(MobileDataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < mobiles.Count; ++i)
                    {
                        MobileEntry entry = mobiles[i];
                        Mobile      m     = entry.Mobile;

                        if (m != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try {
                                m_LoadingType = entry.TypeName;
                                m.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", m.GetType()));
                                }
                            } catch (Exception e) {
                                mobiles.RemoveAt(i);

                                failed        = e;
                                failedMobiles = true;
                                failedType    = m.GetType();
                                failedTypeID  = entry.TypeID;
                                failedSerial  = m.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (!failedMobiles && File.Exists(ItemDataPath))
            {
                using (FileStream bin = new FileStream(ItemDataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < items.Count; ++i)
                    {
                        ItemEntry entry = items[i];
                        Item      item  = entry.Item;

                        if (item != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try {
                                m_LoadingType = entry.TypeName;
                                item.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", item.GetType()));
                                }
                            } catch (Exception e) {
                                items.RemoveAt(i);

                                failed       = e;
                                failedItems  = true;
                                failedType   = item.GetType();
                                failedTypeID = entry.TypeID;
                                failedSerial = item.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            m_LoadingType = null;

            if (!failedMobiles && !failedItems && File.Exists(GuildDataPath))
            {
                using (FileStream bin = new FileStream(GuildDataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < guilds.Count; ++i)
                    {
                        GuildEntry entry = guilds[i];
                        BaseGuild  g     = entry.Guild;

                        if (g != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try {
                                g.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on Guild {0} *****", g.Id));
                                }
                            } catch (Exception e) {
                                guilds.RemoveAt(i);

                                failed       = e;
                                failedGuilds = true;
                                failedType   = typeof(BaseGuild);
                                failedTypeID = g.Id;
                                failedSerial = g.Id;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (failedItems || failedMobiles || failedGuilds)
            {
                Console.WriteLine("An error was encountered while loading a saved object");

                Console.WriteLine(" - Type: {0}", failedType);
                Console.WriteLine(" - Serial: {0}", failedSerial);

                if (!Core.Service)
                {
                    Console.WriteLine("Delete the object? (y/n)");

                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                    {
                        if (failedType != typeof(BaseGuild))
                        {
                            Console.WriteLine("Delete all objects of that type? (y/n)");

                            if (Console.ReadKey(true).Key == ConsoleKey.Y)
                            {
                                if (failedMobiles)
                                {
                                    for (int i = 0; i < mobiles.Count;)
                                    {
                                        if (mobiles[i].TypeID == failedTypeID)
                                        {
                                            mobiles.RemoveAt(i);
                                        }
                                        else
                                        {
                                            ++i;
                                        }
                                    }
                                }
                                else if (failedItems)
                                {
                                    for (int i = 0; i < items.Count;)
                                    {
                                        if (items[i].TypeID == failedTypeID)
                                        {
                                            items.RemoveAt(i);
                                        }
                                        else
                                        {
                                            ++i;
                                        }
                                    }
                                }
                            }
                        }

                        SaveIndex <MobileEntry>(mobiles, MobileIndexPath);
                        SaveIndex <ItemEntry>(items, ItemIndexPath);
                        SaveIndex <GuildEntry>(guilds, GuildIndexPath);
                    }

                    Console.WriteLine("After pressing return an exception will be thrown and the server will terminate.");
                    Console.ReadLine();
                }
                else
                {
                    Console.WriteLine("An exception will be thrown and the server will terminate.");
                }

                throw new Exception(String.Format("Load failed (items={0}, mobiles={1}, guilds={2}, type={3}, serial={4})", failedItems, failedMobiles, failedGuilds, failedType, failedSerial), failed);
            }

            EventSink.InvokeWorldLoad();

            m_Loading = false;

            ProcessSafetyQueues();

            foreach (Item item in m_Items.Values)
            {
                if (item.Parent == null)
                {
                    item.UpdateTotals();
                }

                item.ClearProperties();
            }

            foreach (Mobile m in m_Mobiles.Values)
            {
                m.UpdateRegion();                 // Is this really needed?
                m.UpdateTotals();

                m.ClearProperties();
            }

            watch.Stop();

            Console.WriteLine("done ({1} items, {2} mobiles) ({0:F2} seconds)", watch.Elapsed.TotalSeconds, m_Items.Count, m_Mobiles.Count);
        }
Пример #3
0
        public static void Load()
        {
            if (m_Loaded)
            {
                return;
            }

            m_Loaded      = true;
            m_LoadingType = null;

            Console.Write("World: Loading...");

            DateTime start = DateTime.Now;

            m_Loading    = true;
            m_DeleteList = new ArrayList();

            int mobileCount = 0, itemCount = 0, guildCount = 0, regionCount = 0;

            object[] ctorArgs  = new object[1];
            Type[]   ctorTypes = new Type[1] {
                typeof(Serial)
            };

            ArrayList items   = new ArrayList();
            ArrayList mobiles = new ArrayList();
            ArrayList guilds  = new ArrayList();
            ArrayList regions = new ArrayList();

            if (File.Exists(mobIdxPath) && File.Exists(mobTdbPath))
            {
                using (FileStream idx = new FileStream(mobIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    using (FileStream tdb = new FileStream(mobTdbPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        BinaryReader tdbReader = new BinaryReader(tdb);

                        int count = tdbReader.ReadInt32();

                        ArrayList types = new ArrayList(count);

                        for (int i = 0; i < count; ++i)
                        {
                            string typeName = tdbReader.ReadString();

                            Type t = ScriptCompiler.FindTypeByFullName(typeName);

                            if (t == null)
                            {
                                Console.WriteLine("failed");
                                Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName);

                                if (Console.ReadLine() == "y")
                                {
                                    types.Add(null);
                                    Console.Write("World: Loading...");
                                    continue;
                                }

                                Console.WriteLine("Types will not be deleted. An exception will be thrown when you press return");

                                throw new Exception(String.Format("Bad type '{0}'", typeName));
                            }

                            ConstructorInfo ctor = t.GetConstructor(ctorTypes);

                            if (ctor != null)
                            {
                                types.Add(new object[] { ctor, null });
                            }
                            else
                            {
                                throw new Exception(String.Format("Type '{0}' does not have a serialization constructor", t));
                            }
                        }

                        mobileCount = idxReader.ReadInt32();

                        m_Mobiles = new Hashtable(mobileCount);

                        for (int i = 0; i < mobileCount; ++i)
                        {
                            int  typeID = idxReader.ReadInt32();
                            int  serial = idxReader.ReadInt32();
                            long pos    = idxReader.ReadInt64();
                            int  length = idxReader.ReadInt32();

                            object[] objs = (object[])types[typeID];

                            if (objs == null)
                            {
                                continue;
                            }

                            Mobile          m        = null;
                            ConstructorInfo ctor     = (ConstructorInfo)objs[0];
                            string          typeName = (string)objs[1];

                            try
                            {
                                ctorArgs[0] = (Serial)serial;
                                m           = (Mobile)(ctor.Invoke(ctorArgs));
                            }
                            catch
                            {
                            }

                            if (m != null)
                            {
                                mobiles.Add(new MobileEntry(m, typeID, typeName, pos, length));
                                AddMobile(m);
                            }
                        }

                        tdbReader.Close();
                    }

                    idxReader.Close();
                }
            }
            else
            {
                m_Mobiles = new Hashtable();
            }

            if (File.Exists(itemIdxPath) && File.Exists(itemTdbPath))
            {
                using (FileStream idx = new FileStream(itemIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    using (FileStream tdb = new FileStream(itemTdbPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        BinaryReader tdbReader = new BinaryReader(tdb);

                        int count = tdbReader.ReadInt32();

                        ArrayList types = new ArrayList(count);

                        for (int i = 0; i < count; ++i)
                        {
                            string typeName = tdbReader.ReadString();

                            Type t = ScriptCompiler.FindTypeByFullName(typeName);

                            if (t == null)
                            {
                                Console.WriteLine("failed");
                                Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName);

                                if (Console.ReadLine() == "y")
                                {
                                    types.Add(null);
                                    Console.Write("World: Loading...");
                                    continue;
                                }

                                Console.WriteLine("Types will not be deleted. An exception will be thrown when you press return");

                                throw new Exception(String.Format("Bad type '{0}'", typeName));
                            }

                            ConstructorInfo ctor = t.GetConstructor(ctorTypes);

                            if (ctor != null)
                            {
                                types.Add(new object[] { ctor, typeName });
                            }
                            else
                            {
                                throw new Exception(String.Format("Type '{0}' does not have a serialization constructor", t));
                            }
                        }

                        itemCount = idxReader.ReadInt32();

                        m_Items = new Hashtable(itemCount);

                        for (int i = 0; i < itemCount; ++i)
                        {
                            int  typeID = idxReader.ReadInt32();
                            int  serial = idxReader.ReadInt32();
                            long pos    = idxReader.ReadInt64();
                            int  length = idxReader.ReadInt32();

                            object[] objs = (object[])types[typeID];

                            if (objs == null)
                            {
                                continue;
                            }

                            Item            item     = null;
                            ConstructorInfo ctor     = (ConstructorInfo)objs[0];
                            string          typeName = (string)objs[1];

                            try
                            {
                                ctorArgs[0] = (Serial)serial;
                                item        = (Item)(ctor.Invoke(ctorArgs));
                            }
                            catch
                            {
                            }

                            if (item != null)
                            {
                                items.Add(new ItemEntry(item, typeID, typeName, pos, length));
                                AddItem(item);
                            }
                        }

                        tdbReader.Close();
                    }

                    idxReader.Close();
                }
            }
            else
            {
                m_Items = new Hashtable();
            }

            if (File.Exists(guildIdxPath))
            {
                using (FileStream idx = new FileStream(guildIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    guildCount = idxReader.ReadInt32();

                    CreateGuildEventArgs createEventArgs = new CreateGuildEventArgs(-1);
                    for (int i = 0; i < guildCount; ++i)
                    {
                        idxReader.ReadInt32();                        //no typeid for guilds
                        int  id     = idxReader.ReadInt32();
                        long pos    = idxReader.ReadInt64();
                        int  length = idxReader.ReadInt32();

                        createEventArgs.Id = id;
                        BaseGuild guild = EventSink.InvokeCreateGuild(createEventArgs);                          //new Guild( id );
                        if (guild != null)
                        {
                            guilds.Add(new GuildEntry(guild, pos, length));
                        }
                    }

                    idxReader.Close();
                }
            }

            if (File.Exists(regionIdxPath))
            {
                using (FileStream idx = new FileStream(regionIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    regionCount = idxReader.ReadInt32();

                    for (int i = 0; i < regionCount; ++i)
                    {
                        int  typeID = idxReader.ReadInt32();
                        int  serial = idxReader.ReadInt32();
                        long pos    = idxReader.ReadInt64();
                        int  length = idxReader.ReadInt32();

                        Region r = Region.FindByUId(serial);

                        if (r != null)
                        {
                            regions.Add(new RegionEntry(r, pos, length));
                            Region.AddRegion(r);
                            regionCount++;
                        }
                    }

                    idxReader.Close();
                }
            }

            bool      failedMobiles = false, failedItems = false, failedGuilds = false, failedRegions = false;
            Type      failedType   = null;
            Serial    failedSerial = Serial.Zero;
            Exception failed       = null;
            int       failedTypeID = 0;

            if (File.Exists(mobBinPath))
            {
                using (FileStream bin = new FileStream(mobBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < mobiles.Count; ++i)
                    {
                        MobileEntry entry = (MobileEntry)mobiles[i];
                        Mobile      m     = (Mobile)entry.Object;

                        if (m != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                m_LoadingType = entry.TypeName;
                                m.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", m.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                mobiles.RemoveAt(i);

                                failed        = e;
                                failedMobiles = true;
                                failedType    = m.GetType();
                                failedTypeID  = entry.TypeID;
                                failedSerial  = m.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (!failedMobiles && File.Exists(itemBinPath))
            {
                using (FileStream bin = new FileStream(itemBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < items.Count; ++i)
                    {
                        ItemEntry entry = (ItemEntry)items[i];
                        Item      item  = (Item)entry.Object;

                        if (item != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                m_LoadingType = entry.TypeName;
                                item.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", item.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                items.RemoveAt(i);

                                failed       = e;
                                failedItems  = true;
                                failedType   = item.GetType();
                                failedTypeID = entry.TypeID;
                                failedSerial = item.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            m_LoadingType = null;

            if (!failedMobiles && !failedItems && File.Exists(guildBinPath))
            {
                using (FileStream bin = new FileStream(guildBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < guilds.Count; ++i)
                    {
                        GuildEntry entry = (GuildEntry)guilds[i];
                        BaseGuild  g     = (BaseGuild)entry.Object;

                        if (g != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                g.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on Guild {0} *****", g.Id));
                                }
                            }
                            catch (Exception e)
                            {
                                guilds.RemoveAt(i);

                                failed       = e;
                                failedGuilds = true;
                                failedType   = typeof(BaseGuild);
                                failedTypeID = g.Id;
                                failedSerial = g.Id;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (!failedMobiles && !failedItems && File.Exists(regionBinPath))
            {
                using (FileStream bin = new FileStream(regionBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < regions.Count; ++i)
                    {
                        RegionEntry entry = (RegionEntry)regions[i];
                        Region      r     = (Region)entry.Object;

                        if (r != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                r.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", r.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                regions.RemoveAt(i);

                                failed        = e;
                                failedRegions = true;
                                failedType    = r.GetType();
                                failedTypeID  = entry.TypeID;
                                failedSerial  = r.UId;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (failedItems || failedMobiles || failedGuilds || failedRegions)
            {
                Console.WriteLine("An error was encountered while loading a saved object");

                Console.WriteLine(" - Type: {0}", failedType);
                Console.WriteLine(" - Serial: {0}", failedSerial);

                Console.WriteLine("Delete the object? (y/n)");

                if (Console.ReadLine() == "y")
                {
                    if (failedType != typeof(BaseGuild) && !failedType.IsSubclassOf(typeof(Region)))
                    {
                        Console.WriteLine("Delete all objects of that type? (y/n)");

                        if (Console.ReadLine() == "y")
                        {
                            if (failedMobiles)
                            {
                                for (int i = 0; i < mobiles.Count;)
                                {
                                    if (((MobileEntry)mobiles[i]).TypeID == failedTypeID)
                                    {
                                        mobiles.RemoveAt(i);
                                    }
                                    else
                                    {
                                        ++i;
                                    }
                                }
                            }
                            else if (failedItems)
                            {
                                for (int i = 0; i < items.Count;)
                                {
                                    if (((ItemEntry)items[i]).TypeID == failedTypeID)
                                    {
                                        items.RemoveAt(i);
                                    }
                                    else
                                    {
                                        ++i;
                                    }
                                }
                            }
                        }
                    }

                    SaveIndex(mobiles, mobIdxPath);
                    SaveIndex(items, itemIdxPath);
                    SaveIndex(guilds, guildIdxPath);
                    SaveIndex(regions, regionIdxPath);
                }

                Console.WriteLine("After pressing return an exception will be thrown and the server will terminate");
                Console.ReadLine();

                throw new Exception(String.Format("Load failed (items={0}, mobiles={1}, guilds={2}, regions={3}, type={4}, serial={5})", failedItems, failedMobiles, failedGuilds, failedRegions, failedType, failedSerial), failed);
            }

            EventSink.InvokeWorldLoad();

            m_Loading = false;

            for (int i = 0; i < m_DeleteList.Count; ++i)
            {
                object o = m_DeleteList[i];

                if (o is Item)
                {
                    ((Item)o).Delete();
                }
                else if (o is Mobile)
                {
                    ((Mobile)o).Delete();
                }
            }

            m_DeleteList.Clear();

            foreach (Item item in m_Items.Values)
            {
                if (item.Parent == null)
                {
                    item.UpdateTotals();
                }

                item.ClearProperties();
            }

            ArrayList list = new ArrayList(m_Mobiles.Values);

            foreach (Mobile m in list)
            {
                m.ForceRegionReEnter(true);
                m.UpdateTotals();

                m.ClearProperties();
            }

            Console.WriteLine("done ({1} items, {2} mobiles) ({0:F1} seconds)", (DateTime.Now - start).TotalSeconds, m_Items.Count, m_Mobiles.Count);
        }
Пример #4
0
        private static void LoadEntities()
        {
            ItemEntry[]   itemEntries   = null;
            MobileEntry[] mobileEntries = null;
            GuildEntry[]  guildEntries  = null;
            RegionEntry[] regionEntries = null;

            if (File.Exists(mobIdxPath) && File.Exists(mobTdbPath))
            {
                log.Debug("loading mobile index");
                EntityType[] types = LoadTypes(mobTdbPath);
                mobileEntries = LoadMobileIndex(mobIdxPath, types);
            }
            else
            {
                m_Mobiles = new Hashtable();
            }

            if (File.Exists(itemIdxPath) && File.Exists(itemTdbPath))
            {
                log.Debug("loading item index");
                EntityType[] types = LoadTypes(itemTdbPath);
                itemEntries = LoadItemIndex(itemIdxPath, types);
            }
            else
            {
                m_Items = new Hashtable();
            }

            if (File.Exists(guildIdxPath))
            {
                log.Debug("loading guild index");

                using (FileStream idx = new FileStream(guildIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    int count = idxReader.ReadInt32();
                    guildEntries = new GuildEntry[count];

                    CreateGuildEventArgs createEventArgs = new CreateGuildEventArgs(-1);
                    for (int i = 0; i < count; ++i)
                    {
                        idxReader.ReadInt32();                        //no typeid for guilds
                        int  id     = idxReader.ReadInt32();
                        long pos    = idxReader.ReadInt64();
                        int  length = idxReader.ReadInt32();

                        createEventArgs.Id = id;
                        BaseGuild guild = EventSink.InvokeCreateGuild(createEventArgs);                          //new Guild( id );
                        if (guild != null)
                        {
                            guildEntries[i] = new GuildEntry(guild, pos, length);
                        }
                    }

                    idxReader.Close();
                }
            }

            if (File.Exists(regionIdxPath))
            {
                log.Debug("loading region index");

                using (FileStream idx = new FileStream(regionIdxPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader idxReader = new BinaryReader(idx);

                    int count = idxReader.ReadInt32();
                    regionEntries = new RegionEntry[count];

                    for (int i = 0; i < count; ++i)
                    {
                        idxReader.ReadInt32();                         /* typeID */
                        int  serial = idxReader.ReadInt32();
                        long pos    = idxReader.ReadInt64();
                        int  length = idxReader.ReadInt32();

                        Region r = Region.FindByUId(serial);

                        if (r != null)
                        {
                            regionEntries[i] = new RegionEntry(r, pos, length);
                            Region.AddRegion(r);
                        }
                    }

                    idxReader.Close();
                }
            }

            bool      failedMobiles = false, failedItems = false, failedGuilds = false, failedRegions = false;
            Type      failedType   = null;
            Serial    failedSerial = Serial.Zero;
            Exception failed       = null;
            int       failedTypeID = 0;

            if (File.Exists(mobBinPath))
            {
                log.Debug("loading mobiles");

                using (FileStream bin = new FileStream(mobBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < mobileEntries.Length; ++i)
                    {
                        MobileEntry entry = mobileEntries[i];
                        Mobile      m     = (Mobile)entry.Object;

                        if (m != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                m_LoadingType = entry.TypeName;
                                m.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", m.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                log.Error("failed to load mobile", e);
                                mobileEntries[i].Clear();

                                failed        = e;
                                failedMobiles = true;
                                failedType    = m.GetType();
                                failedTypeID  = entry.TypeID;
                                failedSerial  = m.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }

                if (!failedMobiles)
                {
                    mobileEntries = null;
                }
            }

            if (!failedMobiles && File.Exists(itemBinPath))
            {
                log.Debug("loading items");

                using (FileStream bin = new FileStream(itemBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < itemEntries.Length; ++i)
                    {
                        ItemEntry entry = itemEntries[i];
                        Item      item  = (Item)entry.Object;

                        if (item != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                m_LoadingType = entry.TypeName;
                                item.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", item.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                log.Fatal("failed to load item", e);
                                itemEntries[i].Clear();

                                failed       = e;
                                failedItems  = true;
                                failedType   = item.GetType();
                                failedTypeID = entry.TypeID;
                                failedSerial = item.Serial;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }

                if (!failedItems)
                {
                    itemEntries = null;
                }
            }

            if (!failedMobiles && !failedItems && File.Exists(guildBinPath))
            {
                log.Debug("loading guilds");

                using (FileStream bin = new FileStream(guildBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < guildEntries.Length; ++i)
                    {
                        GuildEntry entry = guildEntries[i];
                        BaseGuild  g     = (BaseGuild)entry.Object;

                        if (g != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                g.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on Guild {0} *****", g.Id));
                                }
                            }
                            catch (Exception e)
                            {
                                log.Fatal("failed to load guild", e);
                                guildEntries[i].Clear();

                                failed       = e;
                                failedGuilds = true;
                                failedType   = typeof(BaseGuild);
                                failedTypeID = g.Id;
                                failedSerial = g.Id;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }

                if (!failedGuilds)
                {
                    guildEntries = null;
                }
            }

            if (!failedMobiles && !failedItems && File.Exists(regionBinPath))
            {
                log.Debug("loading regions");

                using (FileStream bin = new FileStream(regionBinPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryFileReader reader = new BinaryFileReader(new BinaryReader(bin));

                    for (int i = 0; i < regionEntries.Length; ++i)
                    {
                        RegionEntry entry = regionEntries[i];
                        Region      r     = (Region)entry.Object;

                        if (r != null)
                        {
                            reader.Seek(entry.Position, SeekOrigin.Begin);

                            try
                            {
                                r.Deserialize(reader);

                                if (reader.Position != (entry.Position + entry.Length))
                                {
                                    throw new Exception(String.Format("***** Bad serialize on {0} *****", r.GetType()));
                                }
                            }
                            catch (Exception e)
                            {
                                log.Fatal("failed to load region", e);
                                regionEntries[i].Clear();

                                failed        = e;
                                failedRegions = true;
                                failedType    = r.GetType();
                                failedTypeID  = entry.TypeID;
                                failedSerial  = r.UId;

                                break;
                            }
                        }
                    }

                    reader.Close();
                }

                if (!failedRegions)
                {
                    regionEntries = null;
                }
            }

            if (failedItems || failedMobiles || failedGuilds || failedRegions)
            {
                Console.WriteLine("An error was encountered while loading a saved object");

                Console.WriteLine(" - Type: {0}", failedType);
                Console.WriteLine(" - Serial: {0}", failedSerial);

                Console.WriteLine("Delete the object? (y/n)");

                if (Console.ReadLine() == "y")
                {
                    if (failedType != typeof(BaseGuild) && !failedType.IsSubclassOf(typeof(Region)))
                    {
                        Console.WriteLine("Delete all objects of that type? (y/n)");

                        if (Console.ReadLine() == "y")
                        {
                            if (failedMobiles)
                            {
                                for (int i = 0; i < mobileEntries.Length; ++i)
                                {
                                    if (mobileEntries[i].TypeID == failedTypeID)
                                    {
                                        mobileEntries[i].Clear();
                                    }
                                }
                            }
                            else if (failedItems)
                            {
                                for (int i = 0; i < itemEntries.Length; ++i)
                                {
                                    if (itemEntries[i].TypeID == failedTypeID)
                                    {
                                        itemEntries[i].Clear();
                                    }
                                }
                            }
                        }
                    }

                    if (mobileEntries != null)
                    {
                        SaveIndex(mobileEntries, mobIdxPath);
                    }
                    if (itemEntries != null)
                    {
                        SaveIndex(itemEntries, itemIdxPath);
                    }
                    if (guildEntries != null)
                    {
                        SaveIndex(guildEntries, guildIdxPath);
                    }
                    if (regionEntries != null)
                    {
                        SaveIndex(regionEntries, regionIdxPath);
                    }
                }

                Console.WriteLine("After pressing return an exception will be thrown and the server will terminate");
                Console.ReadLine();

                throw new Exception(String.Format("Load failed (items={0}, mobiles={1}, guilds={2}, regions={3}, type={4}, serial={5})", failedItems, failedMobiles, failedGuilds, failedRegions, failedType, failedSerial), failed);
            }
        }