using System; using System.Data; using System.Text; using System.Threading; using System.Collections; using System.Collections.Generic; using Holo.Virtual.Users.Messenger; 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 { private static Hashtable _Users = new Hashtable(); private static List _MessageQueue = new List(); private static Thread _MessageSaver; private static Thread pingChecker; private static Thread effectsChecker; 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 { } try { pingChecker = new Thread(new ThreadStart(checkPings)); pingChecker.Priority = ThreadPriority.Lowest; pingChecker.Start(); effectsChecker = new Thread(new ThreadStart(CheckEffects)); effectsChecker.Priority = ThreadPriority.Lowest; effectsChecker.Start(); _MessageSaver = new Thread(new ThreadStart(WriteAllChatMessages)); _MessageSaver.Priority = ThreadPriority.Lowest; _MessageSaver.Start(); } catch { } } /// /// 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, string ShockwaveID, 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.IP == dbClient.getString("SELECT ipaddress_last FROM users WHERE name = @name LIMIT 1")) { _Users.Add(userID, User); dbClient.AddParamWithValue("shockid", ShockwaveID); dbClient.runQuery("UPDATE users SET ticket_sso = NULL AND shockwaveid = @shockid WHERE id = '" + userID + "' LIMIT 1"); Out.WriteLine("User " + User._Username + " logged in."); } else { User.Disconnect(1000); User.sendData("BK" + "Invalid Session Ticket, please login again!" + Convert.ToChar(2)); } } } /// /// 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 [" + + "] disconnected.", Out.logFlags.BelowStandardAction); } } public static void removeUser(virtualUser User) { if (_Users.ContainsValue(User)) { _Users.Remove(User); } } /// /// 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 + "' AND friendid > 0"); 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 + "' AND userid > 0"); 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(); byte[] DataTosend = System.Text.Encoding.Default.GetBytes(Data + Convert.ToChar(1)); foreach (virtualUser User in Users.Values) { try { User.SendByteArray(DataTosend); } catch { Out.WritePlain("User " + User._Username + " is offline"); } } } catch { } } /// /// Sends a single packet to all guides. /// /// The userID of the request. /// The packet to send. public static void sendToGuides(int userID, int roomID, string Data) { try { foreach (virtualUser User in _Users.Values) { if (userID == User._guideRequest) { User._guideRequest = 0; User._guideRoom = 0; User.sendData(Data); continue; } if (User._guideRequest == 0) { User._guideRequest = userID; User._guideRoom = roomID; User.sendData(Data); } else continue; } } 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 { } } #region Chat system /// /// 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) { ChatMessage MessageStorage = new ChatMessage(); MessageStorage.Message = Message; MessageStorage.RoomID = roomID; MessageStorage.Username = userName; MessageStorage.MessageSent = DateTime.Now.ToString(); _MessageQueue.Add(MessageStorage); } private struct ChatMessage { internal int RoomID; internal string Username; internal string Message; internal string MessageSent; } private static void WriteAllChatMessages() { lock (_MessageQueue) { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { foreach (ChatMessage Message in _MessageQueue) { dbClient.AddParamWithValue("username", Message.Username); dbClient.AddParamWithValue("roomid", Message.RoomID); dbClient.AddParamWithValue("message", Message.Message); dbClient.AddParamWithValue("timesent", Message.MessageSent); dbClient.runQuery("INSERT INTO system_chatlog (username,roomid,mtime,message) VALUES (@username,@roomid,@timesent,@message)"); _MessageQueue.Remove(Message); } } } Thread.Sleep(20000); } #endregion /// /// 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, 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,pixels,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_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 //Info.Append(stringManager.getString("common_pixels") + ": " + Convert.ToString(dRow[13]) + "\r\r"); // Append user's amount of pixels 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. ///// //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).IP); // 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() + Convert.ToString(Convert.ToChar(2)); //} /// /// (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, int userID) { 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.AddParamWithValue("ID", userID); dbClient.runQuery("INSERT INTO users_bans (ipaddress,date_expire,descr,userid) VALUES (@ip,@expires,@reason,@ID)"); 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 //} public static string getBanReason(int userID) { try { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) return dbClient.getString("SELECT descr FROM users_bans WHERE userid = '" + userID + "'"); } catch { return ""; } } /// /// 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 = ""; string banPosted = ""; 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 = ""; string banPosted = ""; 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 + "'"); } 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; } } /// /// interval 150000ms, checks ping status of users and disconnects timed out users. /// private static void checkPings() { List vir = new List(); while (true) { //lock (_Users) { try { Hashtable SafeThread = (Hashtable)_Users.Clone(); foreach (virtualUser User in SafeThread.Values) { if (!User._isDisconnected) { if (User.pingOK) { User._clean = false; User.pingOK = false; User.sendData("@r"); int inRoom = 0; if (User.Room != null || User.roomUser != null) inRoom = User.Room.roomID; if (User._Username != "") { User._Minuteperiod = User._Minuteperiod + 1; if (User._Minuteperiod == 5) { User._Minuteperiod = 0; User._Pixels = User._Pixels + 50; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.runQuery("UPDATE users SET pixels = '" + User._Pixels + "' WHERE id = '" + User.userID + "' LIMIT 1"); } User.sendData("Fv" + Encoding.encodeVL64(User._Pixels) + "RL"); } } } else { vir.Add(User); } } } SafeThread.Clear(); } catch { } foreach (virtualUser User in vir) { User.Disconnect(); } } vir.Clear(); Thread.Sleep(100000); } } /// /// interval 60000ms, checks ping status of users and disconnects timed out users. /// private static void CheckEffects() { while (true) { try { using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dbClient.runQuery("UPDATE users_effects SET effect_timeleft = effect_timeleft - 60 WHERE effect_activated = '1'"); DataColumn dCol = dbClient.getColumn("SELECT num FROM users_effects WHERE effect_timeleft < 0"); int[] effectIDs = dataHandling.dColToArray(dCol, null); foreach (int i in effectIDs) { int userID = dbClient.getInt("SELECT userid FROM users_effects WHERE num = " + i + " LIMIT 1"); if (userManager.containsUser(userID)) { virtualUser User = userManager.getUser(userID); User.refreshEffect(); } } dbClient.runQuery("DELETE FROM users_effects WHERE effect_timeleft < 0"); } } catch { } Thread.Sleep(60000); } } public static void SetuserTempFigure(string Figure) { Hashtable SafeUserTable = (Hashtable)_Users.Clone(); foreach (virtualUser User in SafeUserTable.Values) { User.sendData("@E" + User.ConnectionID + Convert.ToChar(2) + User._Username + Convert.ToChar(2) + Figure + Convert.ToChar(2) + User._Sex + Convert.ToChar(2) + User._Mission + Convert.ToChar(2) + Convert.ToChar(2) + "PCch=s02/53,51,44" + Convert.ToChar(2) + "HI"); if (User.Room != null && User.roomUser != null) User.Room.sendData("DJ" + Encoding.encodeVL64(User.roomUser.roomUID) + Figure + Convert.ToChar(2) + User._Sex + Convert.ToChar(2) + User._Mission + Convert.ToChar(2)); } SafeUserTable.Clear(); } public static void RefreshAllUser() { Hashtable SafeUserTable = (Hashtable)_Users.Clone(); foreach (virtualUser User in SafeUserTable.Values) { User.refreshAppearance(false, true, true); } SafeUserTable.Clear(); } } }