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 { } }
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(); } } }
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); } } } } }
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); }
public static void RemoveMap(BaseInstanceMap map) { m_InstanceMaps.Remove(map.Serial); }
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(); } } }