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
}
}