Exemplo n.º 1
0
        /// <summary>
        /// Fetches a contributor object from the database.
        /// </summary>
        /// <param name="xenforoID">The contributor's xenforo ID, if any.</param>
        /// <returns>A contributor object, or null if not found.</returns>
        public Contributor GetByXenforoId(int xenforoID)
        {
            #region SQL(select_con)
            string select_con = PrepareSql($@"
			SELECT *
			FROM {Main.Config.ContributorTableName}
			WHERE XenforoID = @XenforoID"            );
            #endregion

            #region SQL(select_a)
            string select_a = $@"
			SELECT UserID
			FROM {Main.Config.ContributorAccountsTableName}
			WHERE ContributorID = @ID"            ;
            #endregion

            using (var db = OpenConnection())
            {
                Contributor con = (Contributor)db.QuerySingleOrDefault <Contributor.DataModel>(select_con, new { XenforoID = xenforoID });

                if (con == null)
                {
                    return(null);
                }

                con.Accounts = new List <int>(db.Query <int>(select_a, con.ToDataModel()));
                return(con);
            }
        }
Exemplo n.º 2
0
        /// <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.");
                }
            }
        }
Exemplo n.º 3
0
		public async Task<float> GetContributorCredits(Contributor contributor)
		{
			// Only works if the contributor has linked their Xenforo account to their TShock account
			if (!contributor.XenforoId.HasValue || contributor.Accounts.Count == 0)
				return 0f;

			// Note: Currently, Xenforo will only store the first account to successfully authenticate
			XFUser user = await GetAsync(contributor.Accounts[0]);
			return user.Credits;
		}
Exemplo n.º 4
0
        public async Task <float> GetContributorCredits(Contributor contributor)
        {
            // Only works if the contributor has linked their Xenforo account to their TShock account
            if (!contributor.XenforoId.HasValue || contributor.Accounts.Count == 0)
            {
                return(0f);
            }

            // Note: Currently, Xenforo will only store the first account to successfully authenticate
            XFUser user = await GetAsync(contributor.Accounts[0]);

            return(user.Credits);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Fetches a contributor object from the database.
        /// </summary>
        /// <param name="userID">The user ID of an authenticated account.</param>
        /// <returns>A contributor object, or null if not found.</returns>
        public Contributor Get(int userID)
        {
            #region SQL(select_id)
            string select_id = PrepareSql($@"
			SELECT ContributorID
			FROM {Main.Config.ContributorAccountsTableName}
			WHERE UserID = @UserID"            );
            #endregion

            #region SQL(select_con)
            string select_con = PrepareSql($@"
			SELECT *
			FROM {Main.Config.ContributorTableName}
			WHERE ID = @Id"            );
            #endregion

            #region SQL(select_a)
            string select_a = PrepareSql($@"
			SELECT UserID
			FROM {Main.Config.ContributorAccountsTableName}
			WHERE ContributorID = @ID"            );
            #endregion

            int contributorID;

            using (var db = OpenConnection())
            {
                contributorID = db.QuerySingleOrDefault <int>(select_id, new { UserID = userID });

                if (contributorID == 0)
                {
                    return(null);
                }

                Contributor con = (Contributor)db.QuerySingleOrDefault <Contributor.DataModel>(select_con, new { Id = contributorID });

                // The foreign key constraints would have to fail for this to happen, but better safe than sorry
                if (con == null)
                {
                    return(null);
                }

                con.Accounts = new List <int>(db.Query <int>(select_a, con.ToDataModel()));
                return(con);
            }
        }
Exemplo n.º 6
0
		/// <summary>
		/// Formats the info message sent to players when they use the info command.
		/// {0} - Player Name
		/// {1} - Accounts (comma separated if more than one)
		/// {2} - WebID
		/// {3} - Credits
		/// {4} - TotalCredits
		/// {5} - LastDonation (dd-MMM-yyyy)
		/// {6} - Tier.Name with ChatColor
		/// {7} - NextTier.Name
		/// {8} - CreditsForNextTier
		/// {9} - ChatColor
		/// {10} - Experience Multiplier in percentage aditive: 1.10 = '10%'
		/// {11} - Experience Multiplier in percentage total: 1.10 = '110%'
		/// </summary>
		/// <param name="player">The contributor to take elements from.</param>
		/// <returns>The formatted string.</returns>
		public string FormatInfo(TSPlayer player, Contributor contributor, float credits, Tier tier = null, Tier nextTier = null)
		{

			return String.Format(_config.Texts.Info,
				player.Name,
				contributor.Accounts.Count == 0 ? "N/A" : String.Join(",", contributor.Accounts),
				contributor.XenforoId.HasValue ? contributor.XenforoId.Value.ToString() : "N/A",
				String.Format(_main.Config.CreditsFormat, (int)credits),
				String.Format(_main.Config.CreditsFormat, (int)contributor.TotalCredits),
				!contributor.LastDonation.HasValue ? "N/A" : contributor.LastDonation.Value.ToString("d-MMM-yyyy"),
				tier != null ? tier.ChatColor.HasValue ? TShock.Utils.ColorTag(tier.Name, tier.ChatColor.Value) : tier.Name : "N/A",
				nextTier != null ? nextTier.ChatColor.HasValue ? TShock.Utils.ColorTag(nextTier.Name, nextTier.ChatColor.Value) : nextTier.Name : "N/A",
				String.Format(_main.Config.CreditsFormat, (nextTier != null && tier != null) ? ((int)(nextTier.CreditsRequired - credits)).ToString() : "N/A"),
				Tools.ColorToRGB(contributor.ChatColor),
				tier != null ? $"{Math.Round(tier.ExperienceMultiplier * 100 - 100)}%" : "0%",
				tier != null ? $"{Math.Round(tier.ExperienceMultiplier * 100)}%" : "100%");
		}
		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;
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Inserts data for a contributor object into the database asynchronously.
 /// The contributor object must have a Xenforo Id associated with it.
 /// </summary>
 /// <param name="contributor">The contributor object to save.</param>
 /// <returns>
 /// A task with a <see cref="bool"/> representing whether the operation was successful or not.
 /// </returns>
 public Task <bool> AddAsync(Contributor contributor)
 {
     return(Task.Run(() => Add(contributor)));
 }
Exemplo n.º 10
0
		/// <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;
			}
		}
Exemplo n.º 11
0
		/// <summary>
		/// Inserts data for a contributor object into the database.
		/// The contributor object must have a Xenforo Id associated with it.
		/// </summary>
		/// <param name="contributor">The contributor object to save.</param>
		/// <returns>A <see cref="bool"/> representing whether the operation was successful or not.</returns>
		public bool Add(Contributor contributor)
		{
			#region SQL(query)

			string query = PrepareSql($@"
			INSERT INTO {Main.Config.ContributorTableName} (
				XenforoID,
				TotalCredits,
				LastAmount,
				Notifications,
				Settings
			)
			VALUES (
				@XenforoID,
				@TotalCredits,
				@LastAmount,
				@Notifications,
				@Settings
			)");

			if (contributor.LastDonation != DateTime.MinValue)
			{
				query = PrepareSql($@"
				INSERT INTO {Main.Config.ContributorTableName} (
					XenforoID,
					TotalCredits,
					LastDonation,
					LastAmount,
					Notifications,
					Settings
				)
				VALUES (
					@XenforoID,
					@TotalCredits,
					@LastDonation,
					@LastAmount,
					@Notifications,
					@Settings
				)");
			}

			#endregion

			#region SQL(query_a)
			string query_a = PrepareSql($@"
			INSERT INTO {Main.Config.ContributorAccountsTableName} (
				UserID,
				ContributorID
			)
			VALUES (
				@UserID,
				@ContributorID
			)");
			#endregion

			try
			{
				lock (syncLock)
				{
					using (var db = OpenConnection())
					{
						if (db.Execute(query, contributor.ToDataModel()) == 1)
						{
							contributor.Id = GetLastInsertId();

							for (int i = 0; i < contributor.Accounts.Count; i++)
							{
								if (db.Execute(query_a, new { UserID = contributor.Accounts[i], ContributorID = contributor.Id }) == 0)
								{
									return false;
								}
							}
							return true;
						}
						return false;
					}
				}
			}
			catch (Exception ex)
			{
				if (Main.Config.LogDatabaseErrors)
				{
					TShock.Log.ConsoleError($"CTRS-DB: Unable to add contributor with xenforoID:{contributor.XenforoId.Value}\nMessage: " + ex.Message);
					TShock.Log.Error(ex.ToString());
				}
				return false;
			}
		}
Exemplo n.º 12
0
		public AuthResult(Contributor contributor) : this(LMReturnCode.Success)
		{
			Contributor = contributor;
		}
Exemplo n.º 13
0
		// 0 - player name | 1 - amount formatted to credits
		public string FormatNewDonation(TSPlayer player, Contributor contributor, float amount)
		{
			return String.Format(_config.Texts.NewDonation, player.Name, String.Format(_main.Config.CreditsFormat, (int)amount));
		}
Exemplo n.º 14
0
		// 0 - player name | 1 - Tier.Name with ChatColor
		public string FormatNewTier(TSPlayer player, Contributor contributor, Tier tier)
		{
			return String.Format(_config.Texts.NewTier, player.Name, tier.ChatColor.HasValue ? TShock.Utils.ColorTag(tier.Name, tier.ChatColor.Value) : tier.Name);
		}
Exemplo n.º 15
0
		// 0 - player name
		public string FormatIntroduction(TSPlayer player, Contributor contributor)
		{
			return String.Format(_config.Texts.Introduction,
				player.Name);
		}
Exemplo n.º 16
0
        /// <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);
            }
        }
Exemplo n.º 17
0
 /// <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)));
 }
Exemplo n.º 18
0
		/// <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.");
			}
		}
Exemplo n.º 19
0
		/// <summary>
		/// Authenticates an <see cref="User"/> to a Xenforo forum account and returns the <see cref="Contributor"/>
		/// if the authentication succeeds.
		/// </summary>
		/// <param name="user">The Xenforo account name.</param>
		/// <param name="credentials">The Xenforo account password.</param>
		/// <returns>
		/// A task with the <see cref="AuthResult"/> and a contributor object. The contributor is only defined
		/// if the authentication succeeds.
		/// </returns>
		public async Task<AuthResult> Authenticate(User user, Credentials credentials)
		{
			if (credentials == null)
			{
				return new AuthResult(LMReturnCode.UnloadedCredentials);
			}

			var sb = new StringBuilder();
			sb.Append(_main.Config.Xenforo.XenAPIURI ?? "http://sbplanet.co/forums/api.php");

			// REQUEST: api.php?action=authenticate&username=USERNAME&password=PASSWORD
			sb.Append("?action=authenticate");
			if (String.IsNullOrEmpty(credentials.Username))
			{
				#region DEBUG
#if DEBUG
				TShock.Log.ConsoleInfo("AUTH ERROR: {Username} was null");
#endif
				#endregion
				return new AuthResult(LMReturnCode.EmptyParameter);
			}
			sb.Append("&username="******"AUTH ERROR: {Password} was null");
#endif
				#endregion
				return new AuthResult(LMReturnCode.EmptyParameter);
			}
			sb.Append("&password="******"REQUESTING: " + sb.ToString());
#endif
			#endregion
			string response = "";
			using (WebClient client = new WebClient())
			{
				try
				{
					response = await client.DownloadStringTaskAsync(sb.ToString());
				}
				catch (WebException e)
				{
					using (HttpWebResponse r = (HttpWebResponse)e.Response)
					using (var reader = new StreamReader(r.GetResponseStream()))
					{
						response = reader.ReadToEnd();
					}
				}
			}

			#region DEBUG
#if DEBUG
			TShock.Log.ConsoleInfo("RESPONSE: " + response);
#endif
			#endregion
			var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
			if (dict.ContainsKey("hash"))
			{
				// Store the hash and perform a second query to get the userID
				string hash = (string)dict["hash"];
				sb.Clear();
				sb.Append(_main.Config.Xenforo.XenAPIURI ?? "http://sbplanet.co/forums/api.php");

				// REQUEST: api.php?action=getUser&hash=USERNAME:HASH
				sb.Append("?action=getUser");
				sb.Append("&hash=");
				sb.Append(credentials.Username);
				sb.Append(':');
				sb.Append(hash);

				#region DEBUG
#if DEBUG
				TShock.Log.ConsoleInfo("REQUESTING: " + sb.ToString());
#endif
				#endregion
				using (WebClient client = new WebClient())
				{
					try
					{
						response = await client.DownloadStringTaskAsync(sb.ToString());
					}
					catch (WebException e)
					{
						using (HttpWebResponse r = (HttpWebResponse)e.Response)
						using (var reader = new StreamReader(r.GetResponseStream()))
						{
							response = reader.ReadToEnd();
						}
					}
				}

				#region DEBUG
#if DEBUG
				TShock.Log.ConsoleInfo("RESPONSE: " + response);
#endif
				#endregion
				dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
				if (!dict.ContainsKey("user_id"))
					return new AuthResult(LMReturnCode.UserNotFound);
				else
				{
					// Check if the user is a contributor
					List<int> groups = new List<int>();
					if (dict.ContainsKey("user_group_id"))
					{
						groups.Add(Convert.ToInt32(dict["user_group_id"]));
					}
					if (dict.ContainsKey("secondary_group_ids"))
					{
						((string)dict["secondary_group_ids"]).Split(',').ForEach(s =>
						{
							if (!String.IsNullOrWhiteSpace(s))
								groups.Add(Convert.ToInt32(s));
						});
					}
					if (!_main.Config.Xenforo.ContributorForumGroupIDs.Intersect(groups).Any())
					{
						return new AuthResult(LMReturnCode.UserNotAContributor);
					}

					Contributor contributor =
						await _main.Contributors.GetByXenforoIdAsync(Convert.ToInt32(dict["user_id"]));
					if (contributor == null)
					{
						/* Attempt to find contributor by user ID in the event a transaction
						 * was logged for an unexistant contributor account */
						contributor = await _main.Contributors.GetAsync(user.ID);

						bool success = false;
						if (contributor == null)
						{
							// Add a new contributor
							contributor = new Contributor(user);
							contributor.XenforoId = Convert.ToInt32(dict["user_id"]);
							success = await _main.Contributors.AddAsync(contributor);
						}
						else
						{
							// Set XenforoID for an existing contributor
							contributor.XenforoId = Convert.ToInt32(dict["user_id"]);
							success = await _main.Contributors.UpdateAsync(contributor, ContributorUpdates.XenforoID);
						}

						if (success)
							return new AuthResult(contributor);
						else
							return new AuthResult(LMReturnCode.DatabaseError);
					}
					else
					{
						// Check account limit
						if (_main.Config.AccountLimit > 0 && contributor.Accounts.Count >= _main.Config.AccountLimit)
						{
							return new AuthResult(LMReturnCode.AccountLimitReached);
						}

						if (await _main.Contributors.AddAccountAsync(contributor.Id, user.ID))
						{
							contributor.Accounts.Add(user.ID);
							return new AuthResult(contributor);
						}
						else
							return new AuthResult(LMReturnCode.DatabaseError);
					}
				}
			}
			else
				return new AuthResult((LMReturnCode)Convert.ToInt32((long)dict["error"]));
		}
Exemplo n.º 20
0
		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.");
		}
Exemplo n.º 21
0
		/// <summary>
		/// Inserts data for a contributor object into the database asynchronously.
		/// The contributor object must have a Xenforo Id associated with it.
		/// </summary>
		/// <param name="contributor">The contributor object to save.</param>
		/// <returns>
		/// A task with a <see cref="bool"/> representing whether the operation was successful or not.
		/// </returns>
		public Task<bool> AddAsync(Contributor contributor)
		{
			return Task.Run(() => Add(contributor));
		}
Exemplo n.º 22
0
		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.");
		}
Exemplo n.º 23
0
		/// <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));
		}
Exemplo n.º 24
0
        /// <summary>
        /// Inserts data for a contributor object into the database.
        /// The contributor object must have a Xenforo Id associated with it.
        /// </summary>
        /// <param name="contributor">The contributor object to save.</param>
        /// <returns>A <see cref="bool"/> representing whether the operation was successful or not.</returns>
        public bool Add(Contributor contributor)
        {
            #region SQL(query)

            string query = PrepareSql($@"
			INSERT INTO {Main.Config.ContributorTableName} (
				XenforoID,
				TotalCredits,
				LastAmount,
				Notifications,
				Settings
			)
			VALUES (
				@XenforoID,
				@TotalCredits,
				@LastAmount,
				@Notifications,
				@Settings
			)"            );

            if (contributor.LastDonation != DateTime.MinValue)
            {
                query = PrepareSql($@"
				INSERT INTO {Main.Config.ContributorTableName} (
					XenforoID,
					TotalCredits,
					LastDonation,
					LastAmount,
					Notifications,
					Settings
				)
				VALUES (
					@XenforoID,
					@TotalCredits,
					@LastDonation,
					@LastAmount,
					@Notifications,
					@Settings
				)"                );
            }

            #endregion

            #region SQL(query_a)
            string query_a = PrepareSql($@"
			INSERT INTO {Main.Config.ContributorAccountsTableName} (
				UserID,
				ContributorID
			)
			VALUES (
				@UserID,
				@ContributorID
			)"            );
            #endregion

            try
            {
                lock (syncLock)
                {
                    using (var db = OpenConnection())
                    {
                        if (db.Execute(query, contributor.ToDataModel()) == 1)
                        {
                            contributor.Id = GetLastInsertId();

                            for (int i = 0; i < contributor.Accounts.Count; i++)
                            {
                                if (db.Execute(query_a, new { UserID = contributor.Accounts[i], ContributorID = contributor.Id }) == 0)
                                {
                                    return(false);
                                }
                            }
                            return(true);
                        }
                        return(false);
                    }
                }
            }
            catch (Exception ex)
            {
                if (Main.Config.LogDatabaseErrors)
                {
                    TShock.Log.ConsoleError($"CTRS-DB: Unable to add contributor with xenforoID:{contributor.XenforoId.Value}\nMessage: " + ex.Message);
                    TShock.Log.Error(ex.ToString());
                }
                return(false);
            }
        }