public static async Task RunConverterAsync(string[] args) { using var reader = File.OpenText(string.Concat(args)); using var converter = new AtlantisReportJsonConverter(reader); using JsonWriter writer = new JsonTextWriter(Console.Out); writer.Formatting = Formatting.Indented; await converter.ConvertAsync(writer); }
public async Task UploadReport([Required, FromRoute] long gameId) { using var bodyReader = new StreamReader(Request.Body); using var converter = new AtlantisReportJsonConverter(bodyReader); using var buffer = new MemoryStream(); using var bufferWriter = new StreamWriter(buffer); using JsonWriter writer = new JsonTextWriter(bufferWriter); await converter.ConvertAsync(writer); buffer.Seek(0, SeekOrigin.Begin); using var bufferReader = new StreamReader(buffer); using JsonReader reader = new JsonTextReader(bufferReader); JObject report = await JObject.LoadAsync(reader); var faction = report["faction"] as JObject; var date = report["date"] as JObject; var engine = report["engine"] as JObject; var factionStatus = report["factionStatus"] as JArray; var errors = report["errors"] as JArray; var events = report["events"] as JArray; var skillReports = report["skillReports"] as JArray; var objectReports = report["objectReports"] as JArray; var itemReports = report["itemReports"] as JArray; var attitudes = report["attitudes"] as JObject; var unclaimedSilver = report["unclaimedSilver"]; var regions = report["regions"] as JArray; var ordersTemplate = report["ordersTemplate"] as JObject; var turn = new DbTurn { GameId = gameId, Year = date.Value <int>("year"), Month = MonthToNumber(date.Value <string>("month")), Factions = new List <DbFaction>(), Regions = new List <DbRegion>(), Structures = new List <DbStructure>(), Events = new List <DbEvent>(), Units = new List <DbUnit>() }; turn.Number = (turn.Year - 1) * 12 + turn.Month; // ensure that there are no turn with the same number await RemoveTurn(gameId, turn.Number); db.ChangeTracker.AutoDetectChangesEnabled = false; var lastTurn = await db.Turns .OrderByDescending(x => x.Id) .Include(x => x.Factions) .Include(x => x.Units) .Include(x => x.Structures) .Include(x => x.Regions) .ThenInclude(x => x.Structures) .FirstOrDefaultAsync(x => x.GameId == gameId); Dictionary <string, string> regionMemory = lastTurn != null ? lastTurn.Regions .ToDictionary(k => k.EmpheralId, v => v.Memory) : new Dictionary <string, string>(); Dictionary <int, string> unitMemory = lastTurn != null ? lastTurn.Units .Where(x => x.Own) .ToDictionary(k => k.Number, v => v.Memory) : new Dictionary <int, string>(); Dictionary <string, string> structuresMemory = lastTurn != null ? lastTurn.Structures .ToDictionary(k => DbStructure.GetEmpheralId(k.Region.X, k.Region.Y, k.Region.Z, k.Number, k.Type), v => v.Memory) : new Dictionary <string, string>(); db.ChangeTracker.AutoDetectChangesEnabled = true; var game = await db.Games.FindAsync(gameId); turn.Memory = lastTurn?.Memory; await db.Turns.AddAsync(turn); await db.SaveChangesAsync(); var f = new DbFaction { GameId = gameId, TurnId = turn.Id, Name = faction.Value <string>("name"), Number = faction.Value <int>("number"), Json = new JObject( new JProperty("faction", faction), new JProperty("factionStatus", factionStatus), new JProperty("skillReports", skillReports), new JProperty("objectReports", objectReports), new JProperty("itemReports", itemReports), new JProperty("attitudes", attitudes), new JProperty("unclaimedSilver", unclaimedSilver) ).ToString(), }; if (!game.PlayerFactionNumber.HasValue) { game.PlayerFactionNumber = f.Number; game.EngineVersion = engine.Value <string>("version"); var ruleset = engine["ruleset"] as JObject; game.RulesetName = ruleset.Value <string>("name"); game.RulesetVersion = ruleset.Value <string>("version"); } f.Own = f.Number == game.PlayerFactionNumber; f.Events = (events ?? Enumerable.Empty <JToken>()) .Select(x => new DbEvent { GameId = gameId, TurnId = turn.Id, Type = "event", Json = x.ToString() }) .Concat( (errors ?? Enumerable.Empty <JToken>()) .Select(x => new DbEvent { GameId = gameId, TurnId = turn.Id, Type = "error", Json = x.ToString() }) ) .ToList(); turn.Factions.Add(f); turn.Events.AddRange(f.Events); var orders = (ordersTemplate["units"] as JArray) .ToDictionary(k => k.Value <int>("unit"), v => v.Value <string>("orders")); foreach (JObject region in regions) { var coords = region["coords"] as JObject; var r = new DbRegion { GameId = gameId, TurnId = turn.Id, UpdatedAtTurn = turn.Number, X = coords.Value <int>("x"), Y = coords.Value <int>("y"), Z = coords.TryGetValue("z", StringComparison.OrdinalIgnoreCase, out var zCoord) ? zCoord.Value <int>() : 1, Label = coords.TryGetValue("label", StringComparison.OrdinalIgnoreCase, out var label) ? label.Value <string>() : "surface", Province = region.Value <string>("province"), Terrain = region.Value <string>("terrain"), Structures = new List <DbStructure>(), Units = new List <DbUnit>() }; r.Memory = regionMemory.TryGetValue(r.EmpheralId, out var regMem) ? regMem : null; var units = region["units"] as JArray; if (units != null) { AddUnits(game, turn, units, r, null, unitMemory, orders); } var structures = region["structures"] as JArray; if (structures != null) { AddStructures(game, turn, structures, r, structuresMemory, unitMemory, orders); } region.Remove("units"); region.Remove("structures"); r.Json = region.ToString(); turn.Regions.Add(r); } if (game.PlayerFactionNumber == ordersTemplate.Value <int>("faction")) { game.Password = ordersTemplate.Value <string>("password"); } // copy missing regions from previous turn if (lastTurn != null) { CopyInvisibleRegions(gameId, turn, lastTurn, game); } await db.SaveChangesAsync(); }