using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Threading.Tasks; using AutoMapper; using AutoMapper.QueryableExtensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TOOHUCardAPI.Data; using TOOHUCardAPI.Data.Models; using TOOHUCardAPI.Data.Repositories; using TOOHUCardAPI.DTO; namespace TOOHUCardAPI.Controllers { [Route("api/[controller]")] [ApiController] public class PlayerDataController : MethodBasedController { private readonly ILogger _logger; private readonly UserRepository _userRepository; private readonly IMapper _mapper; public PlayerDataController(ILogger logger, UserRepository userRepository, IMapper mapper) { _logger = logger; _userRepository = userRepository; _mapper = mapper; } /** * The game uses a single endpoint for player data. * The object they send has a method field that's used to decide what's being done * So let's use a single entry point and redirect based on that */ [HttpPost] public async Task EntryPoint([FromBody] object bodyObj) { string body = JsonConvert.SerializeObject(bodyObj); JObject request = JObject.Parse(body); string method = request["method"].ToString(); return await InvokeEndpointHandlerForMethod(this, method, body); } [EndpointHandler("save_card_group")] private async Task SaveCardGroup(string body) { PlayerDataSaveCardGroupRequestObject request = JsonConvert.DeserializeObject(body); User user = _userRepository.GetUser(request.SteamId); if (user == null) { return new PlayerDataSaveCardGroupResponseObject() { Code = "0001", Message = "Invalid player" }; } EncodedCardGroup group = user.EncodedCardGroups.FirstOrDefault(group => group.GroupKey == request.GroupKey) ?? new EncodedCardGroup() { GroupKey = request.GroupKey }; group.EncodedString = request.GroupData; user.EncodedCardGroups = user.EncodedCardGroups.Where(group2 => group.Id != group2.Id).Append(group).ToList(); _userRepository.UpdateUser(user); return new PlayerDataSaveCardGroupResponseObject(); } [EndpointHandler("get")] private async Task Get(string body) { PlayerDataGetRequestObject requestObject = JsonConvert.DeserializeObject(body); IEnumerable users = requestObject.Ids.Values.Select(val => _userRepository.GetOrCreateUser(val)); IEnumerable queriedUserSteamIds = requestObject.Ids.Select(i => i.Value); IEnumerable responsePlayers = users .Where(user => queriedUserSteamIds.Contains(user.SteamId)) .Select(user => _mapper.Map(user)); Dictionary playersStatic = requestObject.Ids .Select(pair => KeyValuePair.Create(pair.Key, responsePlayers.FirstOrDefault(resp => resp.SteamId == pair.Value))) .ToDictionary(kv => kv.Key, kv => kv.Value); Dictionary> dynamicResponses = playersStatic .Select(kv => { var obj = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(kv.Value)); return KeyValuePair.Create(kv.Key, obj); }) .ToDictionary(kv => kv.Key, kv => kv.Value); foreach (var kv in dynamicResponses) { var props = kv.Value; var user = users.FirstOrDefault(user1 => user1.SteamId == requestObject.Ids[kv.Key]); foreach (var cardgroup in user.EncodedCardGroups ?? new List()) { props[$"{cardgroup.GroupKey}"] = cardgroup.EncodedString; } } PlayerDataGetResponseObject response = new PlayerDataGetResponseObject() { Players = dynamicResponses }; return response; } } }