示例#1
0
        private static void AppendSafetyLog(string action, BaseInstanceMap map)
        {
            string message = String.Format("Warning: Attempted to {1} {2} during world save." +
                                           "{0}This action could cause an inconsistent state." +
                                           "{0}It is strongly advised that the offending scripts be corrected.",
                                           Environment.NewLine,
                                           action, map
                                           );

            Console.WriteLine(message);

            try {
                using (StreamWriter op = new StreamWriter("world-save-errors.log", true)) {
                    op.WriteLine("{0}\t{1}", DateTime.Now, message);
                    op.WriteLine(new StackTrace(2).ToString());
                    op.WriteLine();
                }
            } catch {
            }
        }
示例#2
0
        public override void ProcessDecay()
        {
            while (_decayQueue.Count > 0)
            {
                Item item = _decayQueue.Dequeue();

                if (item.OnDecay())
                {
                    item.Delete();
                }
            }

            while (_decayMapQueue.Count > 0)
            {
                BaseInstanceMap map = _decayMapQueue.Dequeue();

                if (map.OnDecay())
                {
                    map.Delete();
                }
            }
        }
示例#3
0
        private void OnSerialized(ConsumableEntry entry)
        {
            ISerializable      value  = entry.value;
            BinaryMemoryWriter writer = entry.writer;

            Item item = value as Item;

            if (item != null)
            {
                Save(item, writer);
            }
            else
            {
                Mobile mob = value as Mobile;

                if (mob != null)
                {
                    Save(mob, writer);
                }
                else
                {
                    BaseGuild guild = value as BaseGuild;

                    if (guild != null)
                    {
                        Save(guild, writer);
                    }
                    else
                    {
                        BaseInstanceMap map = value as BaseInstanceMap;
                        if (map != null)
                        {
                            Save(map, writer);
                        }
                    }
                }
            }
        }
示例#4
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>();

            _addMapQueue    = new Queue <BaseInstanceMap>();
            _deleteMapQueue = new Queue <BaseInstanceMap>();

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

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

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

            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);

                        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");

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

                                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                                    {
                                        types.Add(null);
                                        Console.Write("World: Loading...");
                                        continue;
                                    }

                                    Console.WriteLine("Types will not be deleted. An exception will be thrown.");
                                }
                                else
                                {
                                    Console.WriteLine("Error: Type '{0}' was not found.", typeName);
                                }

                                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 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 = ( 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 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);

                        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");


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

                                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                                    {
                                        types.Add(null);
                                        Console.Write("World: Loading...");
                                        continue;
                                    }

                                    Console.WriteLine("Types will not be deleted. An exception will be thrown.");
                                }
                                else
                                {
                                    Console.WriteLine("Error: Type '{0}' was not found.", typeName);
                                }

                                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 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 = ( 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 Dictionary <Serial, Item>();
            }

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

                    using (FileStream tdb = new FileStream(MapTypesPath, 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");

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

                                    if (Console.ReadKey(true).Key == ConsoleKey.Y)
                                    {
                                        types.Add(null);
                                        Console.Write("World: Loading...");
                                        continue;
                                    }

                                    Console.WriteLine("Types will not be deleted. An exception will be thrown.");
                                }
                                else
                                {
                                    Console.WriteLine("Error: Type '{0}' was not found.", typeName);
                                }

                                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));
                            }
                        }

                        mapCount = idxReader.ReadInt32();

                        m_InstanceMaps = new Dictionary <Serial, BaseInstanceMap>(mapCount);

                        for (int i = 0; i < mapCount; ++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;
                            }

                            BaseInstanceMap map      = null;
                            ConstructorInfo ctor     = ( ConstructorInfo )objs[0];
                            string          typeName = ( string )objs[1];

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

                            if (map != null)
                            {
                                maps.Add(new InstanceMapEntry(map, typeID, typeName, pos, length));
                            }
                        }

                        tdbReader.Close();
                    }

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

            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;
                        BaseGuild guild = EventSink.InvokeCreateGuild(createEventArgs);
                        if (guild != null)
                        {
                            guilds.Add(new GuildEntry(guild, pos, length));
                        }
                    }

                    idxReader.Close();
                }
            }

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

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

                    for (int i = 0; i < maps.Count; ++i)
                    {
                        InstanceMapEntry entry = maps[i];
                        BaseInstanceMap  map   = entry.Map;

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

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

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

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

                                break;
                            }
                        }
                    }

                    reader.Close();
                }
            }

            if (!failedMaps && 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 && !failedMaps && 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 && !failedMaps && 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 || failedMaps || 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;
                                        }
                                    }
                                }
                                else if (failedMaps)
                                {
                                    for (int i = 0; i < maps.Count;)
                                    {
                                        if (maps[i].TypeID == failedTypeID)
                                        {
                                            maps.RemoveAt(i);
                                        }
                                        else
                                        {
                                            ++i;
                                        }
                                    }
                                }
                            }
                        }

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

                    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}, maps=[5], type={3}, serial={4})", failedItems, failedMobiles, failedGuilds, failedType, failedSerial, failedMaps), 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, {3} maps) ({0:F2} seconds)", watch.Elapsed.TotalSeconds, m_Items.Count, m_Mobiles.Count, m_InstanceMaps.Count);
        }
示例#5
0
 public static void RemoveMap(BaseInstanceMap map)
 {
     m_InstanceMaps.Remove(map.Serial);
 }
示例#6
0
        private static void ProcessSafetyQueues()
        {
            while (_addQueue.Count > 0)
            {
                IEntity entity = _addQueue.Dequeue();

                Item item = entity as Item;

                if (item != null)
                {
                    AddItem(item);
                }
                else
                {
                    Mobile mob = entity as Mobile;

                    if (mob != null)
                    {
                        AddMobile(mob);
                    }
                }
            }

            while (_addMapQueue.Count > 0)
            {
                BaseInstanceMap map = _addMapQueue.Dequeue();

                if (map != null)
                {
                    AddMap(map);
                }
            }

            while (_deleteQueue.Count > 0)
            {
                IEntity entity = _deleteQueue.Dequeue();

                Item item = entity as Item;

                if (item != null)
                {
                    item.Delete();
                }
                else
                {
                    Mobile mob = entity as Mobile;

                    if (mob != null)
                    {
                        mob.Delete();
                    }
                }
            }

            while (_deleteMapQueue.Count > 0)
            {
                BaseInstanceMap map = _deleteMapQueue.Dequeue();

                if (map != null)
                {
                    map.Delete();
                }
            }
        }