private Action <IdList> generateActivePlayerListHandler(
            AccountEffectList activeCrewAccountEffects,
            LedgerEffectList activePlayerAccountEffects,
            bool resetCrews = false)
        {
            Action <IdList> handler = playerIdList =>
            {
                var incrementedFactions = new HashSet <int>();
                var updatedCrewInfos    = new Dictionary <int, CrewInfo>();
                var count = 0;

                foreach (var item in playerIdList.list)
                {
                    var id  = new Id(item);
                    var cmd = new APICmd(CmdId.Request_Player_Info) + id;


                    broker.ExecuteCommand <PlayerInfo>(cmd, player =>
                    {
                        updatedCrewInfos = UpdatedCrewManifest(updatedCrewInfos, player);

                        var factionAccount = SafeGetAccount(AccountType.Crew, player.factionId, player);
                        var playerAccount  = SafeGetAccount(AccountType.Player, player.entityId, player);

                        var factionExp = factionAccount.balances[ResourceType.Experience];
                        factionAccount.balances[ResourceType.Experience] = factionExp < player.exp ? player.exp : factionExp;

                        if (!incrementedFactions.Contains(player.factionId))
                        {
                            var factionAccountKey = Account.IdKeyFromInfo(AccountType.Crew, player.factionId);
                            var tmpAcct           = factionAccount;
                            factionAccount        = activeCrewAccountEffects.Aggregate(tmpAcct, (acc, x) => x(acc));
                            incrementedFactions.Add(player.factionId);
                        }

                        var baseLedger     = new PlayerLedger(player, factionAccount, playerAccount);
                        var adjustedLedger = activePlayerAccountEffects.Aggregate(baseLedger, (memo, effect) => effect(memo));
                        playerAccount      = adjustedLedger.PersonalAccount;
                        factionAccount     = adjustedLedger.FactionAccount;

                        SaveAccount(playerAccount);
                        SaveAccount(factionAccount);

                        normalizePlayer(adjustedLedger);
                        count++;
                        log(() => $"normalized {count}/{ playerIdList.list.Count}: {player.playerName}");

                        if (count == playerIdList.list.Count)
                        {
                            log(() => $"updating crews to: {Serializer.Serialize(CrewInfoTracker)}");
                            CrewInfoTracker = updatedCrewInfos;
                        }
                    });
                }
            };

            return(handler);
        }
 private PlayerLedger shiftBalanceToPlayerOnPersonalFaction(PlayerLedger ledger)
 {
     if (ledger.PersonalAccount.id == ledger.FactionAccount.id)
     {
         ledger.PersonalAccount.balances[ResourceType.Points] += ledger.FactionAccount.balances[ResourceType.Points];
         ledger.FactionAccount.balances[ResourceType.Points]   = 0;
     }
     return(ledger);
 }
 private PlayerLedger initializeNewAccount(PlayerLedger ledger)
 {
     if (!initializedPlayerIds.Contains(ledger.info.entityId))
     {
         var points = ledger.info.upgrade > settings.startingUpgradePointBalance ? ledger.info.upgrade: settings.startingUpgradePointBalance;
         ledger.PersonalAccount.balances[ResourceType.Points] = points;
         initializedPlayerIds.Add(ledger.info.entityId);
     }
     return(ledger);
 }
        public void transferBalance(int playerId, int amount, TransactionType type, Action <BalanceActionResult> callback)
        {
            var id  = new Id(playerId);
            var cmd = new APICmd(CmdId.Request_Player_Info) + id;

            broker.ExecuteCommand <PlayerInfo>(cmd, (x, y) => {
                log(() => "****player info received");
                BalanceActionResult result;
                var factionAccount = SafeGetAccount(AccountType.Crew, y.factionId, y);
                var playerAccount  = SafeGetAccount(AccountType.Player, y.entityId, y);

                result = new BalanceActionResult()
                {
                    crewBalance     = factionAccount.balances[ResourceType.Points],
                    playerBalance   = playerAccount.balances[ResourceType.Points],
                    amountRequested = amount,
                    playerAccount   = playerId,
                    crewAccount     = y.factionId,
                    transactionType = type,
                    playerName      = y.playerName
                };

                var requestedCrewBalance   = result.crewBalance - amount;
                var requestedPlayerBalance = result.playerBalance + amount;

                if (requestedCrewBalance < 0)
                {
                    result.reason    = "insufficient crew balance";
                    result.succeeded = false;
                }
                else if (requestedPlayerBalance < 0)
                {
                    result.reason    = "insufficient player balance";
                    result.succeeded = false;
                }
                else
                {
                    result.crewBalance   = requestedCrewBalance;
                    result.playerBalance = requestedPlayerBalance;
                    result.succeeded     = true;
                }

                log(() => $"***transaction: {Serializer.Serialize(result)}");

                playerAccount.balances[ResourceType.Points] = result.playerBalance;
                SaveAccount(playerAccount);
                factionAccount.balances[ResourceType.Points] = result.crewBalance;
                SaveAccount(factionAccount);
                var ledger = new PlayerLedger(y, factionAccount, playerAccount);
                normalizePlayer(ledger);

                callback(result);
            });
        }
        private void normalizePlayer(PlayerLedger ledger)
        {
            var infoSet = new PlayerInfoSet()
            {
                entityId         = ledger.info.entityId,
                experiencePoints = ledger.FactionAccount.balances[ResourceType.Experience],
                upgradePoints    = ledger.PersonalAccount.balances[ResourceType.Points],
            };

            log(() => $"normalizing player: {ledger.info.playerName} with points: { infoSet.upgradePoints}");
            log(() => $"factionAccount: {Serializer.Serialize(ledger.FactionAccount)} playerAccount: {Serializer.Serialize(ledger.PersonalAccount)}");

            var cmd = new APICmd(CmdId.Request_Player_SetPlayerInfo, infoSet);

            broker.ExecuteCommand(cmd);
        }
        private PlayerLedger captureGameEffectPoints(PlayerLedger ledger)
        {
            var norm = new PlayerNorm(ledger.FactionAccount, ledger.PersonalAccount);

            if (norm != ledger.norm)
            {
                return(ledger);
            }

            log(() => $"norm is {Serializer.Serialize(norm)}\nledger norm is:{Serializer.Serialize(ledger.norm)}\nplayer points is:{ledger.info.upgrade}");

            if (ledger.PersonalAccount.balances[ResourceType.Points] != ledger.info.upgrade)
            {
                ledger.PersonalAccount.balances[ResourceType.Points] = ledger.info.upgrade;
            }
            return(ledger);
        }