public static void activateSpell(Player pl, string spellName) { if (pl.isGuest || spellName == Spells.ROCKET) return; checkCoins(pl, spellName, processSpellActivation); }
private static void processArmorPurchase(Player pl, string itemKey) { int armorCount = 0; if (itemKey == ShopItemsInfo.ARMOR_3X) armorCount = 3; else if (itemKey == ShopItemsInfo.ARMOR_5X) armorCount = 5; else if (itemKey == ShopItemsInfo.ARMOR_10X) armorCount = 10; var item = new BuyItemInfo(itemKey); pl.PayVault.Buy(false, new BuyItemInfo[1] {item}, delegate { var items = new BuyItemInfo[armorCount]; for (int i = 0; i < armorCount; i++) { items[i] = new BuyItemInfo(ShopItemsInfo.ARMOR_ITEM); } pl.PayVault.Give(items, delegate { }, delegate(PlayerIOError err) { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item (2nd step)"); pl.roomLink.handleError(err); }); }, delegate(PlayerIOError err) { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item (1st step)"); pl.roomLink.handleError(err); }); }
public static void buyBouncer(Player pl, string itemKey) { if (pl.isGuest) return; checkCoins(pl, itemKey, processBouncerPurchase); }
public static void buyEnergy(Player pl, string itemKey) { if (pl.isGuest) return; checkCoins(pl, itemKey, processEnergyPurchase); }
private static uint updateCoins(Player pl, bool playerWon, string gameType) { uint coinsToGive = 0; if (pl.isGuest) return 0; if (gameType == GameTypes.FAST_SPRINT) { coinsToGive = playerWon ? GameConfig.COINS_FOR_WIN_SPRINT : GameConfig.COINS_FOR_LOSE_SPRINT; } else if (gameType == GameTypes.BIG_BATTLE) { coinsToGive = playerWon ? GameConfig.COINS_FOR_WIN_BIG_BATTLE : GameConfig.COINS_FOR_LOSE_BIG_BATTLE; } else if (gameType == GameTypes.FIRST_100) { coinsToGive = playerWon ? GameConfig.COINS_FOR_WIN_FIRST_100 : GameConfig.COINS_FOR_LOSE_FIRST_100; } else if (gameType == GameTypes.UPSIDE_DOWN) { coinsToGive = playerWon ? GameConfig.COINS_FOR_WIN_UPSIDE_DOWN : GameConfig.COINS_FOR_LOSE_UPSIDE_DOWN; } pl.PayVault.Refresh(delegate { string reason = (playerWon ? "Won " : "Lost ") + Spells.getFullSpellName(gameType); pl.PayVault.Credit(coinsToGive, reason, delegate { }, pl.roomLink.handleError); }); return coinsToGive; }
public void onBattleRequestDenied(Player player) { if (player == _roomCreator) { _battleRequestWaiter.Send(MessageTypes.BATTLE_REQUEST_DENIED); _battleRequestWaiter.Disconnect(); _battleRequestWaiter = null; } else throw new Exception("Unexpected Battle Request Denied message"); }
public void onBattleRequestAccepted(Player player) { if (player == _roomCreator) { addToPlayingUsers(_battleRequestWaiter); addToPlayingUsers(player); _roomLink.initGame(GameTypes.FAST_SPRINT, "-1"); //and it should start right-away _battleRequestWaiter = null; //nullify the link (so that creator may be requested again) } else throw new Exception("Unexpected Battle Request Accepted message"); }
public void onGuestReady(Player player) { Console.WriteLine("onGuestReady: " + player.realID); if (player.ready || _playingUsers.Contains(player)) throw new Exception("Trying to set ready = true to guest which is ready already: " + player.realID); if (_playingUsers.Count < _roomLink.game.capacity) { addToPlayingUsers(player); _roomLink.game.tryStartGame(); } }
private void giveStartCapital(Player player) { /*Console.WriteLine("givestartcapital"); player.PayVault.Credit(1000, "starter", delegate() { Console.WriteLine("1000 credited"); }, handleError); BuyItemInfo[] allItems = new BuyItemInfo[Data.powerupNames.Length * 3]; for (int j = 0; j < Data.powerupNames.Length; j++) { for (int i = 0; i < 3; i++) //3 items of each kind { allItems[j * 3 + i] = new BuyItemInfo(Data.powerupNames[j]); //fill array with "BuyItemInfo" } } player.PayVault.Give(allItems, null, handleError);*/ }
private static void checkCoins(Player pl, string itemKey, Action<Player, string> callback) { pl.PayVault.Refresh(delegate { int itemPrice = ShopItemsInfo.getItemPrice(itemKey); if (pl.PayVault.Coins >= itemPrice) { callback.Invoke(pl, itemKey); } else { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Not enough coins"); } }, pl.roomLink.handleError); }
public FieldSimulation(string mapsProgram, Player plLink) { playerLink = plLink; _ballsManager = new BallsManager(this); _ballsManager.lostBall += onLostBall; _rocketLauncher = new RocketLauncher(_ballsManager); fieldCells = new FieldCells(mapsProgram, playerLink.roomLink); fieldCells.cellCleared += onCellCleared; fieldCells.fieldCleared += onFieldCleared; _laserShotsManager = new LaserShotsManager(fieldCells, bouncer, this); _freezer = new Freezer(GameConfig.FREEZER_SLOWDOWN_TIME, GameConfig.FREEZER_FREEZE_TIME); }
/** * Handles game-specific messages (messages which are sent only during the game) */ public void handleGameMessage(Player player, Message msg) { switch (msg.Type) { case MessageTypes.TRY_USE: tryUseSpell(msg.GetInt(0), player); break; case MessageTypes.TICK: player.onTick(msg.GetDouble(0), msg.GetString(1), msg.GetString(2)); //update sever duplication model break; default: handleSpecialGameMessage(msg); break; } }
public static int consumeEnergy(Player pl, string gameType) { int toConsume = 0; if (pl is NPCPlayer) return 0; if (pl.isGuest) return 0; if (pl.PlayerObject.GetDouble(DBProperties.ENERGY_EXPIRES) > Utils.unixSecs()) //player has bought an energy ticket return 0; if (gameType == GameTypes.BIG_BATTLE) toConsume = GameConfig.ENERGY_CONSUMPTION_BIG_BATTLE; else if (gameType == GameTypes.FAST_SPRINT) toConsume = GameConfig.ENERGY_CONSUMPTION_SPRINT; else if (gameType == GameTypes.FIRST_100) toConsume = GameConfig.ENERGY_CONSUMPTION_FIRST_100; else if (gameType == GameTypes.UPSIDE_DOWN) toConsume = GameConfig.ENERGY_CONSUMPTION_UPSIDE_DOWN; //in some weird scenarios player object did not contain energy property int current = pl.PlayerObject.Contains(DBProperties.ENERGY) ? pl.PlayerObject.GetInt(DBProperties.ENERGY) : 0; if (current < toConsume) { pl.roomLink.PlayerIO.ErrorLog.WriteError("Unexpected low energy amount: " + pl.realID); toConsume = current; } if (current == GameConfig.ENERGY_MAX) pl.roomLink.playerEnergyTimer.resetLastUpdateTime(); //so when we consume energy and ask for more last update time will be fresh pl.PlayerObject.Set(DBProperties.ENERGY, current - toConsume); pl.PlayerObject.Save(); pl.roomLink.playerEnergyTimer.tryRefillEnergy(); return toConsume; }
public void checkIfNewbie(Player player) { if (!player.PlayerObject.Contains(DBProperties.SPELL_OBJECT)) //new guy { double expiresDate = Utils.unixSecs() + GameConfig.SPELL_ACTIVATION_TIME * 60 * 60; if (player.isGuest) expiresDate = Utils.unixSecs() + (60 * 60 * 24 * 365 * 500L); //for 500 years, should be enough; Adding L solves "The operation overflows at compile time in checked mode" problem DatabaseObject spells = new DatabaseObject(); //fill slots DatabaseObject freezeSpell = new DatabaseObject(); freezeSpell.Set(DBProperties.SPELL_SLOT, 1).Set(DBProperties.SPELL_EXPIRES, expiresDate); DatabaseObject splitSpell = new DatabaseObject(); splitSpell.Set(DBProperties.SPELL_SLOT, 2).Set(DBProperties.SPELL_EXPIRES, expiresDate); DatabaseObject lightningSpell = new DatabaseObject(); lightningSpell.Set(DBProperties.SPELL_SLOT, 3).Set(DBProperties.SPELL_EXPIRES, expiresDate); DatabaseObject charmSpell = new DatabaseObject(); charmSpell.Set(DBProperties.SPELL_SLOT, 4).Set(DBProperties.SPELL_EXPIRES, expiresDate); DatabaseObject bouncyShield = new DatabaseObject(); bouncyShield.Set(DBProperties.SPELL_SLOT, 5).Set(DBProperties.SPELL_EXPIRES, expiresDate); spells.Set(Spells.FREEZE, freezeSpell); spells.Set(Spells.SPLIT_IN_TWO, splitSpell); spells.Set(Spells.LIGHTNING_ONE, lightningSpell); spells.Set(Spells.LASER_SHOTS, charmSpell); spells.Set(Spells.BOUNCY_SHIELD, bouncyShield); player.PlayerObject.Set(DBProperties.SPELL_OBJECT, spells); player.PlayerObject.Set(DBProperties.ENERGY, GameConfig.ENERGY_MAX); player.PlayerObject.Set(DBProperties.ENERGY_LAST_UPDATE, Utils.unixSecs()); player.PlayerObject.Set(DBProperties.ENERGY_EXPIRES, (double)0); player.PlayerObject.Set(DBProperties.RANK_NUMBER, 1); player.PlayerObject.Set(DBProperties.RANK_PROGRESS, GameConfig.RANK_PROGRESS_START); player.PlayerObject.Set(DBProperties.BOUNCER_ID, ShopItemsInfo.BOUNCER_STANDART_BLUE); player.PlayerObject.Set(DBProperties.SOUNDS_ON, true); player.PlayerObject.Set(DBProperties.MUSIC_ON, true); player.PlayerObject.Save(); BuyItemInfo bluePanel = new BuyItemInfo(ShopItemsInfo.BOUNCER_STANDART_BLUE); player.PayVault.Give(new BuyItemInfo[1] { bluePanel }, delegate() { }, _roomLink.handleError); player.PayVault.Credit(GameConfig.COINS_START_AMOUNT, "Started playing", delegate() { Console.WriteLine("Player got start coins"); }, handleError); } }
public static PlayerUpdateResult updatePlayerPostGame(Player pl, bool playerWon, string gameType, string mapID, ArrayList otherPlayers) { if (gameType == GameTypes.FAST_SPRINT) updateMaps(pl, mapID); var result = new PlayerUpdateResult(); result.newRankProtectionCount = updateRank(pl, playerWon, otherPlayers); result.coinsAdded = updateCoins(pl, playerWon, gameType); result.newRank = pl.PlayerObject.GetInt(DBProperties.RANK_NUMBER); result.newRankProgress = pl.PlayerObject.GetInt(DBProperties.RANK_PROGRESS); pl.PlayerObject.Save(); Console.WriteLine("Rank updated: new rank: " + result.newRank); Console.WriteLine("Rank updated: new rank progress: " + result.newRankProgress); return result; }
public bool playerIsElegible(int requestID, int slotID, Player player) { if (player.getRequestIDForSlotID(slotID) == -1) //player has no spell { Console.WriteLine("[SpellChecker] player has no spell"); return false; } string spellName = GameRequest.getSpellNameByRequest(requestID); double expires = player.PlayerObject.GetObject(DBProperties.SPELL_OBJECT) .GetObject(spellName) .GetDouble(DBProperties.SPELL_EXPIRES); if (Utils.unixSecs() > expires + 20) //spell expired. 20 seconds buffer for possible time async { if (!activationBuffer.Contains(spellName)) //if spell i snot being activated at the moment { Console.WriteLine("[SpellChecker] spell expired"); return false; } Console.WriteLine( "[SpellChecker] spell expired but activation transaction is being processed, allowing usage"); } if (!lastUses.ContainsKey(player.realID + requestID)) lastUses[player.realID + requestID] = new DateTime(1970, 1, 1); //just fill in, so that key exists TimeSpan sp = DateTime.UtcNow - lastUses[player.realID + requestID]; if (GameConfig.getCooldownTimeByRequest(requestID) >= sp.TotalMilliseconds + 1500) //add some buffer, allowing for whatever delays/differences might be. Client checks properly, so it matters only in case of cheating { Console.WriteLine("[SpellChecker] spell did not cool down"); return false; } //we are good, may use lastUses[player.realID + requestID] = DateTime.UtcNow; //update last usage time return true; }
private ArrayList getOtherPlayersPanelConfiguraions(Player firstDude) { var result = new ArrayList(); foreach (Player pla in roomLink.playingUsers) { if (pla != firstDude) { result.Add(pla.getPanelConfigString()); } } return result; }
private static void purchaseEnergyTicket(string itemKey, Player pl) { var item = new BuyItemInfo(itemKey); pl.PayVault.Buy(false, new BuyItemInfo[1] {item}, delegate { int days = 1; if (itemKey == ShopItemsInfo.ENERGY_TICKET_3_DAYS) days = 3; else if (itemKey == ShopItemsInfo.ENERGY_TICKET_7_DAYS) days = 7; int ticketLengthInSeconds = days*24*60*1000; pl.PlayerObject.Set(DBProperties.ENERGY, GameConfig.ENERGY_MAX); //set current energy to max (so when ticket experies energy is full) pl.PlayerObject.Set(DBProperties.ENERGY_EXPIRES, Utils.unixSecs() + ticketLengthInSeconds); pl.PlayerObject.Save(); }, delegate(PlayerIOError err) { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item (1st step)"); pl.roomLink.handleError(err); }); }
private void tryUseSpell(int slotID, Player requester) { int requestID = requester.getRequestIDForSlotID(slotID); Console.WriteLine("Game: try use spell: reqID: " + requestID + " slotID: " + slotID); //Commented down so that game runs on the Free Playerio plan (not paying for services for now) //if (_spellChecker.playerIsElegible(requestID, slotID, requester) && specificPowerupCheck()) //{ if (requestID == GameRequest.CHARM_BALLS) { var opponent = getOtherPlayers(requester, true)[0] as Player; opponent.goWiggle(); } else if (requestID == GameRequest.FREEZE) { var opponent = getOtherPlayers(requester, true)[0] as Player; opponent.goFreeze(); } else if (requestID == GameRequest.ROCKET) { var opponent = getOtherPlayers(requester, true)[0] as Player; opponent.goLaunchRocket(); } else //used for checking non-attacking spells. Because client insta-launches suvh spells we check them at server on execution requester.addAllowedSpell(requestID); //} //else //should not happen. Clicnt does all the checks. If we get here it means player is cheating //{ // Console.WriteLine("Unexpected spell usage attempt", "PlayerID: " + requester.realID + " RequestID: " + requestID + " SlotID: " + slotID, ""); // roomLink.PlayerIO.ErrorLog.WriteError("Unexpected spell usage attempt", "PlayerID: " + requester.realID + " RequestID: " + requestID + " SlotID: " + slotID, "", null); //} }
private static void processSpellActivation(Player pl, string spellName) { var item = new BuyItemInfo(spellName); bool needActivationBuffer = pl.roomLink.game != null; //user might be activating not during the game if (needActivationBuffer) //user might be activating not during the game pl.roomLink.game.spellChecker.putSpellInActivationBuffer(spellName); //so it is not blocked from usage while transaction is processed pl.PayVault.Buy(false, new BuyItemInfo[1] {item}, //immediately consume items. Instead PlayerObject is updated (for storage convenience) delegate { Console.WriteLine("PayVault ok..."); DatabaseObject spells = pl.getSpellsConfig(); double expiresDate = Utils.unixSecs() + GameConfig.SPELL_ACTIVATION_TIME*60*60; var newSpell = new DatabaseObject(); int prevSlotID = spells.Contains(spellName) ? spells.GetObject(spellName).GetInt(DBProperties.SPELL_SLOT) : -1; //dont lose spell newSpell.Set(DBProperties.SPELL_SLOT, prevSlotID); newSpell.Set(DBProperties.SPELL_EXPIRES, expiresDate); spells.Set(spellName, newSpell); pl.PlayerObject.Save(); pl.sendMessage(MessageTypes.ACTIVATE_SPELL_OK, spellName); //send "ok" back pl.roomLink.statisticsManager.onSpellActivated(spellName); if (needActivationBuffer) //user might be activating not during the game pl.roomLink.game.spellChecker.removeSpellFromActivationBuffer(spellName); //now checks are made as usual foreach (Player play in pl.roomLink.playingUsers) { if (!(play is NPCPlayer)) { play.sendMessage(MessageTypes.ACTIVATE_SPELL_OPPONENT, pl.realID, spellName); } } }, delegate(PlayerIOError err) { if (needActivationBuffer) //user might be activating not during the game pl.roomLink.game.spellChecker.removeSpellFromActivationBuffer(spellName); //now checks are made as usual pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item"); pl.roomLink.handleError(err); }); }
private static void processEnergyPurchase(Player pl, string itemKey) { if (itemKey == ShopItemsInfo.ENERGY_REFILL) { var item = new BuyItemInfo(itemKey); pl.PayVault.Buy(false, new BuyItemInfo[1] {item}, delegate { pl.PlayerObject.Set(DBProperties.ENERGY, GameConfig.ENERGY_MAX); pl.roomLink.playerEnergyTimer.resetLastUpdateTime(); pl.PlayerObject.Save(); }, delegate(PlayerIOError err) { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item (1st step)"); pl.roomLink.handleError(err); }); } else if (itemKey == ShopItemsInfo.ENERGY_TICKET_1_DAY || itemKey == ShopItemsInfo.ENERGY_TICKET_3_DAYS || itemKey == ShopItemsInfo.ENERGY_TICKET_7_DAYS) { purchaseEnergyTicket(itemKey, pl); } }
private static void updateMaps(Player pl, string mapID) { if (pl.isGuest) return; int map = Convert.ToInt32(mapID); int starsEarned = pl.roomLink.maps.getMapStarsByPoints(map, pl.points); Console.WriteLine("starsEarned: " + starsEarned); DatabaseObject maps = pl.PlayerObject.Contains(DBProperties.MAPS) ? pl.PlayerObject.GetObject(DBProperties.MAPS) : new DatabaseObject(); if (!maps.Contains(mapID) || maps.GetInt(mapID) < starsEarned) { maps.Set(mapID, starsEarned); //update stars config if player did better than before if (!pl.PlayerObject.Contains(DBProperties.MAPS)) { pl.PlayerObject.Set(DBProperties.MAPS, maps); } } }
private string getOtherPlayersBouncerIDs(Player firstDude) { var result = new ArrayList(); foreach (Player pla in roomLink.playingUsers) { if (pla != firstDude) { result.Add(pla.getBouncerID()); } } return string.Join(",", result.ToArray()); }
private static int updateRank(Player pl, bool playerWon, ArrayList otherPlayers) { int currentProgress = pl.PlayerObject.GetInt(DBProperties.RANK_PROGRESS); int currentRank = pl.PlayerObject.GetInt(DBProperties.RANK_NUMBER); int newRankProtectionCount = pl.getRankProtectionCount(); if (pl.isGuest) return newRankProtectionCount; if (playerWon) { int amountToAdd = 1; int rankSum = 0; int plCount = 0; foreach (Player pla in otherPlayers) { if (pla != pl && !(pla is NPCPlayer)) { rankSum += pla.PlayerObject.GetInt(DBProperties.RANK_NUMBER); plCount++; } } int avgRank = rankSum/(plCount > 0 ? plCount : 1); // if (avgRank > currentRank + 5) //player defeated dude who is 5 rank points higher // { if (pl.roomLink.rand.Next(10) > 7) //30% chance to receive double progress { amountToAdd = 2; } // } currentProgress += amountToAdd; if (currentProgress > 5) { currentRank++; currentProgress = GameConfig.RANK_PROGRESS_START; } } else { if (!(currentRank == 1 && currentProgress == 0)) //do nothing for 1st rank (that is absolute bottom) { if (newRankProtectionCount > 0) { newRankProtectionCount--; //variable for the sake of returning result var toConsume = new VaultItem[1]; foreach (VaultItem it in pl.PayVault.Items) { if (it.ItemKey == ShopItemsInfo.ARMOR_ITEM) { toConsume[0] = it; break; } } pl.PayVault.Consume(toConsume, delegate { Console.WriteLine("Protection item consumed!"); }, pl.roomLink.handleError); } else { if (currentProgress == 0) { currentProgress = GameConfig.RANK_PROGRESS_START; currentRank--; } else { currentProgress--; } } } } pl.PlayerObject.Set(DBProperties.RANK_NUMBER, currentRank); pl.PlayerObject.Set(DBProperties.RANK_PROGRESS, currentProgress); return newRankProtectionCount; }
/** * Player decided not to "play again". * If it is room owner - kick all other guys out * If it was a guest - just disconnect him */ public void onPlayerLeaving(Player leaver) { if (leaver.isRoomCreator) { foreach (Player pl in _roomLink.Players) { if (!pl.isRoomCreator) pl.Disconnect(); } cleanUp(); } else leaver.Disconnect(); }
private ArrayList getOtherPlayersIDs(Player firstDude) { var result = new ArrayList(); foreach (Player pla in roomLink.playingUsers) { if (pla != firstDude) { result.Add(pla.realID); } } return result; }
public void onPlayerLeftRoom(Player player) { if (player.isRoomCreator) _roomLink.statisticsManager.onCreatorLeftRoom(); //write down session length stats if (player == _battleRequestWaiter) _battleRequestWaiter = null; foreach (Player pl in _roomLink.Players) { pl.Send(MessageTypes.USER_LEFT, player.realID); } }
public void onPlayerJoined(Player player) { if (player.JoinData["gameVersion"] != GameConfig.GAME_VERSION.ToString()) //make sure client & server are of the same version always { //either client or server version is too old (if client - update fixes that, if server - user probably will catch new version next time) player.sendMessage(MessageTypes.GAME_UPDATED); player.Disconnect(); return; } _roomLink.versionManager.checkVersion(); //client & server may be the same, but old version. Check for new one. //Just set values here. Don't care much about what is player's intentions are ATM. player.realID = player.ConnectUserId; player.setRoomLink(_roomLink); _registrationManager.checkIfNewbie(player); if (player.realID == _roomLink.RoomId || (player.isGuest && player.JoinData.ContainsKey("theboss"))) { player.isRoomCreator = true; _roomCreator = player; //save link for convenience _roomLink.playerEnergyTimer.onRoomCreated(_roomCreator, _roomLink); //do energy checks for creator, maybe start timer player.Send(MessageTypes.AUTH_DATA, player.PlayerObject.GetInt(DBProperties.ENERGY), _roomLink.playerEnergyTimer.getTimeOfNextUpdate(), Utils.unixSecs()); } if (player.JoinData.ContainsKey("safeBattle")) //wants to play safe battle { Console.WriteLine("Player join data contains safeBattle! : " + player.realID); if (_roomLink.game == null && _battleRequestWaiter == null) //if not currently playing or awaiting game & nobody is not waiting for response anymore { _battleRequestWaiter = player; _roomCreator.Send(MessageTypes.BATTLE_REQUESTED, player.realID); } else { player.Send(MessageTypes.PLAYER_PLAYING_ALREADY); player.Disconnect(); } } else Console.WriteLine("Player join data does not contain safeBattle! : " + player.realID); }
private static void processBouncerPurchase(Player pl, string itemKey) { var item = new BuyItemInfo(itemKey); pl.PayVault.Buy(true, new BuyItemInfo[1] {item}, delegate { Console.WriteLine("Successfully bought " + itemKey); pl.PlayerObject.Set(DBProperties.BOUNCER_ID, itemKey); pl.PlayerObject.Save(); }, delegate(PlayerIOError err) { pl.sendMessage(MessageTypes.PURCHASE_FAILED, "Service error at buying item"); pl.roomLink.handleError(err); }); }
public void addToPlayingUsers(Player player) { player.ready = true; _playingUsers.Add(player); }