public void SetUp() { //common arrange _userServiceMock = new Mock <IUserService>(MockBehavior.Strict); _userController = new UserController(_userServiceMock.Object); _user = new User("Test User", "secret password"); _client = new MtcgClient(_user, "Test user-mtcgToken"); }
public bool AddToStack(int userId, Guid cardId) { string statement = ""; User user = null; MtcgClient client = null; if ((client = ClientMapSingleton.GetInstance.ClientMap.Values.FirstOrDefault(c => c.User.UserId == userId)) == null) { statement = "SELECT * FROM mtcg.\"User\" " + "WHERE \"Id\"=@userId"; using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Parameters.Add("userId", NpgsqlDbType.Integer).Value = userId; cmd.Prepare(); using (var reader = cmd.ExecuteReader(CommandBehavior.SingleResult)) { if (reader.Read()) { user = new User(reader); } } } if (user == null) { return(false); } user.Stack.AddCard(cardId); } else { client.User.Stack.AddCard(cardId); ClientMapSingleton.GetInstance.ClientMap.AddOrUpdate(client.SessionToken, client, (key, oldValue) => client); user = client.User; } statement = "UPDATE mtcg.\"User\" " + "SET \"Stack\"=@stack " + "WHERE \"Id\"=@userId"; using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Parameters.Add("userId", NpgsqlDbType.Integer).Value = userId; cmd.Parameters.Add("stack", NpgsqlDbType.Varchar).Value = JsonSerializer.Serialize(user.Stack.GetAllCards()); cmd.Prepare(); if (cmd.ExecuteNonQuery() != 1) { return(false); } } return(true); }
public KeyValuePair <StatusCode, object> ViewStats(ref MtcgClient client) { try { return(new KeyValuePair <StatusCode, object>(StatusCode.OK, client.User.Stats)); } catch (Exception e) { return(HandleException(e)); } }
public KeyValuePair <StatusCode, object> ViewScoreboard(MtcgClient client) { try { return(new KeyValuePair <StatusCode, object>(StatusCode.OK, _userService.GetScoreboard(client))); } catch (Exception e) { return(HandleException(e)); } }
public ResponseContext Get(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; if (!request.QueryParams.ContainsKey("username")) { return(new ResponseContext(request, _marketController.GetAllOpenTradingDeals())); } return(new ResponseContext(request, _marketController.GetOpenTradingDealsForUser(request.QueryParams["username"]))); }
public KeyValuePair <StatusCode, object> EditProfile(ref MtcgClient client, Profile profile) { try { if (_userService.EditProfile(ref client, profile)) { return(new KeyValuePair <StatusCode, object>(StatusCode.OK, profile)); } return(new KeyValuePair <StatusCode, object>(StatusCode.InternalServerError, "Something went wrong")); } catch (Exception e) { return(HandleException(e)); } }
public KeyValuePair <StatusCode, object> ConfigureDeck(ref MtcgClient client, Deck deck) { try { if (client == null) { return(new KeyValuePair <StatusCode, object>(StatusCode.Unauthorized, null)); } //save old deck to fallback if necessary Deck oldDeck = new Deck(); foreach (Card card in client.User.Deck.GetAllCards()) { oldDeck.AddCard(card); } //clear user deck client.User.Deck.ClearDeck(); foreach (Card card in deck.GetAllCards()) { if (!client.User.Stack.GetAllCards().Any(c => c.Guid.Equals(card.Guid))) { return(new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You do not possess this card. Acquire some packages and you might will someday.")); } if (!client.User.Deck.AddCard(card)) { client.User.Deck.ClearDeck(); client.User.Deck.AddCards(oldDeck.GetAllCards()); return(new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "The given deck either contains more than 4 cards or has more than 2 same cards.")); } } if (((IDeckService)_userService).ConfigureDeck(ref client)) { return(new KeyValuePair <StatusCode, object>(StatusCode.OK, client.User.Deck.GetAllCards())); } client.User.Deck.ClearDeck(); client.User.Deck.AddCards(oldDeck.GetAllCards()); return(new KeyValuePair <StatusCode, object>(StatusCode.InternalServerError, "")); } catch (Exception e) { return(HandleException(e)); } }
public ResponseContext Post(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; //trade with existing deal if (!string.IsNullOrWhiteSpace(request.RequestedResource)) { TradingDeal pendingDeal = null; if (!_marketController.TradingDealExists(request.RequestedResource, out pendingDeal)) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, $"There is no open deal with the given id {request.RequestedResource}"))); } if (pendingDeal.PublisherId == client.User.UserId) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You can't trade with yourself"))); } Card cardToTrade = null; Guid cardGuid; if (string.IsNullOrWhiteSpace(request.Payload) || !Guid.TryParse(request.Payload, out cardGuid) || (cardToTrade = client.User.Stack.GetAllCards().FirstOrDefault(c => c.Guid.Equals(cardGuid))) == null) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You must provide a card id that you possess and want to trade"))); } return(new ResponseContext(request, _marketController.ProcessTrade(pendingDeal, cardToTrade, client))); } //create new deal TradingDeal deal = JsonSerializer.Deserialize <TradingDeal>(request.Payload); if (deal == null || string.IsNullOrWhiteSpace(deal.RequestedElement) || string.IsNullOrWhiteSpace(deal.RequestedType)) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "All properties must be set: CardId, RequestedElement, MinimumDamage, RequestedType"))); } if (!client.User.Stack.GetAllCards().Any(c => c.Guid == deal.CardId)) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "Nice try, but you don't have this card ;)"))); } deal.PublisherId = client.User.UserId; return(new ResponseContext(request, _marketController.AddTradingDeal(deal))); }
public ResponseContext Post(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; MtcgClient waitingClient = null; foreach (KeyValuePair <string, MtcgClient> clientPair in ClientMapSingleton.GetInstance.ClientMap) { if (clientPair.Value.IsReadyForBattle) { waitingClient = clientPair.Value; break; } } if (waitingClient == null) { if (client.User.Deck.GetAllCards().Count() != 4) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You have an invalid deck. Configure your deck and try again"))); } client.IsReadyForBattle = true; ClientMapSingleton.GetInstance.ClientMap.AddOrUpdate(client.SessionToken, client, (key, oldValue) => client); while (client.IsReadyForBattle == true && client.CurrentBattleLog.Value == null) { Thread.Sleep(100); client = ClientMapSingleton.GetInstance.ClientMap[client.SessionToken]; } KeyValuePair <StatusCode, object> responsePair = new KeyValuePair <StatusCode, object>(client.CurrentBattleLog.Key, client.CurrentBattleLog.Value); //reset battle log and ready for battle ResetBattleProperties(client); return(new ResponseContext(request, responsePair)); } BattleBase battle = new BattleBase(ref client, ref waitingClient); if (!battle.CheckDecks()) { ResetBattleProperties(client); return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You have an invalid deck. Configure your deck and try again"))); } ResetBattleProperties(client); return(new ResponseContext(request, _battleController.StartBattle(battle))); }
public KeyValuePair <StatusCode, object> AcquirePackage(ref MtcgClient client, PackageType type) { if (!(_userService is IPackageTransactionService && _userService is ILoggable)) { return(new KeyValuePair <StatusCode, object>(StatusCode.InternalServerError, null)); } if (client == null) { return(new KeyValuePair <StatusCode, object>(StatusCode.Unauthorized, null)); } try { int packagePrice = ((IPackageTransactionService)_userService).GetPackagePrice(type); if (packagePrice == -1) { return(new KeyValuePair <StatusCode, object>(StatusCode.InternalServerError, null)); } if (!HasEnoughCoins(client.User.Coins, packagePrice)) { return(new KeyValuePair <StatusCode, object>(StatusCode.Conflict, "You don't have enough coins")); } ((IPackageTransactionService)_userService).AcquirePackage(ref client, type); string logDescription = $"{client.User.Username} acquired a {Enum.GetName(typeof(PackageType), type)} package and paid {packagePrice}."; bool logged = ((ILoggable)_userService).Log(new Dictionary <string, object>(new [] { new KeyValuePair <string, object>("client", client), new KeyValuePair <string, object>("description", logDescription) })); if (!logged) { Console.WriteLine("Package transaction was not logged"); } return(new KeyValuePair <StatusCode, object>(StatusCode.OK, logDescription)); } catch (Exception e) { return(HandleException(e)); } }
/// <summary> /// Edit Profile /// </summary> /// <param name="param"></param> /// <returns></returns> public virtual ResponseContext Put(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; if (!param.ContainsKey("client")) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.Unauthorized, "You need to log in to use this service."))); } MtcgClient client = (MtcgClient)param["client"]; if (!request.Headers.ContainsKey("Content-Type") || request.Headers["Content-Type"] != "application/json") { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.UnsupportedMediaType, ""))); } Profile profile = JsonSerializer.Deserialize <Profile>(request.Payload); return(new ResponseContext(request, _userController.EditProfile(ref client, profile))); }
public bool EditStats(MtcgClient client) { string statement = "UPDATE mtcg.\"User\" " + "SET \"Stats\"=@stats " + "WHERE \"Username\"=@username AND \"Password_Hash\"=@password"; string[] credentials = client.User.Credentials.Split(':', 2); using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Parameters.Add("username", NpgsqlDbType.Varchar).Value = credentials[0]; cmd.Parameters.Add("password", NpgsqlDbType.Bytea).Value = Encoding.UTF8.GetBytes(credentials[1]); cmd.Parameters.Add("stats", NpgsqlDbType.Varchar).Value = JsonSerializer.Serialize(client.User.Stats); cmd.Prepare(); if (cmd.ExecuteNonQuery() != 1) { return(false); } } return(true); }
public List <string> GetScoreboard(MtcgClient client) { List <User> users = new List <User>(); string statement = "SELECT * FROM mtcg.\"User\""; using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Prepare(); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { User user = new User(reader); users.Add(user); } } } return(users.OrderByDescending(u => u.Stats.Elo) .Select((u, rank) => GetRankString(client, u, rank + 1)).ToList()); }
public override ResponseContext Post(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; PackageTypeDto packageTypeDto = null; if (request.Payload.Length > 0) { if (!request.Headers.ContainsKey("Content-Type") || request.Headers["Content-Type"] != "application/json") { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.UnsupportedMediaType, ""))); } packageTypeDto = JsonSerializer.Deserialize <PackageTypeDto>(request.Payload); } PackageType packageType = packageTypeDto?.ToObject() ?? PackageType.Basic; return(new ResponseContext(request, _userController.AcquirePackage(ref client, packageType))); }
public ResponseContext Delete(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; //trade with existing deal if (!string.IsNullOrWhiteSpace(request.RequestedResource)) { TradingDeal pendingDeal = null; if (!_marketController.TradingDealExists(request.RequestedResource, out pendingDeal)) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, $"There is no open deal with the given id {request.RequestedResource}"))); } if (pendingDeal.PublisherId != client.User.UserId) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You can't delete a trade that you did not create"))); } return(new ResponseContext(request, _marketController.DeleteTradingDeal(pendingDeal))); } return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "You must provide an id of an open trading deal"))); }
public ResponseContext Put(Dictionary <string, object> param) { RequestContext request = (RequestContext)param["request"]; MtcgClient client = (MtcgClient)param["client"]; if (!request.Headers.ContainsKey("Content-Type") || request.Headers["Content-Type"] != "application/json") { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.UnsupportedMediaType, ""))); } CardCollectionDto deckDto = JsonSerializer.Deserialize <CardCollectionDto>(request.Payload); deckDto.CardCollectionType = typeof(Deck); Deck deck; if (deckDto == null || deckDto.CardGuids.Count != 4 || (deck = deckDto.ToObject() as Deck) == null) { return(new ResponseContext(request, new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, "Either the deck does not contain 4 cards or some cards do not exist"))); } return(new ResponseContext(request, _userController.ConfigureDeck(ref client, deck))); }
public BattleBase(ref MtcgClient player1, ref MtcgClient player2) { Player1 = player1; Player2 = player2; }
public KeyValuePair <StatusCode, object> ProcessTrade(TradingDeal deal, Card cardToTrade, MtcgClient client) { try { if (deal.MinimumDamage > cardToTrade.Damage || cardToTrade.GetType().Name != deal.RequestedType || Enum.GetName(typeof(ElementType), cardToTrade.Element) != deal.RequestedElement) { return(new KeyValuePair <StatusCode, object>(StatusCode.BadRequest, $"The given card does not match the requirements Min Damage:{deal.MinimumDamage} Element: {deal.RequestedElement} Type: {deal.RequestedType}")); } _userService.AddToStack(deal.PublisherId, cardToTrade.Guid); _userService.AddToStack(client.User.UserId, deal.CardId); _userService.DeleteFromStack(deal.PublisherId, deal.Guid); _userService.DeleteFromStack(client.User.UserId, cardToTrade.Guid); _marketService.Trade(deal, client.User.UserId); return(new KeyValuePair <StatusCode, object>(StatusCode.OK, "Trade completed successfully")); } catch (Exception e) { return(HandleException(e)); } }
public bool AcquirePackage(ref MtcgClient client, PackageType type) { Package package = null; CardCollectionDto packageDto = null; int price = 0; string statement; if (type == PackageType.Random) { packageDto = new CardCollectionDto() { CardGuids = AcquireRandomPackage(), CardCollectionType = typeof(Package) }; price = GetPackagePrice(PackageType.Random); } else { statement = "SELECT * FROM mtcg.\"Package\" p, mtcg.\"PackageType\" pT " + "WHERE pt.\"Id\"=@packageTypeId AND p.\"PackageTypeId\"=pT.\"Id\" " + "ORDER BY RANDOM() " + "LIMIT 1;"; using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Parameters.Add("packageTypeId", NpgsqlDbType.Integer).Value = (int)type; cmd.Prepare(); using (var reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) { if (reader.HasRows) { reader.Read(); packageDto = new CardCollectionDto() { CardGuids = JsonSerializer.Deserialize <List <Guid> >(reader["Cards"].ToString()), CardCollectionType = typeof(Package) }; price = (int)reader["Price"]; } }; } } package = packageDto?.ToObject() as Package; if (package == null) { return(false); } package.PackageType = type; //save old properties to fallback if necessary Stack <Package> oldUnopenedPackages = new Stack <Package>(new Stack <Package>(client.User.CurrentUnopenedPackages)); client.User.RemoveCoins(price); client.User.AddPackage(package); statement = "UPDATE mtcg.\"User\" " + "SET \"Coins\"=@coins, \"UnopenedPackages\"=@unopenedPackages " + "WHERE \"Username\"=@username AND \"Password_Hash\"=@password"; string[] credentials = client.User.Credentials.Split(':', 2); using (NpgsqlCommand cmd = new NpgsqlCommand(statement, PostgreSQLSingleton.GetInstance.Connection)) { cmd.Parameters.Add("username", NpgsqlDbType.Varchar).Value = credentials[0]; cmd.Parameters.Add("password", NpgsqlDbType.Bytea).Value = Encoding.UTF8.GetBytes(credentials[1]); cmd.Parameters.Add("coins", NpgsqlDbType.Integer).Value = client.User.Coins; cmd.Parameters.Add("unopenedPackages", NpgsqlDbType.Varchar).Value = JsonSerializer.Serialize(client.User.CurrentUnopenedPackages); cmd.Prepare(); if (cmd.ExecuteNonQuery() != 1) { client.User.AddCoins(price); client.User.CurrentUnopenedPackages = oldUnopenedPackages; return(false); } } return(true); }