using System; using System.Text; using System.Threading; using System.Collections; using Duck.Virtual.Users; namespace Duck.Managers { /// /// Provides management for logged in users, aswell for retrieving details such as ID/name and vice versa from the database. /// public static class userManager { #region Declares private static Hashtable _Users = new Hashtable(); private static Thread pingChecker; private static int _peakUserCount; #endregion #region Initializers /// /// Starts the pingchecker thread. /// public static void Init() { try { pingChecker.Abort(); } catch { } pingChecker = new Thread(new ThreadStart(checkPings)); pingChecker.Priority = ThreadPriority.BelowNormal; pingChecker.Start(); } #endregion #region User management /// /// Adds a virtualUser class together with the userID to the userManager. Previous logged in instances of this user will be dropped. /// /// The database ID of the user to add. /// The virtualUser object of this user. public static void addUser(int userID, virtualUser User) { if (_Users.ContainsKey(userID)) { virtualUser _Old = ((virtualUser)_Users[userID]); _Old.Disconnect(); if (_Users.ContainsKey(userID)) _Users.Remove(userID); } _Users.Add(userID, User); IO.WriteLine("User " + userID + " logged in. [" + User._Username + "]", IO.logFlags.belowStandardAction); if (_Users.Count > _peakUserCount) _peakUserCount = _Users.Count; } /// /// Removes a virtual user from the userManager. [if it exists] /// /// The database ID of the user to remove. public static void removeUser(int userID) { if (_Users.ContainsKey(userID)) { _Users.Remove(userID); IO.WriteLine("User [" + userID + "] disconnected.", IO.logFlags.belowStandardAction); } } /// /// Returns a boolean that indicates if the userManager contains a certain user. /// /// The database ID of the user to check. public static bool containsUser(int userID) { return _Users.ContainsKey(userID); } /// /// Returns a boolean that indicates if the userManager contains a certain user. /// /// The username of the user to check. public static bool containsUser(string userName) { int userID = getUserID(userName); return _Users.ContainsKey(userID); } #endregion #region Properties /// /// Returns the current amount of users in the userManager. /// public static int userCount { get { return _Users.Count; } } /// /// Returns the peak amount of users in the userManager since boot. /// public static int peakUserCount { get { return _peakUserCount; } } #endregion #region Misc methods /// /// Retrieves the ID of a user from the database. /// /// The username of the user. (stripslash if needed) public static int getUserID(string userName) { return DB.runRead("SELECT id FROM users WHERE username = '" + userName + "'", null); } /// /// Retrieves the username of a user from the database. /// /// The ID of the user. public static string getUserName(int userID) { return DB.runRead("SELECT name FROM users WHERE id = '" + userID + "'"); } /// /// Returns a bool that indicates if a user with a certain user ID exists in the database. /// /// The ID of the user to check. public static bool userExists(int userID) { return DB.checkExists("SELECT id FROM users WHERE id = '" + userID + "'"); } /// /// Returns a virtualUser class for a certain user /// /// The ID of the user. public static virtualUser getUser(int userID) { if (_Users.ContainsKey(userID)) return (virtualUser)_Users[userID]; else return null; } /// /// Returns a virtualUser class for a certain user. /// /// The username of the user. public static virtualUser getUser(string userName) { int userID = getUserID(userName); return getUser(userID); } /// /// Sends a single packet to all connected clients. /// /// The packet to send. public static void sendData(string Data) { foreach (virtualUser User in _Users.Values) User.sendData(Data); } /// /// Sends a single packet to all active virtual users with the specified rank. Optionally you can include users who have a higher rank than the specified rank. /// /// The minimum rank that the virtual user required to receive the data. /// Indicates if virtual users with a rank that's higher than the specified rank should also receive the packet. /// The packet to send. public static void sendToRank(byte Rank, bool includeHigher, string Data) { foreach (virtualUser User in _Users.Values) { if (User._Rank < Rank || (includeHigher == false && User._Rank > Rank)) continue; else User.sendData(Data); } } /// /// Ran on a thread at interval 60000ms, checks ping status of users and disconnects timed out users. /// private static void checkPings() { while (true) { foreach (virtualUser User in ((Hashtable)_Users.Clone()).Values) { if (User.pingOK) { User.pingOK = false; User.sendData("@r"); } else { IO.WriteLine(User._Username + " timed out."); User.Disconnect(); } } Thread.Sleep(60000); } } #endregion } }