using System; using System.Data; using System.Text; using System.Threading; using System.Collections; using System.Collections.Generic; using Holo.Virtual.Users; using Ion.Storage; namespace Holo.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 { public static Hashtable _Users = new Hashtable(); private static Thread pingChecker; private static int _peakUserCount; /// /// Starts the pingchecker thread. /// public static void Init() { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { _peakUserCount = dbClient.getInt("SELECT onlinecount_peak FROM system"); } try { pingChecker.Abort(); } catch { } pingChecker = new Thread(new ThreadStart(checkPings)); pingChecker.Priority = ThreadPriority.Lowest; pingChecker.Start(); } /// /// Adds a virtualUser class together with the userID to the userManager. Login ticket will be nulled and previous logged in instances of this user will be dropped. /// /// The ID of the user to add. /// The virtualUser class of this user. public static void addUser(int userID, virtualUser User) { if (_Users.ContainsKey(userID)) { virtualUser oldUser = ((virtualUser)_Users[userID]); oldUser.Disconnect(); if (_Users.ContainsKey(userID)) _Users.Remove(userID); } using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.AddParamWithValue("name", User._Username); if (User.connectionRemoteIP == dbClient.getString("SELECT ipaddress_last FROM users WHERE name = @name LIMIT 1")) { _Users.Add(userID, User); dbClient.runQuery("UPDATE users SET ticket_sso = NULL WHERE id = '" + userID + "' LIMIT 1"); Out.WriteLine("User " + userID + " logged in. [" + User._Username + "]", Out.logFlags.BelowStandardAction); } else { User.Disconnect(1000); User.sendData("BK" + "Invalid Session Ticket, please login again!"); } if (_Users.Count > dbClient.getInt("SELECT onlinecount_peak FROM system")) { _peakUserCount = _Users.Count; } } } /// /// Removes a user from the userManager. [if it exists] /// /// The ID of the user to remove. public static void removeUser(int userID) { if (_Users.ContainsKey(userID)) { _Users.Remove(userID); //Out.WriteLine("User [" + userID + "] disconnected.", Out.logFlags.BelowStandardAction); } } /// /// Returns a bool that indicates if the userManager contains a certain user. /// /// The ID of the user. public static bool containsUser(int userID) { return _Users.ContainsKey(userID); } /// /// Returns a bool that indicates if the userManager contains a certain user. /// /// The username of the user. public static bool containsUser(string userName) { int userID = getUserID(userName); return _Users.ContainsKey(userID); } /// /// 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; } } /// /// Retrieves the ID of a user from the database. /// /// The username of the user. public static int getUserID(string userName) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.AddParamWithValue("name", userName); return dbClient.getInt("SELECT id FROM users WHERE name = @name LIMIT 1"); } } /// /// Retrieves the username of a user from the database. /// /// The ID of the user. public static string getUserName(int userID) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { return dbClient.getString("SELECT name FROM users WHERE id = '" + userID + "' LIMIT 1"); } } /// /// 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) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { return dbClient.findsResult("SELECT id FROM users WHERE id = '" + userID + "'"); } } /// /// Returns an int array with the ID's of the messenger friends of a certain user. /// /// The ID of the user to get the friend ID's from. public static int[] getUserFriendIDs(int userID) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { try { ArrayList idBuilder = new ArrayList(); DataColumn dCol = dbClient.getColumn("SELECT friendid FROM messenger_friendships WHERE userid = '" + userID + "'"); int[] friendIDs = dataHandling.dColToArray(dCol, null); foreach (int i in friendIDs) idBuilder.Add(i); dCol = dbClient.getColumn("SELECT userid FROM messenger_friendships WHERE friendid = '" + userID + "'"); friendIDs = dataHandling.dColToArray(dCol, null); foreach (int i in friendIDs) idBuilder.Add(i); return (int[])idBuilder.ToArray(typeof(int)); } catch { return new int[0]; } } } /// /// Returns a virtualUser class for a certain user /// /// The ID of the user. public static virtualUser getUser(int userID) { try { return (virtualUser)_Users[userID]; } catch { 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) { try { Hashtable Users = (Hashtable)_Users.Clone(); foreach (virtualUser User in Users.Values) { try { User.sendData(Data); } catch { Out.WritePlain("Gebruiker " + User._Username + " is offline"); } } } catch { } } /// /// 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) { try { { foreach (virtualUser User in _Users.Values) { if (User._Rank < Rank || (includeHigher == false && User._Rank > Rank)) continue; else User.sendData(Data); } } } catch { } } /// /// Inserts a single 'chat saying' to the system_chatlog table, together with username of sayer, room ID of sayer and the current timestamp. /// /// The username of the sayer. /// The ID of the room where the sayer is in. /// The message the sayer said. public static void addChatMessage(string userName, int roomID, string Message) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.AddParamWithValue("username", userName); dbClient.AddParamWithValue("roomid", roomID); dbClient.AddParamWithValue("message", Message); dbClient.runQuery("INSERT INTO system_chatlog (username,roomid,mtime,message) VALUES (@username,@roomid,CURRENT_TIMESTAMP,@message)"); } } /// /// Generates an info list about a certain user. If the user isn't found or has a higher rank than the info requesting user, then an access error message is returned. Otherwise, a report with user ID, username, rank, mission, credits amount, tickets amount, virtual birthday (signup date), real birthday, email address and last IP address. If the user is online, then information about the room the user currently is in (including ID and owner name) is supplied, otherwise, the last server access date is supplied. /// /// The database ID of the user to generate the info of. /// The rank of the user that requests this info. If this rank is lower than the rank of the target user, then there is no info returned. public static string generateUserInfo(int userID, byte Rank) { DataRow dRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dRow = dbClient.getRow("SELECT name,rank,mission,credits,tickets,email,birth,hbirth,ipaddress_last,lastvisit FROM users WHERE id = '" + userID + "' AND rank <= " + Rank); } if (dRow.Table.Rows.Count == 0) { return stringManager.getString("userinfo_accesserror"); } else { StringBuilder Info = new StringBuilder(stringManager.getString("userinfo_header") + "\r"); // Append header Info.Append(stringManager.getString("common_userid") + ": " + userID + "\r"); // Append user ID Info.Append(stringManager.getString("common_username") + ": " + Convert.ToString(dRow[0]) + "\r"); // Append username Info.Append(stringManager.getString("common_userrank") + ": " + Convert.ToString(dRow[1]) + "\r"); // Append rank Info.Append(stringManager.getString("common_usermission") + ": " + Convert.ToString(dRow[2]) + "\r"); // Append user's mission Info.Append(stringManager.getString("common_credits") + ": " + Convert.ToString(dRow[3]) + "\r"); // Append user's amount of credits Info.Append(stringManager.getString("common_tickets") + ": " + Convert.ToString(dRow[4]) + "\r"); // Append user's amount of tickets Info.Append(stringManager.getString("common_hbirth") + ": " + Convert.ToString(dRow[7]) + "\r\r"); // Append 'registered at' date + blank line Info.Append(stringManager.getString("common_birth") + ": " + Convert.ToString(dRow[6]) + "\r"); // Append real birthday Info.Append(stringManager.getString("common_email") + ": " + Convert.ToString(dRow[5]) + "\r"); // Append email address Info.Append(stringManager.getString("common_ip") + ": " + Convert.ToString(dRow[8]) + "\r\r"); // Append user's last used IP address if (_Users.ContainsKey(userID)) // User online { virtualUser User = (virtualUser)_Users[userID]; string Location = ""; if (User._roomID == 0) Location = stringManager.getString("common_hotelview"); else { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { Location = stringManager.getString("common_room") + " '" + dbClient.getString("SELECT name FROM rooms WHERE id = '" + User._roomID + "'") + "' [id: " + User._roomID + ", " + stringManager.getString("common_owner") + ": " + dbClient.getString("SELECT owner FROM rooms WHERE id = '" + User._roomID + "'") + "]"; // Roomname, room ID and name of the user that owns the room } } Info.Append(stringManager.getString("common_location") + ": " + Location); } else // User is offline Info.Append(stringManager.getString("common_lastaccess") + ": " + Convert.ToString(dRow[9])); // Append last server access date return Info.ToString(); } } /// /// Generates a string containing the packet to send the the user. /// /// The rank of the user. public static string generateCommands(byte Rank, int userID) { //Hashtable Commands = new Hashtable(); string[] Commands = null; StringBuilder Packet = new StringBuilder("BKYour Commands:"); // % = next string Cmds = ""; Cmds += "%"; Cmds += ":im NAME [MESSAGE] - Stuur een bericht naar een vriend%"; Cmds += ":events - Laat evenementen venster zien%"; Cmds += ":about - Laat informatie over de server zien%"; Cmds += ":whosonline - Laat alle gebruikers + rank die online zijn zien%"; Cmds += ":cleanhand - Verwijderd ALLE items in je hand (geen vergoeding)%"; Cmds += ":brb - Zegt tegen iedereen dat je weg bent (Max 15 minutes)%"; Cmds += ":back - Stop met het vertellen dat je weg bent%"; Cmds += ":hotel/:info/:version - laat de informatie over dit hotel zien.%"; Cmds += ":staff - Verteld je hoe je de staff kan bereiken%"; if (Rank > 1) { Cmds += "%"; Cmds += ":chooser - Laat iedereen zien in de kamer%"; Cmds += ":furni - Laat alle meubels zien in de kamer%"; if (rankManager.containsRight(Rank, "fuse_alert", userID)) { Cmds += "%"; Cmds += ":alert NAME MESSAGE - Sends a moderator alert%"; } if (rankManager.containsRight(Rank, "fuse_room_alert", userID)) { Cmds += "%"; Cmds += ":roomalert MESSAGE - Sends a moderator alert to a whole room%"; } if (rankManager.containsRight(Rank, "fuse_kick", userID)) { Cmds += "%"; Cmds += ":kick [MESSAGE] - Kicks a user from the room they are in%"; } if (rankManager.containsRight(Rank, "fuse_room_kick", userID)) { Cmds += "%"; Cmds += ":roomkick [MESSAGE] - Kicks all users but you from the room"; } if (rankManager.containsRight(Rank, "fuse_mute", userID)) { Cmds += "%"; Cmds += ":shutup NAME [MESSAGE] - Stops a user from using say/shout%"; Cmds += ":unmute NAME - Allows a user to say/shout again%"; } if (rankManager.containsRight(Rank, "fuse_room_mute", userID)) { Cmds += "%"; Cmds += ":roomshutup [MESSAGE] - Stops all users in the room from using say/shout%"; Cmds += ":roomunmute Allows all users in the room to say/shout again%"; } if (rankManager.containsRight(Rank, "fuse_ban", userID)) { Cmds += "%"; Cmds += ":ban NAME HOURS REASON - Bans a user for the how many hours%"; } if (rankManager.containsRight(Rank, "fuse_superban", userID)) { Cmds += "%"; Cmds += ":superban NAME HOURS REASON - Bans a user and there IP for how many hours%"; } if (rankManager.containsRight(Rank, "fuse_administrator_access", userID)) { Cmds += "%"; Cmds += ":ha MESSAGE - Sends an alert to all online users%"; Cmds += ":offline MINUTES - Informs all online users that the hotel is going offline in how long you said%"; Cmds += ":refresh - Updates certain parts of the server%"; Cmds += ":cords - Display your current room position%"; Cmds += ":teleport - Turns on teleport mode (WARNING: It causes the room to screw up)%"; Cmds += ":warp X Y - Teleports you the the the location input%"; Cmds += ":sendme PACKET - Sends a packet to your self (For debuging)%"; } if (rankManager.containsRight(Rank, "fuse_alert", userID)) { Cmds += "%"; Cmds += ":ra MESSAGE - Sends an alert to all online users with the same rank as you%"; } if (rankManager.containsRight(Rank, "fuse_teleport", userID)) { Cmds += "%"; Cmds += ":teleport - Toggles your movent to teleport mode on/off%"; Cmds += ":warp X Y - Teleports you to the co-ordinates entered%"; } if (rankManager.containsRight(Rank, "fuse_moderator_access", userID)) { Cmds += "%"; Cmds += ":userinfo NAME/:ui NAME - Displays infomation about a user%"; } } Commands = Cmds/*.Replace("%", "|")*/.Split("%".ToCharArray()); int r = 30; foreach (string Command in Commands) { if (r == 0) { Packet.Append(Convert.ToChar(1) + "BKYour Commands:"); r = 30; } Packet.Append("\r" + Command); r--; } return Packet.ToString(); } /// /// Generates a string containing the packet to send the the user. /// /// public static string generateWhosOnline(bool Admin) { int i = userCount; int alerts = 0; while (i > 30) { alerts++; i -= 30; } alerts++; StringBuilder packet = new StringBuilder("BKOnline Users"); if (alerts > 1) packet.Append(" page 1/" + alerts); packet.Append(" Total online: " + userCount); int r = 30; int p = 1; if (Admin) foreach (DictionaryEntry user in _Users) { if (r == 0) { p++; packet.Append(Convert.ToChar(1) + "BKOnline Users" + " page " + p + "/" + alerts + " Total online: " + userCount); r = 30; } packet.Append("\r" + getUserName((int)user.Key) + " [" + user.Key.ToString() + "] {" + getUser((int)user.Key)._Rank + "} " + getUser((int)user.Key).connectionRemoteIP); r--; } else { foreach (DictionaryEntry user in _Users) { if (r == 0) { p++; packet.Append(Convert.ToChar(1) + "BKOnline Users" + " page " + p + " Total online: " + userCount); r = 30; } packet.Append("\r" + getUserName((int)user.Key) + " {" + getUser((int)user.Key)._Rank + "}"); r--; } } return packet.ToString(); } /// /// (Re)bans a single user for a specified amount of hours and reason. If the user is online, then it receives the ban message and get's disconnected. /// /// The database ID of the user to ban. /// The amount of hours (starts now) till the ban is lifted. /// The reason for the ban, that describes the user why it's account is blocked from the system. public static void setBan(int userID, int Hours, string Reason) { string Expires = DateTime.Now.AddHours(Hours).ToString().Replace("/", "-").Replace(".", "-"); using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.AddParamWithValue("userid", userID); dbClient.AddParamWithValue("expires", Expires); dbClient.AddParamWithValue("reason", Reason); dbClient.runQuery("INSERT INTO users_bans (userid,date_expire,descr) VALUES (@userid,@expires,@reason)"); } if (_Users.ContainsKey(userID)) { virtualUser User = ((virtualUser)_Users[userID]); User.sendData("@c" + Reason); User.Disconnect(1000); } } /// /// Checks if there are system bans for a certain IP address. /// If a ban is detected, it checks if it's already expired. /// If that is the case, then it lifts the ban. /// If there is a pending ban, it returns the reason that was supplied with the banning, otherwise, it returns "". /// /// The IP address to check bans for. public static string getBanReason(string IP) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { if (dbClient.findsResult("SELECT ipaddress FROM users_bans WHERE ipaddress = '" + IP + "'")) { string banExpires = dbClient.getString("SELECT date_expire FROM users_bans WHERE ipaddress = '" + IP + "'"); if (DateTime.Compare(DateTime.Parse(banExpires), DateTime.Now) > 0) return dbClient.getString("SELECT descr FROM users_bans WHERE ipaddress = '" + IP + "'"); // Still banned, return reason else dbClient.runQuery("DELETE FROM user_bans WHERE ipaddress = '" + IP + "' LIMIT 1"); } } return ""; // No pending ban/ban expired } /// /// (Re)bans all the users on a certain IP address, making them unable to login, and making them unable to connect to the system. The ban is applied with a specified amount and reason. All affected users receive the ban message (which contains the reason) and they are disconnected. /// /// The IP address to ban. /// The amount of hours (starts now) till the ban is lifted. /// The reason for the ban, that describes thes user why their IP address/accounts are blocked from the system. public static void setBan(string IP, int Hours, string Reason) { string Expires = DateTime.Now.AddHours(Hours).ToString().Replace("/", "-").Replace(".", "-"); DataColumn dCol; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.AddParamWithValue("ip", IP); dbClient.AddParamWithValue("expires", Expires); dbClient.AddParamWithValue("reason", Reason); dbClient.runQuery("INSERT INTO users_bans (ipaddress,date_expire,descr) VALUES (@ip,@expires,@reason)"); dCol = dbClient.getColumn("SELECT id FROM users WHERE ipaddress_last = '" + IP + "'"); } virtualUser User; foreach (DataRow dRow in dCol.Table.Rows) { if (_Users.ContainsKey(Convert.ToInt32(dRow["id"]))) { User = ((virtualUser)_Users[Convert.ToInt32(dRow["ID"])]); User.sendData("@c" + Reason); User.Disconnect(1000); } } } /// /// Checks if there is a system ban for a certain user. /// If a ban is detected, it checks if it's already expired. /// If that is the case, then it lifts the ban. /// If there is a pending ban, it returns the reason that was supplied with the banning, otherwise, it returns "". /// /// The database ID of the user to check for bans. public static string getBanReason(int userID) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { if (dbClient.findsResult("SELECT userid FROM users_bans WHERE userid = '" + userID + "'")) { string banExpires = dbClient.getString("SELECT date_expire FROM users_bans WHERE userid = '" + userID + "'"); if (DateTime.Compare(DateTime.Parse(banExpires), DateTime.Now) > 0) // Still banned, return reason return dbClient.getString("SELECT descr FROM users_bans WHERE userid = '" + userID + "'"); else dbClient.runQuery("DELETE FROM users_bans WHERE userid = '" + userID + "' LIMIT 1"); } } return ""; // No pending ban/ban expired } /// /// Generates a ban report for a certain ban on a user, including all details that could be of use. If there was no ban found, or the user that was banned doesn't exist, then a holo.cast.banreport.null is returned. /// /// The database ID of the user to generate the ban report for. public static string generateBanReport(int userID) { try { DataRow dbRow; DataRow dRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dRow = dbClient.getRow("SELECT date_expire,descr,ipaddress FROM users_bans WHERE userid = '" + userID + "'"); dbRow = dbClient.getRow("SELECT name,rank,ipaddress_last FROM users WHERE id = '" + userID + "'"); } if (dRow.Table.Rows.Count == 0 || dbRow.Table.Rows.Count == 0) { return "holo.cast.banreport.null"; } else { string Note = "-"; string banPoster = "not available"; string banPosted = "not available"; DataRow DRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { DRow = dbClient.getRow("SELECT userid,note,timestamp FROM system_stafflog WHERE action = 'ban' AND targetid = '" + userID + "' ORDER BY id ASC"); // Get latest stafflog entry for this action (if exists) } if (DRow.Table.Rows.Count > 0) // system_stafflog table could be cleaned up { if (Convert.ToString(DRow[1]) != "") Note = Convert.ToString(DRow[1]); using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { banPoster = dbClient.getString("SELECT name FROM users WHERE id = '" + Convert.ToString(DRow[0]) + "'"); } banPosted = Convert.ToString(DRow[2]); } StringBuilder Report = new StringBuilder(stringManager.getString("banreport_header") + " "); Report.Append(Convert.ToString(dbRow[0]) + " [" + userID + "]" + "\r"); // Append username and user ID Report.Append(stringManager.getString("common_userrank") + ": " + Convert.ToString(dbRow[1]) + "\r"); // Append user's rank Report.Append(stringManager.getString("common_ip") + ": " + Convert.ToString(dbRow[2]) + "\r"); // Append the IP address of user Report.Append(stringManager.getString("banreport_banner") + ": " + banPoster + "\r"); // Append username of banner Report.Append(stringManager.getString("banreport_posted") + ": " + banPosted + "\r"); // Append datetime when ban was posted Report.Append(stringManager.getString("banreport_expires") + ": " + Convert.ToString(dRow[0]) + "\r"); // Append datetime when ban expires Report.Append(stringManager.getString("banreport_reason") + ": " + Convert.ToString(dRow[1]) + "\r"); // Append the reason that went with the ban Report.Append(stringManager.getString("banreport_ipbanflag") + ": " + (Convert.ToString(dRow[2]) != "").ToString().ToLower() + "\r"); // Append true/false for the IP ban status Report.Append(stringManager.getString("banreport_staffnote") + ": " + Note); // Append the staffnote that went with the ban return Report.ToString(); } } catch (Exception ex) { throw ex; } } /// /// Generates a ban report for a certain IP address, including all details that could be of use. If there was no ban found, or the user that was banned doesn't exist, then a holo.cast.banreport.null is returned. /// /// The IP address to generate the ban report for. public static string generateBanReport(string IP) { try { DataRow dRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dRow = dbClient.getRow("SELECT userid,date_expire,descr FROM users_bans WHERE ipaddress = '" + IP + "'"); } if (dRow.Table.Rows.Count == 0) { return "holo.cast.banreport.null"; } else { string Note = "-"; string banPoster = "not available"; string banPosted = "not available"; DataRow DRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { DRow = dbClient.getRow("SELECT userid,note,timestamp FROM system_stafflog WHERE action = 'ban' AND targetid = '" + Convert.ToString(dRow[0]) + "' ORDER BY id ASC"); // Get latest stafflog entry for this action (if exists) } if (DRow.Table.Rows.Count > 0) // system_stafflog table could be cleaned up { if (Convert.ToString(DRow[1]) != "") Note = Convert.ToString(DRow[1]); using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { banPoster = dbClient.getString("SELECT name FROM users WHERE id = '" + Convert.ToString(DRow[0]) + "'"); } banPosted = Convert.ToString(DRow[2]); } StringBuilder Report = new StringBuilder(stringManager.getString("banreport_header") + " "); Report.Append(IP + "\r"); // Append IP address Report.Append(stringManager.getString("banreport_banner") + ": " + banPoster + "\r"); // Append username of banner Report.Append(stringManager.getString("banreport_posted") + ": " + banPosted + "\r"); // Append datetime when ban was posted Report.Append(stringManager.getString("banreport_expires") + ": " + Convert.ToString(dRow[0]) + "\r"); // Append datetime when ban expires Report.Append(stringManager.getString("banreport_reason") + ": " + Convert.ToString(dRow[1]) + "\r"); // Append the reason that went with the ban Report.Append(stringManager.getString("banreport_ipbanflag") + ": " + (Convert.ToString(dRow[2]) != "").ToString().ToLower() + "\r"); // Append true/false for the IP ban status Report.Append(stringManager.getString("banreport_staffnote") + ": " + Note + "\r\r"); // Append the staffnote that went with the ban DataColumn dCol; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dCol = dbClient.getColumn("SELECT name FROM users WHERE ipaddress_last = '" + IP + "'"); } //string[] affectedUsernames = dataHandling.dColToArray(dCol); Report.Append(stringManager.getString("banreport_affectedusernames") + ":"); foreach (DataRow dbRow in dCol.Table.Rows) Report.Append("\r - " + Convert.ToString(dRow["name"])); return Report.ToString(); } } catch (Exception ex) { throw ex; } } /// /// Ran on a thread at interval 60000ms, checks ping status of users and disconnects timed out users. /// private static void checkPings() { List vir = new List(); while (true) { try { foreach (virtualUser User in _Users.Values) { if (User.pingOK) { User.pingOK = false; User.sendData("@r"); } else { Holo.Out.WriteLine(User._Username + " timed out."); vir.Add(User); } } } catch { } foreach (virtualUser User in vir) { User.Disconnect(); } vir.Clear(); Thread.Sleep(60000); Out.WriteTrace("Checking virtual user pings"); } } } }