/// <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; })); }
/// <summary> /// Returns a bank account by it's key. /// </summary> public static XBankAccount GetBankAccount(string BankAccountK) { lock (__staticLock) { Economy.EconomyPlayer matchingAccount = SEconomyPlugin.EconomyPlayers.Where(i => i.BankAccount != null).FirstOrDefault(i => i.BankAccount.BankAccountK != null && i.BankAccount.BankAccountK == BankAccountK); //if the player is logged in return the logged in bank account reference if (matchingAccount != null) { return(matchingAccount.BankAccount); } else { lock (XmlJournal) { return(BankAccounts.FirstOrDefault(i => i.BankAccountK == BankAccountK)); } } } }
/// <summary> /// Occurs when someone executes an alias command /// </summary> void ChatCommand_AliasExecuted(TShockAPI.CommandArgs e) { string commandIdentifier = e.Message; if (!string.IsNullOrEmpty(e.Message)) { commandIdentifier = e.Message.Split(' ').FirstOrDefault(); } //Get the corresponding alias in the config that matches what the user typed. foreach (AliasCommand alias in Configuration.CommandAliases.Where(i => i.CommandAlias == commandIdentifier)) { if (alias != null) { TimeSpan timeSinceLastUsedCommand = TimeSpan.MaxValue; //cooldown key is a pair of the user's character name, and the command they have called. //cooldown value is a DateTime they last used the command. KeyValuePair <string, AliasCommand> cooldownReference = new KeyValuePair <string, AliasCommand>(e.Player.Name, alias); if (CooldownList.ContainsKey(cooldownReference)) { //UTC time so we don't get any daylight saving shit cuntery timeSinceLastUsedCommand = DateTime.UtcNow.Subtract(CooldownList[cooldownReference]); } //has the time elapsed greater than the cooldown period? if (timeSinceLastUsedCommand.TotalSeconds >= alias.CooldownSeconds || e.Player.Group.HasPermission("aliascmd.bypasscooldown")) { Money commandCost = 0; Economy.EconomyPlayer ePlayer = SEconomyPlugin.GetEconomyPlayerSafe(e.Player.Index); if (!string.IsNullOrEmpty(alias.Cost) && Money.TryParse(alias.Cost, out commandCost) && !e.Player.Group.HasPermission("aliascmd.bypasscost")) { if (ePlayer.BankAccount != null) { if (!ePlayer.BankAccount.IsAccountEnabled) { e.Player.SendErrorMessageFormat("You cannot use this command because your account is disabled."); } else if (ePlayer.BankAccount.Balance >= commandCost) { //Take money off the player, and indicate that this is a payment for something tangible. Journal.BankTransferEventArgs trans = SEconomyPlugin.WorldAccount.TransferTo(ePlayer.BankAccount, -commandCost, Journal.BankAccountTransferOptions.AnnounceToReceiver | Journal.BankAccountTransferOptions.IsPayment); if (trans.TransferSucceeded) { DoCommands(alias, ePlayer.TSPlayer, e.Parameters); } else { e.Player.SendErrorMessageFormat("Your payment failed."); } } else { e.Player.SendErrorMessageFormat("This command costs {0}. You need {1} more to be able to use this.", commandCost.ToLongString(), ((Money)(ePlayer.BankAccount.Balance - commandCost)).ToLongString()); } } else { e.Player.SendErrorMessageFormat("This command costs money and you don't have a bank account. Please log in first."); } } else { //Command is free DoCommands(alias, e.Player, e.Parameters); } //populate the cooldown list. This dictionary does not go away when people leave so they can't //reset cooldowns by simply logging out or disconnecting. They can reset it however by logging into //a different account. if (CooldownList.ContainsKey(cooldownReference)) { CooldownList[cooldownReference] = DateTime.UtcNow; } else { CooldownList.Add(cooldownReference, DateTime.UtcNow); } } else { e.Player.SendErrorMessageFormat("{0}: You need to wait {1:0} more seconds to be able to use that.", alias.CommandAlias, (alias.CooldownSeconds - timeSinceLastUsedCommand.TotalSeconds)); } } } }
/// <summary> /// Executes the AliasCommand. Will either forward the command to the tshock handler or do something else /// </summary> void DoCommands(AliasCommand alias, TShockAPI.TSPlayer player, List <string> parameters) { //loop through each alias and do the commands. foreach (string commandToExecute in alias.CommandsToExecute) { //todo: parse paramaters and dynamics string mangledString = commandToExecute; //specifies whether the command to run should be executed as a command, or ignored. //useful for functions like $msg that does other shit bool executeCommand = true; //replace parameter markers with actual parameter values ReplaceParameterMarkers(parameters, ref mangledString); mangledString = mangledString.Replace("$calleraccount", player.UserAccountName); mangledString = mangledString.Replace("$callername", player.Name); //$random(x,y) support. Returns a random number between x and y if (randomRegex.IsMatch(mangledString)) { foreach (Match match in randomRegex.Matches(mangledString)) { int randomFrom = 0; int randomTo = 0; if (!string.IsNullOrEmpty(match.Groups[2].Value) && int.TryParse(match.Groups[2].Value, out randomTo) && !string.IsNullOrEmpty(match.Groups[1].Value) && int.TryParse(match.Groups[1].Value, out randomFrom)) { Random random = new Random(); mangledString = mangledString.Replace(match.ToString(), random.Next(randomFrom, randomTo).ToString()); } else { TShockAPI.Log.ConsoleError(match.ToString() + " has some stupid shit in it, have a look at your AliasCmd config file."); mangledString = mangledString.Replace(match.ToString(), ""); } } } // $runas(u,cmd) support. Run command as user if (runasFunctionRegex.IsMatch(mangledString)) { foreach (Match match in runasFunctionRegex.Matches(mangledString)) { string impersonatedName = match.Groups[2].Value; Economy.EconomyPlayer impersonatedPlayer = SEconomyPlugin.GetEconomyPlayerSafe(impersonatedName); if (impersonatedPlayer != null) { string commandToRun = match.Groups[3].Value;; player = impersonatedPlayer.TSPlayer; mangledString = commandToRun.Trim(); } } } // $msg(u,msg) support. Sends the user a non-chat informational message if (msgRegex.IsMatch(mangledString)) { foreach (Match match in msgRegex.Matches(mangledString)) { string msgTarget = match.Groups[2].Value.Trim(); string message = match.Groups[3].Value.Trim(); Economy.EconomyPlayer destinationPlayer = SEconomyPlugin.GetEconomyPlayerSafe(msgTarget); if (destinationPlayer != null) { //custom command, skip forwarding of the command to the tshock executer executeCommand = false; destinationPlayer.TSPlayer.SendInfoMessage(message); } } } //and send the command to tshock to do. try { //prevent an infinite loop for a subcommand calling the alias again causing a commandloop string command = mangledString.Split(' ')[0].Substring(1); if (!command.Equals(alias.CommandAlias, StringComparison.CurrentCultureIgnoreCase)) { if (executeCommand) { HandleCommandWithoutPermissions(player, mangledString); } } else { TShockAPI.Log.ConsoleError(string.Format("cmdalias {0}: calling yourself in an alias will cause an infinite loop. Ignoring.", alias.CommandAlias)); } } catch { //execute the command disregarding permissions player.SendErrorMessage(alias.UsageHelpText); } } }
/// <summary> /// Transfers money from this player to the destination account. If negative, takes money from the destionation account into this account. /// </summary> public BankTransferEventArgs TransferTo(int Index, Money Amount, Journal.BankAccountTransferOptions Options, string Message = "") { Economy.EconomyPlayer ePlayer = SEconomyPlugin.GetEconomyPlayerSafe(Index); return(TransferTo(ePlayer.BankAccount, Amount, Options, Message: Message)); }
/// <summary> /// Occurs when the server sends data. /// </summary> void NetHooks_SendData(Hooks.SendDataEventArgs e) { if (e.MsgID == PacketTypes.NpcStrike) { NPC npc = Main.npc[e.number]; if (npc != null) { if (npc.boss) { if (npc.life <= 0) { for (int i = BossList.Count - 1; i >= 0; i--) { if (BossList[i].Npc == null) { BossList.RemoveAt(i); } else if (BossList[i].Npc == npc) { var rewardDict = BossList[i].GetRecalculatedReward(); foreach (KeyValuePair <int, long> reward in rewardDict) { if (PlayerList[reward.Key] != null) { SEconomy.Economy.EconomyPlayer ePlayer = SEconomyPlugin.GetEconomyPlayerSafe(reward.Key); if (ePlayer != null) { //Pay from the world account to the reward recipient. Journal.BankAccountTransferOptions options = Journal.BankAccountTransferOptions.None; if (Config.AnnounceBossGain) { options |= Journal.BankAccountTransferOptions.AnnounceToReceiver; } SEconomyPlugin.WorldAccount.TransferTo(ePlayer.BankAccount, reward.Value, options); } } } BossList.RemoveAt(i); } else if (!BossList[i].Npc.active) { BossList.RemoveAt(i); } } if (e.ignoreClient >= 0) { var player = PlayerList[e.ignoreClient]; if (player != null) { player.AddKill(npc.netID); } } } else if (e.ignoreClient >= 0) { var bossnpc = BossList.Find(n => n.Npc == npc); if (bossnpc != null) { bossnpc.AddDamage(e.ignoreClient, (int)e.number2); } else { BossNPC newBoss = new BossNPC(npc); newBoss.AddDamage(e.ignoreClient, (int)e.number2); BossList.Add(newBoss); } } } else if (npc.life <= 0 && e.ignoreClient >= 0) { var player = PlayerList[e.ignoreClient]; if (player != null) { if (npc.value > 0) { float Mod = 1; if (player.TSPlayer.TPlayer.buffType.Contains(13)) // battle potion { Mod *= Config.BattlePotionModifier; } if (Config.OptionalMobModifier.ContainsKey(npc.netID)) { Mod *= Config.OptionalMobModifier[npc.netID]; // apply custom modifiers } int minVal = (int)((npc.value - (npc.value * 0.1)) * Mod); int maxVal = (int)((npc.value + (npc.value * 0.1)) * Mod); int rewardAmt = _r.Next(minVal, maxVal); int i = player.TSPlayer.Index; SEconomy.Economy.EconomyPlayer epl = SEconomyPlugin.GetEconomyPlayerSafe(i); Journal.BankAccountTransferOptions options = Journal.BankAccountTransferOptions.None; if (Config.AnnounceKillGain) { options |= Journal.BankAccountTransferOptions.AnnounceToReceiver; } SEconomyPlugin.WorldAccount.TransferTo(i, rewardAmt, options); } player.AddKill(npc.netID); } } } } else if (e.MsgID == PacketTypes.PlayerKillMe) { //Console.WriteLine("(SendData) PlayerKillMe -> 1:{0} 2:{4} 3:{5} 4:{6} 5:{1} remote:{2} ignore:{3}", e.number, e.number5, e.remoteClient, e.ignoreClient, e.number2, e.number3, e.number4); // 1-playerID, 2-direction, 3-dmg, 4-PVP var deadPlayer = PlayerList[e.number]; Economy.EconomyPlayer eDeadPlayer = SEconomyPlugin.GetEconomyPlayerSafe(e.number); if (deadPlayer != null) { long penaltyAmmount = 0; if (Config.StaticDeathPenalty) { penaltyAmmount = _r.Next(Config.DeathPenaltyMin, Config.DeathPenaltyMax); } else if (eDeadPlayer.BankAccount != null) { penaltyAmmount = (long)(eDeadPlayer.BankAccount.Balance * (Config.DeathPenaltyPercent / 100f)); } // Console.WriteLine("penalty ammount: {0}", penaltyAmmount); if (e.number4 == 1) { if (!deadPlayer.TSPlayer.Group.HasPermission("vault.bypass.death") /* && deadPlayer.ChangeMoney(-penaltyAmmount, MoneyEventFlags.PvP, true) */ && Config.PvPWinnerTakesLoosersPenalty && deadPlayer.LastPVPID != -1) { var killer = PlayerList[deadPlayer.LastPVPID]; Economy.EconomyPlayer eKiller = SEconomyPlugin.GetEconomyPlayerSafe(deadPlayer.LastPVPID); if (eKiller != null && eKiller.BankAccount != null) { Journal.BankAccountTransferOptions options = Journal.BankAccountTransferOptions.MoneyFromPvP | Journal.BankAccountTransferOptions.AnnounceToReceiver | Journal.BankAccountTransferOptions.AnnounceToSender; // killer.ChangeMoney(penaltyAmmount, MoneyEventFlags.PvP, true); //Here in PVP the loser pays the winner money out of their account. eDeadPlayer.BankAccount.TransferTo(deadPlayer.LastPVPID, penaltyAmmount, options); } } } else if (!deadPlayer.TSPlayer.Group.HasPermission("vault.bypass.death")) { Journal.BankAccountTransferOptions options = Journal.BankAccountTransferOptions.MoneyFromPvP | Journal.BankAccountTransferOptions.AnnounceToReceiver | Journal.BankAccountTransferOptions.AnnounceToSender; // deadPlayer.ChangeMoney(-penaltyAmmount, MoneyEventFlags.Death, true); SEconomyPlugin.WorldAccount.TransferTo(deadPlayer.Index, -penaltyAmmount, options); } } } else if (e.MsgID == PacketTypes.PlayerDamage) { // Console.WriteLine("(SendData) PlayerDamage -> 1:{0} 2:{4} 3:{5} 4:{6} 5:{1} remote:{2} ignore:{3}", e.number, e.number5, e.remoteClient, e.ignoreClient, e.number2, e.number3, e.number4); // 1: pID, ignore: Who, 2: dir, 3:dmg, 4:pvp; if (e.number4 == 1) // if PvP { { var player = PlayerList[e.number]; if (player != null) { player.LastPVPID = e.ignoreClient; } } } }