/// <summary> /// Now at the open tag of a single object in our XML, we want to dump the entire contents into an XDocument. /// If we have a World Construction it's a new item so it needs to be added, /// in other cases, it already exists and details need to be added to the existing items. /// Individual object reads are separated out to allow us to work past failing to load any specific XML item for any reason. /// </summary> private static void PlusLoadItem <T>(IDictionary <int, T> worldList, World world, XmlReader xReader) where T : XMLObject { XDocument xdoc = null; try { xdoc = XDocument.Load(xReader.ReadSubtree()); var id = Convert.ToInt32(xdoc.Root.Element("id").Value); if (!worldList.ContainsKey(id)) { if (typeof(T) == typeof(WorldConstruction)) { var newWc = new WorldConstruction(xdoc, world); world.WorldConstructions[newWc.Id] = newWc; return; } if (typeof(T) == typeof(Landmass)) { var newLandmass = new Landmass(xdoc, world); world.Landmasses.Add(newLandmass.Id, newLandmass); return; } if (typeof(T) == typeof(Mountain)) { var newMountain = new Mountain(xdoc, world); world.Mountains.Add(newMountain.Id, newMountain); return; } if (typeof(T) == typeof(River)) { var newRiver = new River(xdoc, world); world.Rivers.Add(newRiver.Id, newRiver); return; } if (typeof(T) == typeof(Army)) { var newArmy = new Army(xdoc, world); world.Armies.Add(newArmy.Id, newArmy); return; } if (typeof(T) == typeof(Unit)) { var newUnit = new Unit(xdoc, world); world.Units.Add(newUnit.Id, newUnit); return; } if (typeof(T) == typeof(Engraving)) { var newEngraving = new Engraving(xdoc, world); world.Engravings.Add(newEngraving.Id, newEngraving); return; } if (typeof(T) == typeof(Report)) { var newReport = new Report(xdoc, world); world.Reports.Add(newReport.Id, newReport); return; } if (typeof(T) == typeof(Building)) { var newBuilding = new Building(xdoc, world); world.Buildings.Add(newBuilding.Id, newBuilding); return; } if (typeof(T) == typeof(Construction)) { var newConstruction = new Construction(xdoc, world); world.Constructions.Add(newConstruction.Id, newConstruction); return; } if (typeof(T) == typeof(Item)) { var newItem = new Item(xdoc, world); world.Items.Add(newItem.Id, newItem); return; } if (typeof(T) == typeof(Plant)) { var newPlant = new Plant(xdoc, world); world.Plants.Add(newPlant.Id, newPlant); return; } if (typeof(T) == typeof(Squad)) { var newSquad = new Squad(xdoc, world); world.Squads.Add(newSquad.Id, newSquad); return; } if (typeof(T) == typeof(WrittenContent)) { var newWrittenContent = new WrittenContent(xdoc, world); world.WrittenContents.Add(newWrittenContent.Id, newWrittenContent); return; } if (typeof(T) == typeof(PoeticForm)) { var newPoeticForm = new PoeticForm(xdoc, world); world.PoeticForms.Add(newPoeticForm.Id, newPoeticForm); Console.WriteLine(newPoeticForm.Id); return; } if (typeof(T) == typeof(MusicalForm)) { var newMusicalForm = new MusicalForm(xdoc, world); world.MusicalForms.Add(newMusicalForm.Id, newMusicalForm); return; } if (typeof(T) == typeof(DanceForm)) { var newDanceForm = new DanceForm(xdoc, world); world.DanceForms.Add(newDanceForm.Id, newDanceForm); return; } } if (typeof(T) == typeof(Race)) { var key = xdoc.Root.Element("key").Value.ToLower(); var associatedRace = world.FindRace(key) ?? world.FindRace(xdoc.Root.Element("nameS").Value.ToLower()) ?? world.FindRace(xdoc.Root.Element("nameP").Value.ToLower()); if (associatedRace == null || associatedRace.Id > 0) { var newRace = new Race(xdoc, world) { AddedOrder = world.Races.Keys.Min() - 1 }; if (!world.Races.TryAdd(id, newRace)) { Program.Log(LogType.Error, "Failed to add race - " + newRace.ToString() + " while adding Plus XML"); } return; } id = associatedRace.AddedOrder; } if (worldList.ContainsKey(id)) { worldList[id].Plus(xdoc); } } catch (OutOfMemoryException e) { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); var fi = new FileInfo(_path); Program.Log(LogType.Error, "XML file is" + Math.Round(fi.Length / 1024f / 1024f / 1024f, 2) + " GB"); Program.Log(LogType.Error, $"Running {(Environment.Is64BitProcess ? "64" : "32")} Bit World Viewer"); Program.Log(LogType.Error, $"Running {(Environment.Is64BitOperatingSystem ? "64" : "32")} Bit Operating System"); if (!Environment.Is64BitOperatingSystem) //Running 32 bit OS { Program.Log(LogType.Error, "32 Bit World Viewer does not support Huge XML files"); } else if (!Environment.Is64BitProcess) //Running 32 bit app in 64 bit OS { Program.Log(LogType.Error, "Recommend using 64 Bit World Viewer"); } else { Program.Log(LogType.Error, "Please report Log"); } MemoryFailureQuitParsing = true; } catch (Exception e) { try { if (xdoc != null) { var id = int.Parse(((XElement)xdoc.Root.Nodes().ToArray()[1]).Value); if (id < 0) { switch (xdoc.Root.Name.LocalName) { case "historical_event": if (!_workflowDetected) { Program.Log(LogType.Error, "Negative ID historical event. Likely due to dfHack Workflow, ignoring\n" + xdoc); _workflowDetected = true; } break; case "historical_figure": if (!_autochopDetected) { Program.Log(LogType.Error, "Negative ID historical figure detected. Likely due to autochop, ignoring\n" + xdoc); _autochopDetected = true; } break; default: Program.Log(LogType.Error, "Negative ID " + xdoc.Root.Name.LocalName + " detected. Unknown cause, ignoring\n" + xdoc); break; } } else { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); } } } catch (Exception) { Program.Log(LogType.Error, "Error reading XML item: id\n" + e.Message); throw; } } }
public override string Print(bool link = true, DwarfObject pov = null) { string eventString = GetYearTime(); eventString += Civ != null?Civ.ToLink(link, pov) : "UNKNOWN CIV"; eventString += " held a "; if (Schedule != null) { if (!string.IsNullOrWhiteSpace(Schedule.ItemType) || !string.IsNullOrWhiteSpace(Schedule.ItemSubType)) { eventString += !string.IsNullOrWhiteSpace(Schedule.ItemSubType) ? Schedule.ItemSubType : Schedule.ItemType; eventString += " "; } } eventString += Schedule != null?Schedule.Type.GetDescription().ToLower() : OccasionType.ToString().ToLower(); if (Schedule != null) { switch (Schedule.Type) { case ScheduleType.PoetryRecital: if (Schedule.Reference != -1) { PoeticForm form = World.GetPoeticForm(Schedule.Reference); eventString += " of "; eventString += form != null?form.ToLink(link, pov) : "UNKNOWN POETRICFORM"; } break; case ScheduleType.MusicalPerformance: if (Schedule.Reference != -1) { MusicalForm form = World.GetMusicalForm(Schedule.Reference); eventString += " of "; eventString += form != null?form.ToLink(link, pov) : "UNKNOWN MUSICALFORM"; } break; case ScheduleType.DancePerformance: if (Schedule.Reference != -1) { DanceForm form = World.GetDanceForm(Schedule.Reference); eventString += " of "; eventString += form != null?form.ToLink(link, pov) : "UNKNOWN DANCEFORM"; } break; case ScheduleType.Storytelling: if (Schedule.Reference != -1) { WorldEvent worldEvent = World.GetEvent(Schedule.Reference); if (worldEvent is IFeatured) { eventString += " of "; eventString += worldEvent != null ? ((IFeatured)worldEvent).PrintFeature() : "UNKNOWN EVENT"; } } break; } } eventString += " in "; eventString += Site != null?Site.ToLink(link, pov) : "UNKNOWN SITE"; eventString += " as part of "; eventString += EntityOccasion != null?EntityOccasion.ToLink(link, pov) : "UNKNOWN OCCASION"; eventString += "."; if (Schedule != null) { switch (Schedule.Type) { case ScheduleType.Procession: Structure startStructure = Site.Structures.FirstOrDefault(s => s.Id == Schedule.Reference); Structure endStructure = Site.Structures.FirstOrDefault(s => s.Id == Schedule.Reference2); if (startStructure != null || endStructure != null) { eventString += " It started at "; eventString += startStructure != null?startStructure.ToLink(link, pov) : "UNKNOWN STRUCTURE"; eventString += " and ended at "; eventString += endStructure != null?endStructure.ToLink(link, pov) : "UNKNOWN STRUCTURE"; eventString += "."; } break; } } return(eventString); }