/// <summary> /// Raises the BankTransferComplete event /// </summary> /// <param name="Args"></param> void OnBankTransferComplete(BankTransferEventArgs Args) { if (BankTransferCompleted != null) { BankTransferCompleted(this, Args); } }
/// <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> /// Asynchronously transfers to another account. /// </summary> public Task <BankTransferEventArgs> TransferToAsync(XBankAccount ToAccount, Money Amount, BankAccountTransferOptions Options, string Message = "") { Guid profile = SEconomyPlugin.Profiler.Enter(string.Format("transferAsync: {0} to {1}", this.UserAccountName, ToAccount.UserAccountName)); return(Task.Factory.StartNew <BankTransferEventArgs>(() => { BankTransferEventArgs args = TransferTo(ToAccount, Amount, Options, UseProfiler: false, Message: Message); return args; }).ContinueWith((task) => { SEconomyPlugin.Profiler.ExitLog(profile); return task.Result; })); }
/// <summary> /// Asynchronously transfers to another account. /// </summary> public Task <BankTransferEventArgs> TransferToAsync(int Index, Money Amount, BankAccountTransferOptions Options, string Message = "") { Economy.EconomyPlayer ePlayer = SEconomyPlugin.GetEconomyPlayerSafe(Index); Guid profile = SEconomyPlugin.Profiler.Enter(string.Format("transferAsync: {0} to {1}", this.UserAccountName, ePlayer.BankAccount != null ? ePlayer.BankAccount.UserAccountName : "Unknown")); return(Task.Factory.StartNew <BankTransferEventArgs>(() => { BankTransferEventArgs args = TransferTo(ePlayer.BankAccount, Amount, Options, UseProfiler: false, Message: Message); return args; }).ContinueWith((task) => { SEconomyPlugin.Profiler.ExitLog(profile); return task.Result; })); }
public async void SEconomyTransferAsync(Journal.IBankAccount From, Journal.IBankAccount To, Money Amount, string TxMessage, JsValue completedCallback) { BankTransferEventArgs result = null; if (JistPlugin.Instance == null || SEconomyPlugin.Instance == null || From == null || To == null) { return; } result = await From.TransferToAsync(To, Amount, Journal.BankAccountTransferOptions.AnnounceToSender, TxMessage, TxMessage); if (result == null) { result = new BankTransferEventArgs() { TransferSucceeded = false }; } Jist.JistPlugin.Instance.CallFunction(completedCallback, null, result); }
/// <summary> /// Default messages sent to players when a transaction happens within SEconomy. /// </summary> protected void BankAccount_BankTransferCompleted(object s, Journal.BankTransferEventArgs e) { TSPlayer sender, receiver; if (e.ReceiverAccount == null || (e.TransferOptions & Journal.BankAccountTransferOptions.SuppressDefaultAnnounceMessages) == Journal.BankAccountTransferOptions.SuppressDefaultAnnounceMessages) { return; } sender = TShockAPI.TShock.Players.FirstOrDefault(i => i != null && i.Name == e.SenderAccount.UserAccountName); receiver = TShockAPI.TShock.Players.FirstOrDefault(i => i != null && i.Name == e.ReceiverAccount.UserAccountName); Wolfje.Plugins.SEconomy.Configuration.WorldConfiguration.WorldConfig wConfig = Parent.WorldEc.WorldConfiguration; int cRGB = (int)new Color( wConfig.OverheadColor[0], wConfig.OverheadColor[1], wConfig.OverheadColor[2] ).PackedValue; if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && e.ReceiverAccount != null && receiver != null) { bool gained = (e.Amount > 0 && (e.TransferOptions & BankAccountTransferOptions.IsPayment) == BankAccountTransferOptions.None); if (wConfig.ShowKillGainsDetailed) { string message = string.Format("{5}SEconomy\r\n{0}{1}\r\n{2}\r\nBal: {3}{4}", (gained ? "+" : ""), e.Amount.ToString(), "for " + e.TransactionMessage, e.ReceiverAccount.Balance.ToString(), RepeatLineBreaks(59), RepeatLineBreaks(11)); receiver.SendData(PacketTypes.Status, message, 0); } if (wConfig.ShowKillGainsOverhead) { receiver.SendData((PacketTypes)119, (gained ? "+" : "") + e.Amount.ToString(), cRGB, receiver.X, receiver.Y); } } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && sender != null) { //bool gained = (e.Amount > 0 && (e.TransferOptions & BankAccountTransferOptions.IsPayment) == BankAccountTransferOptions.None); bool gained = false; // because sender always loses money? if (wConfig.ShowKillGainsDetailed) { string message = string.Format("{5}SEconomy\r\n{0}{1}\r\n{2}\r\nBal: {3}{4}", (gained ? "+" : "-"), e.Amount.ToString(), "for " + e.TransactionMessage, e.SenderAccount.Balance.ToString(), RepeatLineBreaks(59), RepeatLineBreaks(11)); sender.SendData(PacketTypes.Status, message, 0);; } if (wConfig.ShowKillGainsOverhead) { sender.SendData((PacketTypes)119, (gained ? "+" : "-") + e.Amount.ToString(), cRGB, sender.X, sender.Y); } } return; if ((e.TransferOptions & Journal.BankAccountTransferOptions.IsPlayerToPlayerTransfer) == Journal.BankAccountTransferOptions.IsPlayerToPlayerTransfer) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && e.ReceiverAccount != null && receiver != null) { //string message = string.Format(SEconomyPlugin.Locale.StringOrDefault(16, "You {3} {0} from {1}. Transaction # {2}"), e.Amount.ToLongString(), // sender != null ? sender.Name : SEconomyPlugin.Locale.StringOrDefault(17, "The server"), e.TransactionID, // e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(18, "received") : SEconomyPlugin.Locale.StringOrDefault(19, "sent")); //receiver.SendData(PacketTypes.Status, message, 50); // receiver.SendMessage(), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && sender != null) { sender.SendMessage(string.Format(SEconomyPlugin.Locale.StringOrDefault(16, "You {3} {0} from {1}. Transaction # {2}"), e.Amount.ToLongString(), receiver.Name, e.TransactionID, e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(19, "sent") : SEconomyPlugin.Locale.StringOrDefault(18, "received")), Color.Orange); } //Everything else, including world to player, and player to world. } else { if ((e.TransferOptions & Journal.BankAccountTransferOptions.IsPayment) == Journal.BankAccountTransferOptions.IsPayment) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && sender != null) { sender.SendMessage(string.Format(SEconomyPlugin.Locale.StringOrDefault(20, "You {0} {1}{2}"), e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(21, "paid") : SEconomyPlugin.Locale.StringOrDefault(22, "got paid"), e.Amount.ToLongString(), !string.IsNullOrEmpty(e.TransactionMessage) ? SEconomyPlugin.Locale.StringOrDefault(25, " for ") + e.TransactionMessage : ""), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && receiver != null) { receiver.SendMessage(string.Format(SEconomyPlugin.Locale.StringOrDefault(20, "You {0} {1}{2}"), e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(22, "got paid") : SEconomyPlugin.Locale.StringOrDefault(22, "paid"), e.Amount.ToLongString(), !string.IsNullOrEmpty(e.TransactionMessage) ? SEconomyPlugin.Locale.StringOrDefault(25, " for ") + e.TransactionMessage : ""), Color.Orange); } } else { if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && sender != null) { sender.SendMessage(string.Format(SEconomyPlugin.Locale.StringOrDefault(20, "You {0} {1}{2}"), e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(23, "lost") : SEconomyPlugin.Locale.StringOrDefault(24, "gained"), e.Amount.ToLongString(), !string.IsNullOrEmpty(e.TransactionMessage) ? SEconomyPlugin.Locale.StringOrDefault(25, " for ") + e.TransactionMessage : ""), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && receiver != null) { //string message = string.Format(SEconomyPlugin.Locale.StringOrDefault(20, "You {0} {1}{2}"), e.Amount > 0 ? SEconomyPlugin.Locale.StringOrDefault(24, "gained") // : SEconomyPlugin.Locale.StringOrDefault(23, "lost"), e.Amount.ToLongString(), // !string.IsNullOrEmpty(e.TransactionMessage) ? SEconomyPlugin.Locale.StringOrDefault(25, " for ") + e.TransactionMessage : ""); //string message = string.Format("SEconomy\r\n{0}{1}\r\n{2}\r\nBal: {3}{4}", // (e.Amount > 0 ? "+" : "-"), e.Amount.ToString(), // e.TransactionMessage, // e.ReceiverAccount.Balance.ToString(), // RepeatLineBreaks(50)); //receiver.SendData(PacketTypes.Status, message, 0); // receiver.SendMessage(), Color.Orange); } } } }
/// <summary> /// Transfers money from this account to the destination account, if negative, takes money from the destination account into this account. /// </summary> public BankTransferEventArgs TransferTo(XBankAccount ToAccount, Money Amount, BankAccountTransferOptions Options, bool UseProfiler = true, string Message = "") { lock (__tranlock) { BankTransferEventArgs args = new BankTransferEventArgs(); Guid profile = Guid.Empty; if (UseProfiler) { profile = SEconomyPlugin.Profiler.Enter(string.Format("transfer: {0} to {1}", this.UserAccountName, ToAccount.UserAccountName)); } if (ToAccount != null && TransferMaySucceed(this, ToAccount, Amount, Options)) { args.Amount = Amount; args.SenderAccount = this; args.ReceiverAccount = ToAccount; args.TransferOptions = Options; args.TransferSucceeded = false; //insert the source negative transaction XTransaction sourceTran = BeginSourceTransaction(Amount, Message); if (sourceTran != null && !string.IsNullOrEmpty(sourceTran.BankAccountTransactionK)) { //insert the destination inverse transaction XTransaction destTran = FinishEndTransaction(sourceTran.BankAccountTransactionK, ToAccount, Amount, Message); if (destTran != null && !string.IsNullOrEmpty(destTran.BankAccountTransactionK)) { //perform the double-entry binding BindTransactions(ref sourceTran, ref destTran); args.TransactionID = sourceTran.BankAccountTransactionK; //update balances this.Balance += (Amount * (-1)); ToAccount.Balance += Amount; //transaction complete args.TransferSucceeded = true; } } } else { args.TransferSucceeded = false; if (!ToAccount.IsSystemAccount && !ToAccount.IsPluginAccount) { if (Amount < 0) { this.Owner.TSPlayer.SendErrorMessageFormat("Invalid amount."); } else { this.Owner.TSPlayer.SendErrorMessageFormat("You need {0} more money to make this payment.", ((Money)(this.Balance - Amount)).ToLongString()); } } } //raise the transfer event OnBankTransferComplete(args); if (UseProfiler) { SEconomyPlugin.Profiler.ExitLog(profile); } return(args); } }
/// <summary> /// Occurs when a bank transfer completes. /// </summary> void BankAccount_BankTransferCompleted(object sender, Journal.BankTransferEventArgs e) { //this is pretty balls too, but will do for now. lock (__transferCompleteLock) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.SuppressDefaultAnnounceMessages) == Journal.BankAccountTransferOptions.SuppressDefaultAnnounceMessages) { return; } else if (e.ReceiverAccount != null) { //Player died from PvP if ((e.TransferOptions & Journal.BankAccountTransferOptions.MoneyFromPvP) == Journal.BankAccountTransferOptions.MoneyFromPvP) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver) { e.ReceiverAccount.Owner.TSPlayer.SendMessage(string.Format("You killed {0} and gained {1}.", e.SenderAccount.Owner.TSPlayer.Name, e.Amount.ToLongString()), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender) { e.SenderAccount.Owner.TSPlayer.SendMessage(string.Format("{0} killed you and you lost {1}.", e.ReceiverAccount.Owner.TSPlayer.Name, e.Amount.ToLongString()), Color.Orange); } //P2P transfers, both the sender and the reciever get notified. } else if ((e.TransferOptions & Journal.BankAccountTransferOptions.IsPlayerToPlayerTransfer) == Journal.BankAccountTransferOptions.IsPlayerToPlayerTransfer) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && e.ReceiverAccount != null && e.ReceiverAccount.Owner != null) { e.ReceiverAccount.Owner.TSPlayer.SendMessage(string.Format("You received {0} from {1}. Transaction # {2}", e.Amount.ToLongString(), e.SenderAccount.Owner != null ? e.SenderAccount.Owner.TSPlayer.Name : "The server", e.TransactionID), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && e.SenderAccount.Owner != null) { e.SenderAccount.Owner.TSPlayer.SendMessage(string.Format("You sent {0} to {1}. Transaction # {2}", e.Amount.ToLongString(), e.ReceiverAccount.Owner.TSPlayer.Name, e.TransactionID), Color.Orange); } //Everything else, including world to player, and player to world. } else { string moneyVerb = ""; if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToSender) == Journal.BankAccountTransferOptions.AnnounceToSender && e.SenderAccount.Owner != null) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.IsPayment) == Journal.BankAccountTransferOptions.IsPayment) { moneyVerb = "paid"; } else if (e.Amount > 0) { moneyVerb = "gained"; } else { moneyVerb = "lost"; } e.SenderAccount.Owner.TSPlayer.SendMessage(string.Format("You {0} {1}", moneyVerb, e.Amount.ToLongString()), Color.Orange); } if ((e.TransferOptions & Journal.BankAccountTransferOptions.AnnounceToReceiver) == Journal.BankAccountTransferOptions.AnnounceToReceiver && e.ReceiverAccount.Owner != null) { if ((e.TransferOptions & Journal.BankAccountTransferOptions.IsPayment) == Journal.BankAccountTransferOptions.IsPayment) { moneyVerb = "got paid"; } else if (e.Amount > 0) { moneyVerb = "gained"; } else { moneyVerb = "lost"; } e.ReceiverAccount.Owner.TSPlayer.SendMessage(string.Format("You {0} {1}", moneyVerb, e.Amount.ToLongString()), Color.Orange); } } } else if (e.TransferSucceeded == true) { TShockAPI.Log.ConsoleError("seconomy error: Bank account transfer completed without a receiver: ID " + e.TransactionID); } } }
/// <summary> /// Transfers money from this account to the destination account, if negative, takes money from the destination account into this account. /// </summary> public BankTransferEventArgs TransferTo(XBankAccount ToAccount, Money Amount, BankAccountTransferOptions Options, string TransactionMessage, string JournalMessage) { BankTransferEventArgs args = new BankTransferEventArgs(); Guid profile = Guid.Empty; try { lock (__tranlock) { if (ToAccount != null) { if (TransferMaySucceed(this, ToAccount, Amount, Options)) { if (SEconomyPlugin.Configuration.EnableProfiler) { profile = SEconomyPlugin.Profiler.Enter(string.Format("transfer: {0} to {1}", !string.IsNullOrEmpty(this.UserAccountName) ? this.UserAccountName : "Unknown", ToAccount != null && !string.IsNullOrEmpty(ToAccount.UserAccountName) ? ToAccount.UserAccountName : "Unknown")); } args.Amount = Amount; args.SenderAccount = this; args.ReceiverAccount = ToAccount; args.TransferOptions = Options; args.TransferSucceeded = false; args.TransactionMessage = TransactionMessage; //insert the source negative transaction XTransaction sourceTran = BeginSourceTransaction(Amount, JournalMessage); if (sourceTran != null && !string.IsNullOrEmpty(sourceTran.BankAccountTransactionK)) { //insert the destination inverse transaction XTransaction destTran = FinishEndTransaction(sourceTran.BankAccountTransactionK, ToAccount, Amount, JournalMessage); if (destTran != null && !string.IsNullOrEmpty(destTran.BankAccountTransactionK)) { //perform the double-entry binding BindTransactions(ref sourceTran, ref destTran); args.TransactionID = sourceTran.BankAccountTransactionK; //update balances this.Balance += (Amount * (-1)); ToAccount.Balance += Amount; //transaction complete args.TransferSucceeded = true; } } } else { args.TransferSucceeded = false; //concept: ?????? //if the amount coming from "this" account is a negative then the "sender account" needs to know the transfer failed. //if the amount coming from "this" acount is a positive then the "reciever account" needs to know the transfer failed. if (!ToAccount.IsSystemAccount && !ToAccount.IsPluginAccount) { if (this.Owner != null) { if (Amount < 0) { this.Owner.TSPlayer.SendErrorMessageFormat("Invalid amount."); } else { this.Owner.TSPlayer.SendErrorMessageFormat("You need {0} more money to make this payment.", ((Money)(this.Balance - Amount)).ToLongString()); } } } } } //raise the transfer event OnBankTransferComplete(args); if (SEconomyPlugin.Configuration.EnableProfiler) { SEconomyPlugin.Profiler.ExitLog(profile); } } } catch (Exception ex) { args.Exception = ex; args.TransferSucceeded = false; } return args; }