Holds information about a transaction that is to be cached, and committed some time in the future.
Beispiel #1
0
        /// <summary>
        /// Runs when a player dies, and hands out penalties if enabled, and rewards for PVP
        /// </summary>
        protected void ProcessDeath(int DeadPlayerSlot, bool PVPDeath)
        {
            TSPlayer     murderer = null, murdered = null;
            IBankAccount murderedAccount, murdererAccount;
            Money        penalty        = default(Money);
            int          lastHitterSlot = default(int);

            Journal.CachedTransaction worldToPlayerTx = null,
                                      playerToWorldTx = null;

            //get the last hitter ID out of the dictionary
            lock (__pvpDictMutex) {
                if (PVPDamage.ContainsKey(DeadPlayerSlot))
                {
                    lastHitterSlot = PVPDamage[DeadPlayerSlot];
                    PVPDamage.Remove(DeadPlayerSlot);
                }
            }

            if ((murdered = TShockAPI.TShock.Players.ElementAtOrDefault(DeadPlayerSlot)) == null ||
                murdered.Group.HasPermission("seconomy.world.bypassdeathpenalty") == true ||
                (murderedAccount = Parent.GetBankAccount(murdered)) == null ||
                (penalty = GetDeathPenalty(murdered)) == 0)
            {
                return;
            }

            playerToWorldTx = new Journal.CachedTransaction()
            {
                DestinationBankAccountK = Parent.WorldAccount.BankAccountK,
                SourceBankAccountK      = murderedAccount.BankAccountK,
                Message = "dying",
                Options = Journal.BankAccountTransferOptions.MoneyTakenOnDeath | Journal.BankAccountTransferOptions.AnnounceToSender,
                Amount  = penalty
            };

            //the dead player loses money unconditionally
            Parent.TransactionCache.AddCachedTransaction(playerToWorldTx);

            //but if it's a PVP death, the killer gets the losers penalty if enabled
            if (PVPDeath && WorldConfiguration.MoneyFromPVPEnabled && WorldConfiguration.KillerTakesDeathPenalty)
            {
                if ((murderer = TShockAPI.TShock.Players.ElementAtOrDefault(lastHitterSlot)) == null ||
                    (murdererAccount = Parent.GetBankAccount(murderer)) == null)
                {
                    return;
                }

                worldToPlayerTx = new Journal.CachedTransaction()
                {
                    SourceBankAccountK      = Parent.WorldAccount.BankAccountK,
                    DestinationBankAccountK = murdererAccount.BankAccountK,
                    Amount  = penalty,
                    Message = "killing " + murdered.Name,
                    Options = Journal.BankAccountTransferOptions.AnnounceToReceiver,
                };

                Parent.TransactionCache.AddCachedTransaction(worldToPlayerTx);
            }
        }
        /// <summary>
        /// Processes all elements in the queue and transfers them
        /// </summary>
        protected async Task ProcessQueueAsync()
        {
            List <CachedTransaction> aggregatedFunds = new List <CachedTransaction>();
            CachedTransaction        fund;

            while (CachedTransactions.TryDequeue(out fund))
            {
                //The idea of this is that the concurrent queue will aggregate everything with the same message.
                //So instead of spamming eye of ctaltlatlatututlutultu (shut up) it'll just agg them into one
                //and print something like "You gained 60 silver from 20 eyes" instead of spamming both the chat log
                //and the journal with bullshit
                CachedTransaction existingFund = aggregatedFunds.FirstOrDefault(i => i.Message == fund.Message && i.SourceBankAccountK == fund.SourceBankAccountK && i.DestinationBankAccountK == fund.DestinationBankAccountK);
                if (existingFund != null)
                {
                    existingFund.Amount += fund.Amount;

                    //indicate that this is an aggregate of a previous uncommitted fund
                    existingFund.Aggregations++;
                }
                else
                {
                    aggregatedFunds.Add(fund);
                }
            }

            foreach (CachedTransaction aggregatedFund in aggregatedFunds)
            {
                Journal.IBankAccount sourceAccount = SEconomyPlugin.Instance.RunningJournal.GetBankAccount(aggregatedFund.SourceBankAccountK);
                Journal.IBankAccount destAccount   = SEconomyPlugin.Instance.RunningJournal.GetBankAccount(aggregatedFund.DestinationBankAccountK);

                if (sourceAccount != null && destAccount != null)
                {
                    StringBuilder messageBuilder = new StringBuilder(aggregatedFund.Message);

                    if (aggregatedFund.Aggregations > 1)
                    {
                        messageBuilder.Insert(0, aggregatedFund.Aggregations + " ");
                        messageBuilder.Append("s");
                    }
                    //transfer the money
                    BankTransferEventArgs transfer = await sourceAccount.TransferToAsync(destAccount, aggregatedFund.Amount, aggregatedFund.Options, messageBuilder.ToString(), messageBuilder.ToString());

                    if (!transfer.TransferSucceeded)
                    {
                        if (transfer.Exception != null)
                        {
                            TShock.Log.ConsoleError(string.Format("seconomy cache: error source={0} dest={1}: {2}", aggregatedFund.SourceBankAccountK, aggregatedFund.DestinationBankAccountK, transfer.Exception));
                        }
                    }
                }
                else
                {
                    TShock.Log.ConsoleError(string.Format("seconomy cache: transaction cache has no source or destination. source key={0} dest key={1}", aggregatedFund.SourceBankAccountK, aggregatedFund.DestinationBankAccountK));
                }
            }
        }
 /// <summary>
 /// Adds a fund to the uncommitted cache
 /// </summary>
 public void AddCachedTransaction(CachedTransaction Fund)
 {
     CachedTransactions.Enqueue(Fund);
 }
Beispiel #4
0
        /// <summary>
        /// Should occur when an NPC dies; gives rewards out to all the players that hit it.
        /// </summary>
        protected void GiveRewardsForNPC(OTAPI.Terraria.NPC NPC)
        {
            List <PlayerDamage> playerDamageList = null;
            IBankAccount        account;
            TSPlayer            player;
            Money rewardMoney = 0L;

            lock (__dictionaryMutex)
            {
                if (DamageDictionary.ContainsKey(NPC))
                {
                    playerDamageList = DamageDictionary[NPC];

                    if (DamageDictionary.Remove(NPC) == false)
                    {
                        TShock.Log.ConsoleError("[SEconomy World] Removal of NPC after reward failed. This is an internal error.");
                    }
                }
            }

            if (playerDamageList == null)
            {
                return;
            }

            if (((NPC.boss && WorldConfiguration.MoneyFromBossEnabled) || (!NPC.boss && WorldConfiguration.MoneyFromNPCEnabled)) && !(NPC.SpawnedFromStatue && WorldConfiguration.IgnoreSpawnedFromStatue))
            {
                foreach (PlayerDamage damage in playerDamageList)
                {
                    if (damage.Player == null ||
                        (player = TShockAPI.TShock.Players.FirstOrDefault(i => i != null && i.Index == damage.Player.whoAmI)) == null ||
                        (account = Parent.GetBankAccount(player)) == null)
                    {
                        continue;
                    }

                    rewardMoney = CustomMultiplier * Convert.ToInt64(Math.Round(Convert.ToDouble(WorldConfiguration.MoneyPerDamagePoint) * damage.Damage));

                    //load override by NPC type, this allows you to put a modifier on the base for a specific mob type.
                    Configuration.WorldConfiguration.NPCRewardOverride overrideReward = WorldConfiguration.Overrides.FirstOrDefault(i => i.NPCID == NPC.type);
                    if (overrideReward != null)
                    {
                        rewardMoney = CustomMultiplier * Convert.ToInt64(Math.Round(Convert.ToDouble(overrideReward.OverridenMoneyPerDamagePoint) * damage.Damage));
                    }

                    if (rewardMoney <= 0 || player.Group.HasPermission("seconomy.world.mobgains") == false)
                    {
                        continue;
                    }

                    Journal.CachedTransaction fund = new Journal.CachedTransaction()
                    {
                        Aggregations            = 1,
                        Amount                  = rewardMoney,
                        DestinationBankAccountK = account.BankAccountK,
                        Message                 = NPC.FullName,
                        SourceBankAccountK      = Parent.WorldAccount.BankAccountK
                    };

                    if ((NPC.boss && WorldConfiguration.AnnounceBossKillGains) || (!NPC.boss && WorldConfiguration.AnnounceNPCKillGains))
                    {
                        fund.Options |= Journal.BankAccountTransferOptions.AnnounceToReceiver;
                    }

                    //commit it to the transaction cache
                    Parent.TransactionCache.AddCachedTransaction(fund);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Runs when a player dies, and hands out penalties if enabled, and rewards for PVP
        /// </summary>
        protected void ProcessDeath(int DeadPlayerSlot, bool PVPDeath)
        {
            TSPlayer murderer = null, murdered = null;
            IBankAccount murderedAccount, murdererAccount;
            Money penalty = default(Money);
            int lastHitterSlot = default(int);
            Journal.CachedTransaction worldToPlayerTx = null,
            playerToWorldTx = null;

            //get the last hitter ID out of the dictionary
            lock (__pvpDictMutex) {
                if (PVPDamage.ContainsKey(DeadPlayerSlot)) {
                    lastHitterSlot = PVPDamage[DeadPlayerSlot];
                    PVPDamage.Remove(DeadPlayerSlot);
                }
            }

            if ((murdered = TShockAPI.TShock.Players.ElementAtOrDefault(DeadPlayerSlot)) == null
                || murdered.Group.HasPermission("seconomy.world.bypassdeathpenalty") == true
                || (murderedAccount = Parent.GetBankAccount(murdered)) == null
                || (penalty = GetDeathPenalty(murdered)) == 0) {
                return;
            }

            playerToWorldTx = new Journal.CachedTransaction() {
                DestinationBankAccountK = Parent.WorldAccount.BankAccountK,
                SourceBankAccountK = murderedAccount.BankAccountK,
                Message = "dying",
                Options = Journal.BankAccountTransferOptions.MoneyTakenOnDeath | Journal.BankAccountTransferOptions.AnnounceToSender,
                Amount = penalty
            };

            //the dead player loses money unconditionally
            Parent.TransactionCache.AddCachedTransaction(playerToWorldTx);

            //but if it's a PVP death, the killer gets the losers penalty if enabled
            if (PVPDeath && WorldConfiguration.MoneyFromPVPEnabled && WorldConfiguration.KillerTakesDeathPenalty) {
                if ((murderer = TShockAPI.TShock.Players.ElementAtOrDefault(lastHitterSlot)) == null
                    || (murdererAccount = Parent.GetBankAccount(murderer)) == null) {
                    return;
                }

                worldToPlayerTx = new Journal.CachedTransaction() {
                    SourceBankAccountK = Parent.WorldAccount.BankAccountK,
                    DestinationBankAccountK = murdererAccount.BankAccountK,
                    Amount = penalty,
                    Message = "killing " + murdered.Name,
                    Options = Journal.BankAccountTransferOptions.AnnounceToReceiver,
                };

                Parent.TransactionCache.AddCachedTransaction(worldToPlayerTx);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Should occur when an NPC dies; gives rewards out to all the players that hit it.
        /// </summary>
        protected void GiveRewardsForNPC(Terraria.NPC NPC)
        {
            List<PlayerDamage> playerDamageList = null;
            IBankAccount account;
            TSPlayer player;
            Money rewardMoney = 0L;

            lock (__dictionaryMutex) {
                if (DamageDictionary.ContainsKey(NPC)) {
                    playerDamageList = DamageDictionary[NPC];

                    if (DamageDictionary.Remove(NPC) == false) {
                        TShock.Log.ConsoleError("seconomy: world economy: Remove of NPC after reward failed.  This is an internal error.");
                    }
                }
            }

            if (playerDamageList == null) {
                return;
            }

            if ((NPC.boss && WorldConfiguration.MoneyFromBossEnabled) || (!NPC.boss && WorldConfiguration.MoneyFromNPCEnabled)) {
                foreach (PlayerDamage damage in playerDamageList) {
                    if (damage.Player == null
                        || (player = TShockAPI.TShock.Players.FirstOrDefault(i => i != null && i.Index == damage.Player.whoAmI)) == null
                        || (account = Parent.GetBankAccount(player)) == null) {
                        continue;
                    }

                    rewardMoney = CustomMultiplier * Convert.ToInt64(Math.Round(Convert.ToDouble(WorldConfiguration.MoneyPerDamagePoint) * damage.Damage));

                    //load override by NPC type, this allows you to put a modifier on the base for a specific mob type.
                    Configuration.WorldConfiguration.NPCRewardOverride overrideReward = WorldConfiguration.Overrides.FirstOrDefault(i => i.NPCID == NPC.type);
                    if (overrideReward != null) {
                        rewardMoney = CustomMultiplier * Convert.ToInt64(Math.Round(Convert.ToDouble(overrideReward.OverridenMoneyPerDamagePoint) * damage.Damage));
                    }

                    if (rewardMoney <= 0 || player.Group.HasPermission("seconomy.world.mobgains") == false) {
                        continue;
                    }

                    Journal.CachedTransaction fund = new Journal.CachedTransaction() {
                        Aggregations = 1,
                        Amount = rewardMoney,
                        DestinationBankAccountK = account.BankAccountK,
                        Message = NPC.name,
                        SourceBankAccountK = Parent.WorldAccount.BankAccountK
                    };

                    if ((NPC.boss && WorldConfiguration.AnnounceBossKillGains) || (!NPC.boss && WorldConfiguration.AnnounceNPCKillGains)) {
                        fund.Options |= Journal.BankAccountTransferOptions.AnnounceToReceiver;
                    }

                    //commit it to the transaction cache
                    Parent.TransactionCache.AddCachedTransaction(fund);
                }
            }
        }
		/// <summary>
		/// Adds a fund to the uncommitted cache
		/// </summary>
		public void AddCachedTransaction(CachedTransaction Fund)
		{
			CachedTransactions.Enqueue(Fund);
		}