/// <summary> /// Upgrades a contributor's tier based on their total credit balance. /// </summary> /// <param name="contributor">A reference to the contributor object to upgrade.</param> /// <param name="suppressNotifications">Whether or not notification updates should be suppressed.</param> /// <returns>A task for this action.</returns> public async Task UpgradeTier(Contributor contributor, bool suppressNotifications = false) { if (suppressNotifications || (contributor.Notifications & Notifications.TierUpdate) == Notifications.TierUpdate) { ContributorUpdates updates = 0; Tier tier = await GetByCreditsAsync(contributor.TotalCredits); if (contributor.Tier != tier.ID) { contributor.Tier = tier.ID; // Don't touch notifications on suppress if (!suppressNotifications) { contributor.Notifications |= Notifications.NewTier; contributor.Notifications ^= Notifications.TierUpdate; updates |= ContributorUpdates.Notifications; } updates |= ContributorUpdates.Tier; } if (!await Main.Contributors.UpdateAsync(contributor, updates)) { TShock.Log.ConsoleError("CTRS-DB: something went wrong while updating a contributor's notifications."); } } }
public ContributorUpdateEventArgs(Contributor contributor, ContributorUpdates updates) { ContributorId = contributor.Id; Updates = updates; if ((Updates & ContributorUpdates.XenforoID) == ContributorUpdates.XenforoID) XenforoId = contributor.XenforoId.Value; if ((Updates & ContributorUpdates.TotalCredits) == ContributorUpdates.TotalCredits) TotalCredits = contributor.TotalCredits; if ((Updates & ContributorUpdates.LastDonation) == ContributorUpdates.LastDonation) LastDonation = contributor.LastDonation; if ((Updates & ContributorUpdates.LastAmount) == ContributorUpdates.LastAmount) LastAmount = contributor.LastAmount; if ((Updates & ContributorUpdates.Tier) == ContributorUpdates.Tier) Tier = contributor.Tier; if ((Updates & ContributorUpdates.ChatColor) == ContributorUpdates.ChatColor) ChatColor = contributor.ChatColor; if ((Updates & ContributorUpdates.Notifications) == ContributorUpdates.Notifications) Notifications = contributor.Notifications; if ((Updates & ContributorUpdates.Settings) == ContributorUpdates.Settings) Settings = contributor.Settings; }
public ContributorUpdateEventArgs(Contributor contributor, ContributorUpdates updates) { ContributorId = contributor.Id; Updates = updates; if ((Updates & ContributorUpdates.XenforoID) == ContributorUpdates.XenforoID) { XenforoId = contributor.XenforoId.Value; } if ((Updates & ContributorUpdates.TotalCredits) == ContributorUpdates.TotalCredits) { TotalCredits = contributor.TotalCredits; } if ((Updates & ContributorUpdates.LastDonation) == ContributorUpdates.LastDonation) { LastDonation = contributor.LastDonation; } if ((Updates & ContributorUpdates.LastAmount) == ContributorUpdates.LastAmount) { LastAmount = contributor.LastAmount; } if ((Updates & ContributorUpdates.Tier) == ContributorUpdates.Tier) { Tier = contributor.Tier; } if ((Updates & ContributorUpdates.ChatColor) == ContributorUpdates.ChatColor) { ChatColor = contributor.ChatColor; } if ((Updates & ContributorUpdates.Notifications) == ContributorUpdates.Notifications) { Notifications = contributor.Notifications; } if ((Updates & ContributorUpdates.Settings) == ContributorUpdates.Settings) { Settings = contributor.Settings; } }
/// <summary> /// Asynchronously sends updated contributor data to the database. /// Logs any exception thrown. /// </summary> /// <param name="contributor">The contributor to update with the already-updated values set.</param> /// <param name="updates">The list of values to update.</param> /// <returns>True if it updates one row, false if anything else.</returns> public async Task<bool> UpdateAsync(Contributor contributor, ContributorUpdates updates) { return await Task.Run(() => Update(contributor, updates)); }
/// <summary> /// Sends updated contributor data to the database. /// Logs any exception thrown. /// </summary> /// <param name="contributor">The contributor to update with the already-updated values set.</param> /// <param name="updates">The list of values to update.</param> /// <returns>True if it updates one row, false if anything else..</returns> public bool Update(Contributor contributor, ContributorUpdates updates) { if (updates == 0) return true; List<string> updatesList = new List<string>(); if ((updates & ContributorUpdates.XenforoID) == ContributorUpdates.XenforoID) updatesList.Add("XenforoID = @XenforoID"); if ((updates & ContributorUpdates.TotalCredits) == ContributorUpdates.TotalCredits) updatesList.Add("TotalCredits = @TotalCredits"); if ((updates & ContributorUpdates.LastDonation) == ContributorUpdates.LastDonation) updatesList.Add("LastDonation = @LastDonation"); if ((updates & ContributorUpdates.LastAmount) == ContributorUpdates.LastAmount) updatesList.Add("LastAmount = @LastAmount"); if ((updates & ContributorUpdates.Tier) == ContributorUpdates.Tier) updatesList.Add("Tier = @Tier"); if ((updates & ContributorUpdates.ChatColor) == ContributorUpdates.ChatColor) updatesList.Add("ChatColor = @ChatColor"); if ((updates & ContributorUpdates.Notifications) == ContributorUpdates.Notifications) updatesList.Add("Notifications = @Notifications"); if ((updates & ContributorUpdates.Settings) == ContributorUpdates.Settings) updatesList.Add("Settings = @Settings"); #region SQL(update) string update = PrepareSql($@" UPDATE {Main.Config.ContributorTableName} SET {String.Join(", ", updatesList)} WHERE ID = @ID"); #endregion try { lock (syncLock) { using (var db = OpenConnection()) { return db.Execute(update, contributor.ToDataModel()) == 1; } } } catch (Exception ex) { TShock.Log.ConsoleError("{0}\n{1}\n{2}", "CTRS: An error occurred while updating a contributor's info", $"Message: {ex.Message}", "Check logs for more details"); TShock.Log.Error(ex.ToString()); return false; } }
/// <summary> /// Asynchronously sends updated contributor data to the database. /// Logs any exception thrown. /// </summary> /// <param name="contributor">The contributor to update with the already-updated values set.</param> /// <param name="updates">The list of values to update.</param> /// <returns>True if it updates one row, false if anything else.</returns> public async Task <bool> UpdateAsync(Contributor contributor, ContributorUpdates updates) { return(await Task.Run(() => Update(contributor, updates))); }
/// <summary> /// Sends updated contributor data to the database. /// Logs any exception thrown. /// </summary> /// <param name="contributor">The contributor to update with the already-updated values set.</param> /// <param name="updates">The list of values to update.</param> /// <returns>True if it updates one row, false if anything else..</returns> public bool Update(Contributor contributor, ContributorUpdates updates) { if (updates == 0) { return(true); } List <string> updatesList = new List <string>(); if ((updates & ContributorUpdates.XenforoID) == ContributorUpdates.XenforoID) { updatesList.Add("XenforoID = @XenforoID"); } if ((updates & ContributorUpdates.TotalCredits) == ContributorUpdates.TotalCredits) { updatesList.Add("TotalCredits = @TotalCredits"); } if ((updates & ContributorUpdates.LastDonation) == ContributorUpdates.LastDonation) { updatesList.Add("LastDonation = @LastDonation"); } if ((updates & ContributorUpdates.LastAmount) == ContributorUpdates.LastAmount) { updatesList.Add("LastAmount = @LastAmount"); } if ((updates & ContributorUpdates.Tier) == ContributorUpdates.Tier) { updatesList.Add("Tier = @Tier"); } if ((updates & ContributorUpdates.ChatColor) == ContributorUpdates.ChatColor) { updatesList.Add("ChatColor = @ChatColor"); } if ((updates & ContributorUpdates.Notifications) == ContributorUpdates.Notifications) { updatesList.Add("Notifications = @Notifications"); } if ((updates & ContributorUpdates.Settings) == ContributorUpdates.Settings) { updatesList.Add("Settings = @Settings"); } #region SQL(update) string update = PrepareSql($@" UPDATE {Main.Config.ContributorTableName} SET {String.Join(", ", updatesList)} WHERE ID = @ID" ); #endregion try { lock (syncLock) { using (var db = OpenConnection()) { return(db.Execute(update, contributor.ToDataModel()) == 1); } } } catch (Exception ex) { TShock.Log.ConsoleError("{0}\n{1}\n{2}", "CTRS: An error occurred while updating a contributor's info", $"Message: {ex.Message}", "Check logs for more details"); TShock.Log.Error(ex.ToString()); return(false); } }
object restNewTransaction(RestRequestArgs args) { var ret = UserFind(args.Parameters); if (ret is RestObject) { return(ret); } User user = (User)ret; if (String.IsNullOrWhiteSpace(args.Parameters["credits"])) { return(RestMissingParam("credits")); } float credits; if (!Single.TryParse(args.Parameters["credits"], out credits)) { return(RestInvalidParam("credits")); } long dateUnix = 0; if (!String.IsNullOrWhiteSpace(args.Parameters["date"])) { Int64.TryParse(args.Parameters["date"], out dateUnix); } Contributor con = _main.Contributors.Get(user.ID); bool success = false; if (con == null) { // Transactions must never be ignored. If the contributor doesn't exist, create it con = new Contributor(user); con.LastAmount = credits; if (dateUnix > 0) { con.LastDonation = dateUnix.FromUnixTime(); } con.Tier = 1; con.TotalCredits = credits; success = _main.Contributors.AddLocal(con); if (!success) { TShock.Log.ConsoleInfo($"CTRS-WARNING: Failed to register contribution made by user '{user.Name}'!"); } } else { ContributorUpdates updates = 0; con.LastAmount = credits; updates |= ContributorUpdates.LastAmount; if (dateUnix > 0) { con.LastDonation = dateUnix.FromUnixTime(); updates |= ContributorUpdates.LastDonation; } con.TotalCredits += credits; updates |= ContributorUpdates.TotalCredits; con.Notifications |= Notifications.NewDonation; // Always prompt a tier update check here con.Notifications |= Notifications.TierUpdate; updates |= ContributorUpdates.Notifications; success = _main.Contributors.Update(con, updates); } if (!success) { return(RestError("Transaction was not registered properly.")); } else { return(RestResponse("Transaction successful.")); } }
object restNewTransactionV2(RestRequestArgs args) { int userID; if (!Int32.TryParse(args.Verbs["user_id"], out userID)) { return(RestInvalidParam("user_id")); } if (String.IsNullOrWhiteSpace(args.Parameters["credits"])) { return(RestMissingParam("credits")); } float credits; if (!Single.TryParse(args.Parameters["credits"], out credits)) { return(RestInvalidParam("credits")); } long dateUnix = 0; if (!String.IsNullOrWhiteSpace(args.Parameters["date"])) { Int64.TryParse(args.Parameters["date"], out dateUnix); } Contributor con = _main.Contributors.GetByXenforoId(userID); bool success = false; if (con == null) { // Transactions must never be ignored. If the contributor doesn't exist, create it con = new Contributor(0); con.XenforoId = userID; con.LastAmount = credits; if (dateUnix > 0) { con.LastDonation = dateUnix.FromUnixTime(); } con.Tier = 1; con.TotalCredits = credits; success = _main.Contributors.Add(con); if (!success) { TShock.Log.ConsoleInfo($"CTRS-WARNING: Failed to register contribution made by forum user ID [{userID}]!"); } // Fire the Transaction event (must be done after Add to include the contributor Id) Transaction?.Invoke(_main.Contributors, new TransactionEventArgs(con.Id, credits, dateUnix.FromUnixTime())); } else { ContributorUpdates updates = 0; con.LastAmount = credits; updates |= ContributorUpdates.LastAmount; if (dateUnix > 0) { con.LastDonation = dateUnix.FromUnixTime(); updates |= ContributorUpdates.LastDonation; } con.TotalCredits += credits; updates |= ContributorUpdates.TotalCredits; // Fire the Transaction event var transactionArgs = new TransactionEventArgs(con.Id, credits, dateUnix.FromUnixTime()); Transaction?.Invoke(_main.Contributors, transactionArgs); // Suppress notifications if needed if (!transactionArgs.SuppressNotifications) { con.Notifications |= Notifications.NewDonation; con.Notifications |= Notifications.TierUpdate; updates |= ContributorUpdates.Notifications; } success = _main.Contributors.Update(con, updates); } if (!success) { return(RestError("Transaction was not registered properly.")); } else { return(RestResponse("Transaction successful.")); } }
public async Task UpdateNotifications() { if (_receiver == null || _scope == null) { return; } ContributorUpdates updates = 0; // Upgrade tier before anything else await _scope.Tiers.UpgradeTier(this); // Initial delay await Task.Delay(_scope.Config.NotificationDelaySeconds * 1000); // This should only occur once if ((Notifications & Notifications.Introduction) != Notifications.Introduction) { // Do Introduction message foreach (string s in Texts.SplitIntoLines( _scope.Formatter.FormatIntroduction(_receiver, this))) { _receiver.SendInfoMessage(s); } Notifications |= Notifications.Introduction; updates |= ContributorUpdates.Notifications; // If there are more notifications in the pile, run the regular relay if (Notifications != Notifications.Introduction) { await Task.Delay(_scope.Config.NotificationCheckSeconds * 1000); } } // Regular notification loop (Notifications.Introduction is the regular state for the enum) while (Notifications != Notifications.Introduction) { if ((Notifications & Notifications.NewDonation) == Notifications.NewDonation) { // Do NewDonation message foreach (string s in Texts.SplitIntoLines( _scope.Formatter.FormatNewDonation(_receiver, this, LastAmount))) { _receiver.SendInfoMessage(s); } Notifications ^= Notifications.NewDonation; updates |= ContributorUpdates.Notifications; } else if ((Notifications & Notifications.NewTier) == Notifications.NewTier) { // Do Tier Rank Up message foreach (string s in Texts.SplitIntoLines( _scope.Formatter.FormatNewTier(_receiver, this, _scope.Tiers.Get(Tier)))) { _receiver.SendInfoMessage(s); } Notifications ^= Notifications.NewTier; updates |= ContributorUpdates.Notifications; } // If there are more notifications in the pile, run the regular relay if (Notifications != Notifications.Introduction) { await Task.Delay(_scope.Config.NotificationCheckSeconds * 1000); } } if (!await _scope.Contributors.UpdateAsync(this, updates) && _scope.Config.LogDatabaseErrors) { TShock.Log.ConsoleError("CTRS-DB: something went wrong while updating a contributor's notifications."); } }