public async Task <bool> AppendPlayerToBottomAsync(int id, int?lootRequestId, string comment) { if (lootRequestId == null && comment == null) { return(false); } var playerExists = _dbContext.Player.Any(p => p.Id == id); if (!playerExists) { return(false); } var lootRequestExists = !lootRequestId.HasValue || _dbContext.LootRequest.Any(lr => lr.Id == lootRequestId.Value && lr.RequestedForId == id); if (!lootRequestExists) { return(false); } var newEntry = new PlayerListPositionHistory { PlayerId = id, LootRequestId = lootRequestId, Comment = comment, CreatedAt = DateTime.Now }; _dbContext.Add(newEntry); await _dbContext.SaveChangesAsync(); return(true); }
public async Task <bool> AwardLoot(int lootId, int?lootRequestId, CampaignLoot.CampaignLootStatus status, bool?lootAvailableToOtherSyndicates, bool dropRequestorDown = true) { var loot = _dbContext.CampaignLoot.SingleOrDefault(cl => cl.Id == lootId); if (loot == null) { return(false); } var lootRequest = lootRequestId.HasValue ? _dbContext.LootRequest.SingleOrDefault(lr => lr.Id == lootRequestId.Value) : null; if (lootRequestId.HasValue && lootRequest == null) { return(false); } loot.Status = status; loot.AvailableToOtherSyndicates = lootAvailableToOtherSyndicates; if (lootRequestId.HasValue) { loot.HolderId = lootRequest.RequestedForId; lootRequest.Status = LootRequest.LootRequestStatus.Awarded; if (dropRequestorDown) { var newHistoryEntry = new PlayerListPositionHistory { LootRequest = lootRequest, PlayerId = lootRequest.RequestedForId, CreatedAt = DateTime.Now, Comment = "Drop associated with loot request", }; await _dbContext.AddAsync(newHistoryEntry); } } await _dbContext.SaveChangesAsync(); return(true); }
public async Task <string> ParsePlayerPageAsync(string fileContents, int syndicateId) { string message; HtmlDocument document = new HtmlDocument(); document.LoadHtml(fileContents); var characterName = document.DocumentNode.SelectSingleNode("//*[contains(concat(\" \",normalize-space(@class),\" \"),\" character-name \")]").InnerHtml.Trim(); var recordedAt = DateTime.Parse(document.DocumentNode.SelectSingleNode("//html").Attributes["data-time"].Value); var levelText = document.DocumentNode.SelectSingleNode("//*[contains(concat(\" \",normalize-space(@class),\" \"),\" statistics \")]/dd[position()=5]").InnerHtml.Trim(); var levelParts = levelText.Split(" @ "); decimal level = int.Parse(levelParts[0]) + (decimal.Parse(levelParts[1].Replace("%", "")) / 100); var lastCourseDate = Utils.GCT.ParseGCTDate(document.DocumentNode.SelectSingleNode("//*[contains(concat(\" \",normalize-space(@class),\" \"),\" not-enrolled \")]").InnerHtml.Trim()); var nodes = document.DocumentNode.SelectNodes("//div[contains(concat(\" \",normalize-space(@class),\" \"),\" accordion-panel \")]"); var nodeValues = new Dictionary <String, Dictionary <String, String> >(); foreach (var node in nodes) { var tableId = node.Attributes["Id"].Value; nodeValues[tableId] = new Dictionary <string, string>(); var tbodyElements = node.Descendants("tbody"); if (tbodyElements.Count() == 0) { tbodyElements = node.Descendants("table"); } if (tbodyElements.Count() > 0) { var tbody = tbodyElements.First(); foreach (var tr in tbody.Descendants("tr")) { var tds = tr.Descendants("td").Take(2); if (tds.Count() == 2) { nodeValues[tableId][tds.First().InnerHtml] = tds.Last().InnerHtml; } else { // We are dealing with the nested structure inside a single <td> if (tableId == "character_bank" && tds.First().Descendants("div").Count() > 0) { nodeValues[tableId][tds.First().Descendants("div").First().Attributes["class"].Value] = tds.First().Descendants("span").First().Descendants("span").First().InnerHtml; } } } } } if (!lastCourseDate.HasValue) { lastCourseDate = nodeValues["character_education"].Keys.Count > 0 ? Utils.GCT.ParseGCTDate(nodeValues["character_education"].Values.OrderByDescending(v => v).First()) : null; } var visaText = nodeValues["character_visas"].ContainsKey("Gaule") ? nodeValues["character_visas"]["Gaule"] : string.Empty; DateTime?visaDate = string.IsNullOrEmpty(visaText) ? null : Utils.GCT.ParseGCTDateExact(visaText); var player = _dbContext.Player.FirstOrDefault(p => p.Name.Equals(characterName)); if (player == null) // We are dealing with completely new player { player = new Player { Strength = Decimal.Parse(nodeValues["character_stats"]["Strength"]), Agility = Decimal.Parse(nodeValues["character_stats"]["Agility"]), Stamina = Decimal.Parse(nodeValues["character_stats"]["Stamina"]), Intelligence = Decimal.Parse(nodeValues["character_stats"]["Intelligence"]), Social = Decimal.Parse(nodeValues["character_stats"]["Social"]), Level = level, Wallet = 0, Bank = Decimal.Parse(nodeValues["character_bank"]["credits"].Replace(",", "")), Bonds = int.Parse(nodeValues["character_bank"]["bonds"].Replace(",", "")), LastUpdate = recordedAt, UniCourseDate = lastCourseDate, GauleVisaExpiry = visaDate, Name = characterName, Active = true, // By default all players start active SyndicateId = syndicateId, // By default all new players are assigned to the same syndicate as the uploading officer }; foreach (var skillName in nodeValues["character_skills"].Keys) { var skill = _dbContext.Skill.SingleOrDefault(s => s.Name == skillName); if (skill == null) { skill = new Skill { Name = skillName, }; _dbContext.Add(skill); } var playerSkill = new PlayerSkill { Skill = skill, Player = player, SkillLevel = int.Parse(nodeValues["character_skills"][skillName]), }; _dbContext.Add(playerSkill); } var playerHistory = new PlayerHistory(player); _dbContext.Add(player); _dbContext.Add(playerHistory); // Other things that need to happen when a new player is added var ldlPosition = new PlayerListPositionHistory { Player = player, Comment = "Initial seeding", CreatedAt = DateTime.Now, }; _dbContext.Add(ldlPosition); message = "Player, history entry and loot distribution position added, player activated."; } else { if (_dbContext.PlayerHistory .Where(ph => ph.PlayerId == player.Id) .AsEnumerable() // TODO: Bad performance almost 100%; try converting to SQL-suitable .Any(ph => Math.Abs(ph.RecordedAt.Subtract(recordedAt).TotalMinutes) < 1)) { message = "File has been already processed before"; } else { var playerHistory = new PlayerHistory { Strength = Decimal.Parse(nodeValues["character_stats"]["Strength"]), Agility = Decimal.Parse(nodeValues["character_stats"]["Agility"]), Stamina = Decimal.Parse(nodeValues["character_stats"]["Stamina"]), Intelligence = Decimal.Parse(nodeValues["character_stats"]["Intelligence"]), Social = Decimal.Parse(nodeValues["character_stats"]["Social"]), Level = level, Wallet = 0, Bank = Decimal.Parse(nodeValues["character_bank"]["credits"].Replace(",", "")), Bonds = int.Parse(nodeValues["character_bank"]["bonds"].Replace(",", "")), RecordedAt = recordedAt, Player = player, PlayerId = player.Id, }; _dbContext.Add(playerHistory); message = "History entry added"; if (recordedAt > player.LastUpdate) { message += " and player entry updated"; player.Update(playerHistory); if (player.NotificationSettings.HasFlag(Player.NotificationFlags.GauleVisa) && player.GauleVisaExpiry != visaDate && visaDate.HasValue) { _dbContext.Notification.Add( new Notification { Kind = NotificationKind.GauleVisa, RecipientId = player.Id, SendAfter = visaDate.Value.AddDays(-2), Status = NotificationStatus.NotSent } ); } if (player.NotificationSettings.HasFlag(Player.NotificationFlags.University) && player.UniCourseDate != lastCourseDate && lastCourseDate.HasValue && !player.UniversityComplete) { _dbContext.Notification.Add( new Notification { Kind = NotificationKind.University, RecipientId = player.Id, SendAfter = lastCourseDate.Value.AddDays(-1), Status = NotificationStatus.NotSent } ); } player.UniCourseDate = lastCourseDate; player.GauleVisaExpiry = visaDate; _dbContext.Update(player); } foreach (var skillName in nodeValues["character_skills"].Keys) { var skill = _dbContext.Skill.SingleOrDefault(s => s.Name == skillName); if (skill == null) { skill = new Skill { Name = skillName, }; _dbContext.Add(skill); } var playerSkill = _dbContext.PlayerSkill.SingleOrDefault(ps => ps.PlayerId == player.Id && ps.Skill == skill); if (playerSkill == null) { playerSkill = new PlayerSkill { Skill = skill, Player = player, }; _dbContext.Add(playerSkill); } playerSkill.SkillLevel = int.Parse(nodeValues["character_skills"][skillName]); } message += "."; } } await _dbContext.SaveChangesAsync(); return(message); }
public async Task <bool> SetLootRequestStatus(int playerId, int currentPlayerId, int campaignLootId, int status, int lootStatus, string comments, bool dropRequestorDown) { var lootItem = _dbContext.CampaignLoot.SingleOrDefault(cl => cl.Id == campaignLootId); if (lootItem == null) { return(false); } var player = _dbContext.Player.SingleOrDefault(p => p.Id == playerId); if (player == null) { return(false); } var lootRequest = _dbContext.LootRequest.SingleOrDefault(lr => lr.LootId == campaignLootId && lr.RequestedForId == playerId); if (lootRequest == null) { if (status == -1) { return(false); // What is dead may never die } lootRequest = new LootRequest { LootId = campaignLootId, RequestedById = currentPlayerId, RequestedForId = playerId, Status = (LootRequest.LootRequestStatus)status, SpecialOfferDescription = comments, }; if (lootStatus > -1) { lootItem.HolderId = playerId; lootItem.Status = (CampaignLoot.CampaignLootStatus)lootStatus; } await _dbContext.AddAsync(lootRequest); } else if (status == -1) { if (lootRequest.HistoryEntry != null) { _dbContext.Remove(lootRequest.HistoryEntry); } _dbContext.Remove(lootRequest); } else { lootRequest.Status = (LootRequest.LootRequestStatus)status; lootRequest.SpecialOfferDescription = comments; if (status == (int)LootRequest.LootRequestStatus.Awarded) { lootRequest.Loot.HolderId = playerId; } if (lootStatus > -1) { lootItem.HolderId = playerId; lootItem.Status = (CampaignLoot.CampaignLootStatus)lootStatus; } } if (dropRequestorDown) { var newHistoryEntry = new PlayerListPositionHistory { LootRequest = lootRequest, PlayerId = playerId, CreatedAt = DateTime.Now, Comment = "Drop associated with loot request", }; await _dbContext.AddAsync(newHistoryEntry); } await _dbContext.SaveChangesAsync(); return(true); }