public WikiBuildingInfoPresets FetchBuildingDetails(WikiBuildingInfoPresets wikiBuildingInfoList) { //download complete wikitext for each building SaveCompleteInfos(wikiBuildingInfoList); //extract infobox for each found wikitext ExtractAllInfoboxes(); //parse infoboxes return(GetUpdatedWikiBuildingInfoList(wikiBuildingInfoList)); }
public WikiBuildingInfoPresets GetWikiBuildingInfos(WikiTextTableContainer list) { var wikibuildingList = new WikiBuildingInfoPresets(); foreach (var curentry in list.Entries) { wikibuildingList.Infos.Add(ParseWikiBuildingInfo(curentry)); } //order buildings by name wikibuildingList.Infos = wikibuildingList.Infos.OrderBy(x => x.Name).ToList(); return(wikibuildingList); }
public WikiBuildingInfoPresets Load(string pathToPresetsFile) { WikiBuildingInfoPresets result = null; try { result = SerializationHelper.LoadFromFile <WikiBuildingInfoPresets>(pathToPresetsFile); } catch (Exception ex) { Trace.WriteLine($"Error loading the buildings.{Environment.NewLine}{ex}"); throw; } return(result); }
private async Task GenerateTemplate(object param) { try { IsBusy = true; StatusMessage = string.Empty; var buildingPresetsTask = Task.Run(() => { //load building presets BuildingPresets localBuildingPresets = null; try { var loader = new BuildingPresetsLoader(); localBuildingPresets = loader.Load(PresetsVM.SelectedFile); if (localBuildingPresets == null || localBuildingPresets.Buildings == null) { throw new ArgumentException(); } } catch (Exception ex) { var message = $"Error parsing {nameof(BuildingPresets)}."; logger.Error(ex, message); MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); StatusMessage = $"{message} -> Maybe wrong selected file?"; return(null); } PresetsVersion = localBuildingPresets.Version; return(localBuildingPresets); }); var wikiBuildingInfoPresetsTask = Task.Run(() => { //load wiki buildng info WikiBuildingInfoPresets localWikiBuildingInfoPresets = null; try { var loader = new WikiBuildingInfoPresetsLoader(); localWikiBuildingInfoPresets = loader.Load(WikiBuildingsInfoVM.SelectedFile); } catch (Exception ex) { var message = $"Error parsing {nameof(WikiBuildingInfoPresets)}."; logger.Error(ex, message); MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); StatusMessage = $"{message} -> Maybe wrong selected file?"; return(null); } WikiBuildingInfoPresetsVersion = localWikiBuildingInfoPresets.Version.ToString(); return(localWikiBuildingInfoPresets); }); var layoutTask = Task.Run(() => { //load layout List <AnnoObject> localLayout = null; try { ILayoutLoader loader = new LayoutLoader(); localLayout = loader.LoadLayout(LayoutVM.SelectedFile); } catch (Exception ex) { var message = "Error parsing layout file."; logger.Error(ex, message); MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); StatusMessage = $"{message} -> Maybe wrong selected file?"; return(null); } LayoutName = Path.GetFileName(LayoutVM.SelectedFile); return(localLayout); }); await Task.WhenAll(buildingPresetsTask, wikiBuildingInfoPresetsTask, layoutTask); var buildingPresets = buildingPresetsTask.Result; var wikiBuildingInfoPresets = wikiBuildingInfoPresetsTask.Result; var layout = layoutTask.Result; if (buildingPresets == null || wikiBuildingInfoPresets == null || layout == null) { return; } var layoutNameForTemplate = Path.GetFileNameWithoutExtension(LayoutVM.SelectedFile).Replace("_", " "); await Task.Run(() => { var exporter = new FandomExporter(); Template = exporter.StartExport(layoutNameForTemplate, layout, buildingPresets, wikiBuildingInfoPresets, true); }); StatusMessage = "Template successfully generated."; } catch (Exception ex) { var message = "Error generating template."; logger.Error(ex, message); MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); StatusMessage = $"{message} -> Details in log file."; } finally { IsBusy = false; } }
public string StartExport(string layoutName, LayoutFile layout, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets, bool exportUnsupportedTags) { //https://anno1800.fandom.com/wiki/Template:Production_layout //https://anno1800.fandom.com/wiki/Template:Production_layout/doc //https://anno1800.fandom.com/wiki/Category:Template_documentation //https://anno1800.fandom.com/wiki/Testing_page //TODO warn user when layout contains more than 15 building types because template only supports 1-15 //template only supports 1-8 for "Production x Type" and "Production x per minute" //TODO warn user (or exit) when layout contains buildings other than Anno 1800 var calculatedStatistics = _statisticsCalculationHelper.CalculateStatistics(layout.Objects); var exportString = new StringBuilder(900);//best guess on minimal layout exportString.Append(TEMPLATE_START) .AppendLine(HEADER_PRODUCTION_LAYOUT) .Append(TEMPLATE_LINE_START).Append(HEADER_ICON).AppendLine(TEMPLATE_ENTRY_DELIMITER) .Append(TEMPLATE_LINE_START).Append(HEADER_LAYOUT_NAME).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(layoutName) .Append(TEMPLATE_LINE_START).Append(HEADER_LAYOUT_IMAGE).AppendLine(TEMPLATE_ENTRY_DELIMITER); //add buildings exportString = addBuildingInfo(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString.Append(TEMPLATE_LINE_START).Append(HEADER_LAYOUT_DESCRIPTION).AppendLine(TEMPLATE_ENTRY_DELIMITER) .Append(TEMPLATE_LINE_START).Append(HEADER_SIZE).Append(TEMPLATE_ENTRY_DELIMITER).Append(calculatedStatistics.UsedAreaWidth.ToString()).Append(TEMPLATE_SIZE_ENTRY_DELIMITER).AppendLine(calculatedStatistics.UsedAreaHeight.ToString()) .Append(TEMPLATE_LINE_START).Append(HEADER_TILES).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(calculatedStatistics.UsedTiles.ToString()) .Append(TEMPLATE_LINE_START).Append(HEADER_AUTHOR).AppendLine(TEMPLATE_ENTRY_DELIMITER) .Append(TEMPLATE_LINE_START).Append(HEADER_SOURCE).AppendLine(TEMPLATE_ENTRY_DELIMITER); exportString = addProductionInfo(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString = addConstructionInfo(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString = addBalance(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString = addWorkforceInfo(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString = addInfluence(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); exportString = addAttractiveness(exportString, layout.Objects, buildingPresets, wikiBuildingInfoPresets); if (exportUnsupportedTags) { exportString = addUnsupportedEntries(exportString); } exportString.Append(TEMPLATE_END); return(exportString.ToString()); }
private WikiBuildingInfo getWikiBuildingInfo(string buildingIdentifier, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { WikiBuildingInfo result = null; var foundPresetBuilding = buildingPresets.Buildings.FirstOrDefault(x => x.Identifier.Equals(buildingIdentifier, StringComparison.OrdinalIgnoreCase)); var buildingName = foundPresetBuilding?.Localization["eng"]; var buildingFaction = foundPresetBuilding?.Faction; var buildingRegion = WorldRegion.OldWorld; if (buildingFaction?.Contains("Obreros") == true || buildingFaction?.Contains("Jornaleros") == true) { buildingRegion = WorldRegion.NewWorld; } if (string.IsNullOrWhiteSpace(buildingName)) { //TODO error? logger.Warn($"found no building name for identifier: {buildingIdentifier}"); return(result); } //try to find by name result = wikiBuildingInfoPresets.Infos.FirstOrDefault(x => x.Name.Equals(buildingName, StringComparison.OrdinalIgnoreCase) && x.Region == buildingRegion); if (result == null) { //Is it a farm with field info? (e.g. "Potato Farm - (72)") var matchFieldCount = regexFieldCount.Match(buildingName); if (matchFieldCount.Success) { //strip field info and search again var strippedBuildingName = buildingName.Replace(matchFieldCount.Value, string.Empty).Trim(); result = wikiBuildingInfoPresets.Infos.FirstOrDefault(x => x.Name.Equals(strippedBuildingName, StringComparison.OrdinalIgnoreCase) && x.Region == buildingRegion); } } return(result); }
private StringBuilder addAttractiveness(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { double attractiveness = 0; var groupedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Identifier); foreach (var curGroup in groupedBuildings) { var buildingIdentifier = curGroup.Key; var buildingCount = curGroup.Count(); var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.MaintenanceInfos.Count == 0) { //no info found -> skip logger.Trace($"found no wiki info for identifier: {buildingIdentifier}"); continue; } //get attractiveness var foundAttractivenessEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.StartsWith("Attractiveness", StringComparison.OrdinalIgnoreCase)); if (foundAttractivenessEntry != null) { attractiveness = attractiveness + (foundAttractivenessEntry.Value * buildingCount); } } exportString.Append(TEMPLATE_LINE_START).Append(HEADER_ATTRACTIVENESS).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(attractiveness != 0 ? attractiveness.ToString("0") : string.Empty); return(exportString); }
private StringBuilder addWorkforceInfo(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { double farmers = 0; double workers = 0; double artisans = 0; double engineers = 0; double jornaleros = 0; double obreros = 0; double explorers = 0; double technicians = 0; var groupedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Identifier); foreach (var curGroup in groupedBuildings) { var buildingIdentifier = curGroup.Key; var buildingCount = curGroup.Count(); var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.MaintenanceInfos.Count == 0) { //no info found -> skip logger.Trace($"found no wiki info for identifier: {buildingIdentifier}"); continue; } //get farmers var foundFarmersEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Farmers", StringComparison.OrdinalIgnoreCase)); if (foundFarmersEntry != null) { farmers += (foundFarmersEntry.Value * buildingCount); } //get workers var foundWorkersEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Workers", StringComparison.OrdinalIgnoreCase)); if (foundWorkersEntry != null) { workers += (foundWorkersEntry.Value * buildingCount); } //get artisans var foundArtisansEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Artisans", StringComparison.OrdinalIgnoreCase)); if (foundArtisansEntry != null) { artisans += (foundArtisansEntry.Value * buildingCount); } //get engineers var foundEngineersEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Engineers", StringComparison.OrdinalIgnoreCase)); if (foundEngineersEntry != null) { engineers += (foundEngineersEntry.Value * buildingCount); } //get jornaleros var foundJornalerosEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Jornaleros", StringComparison.OrdinalIgnoreCase)); if (foundJornalerosEntry != null) { jornaleros += (foundJornalerosEntry.Value * buildingCount); } //get obreros var foundObrerosEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Obreros", StringComparison.OrdinalIgnoreCase)); if (foundObrerosEntry != null) { obreros += (foundObrerosEntry.Value * buildingCount); } //get explorers var foundExplorersEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Explorers", StringComparison.OrdinalIgnoreCase)); if (foundExplorersEntry != null) { explorers += (foundExplorersEntry.Value * buildingCount); } //get technicians var foundTechniciansEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Workforce Technicians", StringComparison.OrdinalIgnoreCase)); if (foundTechniciansEntry != null) { technicians += (foundTechniciansEntry.Value * buildingCount); } } //add info to template exportString.Append(TEMPLATE_LINE_START).Append(HEADER_FARMERS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(farmers != 0 ? farmers.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_WORKERS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(workers != 0 ? workers.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_ARTISANS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(artisans != 0 ? artisans.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_ENGINEERS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(engineers != 0 ? engineers.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_JORNALEROS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(jornaleros != 0 ? jornaleros.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_OBREROS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(obreros != 0 ? obreros.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_OBREROS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(obreros != 0 ? obreros.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_EXPLORERS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(explorers != 0 ? explorers.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_TECHNICIANS_WORKFORCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(technicians != 0 ? technicians.ToString("0") : string.Empty); return(exportString); }
private StringBuilder addConstructionInfo(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { double credits = 0; double timber = 0; double bricks = 0; double steelBeams = 0; double windows = 0; double reinforcedConcrete = 0; var groupedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Identifier); foreach (var curGroup in groupedBuildings) { var buildingIdentifier = curGroup.Key; var buildingCount = curGroup.Count(); var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.ConstructionInfos.Count == 0) { //no info found -> skip logger.Trace($"found no wiki info for identifier: {buildingIdentifier}"); continue; } //get credits var foundCreditsEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Credits", StringComparison.OrdinalIgnoreCase)); if (foundCreditsEntry != null) { credits += (foundCreditsEntry.Value * buildingCount); } //get timber var foundTimberEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Timber", StringComparison.OrdinalIgnoreCase)); if (foundTimberEntry != null) { timber += (foundTimberEntry.Value * buildingCount); } //get bricks var foundBricksEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Bricks", StringComparison.OrdinalIgnoreCase)); if (foundBricksEntry != null) { bricks += (foundBricksEntry.Value * buildingCount); } //get steel beams var foundSteelBeamsEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Steel Beams", StringComparison.OrdinalIgnoreCase)); if (foundSteelBeamsEntry != null) { steelBeams += (foundSteelBeamsEntry.Value * buildingCount); } //get windows var foundWindowsEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Windows", StringComparison.OrdinalIgnoreCase)); if (foundWindowsEntry != null) { windows += (foundWindowsEntry.Value * buildingCount); } //get reinforced concrete var foundReinforcedConcreteEntry = foundWikiBuildingInfo.ConstructionInfos.FirstOrDefault(x => x.Unit.Name.Equals("Reinforced Concrete", StringComparison.OrdinalIgnoreCase)); if (foundReinforcedConcreteEntry != null) { reinforcedConcrete += (foundReinforcedConcreteEntry.Value * buildingCount); } } //add info to template exportString.Append(TEMPLATE_LINE_START).Append(HEADER_CREDITS).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(credits > 0 ? credits.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_TIMBER).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(timber > 0 ? timber.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_BRICKS).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(bricks > 0 ? bricks.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_STEEL_BEAMS).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(steelBeams > 0 ? steelBeams.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_WINDOWS).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(windows > 0 ? windows.ToString("0") : string.Empty) .Append(TEMPLATE_LINE_START).Append(HEADER_REINFORCED_CONCRETE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(reinforcedConcrete > 0 ? reinforcedConcrete.ToString("0") : string.Empty); return(exportString); }
private StringBuilder addBalance(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { double balance = 0; var groupedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Identifier); foreach (var curGroup in groupedBuildings) { var buildingIdentifier = curGroup.Key; var buildingCount = curGroup.Count(); var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.MaintenanceInfos.Count == 0) { //no info found -> skip continue; } //get balance var foundBalanceEntry = foundWikiBuildingInfo.MaintenanceInfos.FirstOrDefault(x => x.Unit.Name.Equals("Balance", StringComparison.OrdinalIgnoreCase)); if (foundBalanceEntry != null) { balance = balance + (foundBalanceEntry.Value * buildingCount); } } exportString.Append(TEMPLATE_LINE_START).Append(HEADER_BALANCE).Append(TEMPLATE_ENTRY_DELIMITER).AppendLine(balance != 0 ? balance.ToString("0") : string.Empty); return(exportString); }
private StringBuilder addProductionInfo(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { var buildingCounter = 0; var supportedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)).ToList(); //1. get all buildings that need input //2. gat all buildings that have an endproduct //3. foreach building with input -> remove it from list of buildings with an endproduct //4. foreach building with an endproduct -> add it to the template //1. get all buildings that need input var buildingsWithInputProduct = new Dictionary <AnnoObject, List <InputProduct> >(); foreach (var curBuilding in supportedBuildings) { var foundWikiBuildingInfo = getWikiBuildingInfo(curBuilding.Identifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.ProductionInfos == null || foundWikiBuildingInfo.ProductionInfos.InputProducts.Count == 0) { //no Production building or no info found -> skip continue; } foreach (var curInput in foundWikiBuildingInfo.ProductionInfos.InputProducts) { if (!buildingsWithInputProduct.ContainsKey(curBuilding)) { buildingsWithInputProduct.Add(curBuilding, new List <InputProduct> { curInput }); } else { buildingsWithInputProduct[curBuilding].Add(curInput); } } } //2. gat all buildings that have an endproduct var buildingsWithEndProduct = new Dictionary <AnnoObject, EndProduct>(); foreach (var curBuilding in supportedBuildings) { var foundWikiBuildingInfo = getWikiBuildingInfo(curBuilding.Identifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null || foundWikiBuildingInfo.ProductionInfos == null || foundWikiBuildingInfo.ProductionInfos.EndProduct == null) { //no Production building or no info found -> skip continue; } buildingsWithEndProduct.Add(curBuilding, foundWikiBuildingInfo.ProductionInfos.EndProduct); } //3. foreach building with input -> remove it from list of buildings with an endproduct foreach (var curBuildingWithInputProduct in buildingsWithInputProduct) { foreach (var curInputProduct in curBuildingWithInputProduct.Value) { var foundBuildingWithSameEndProduct = buildingsWithEndProduct.FirstOrDefault(x => string.Equals(x.Value.Icon, curInputProduct.Icon, StringComparison.OrdinalIgnoreCase)).Key; if (foundBuildingWithSameEndProduct != null) { buildingsWithEndProduct.Remove(foundBuildingWithSameEndProduct); } } } //4. foreach building with an endproduct -> add it to the template var groupedBuildingsWithEndProduct = buildingsWithEndProduct.GroupBy(x => x.Key.Identifier).ToList(); foreach (var curGroup in groupedBuildingsWithEndProduct) { var buildingIdentifier = curGroup.Key; var buildingCount = curGroup.Count(); var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (foundWikiBuildingInfo == null) { //no Production building or no info found -> skip continue; } if (buildingCount == 1 && foundWikiBuildingInfo.ProductionInfos.EndProduct.Amount <= 1) { continue; } //add info about end product ++buildingCounter; var productionAmount = foundWikiBuildingInfo.ProductionInfos.EndProduct.Amount * buildingCount; var endProductIcon = Path.GetFileNameWithoutExtension(foundWikiBuildingInfo.ProductionInfos.EndProduct.Icon); exportString.Append(TEMPLATE_LINE_START) .Append(HEADER_PRODUCTION) .Append(buildingCounter) .Append(HEADER_PRODUCTION_TYPE) .Append(TEMPLATE_ENTRY_DELIMITER) .AppendLine(endProductIcon); exportString.Append(TEMPLATE_LINE_START) .Append(HEADER_PRODUCTION) .Append(buildingCounter) .Append(HEADER_PRODUCTION_PER_MINUTE) .Append(TEMPLATE_ENTRY_DELIMITER) .AppendLine(productionAmount.ToString("0.##")); } return(exportString); }
private string getBuildingName(string buildingIdentifier, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { var result = MAPPING_NOT_FOUND + buildingIdentifier; var foundFandomNameMapping = FandomeNamePresets.Names.FirstOrDefault(x => x.Identifiers.Contains(buildingIdentifier)); if (foundFandomNameMapping != null) { result = foundFandomNameMapping.FandomName; } else { //try to get by wiki info var foundWikiBuildingInfo = getWikiBuildingInfo(buildingIdentifier, buildingPresets, wikiBuildingInfoPresets); if (!string.IsNullOrWhiteSpace(foundWikiBuildingInfo?.Icon)) { result = Path.GetFileNameWithoutExtension(foundWikiBuildingInfo.Icon); } } return(result); }
private StringBuilder addBuildingInfo(StringBuilder exportString, List <AnnoObject> placedObjects, BuildingPresets buildingPresets, WikiBuildingInfoPresets wikiBuildingInfoPresets) { var buildingCounter = 0; var groupedBuildings = placedObjects.Where(x => !x.Road && !string.IsNullOrWhiteSpace(x.Identifier) && !x.Identifier.Equals("Unknown Object", StringComparison.OrdinalIgnoreCase)) .GroupBy(x => x.Identifier) .OrderBy(x => x.Count()); foreach (var curGroup in groupedBuildings) { ++buildingCounter; exportString.Append(TEMPLATE_LINE_START) .Append(HEADER_BUILDING) .Append(buildingCounter) .Append(HEADER_BUILDING_TYPE) .Append(TEMPLATE_ENTRY_DELIMITER) .AppendLine(getBuildingName(curGroup.Key, buildingPresets, wikiBuildingInfoPresets)); exportString.Append(TEMPLATE_LINE_START) .Append(HEADER_BUILDING) .Append(buildingCounter) .Append(HEADER_BUILDING_AMOUNT) .Append(TEMPLATE_ENTRY_DELIMITER) .AppendLine(curGroup.Count().ToString()); } return(exportString); }
private void SaveCompleteInfos(WikiBuildingInfoPresets wikiBuildingInfoList) { Console.WriteLine("start fetching building details"); if (!Directory.Exists(PathToDetailsFolder)) { Directory.CreateDirectory(PathToDetailsFolder); } var existingMissingInfos = new List <string>(); if (File.Exists(Path.Combine(PathToDetailsFolder, FILENAME_MISSING_INFOS))) { existingMissingInfos.AddRange(File.ReadAllLines(Path.Combine(PathToDetailsFolder, FILENAME_MISSING_INFOS), Encoding.UTF8)); } var missingInfos = new List <string>(); Stopwatch sw = new Stopwatch(); sw.Start(); Parallel.ForEach(wikiBuildingInfoList.Infos, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, curBuilding => { var pageName = curBuilding.Name.Replace(" ", "_"); //only download when not present and not forced to download var fileName = GetCleanedFilename(pageName); var destinationFilePath = Path.Combine(PathToDetailsFolder, $"{fileName}{FILE_ENDING_WIKITEXT}"); if (!Program.ForceDownload && (File.Exists(destinationFilePath) || existingMissingInfos.Contains(curBuilding.Name))) { return; } var provider = new WikiTextProvider(); var providerResult = provider.GetWikiTextAsync(pageName).GetAwaiter().GetResult(); if (!string.IsNullOrWhiteSpace(providerResult.WikiText)) { providerResult.WikiText = GetLineBreakAlignedWikiText(providerResult.WikiText); //align infobox name providerResult.WikiText = providerResult.WikiText.Replace("{{Infobox_Buildings", "{{Infobox Buildings"); File.WriteAllText(destinationFilePath, providerResult.WikiText, Encoding.UTF8); File.AppendAllLines(destinationFilePath, new List <string> { Environment.NewLine, $"{REVISION_HEADER_ID}{REVISION_SEPARATOR}{providerResult.RevisionId}", $"{REVISION_HEADER_DATE}{REVISION_SEPARATOR}{providerResult.EditDate.ToString("o")}" }, Encoding.UTF8); } else { missingInfos.Add(curBuilding.Name); } }); if (missingInfos.Count > 0) { File.WriteAllLines(Path.Combine(PathToDetailsFolder, FILENAME_MISSING_INFOS), missingInfos.Distinct().OrderBy(x => x), Encoding.UTF8); } sw.Stop(); var message = $"finished fetching building details (took {sw.ElapsedMilliseconds} ms)"; logger.Trace(message); Console.WriteLine(message); }
private WikiBuildingInfoPresets GetUpdatedWikiBuildingInfoList(WikiBuildingInfoPresets wikiBuildingInfoList) { Console.WriteLine("start parsing infoboxes"); Stopwatch sw = new Stopwatch(); sw.Start(); try { var infoboxParser = new InfoboxParser.InfoboxParser(_commons); foreach (var curFile in Directory.EnumerateFiles(PathToExtractedInfoboxesFolder, $"*{FILE_ENDING_INFOBOX}", SearchOption.TopDirectoryOnly)) { var fileContent = File.ReadAllText(curFile, Encoding.UTF8); var infoboxes = infoboxParser.GetInfobox(fileContent); if (infoboxes.Count == 1) { var parsedInfobox = infoboxes[0]; WikiBuildingInfo foundWikiBuildingInfo; if (parsedInfobox.Region == WorldRegion.Unknown) { foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.Equals(parsedInfobox.Name, StringComparison.OrdinalIgnoreCase)); } else { throw new Exception("expected unknown region"); } if (foundWikiBuildingInfo == null) { throw new Exception("no WikiBuildingInfo found!"); } var buildingNameForUrl = foundWikiBuildingInfo.Name.Replace(" ", "_"); foundWikiBuildingInfo.Type = parsedInfobox.Type; foundWikiBuildingInfo.ProductionInfos = parsedInfobox.ProductionInfos; foundWikiBuildingInfo.SupplyInfos = parsedInfobox.SupplyInfos; foundWikiBuildingInfo.UnlockInfos = parsedInfobox.UnlockInfos; //check Url for "World's Fair" | correct: https://anno1800.fandom.com/wiki/World%27s_Fair if (buildingNameForUrl.Contains("World's_Fair")) { buildingNameForUrl = "World%27s_Fair"; } //(maybe) TODO check Url for "Bombín Weaver" | correct: https://anno1800.fandom.com/wiki/Bomb%C2%AD%C3%ADn_Weaver //contains unicode char (https://www.utf8-chartable.de/unicode-utf8-table.pl): U+00AD c2 ad SOFT HYPHEN foundWikiBuildingInfo.Url = new Uri("https://anno1800.fandom.com/wiki/" + buildingNameForUrl); var revisionInfo = GetRevisionInfo(foundWikiBuildingInfo); if (revisionInfo != null) { foundWikiBuildingInfo.RevisionId = revisionInfo.Item1; foundWikiBuildingInfo.RevisionDate = revisionInfo.Item2; } } else if (infoboxes.Count > 1) { foreach (var curInfobox in infoboxes) { //multiple entries possible e.g. "Police Station" or "Museum" var foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.Equals(curInfobox.Name, StringComparison.OrdinalIgnoreCase) && x.Region == curInfobox.Region); if (foundWikiBuildingInfo == null) { throw new Exception("no WikiBuildingInfo found!"); } var buildingNameForUrl = foundWikiBuildingInfo.Name.Replace(" ", "_"); foundWikiBuildingInfo.Type = curInfobox.Type; foundWikiBuildingInfo.ProductionInfos = curInfobox.ProductionInfos; foundWikiBuildingInfo.SupplyInfos = curInfobox.SupplyInfos; foundWikiBuildingInfo.UnlockInfos = curInfobox.UnlockInfos; foundWikiBuildingInfo.Url = new Uri("https://anno1800.fandom.com/wiki/" + buildingNameForUrl); var revisionInfo = GetRevisionInfo(foundWikiBuildingInfo); if (revisionInfo != null) { foundWikiBuildingInfo.RevisionId = revisionInfo.Item1; foundWikiBuildingInfo.RevisionDate = revisionInfo.Item2; } } } else { //got no infoboxes } } } catch (Exception ex) { logger.Error(ex, $"error parsing infoboxes"); Console.WriteLine(ex); } sw.Stop(); Console.WriteLine($"finished parsing infoboxes (took {sw.ElapsedMilliseconds} ms)"); return(wikiBuildingInfoList); }
private WikiBuildingInfoPresets GetUpdatedWikiBuildingInfoList(WikiBuildingInfoPresets wikiBuildingInfoList) { Console.WriteLine("start parsing infoboxes"); Stopwatch sw = new Stopwatch(); sw.Start(); try { foreach (var curFile in Directory.EnumerateFiles(PathToExtractedInfoboxesFolder, $"*{FILE_ENDING_INFOBOX}", SearchOption.TopDirectoryOnly)) { var fileContent = File.ReadAllText(curFile, Encoding.UTF8); var infoboxes = _infoboxParser.GetInfobox(fileContent); if (infoboxes.Count == 1) { var parsedInfobox = infoboxes[0]; WikiBuildingInfo foundWikiBuildingInfo; if (parsedInfobox.Region == WorldRegion.Unknown) { foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.Equals(parsedInfobox.Name, StringComparison.OrdinalIgnoreCase)); } else { throw new Exception("expected unknown region"); } if (foundWikiBuildingInfo is null) { //if (parsedInfobox?.Name.Contains("Road") == true) //{ foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.EndsWith(parsedInfobox.Name)); if (foundWikiBuildingInfo is null) { var wikiBuildingInfo = CreateNewBuildingInfo(parsedInfobox); wikiBuildingInfoList.Infos.Add(wikiBuildingInfo); continue; //var exception = new Exception("No WikiBuildingInfo found!"); //exception.Data.Add(nameof(curFile), curFile); //exception.Data.Add($"{nameof(parsedInfobox)}.{nameof(parsedInfobox.Name)}", parsedInfobox.Name); //logger.Error(exception); //continue; //throw exception; //is page with multiple infoboxes -> not supported yet //continue; } //} else { } } foundWikiBuildingInfo = CopyInfoboxToBuildingInfo(parsedInfobox, foundWikiBuildingInfo); } else if (infoboxes.Count > 1) { foreach (var curInfobox in infoboxes) { //multiple entries possible e.g. "Police Station" or "Museum" var foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.Equals(curInfobox.Name, StringComparison.OrdinalIgnoreCase) && x.Region == curInfobox.Region); if (foundWikiBuildingInfo is null) { //if (curInfobox?.Name.Contains("Road") == true) //{ foundWikiBuildingInfo = wikiBuildingInfoList.Infos.FirstOrDefault(x => x.Name.EndsWith(curInfobox.Name)); if (foundWikiBuildingInfo is null) { var exception = new Exception("No WikiBuildingInfo found!"); exception.Data.Add(nameof(curFile), curFile); exception.Data.Add($"{nameof(curInfobox)}.{nameof(curInfobox.Name)}", curInfobox.Name); logger.Error(exception); continue; //throw exception; //is page with multiple infoboxes -> not supported yet //continue; } //} else { } } foundWikiBuildingInfo = CopyInfoboxToBuildingInfo(curInfobox, foundWikiBuildingInfo); } } else { //got no infoboxes } } } catch (Exception ex) { logger.Error(ex, $"error parsing infoboxes"); Console.WriteLine(ex); } sw.Stop(); Console.WriteLine($"finished parsing infoboxes (took {sw.ElapsedMilliseconds} ms)"); return(wikiBuildingInfoList); }