using System; using System.Data; using System.Collections.Generic; using Woodpecker.Core; using Woodpecker.Storage; using Woodpecker.Specialized.Text; using Woodpecker.Sessions; using Woodpecker.Net.Game.Messages; using Woodpecker.Game.Users.Roles; namespace Woodpecker.Game.Users { /// /// Provides management for logged in users. This class works together with the sessionManager. /// public class userManager { #region Fields /// /// A private Dictionary object with an integer as key (user ID) and a Session object as value. /// private Dictionary mUserSessions = new Dictionary(); /// /// The current amount of active users on the server. /// public int userCount { get { return mUserSessions.Count; } } #endregion #region Methods #region Manager /// /// Clears the user collection of the manager. /// public void Clear() { mUserSessions.Clear(); } /// /// Lists various statistics about the registered users in the textbox on the GUI. /// public void listUserStats() { Database db = new Database(false, false); DataTable dTable = null; System.Text.StringBuilder sb = new System.Text.StringBuilder(); int Counter = 0; Logging.Log("Listing user statistics...\n"); db.Open(); sb.Append("Role user amounts:\n"); for (int roleID = 0; roleID <= 6; roleID++) { int Count = db.getInteger("SELECT COUNT(id) FROM users WHERE role = '" + roleID + "'"); sb.Append("Role '" + ((userRole)roleID).ToString() + "' has " + Count + " users.\n"); } sb.Append("\n> Top 20 of richest normal users:\n"); dTable = db.getTable("SELECT id,username,credits FROM users WHERE role <= '3' ORDER BY credits DESC LIMIT 20"); foreach (DataRow dRow in dTable.Rows) { Counter++; int userID = (int)dRow["id"]; string Username = (string)dRow["username"]; int Credits = (int)dRow["credits"]; sb.Append(Counter + ") " + Username + " [id: " + userID + "] has " + Credits + " credits.\n"); } Logging.Log(sb.ToString()); Logging.Log("User statistics listed.\n"); db.Close(); } #endregion #region User sessions /// /// Returns a boolean indicating if a value for a certain user ID (key) is found in the user collecting, thus meaning the user is logged in. /// /// The database ID of the user to get the login status for. public bool userIsLoggedIn(int userID) { return mUserSessions.ContainsKey(userID); } /// /// If the given user is currently logged in, the Woodpecker.Sessions.Session object of this user is returned. Otherwise, null is returned. /// /// The database ID of the user to get the session of. public Session getUserSession(int userID) { if (mUserSessions.ContainsKey(userID)) return mUserSessions[userID]; else return null; } public Session getUserSession(string Username) { Session ret = null; Username = Username.ToLower(); lock (mUserSessions) { foreach (Session lSession in mUserSessions.Values) { if (lSession.User != null && lSession.User.Username.ToLower() == Username) { ret = lSession; break; } } } return ret; } /// /// Returns the session ID of a user as an unsigned integer. If the user is not logged in, then 0 is returned. /// /// The database ID of the user to get the session ID of. public uint getUserSessionID(int userID) { if (mUserSessions.ContainsKey(userID)) return mUserSessions[userID].ID; else return 0; } /// /// Adds a Woodpecker.Sessions.Session object to the collection of user sessions, with the user ID as key. /// /// The Woodpecker.Sessions.Session to add. public void addUserSession(Session userSession) { if (!mUserSessions.ContainsKey(userSession.User.ID)) mUserSessions.Add(userSession.User.ID, userSession); } /// /// Removes a user session from the user sessions collection, when the user ID is given. /// /// The database ID of the user to remove the session of. public void removeUserSession(int userID) { mUserSessions.Remove(userID); } /// /// Tries to send a game message (serverMessage object) to a user, catching & dumping any exceptions that occur. /// /// The database ID of the user to send the message to. /// The message to send to the user as serverMessage object. public void trySendGameMessage(int userID, serverMessage Message) { try { mUserSessions[userID].gameConnection.sendMessage(Message); } catch { } } /// /// Tries to send a game message (string, don't forget that char1 is used to break messages) to a user, after checking if the user is logged in. /// /// The database ID of the user to send the message to. /// The message to send to the user as a string. public void trySendGameMessage(int userID, string Message) { try { mUserSessions[userID].gameConnection.sendMessage(Message); } catch { } } #endregion #region User info /// /// Returns a boolean that indicates if a user with a certain username exists in the 'users' table of the database. /// /// The username to check. public bool userExists(string Username) { Database Database = new Database(false, true); Database.addParameterWithValue("username", Username); Database.Open(); return Database.findsResult("SELECT id FROM users WHERE username = @username"); } /// /// Retrieves the database ID of a user, when only the username is known. /// /// The username of the user to get the user ID of. public int getUserID(string Username) { Database Database = new Database(false, true); Database.addParameterWithValue("username", Username); Database.Open(); return Database.getInteger("SELECT id FROM users WHERE username = @username"); } /// /// Retrieves the username of a user, when only the user ID is known. /// /// The user ID of the user to get the username of. public string getUsername(int userID) { Database Database = new Database(false, true); Database.addParameterWithValue("userid", userID); Database.Open(); return Database.getString("SELECT username FROM users WHERE id = @userid"); } public basicUserInformation getBasicUserInfo(int userID) { basicUserInformation returnInfo = new basicUserInformation(); Database Database = new Database(false, true); Database.addParameterWithValue("userid", userID); Database.Open(); if (Database.Ready) { try { DataRow dRow = Database.getRow("SELECT username,figure,sex,motto,motto_messenger,lastactivity FROM users WHERE id = @userid"); returnInfo.ID = userID; returnInfo.Username = (string)dRow["username"]; returnInfo.Figure = (string)dRow["figure"]; returnInfo.Sex = Convert.ToChar(dRow["sex"].ToString()); returnInfo.Motto = (string)dRow["motto"]; returnInfo.messengerMotto = (string)dRow["motto_messenger"]; returnInfo.lastActivity = (DateTime)dRow["lastactivity"]; } catch { returnInfo = new basicUserInformation(); } } return returnInfo; } public basicUserInformation getBasicUserInfo(string Username) { int userID = this.getUserID(Username); if (userID > 0) return this.getBasicUserInfo(userID); else return new basicUserInformation(); } public userInformation getUserInfo(int userID, bool forceRefresh) { if (!forceRefresh && mUserSessions.ContainsKey(userID)) // Why load it? :) return mUserSessions[userID].User; userInformation returnInfo = new userInformation(); Database Database = new Database(false, true); Database.addParameterWithValue("userid", userID); Database.Open(); if (Database.Ready) { try { DataRow dRow = Database.getRow("SELECT username,password,role,figure,sex,motto,motto_messenger,credits,tickets,film,currentbadge,lastactivity,club_daysleft,club_monthsleft,club_monthsexpired,club_lastupdate,email,dob FROM users WHERE id = @userid"); returnInfo.ID = userID; returnInfo.Username = (string)dRow["username"]; returnInfo.Password = (string)dRow["password"]; returnInfo.Role = (userRole)(int.Parse(dRow["role"].ToString())); returnInfo.Figure = (string)dRow["figure"]; returnInfo.Sex = Convert.ToChar(dRow["sex"].ToString()); returnInfo.Motto = (string)dRow["motto"]; returnInfo.messengerMotto = (string)dRow["motto_messenger"]; returnInfo.Credits = (int)dRow["credits"]; returnInfo.Tickets = (int)dRow["tickets"]; returnInfo.Film = (int)dRow["film"]; returnInfo.Badge = (string)dRow["currentbadge"]; returnInfo.lastActivity = (DateTime)dRow["lastactivity"]; returnInfo.Email = (string)dRow["email"]; returnInfo.DateOfBirth = (string)dRow["dob"]; returnInfo.clubDaysLeft = (int)dRow["club_daysleft"]; returnInfo.clubMonthsLeft = (int)dRow["club_monthsleft"]; returnInfo.clubMonthsExpired = (int)dRow["club_monthsexpired"]; returnInfo.clubLastUpdate = (DateTime)dRow["club_lastupdate"]; } catch { returnInfo = null; } } return returnInfo; } public userInformation getUserInfo(string Username, bool forceRefresh) { if (!forceRefresh) { lock (mUserSessions) { Username = Username.ToLower(); foreach (Session lSession in mUserSessions.Values) { if (lSession.User != null && lSession.User.Username.ToLower() == Username) return lSession.User; } } } int userID = this.getUserID(Username); if (userID > 0) return this.getUserInfo(userID, forceRefresh); else return null; } public userAccessInformation getLastAccess(int userID) { if (mUserSessions.ContainsKey(userID)) return mUserSessions[userID].Access; Database dbClient = new Database(false, true); dbClient.addParameterWithValue("userid", userID); dbClient.Open(); if (dbClient.Ready) return userAccessInformation.Parse(dbClient.getRow("SELECT * FROM users_access WHERE userid = @userid ORDER BY moment DESC LIMIT 1")); else return null; } #endregion #region Registration etc /// /// Returns the ID of the error at a name check of a username/new pet. If no errors, then 0 is returned. /// /// Specifies if this namecheck is for a pet purchase. /// The name to check. public int getNameCheckError(bool Pet, string Name) { if (Name.Length > 15 || !stringFunctions.usernameIsValid(Name)) // TODO: MOD-, ADM-, SOS- etc blocking return 2; // Invalid else { if (Pet == false && userExists(Name)) return 4; // Username already taken else return 0; // OK } } /// /// Registers a new user by writing the given details into the 'users' table of the database. /// /// /// The information about the new user in a userInformation object. public void registerUser(Session Session, userInformation Info) { Database Database = new Database(false, true); Database.addParameterWithValue("username", Info.Username); Database.addParameterWithValue("password", Info.Password); Database.addParameterWithValue("role", "1"); Database.addParameterWithValue("figure", Info.Figure); Database.addParameterWithValue("sex", Info.Sex.ToString()); Database.addParameterWithValue("motto", Configuration.getConfigurationValue("users.registration.motto")); Database.addParameterWithValue("motto_messenger", Configuration.getConfigurationValue("users.registration.messengermotto")); Database.addParameterWithValue("credits", Configuration.getNumericConfigurationValue("users.registration.credits")); Database.addParameterWithValue("tickets", Configuration.getNumericConfigurationValue("users.registration.tickets")); Database.addParameterWithValue("film", 0); Database.addParameterWithValue("email", Info.Email); Database.addParameterWithValue("dob", Info.DateOfBirth); Database.Open(); if (Database.Ready) { //Database.runQuery("CALL register_user(@username,@password,@figure,@sex,@email,@dob,@receivemails)"); Database.runQuery( "INSERT INTO users " + "(username,password,role,signedup,figure,sex,motto,motto_messenger,credits,tickets,film,lastactivity,club_lastupdate,email,dob) " + "VALUES " + "(@username,@password,@role,NOW(),@figure,@sex,@motto,@motto_messenger,@credits,@tickets,@film,NOW(),NOW(),@email,@dob)"); Logging.Log("Created user '" + Info.Username + "'.", Logging.logType.userVisitEvent); } else Logging.Log("Failed to create user " + Info.Username + ", because the database was not contactable!", Logging.logType.commonWarning); } #endregion #region Hotel alert & CFH public void broadcastMessage(serverMessage Message) { string sMessage = Message.ToString(); lock (mUserSessions) { foreach (Session lSession in mUserSessions.Values) { lSession.gameConnection.sendMessage(sMessage); } } } public void broadcastHotelAlert(string Text) { serverMessage hhCast = genericMessageFactory.createMessageBoxCast("Message from staff:
" + Text); this.broadcastMessage(hhCast); Logging.Log("Broadcoasted hotel alert ('" + Text + "') to all online users."); } #endregion #region Badges /// /// Gives a badge to user, after checking if the user doesn't already have this badge. A boolean is returned that indicates if the badge is given or not. /// /// The database ID of the user to give the badge to. /// The badge of the user to public bool giveBadgeToUser(int userID, string Badge) { Database Database = new Database(false, false); Database.addParameterWithValue("userid", userID); Database.addParameterWithValue("badge", Badge); Database.Open(); if (Database.Ready) { if (!Database.findsResult("SELECT userid FROM users_badges WHERE userid = @userid AND badge = @badge LIMIT 1")) { Database.runQuery("INSERT INTO users_badges(userid,badge) VALUES (@userid,@badge)"); return true; } Database.Close(); } return false; } /// /// Removes a certain badge from a given user. /// /// The database ID of the user to remove the badge of. /// The badge to remove. public void removeBadgeFromUser(int userID, string Badge) { Database Database = new Database(false, false); Database.addParameterWithValue("userid", userID); Database.addParameterWithValue("badge", Badge); Database.Open(); if (Database.Ready) Database.runQuery("DELETE FROM users_badges WHERE userid = @userid AND badge = @badge LIMIT 1"); } /// /// Returns a boolean indicating if a given user posesses a given badge. /// /// The database ID of the user to check. /// The badge to check. public bool userHasBadge(userInformation User, string Badge) { if ((Badge == "HC1" && User.hasClub) || (Badge == "HC2" && User.hasGoldClub)) // Club badge return true; if (Engine.Game.Roles.roleHasBadge(User.Role, Badge)) // Role badge return true; // Private badge check Database Database = new Database(false, true); Database.addParameterWithValue("userid", User.ID); Database.addParameterWithValue("badge", Badge); Database.Open(); return Database.findsResult("SELECT userid FROM users_badges WHERE userid = @userid AND badge = @badge LIMIT 1"); // True if this user has the searched badge as private } public void addPrivateBadgesToList(int userID, userRole Role, ref List lBadges) { Database db = new Database(false, true); db.addParameterWithValue("userid", userID); db.Open(); if (db.Ready) { DataTable dTable = db.getTable("SELECT badge FROM users_badges WHERE userid = @userid"); foreach (DataRow dRow in dTable.Rows) { lBadges.Add(dRow["badge"].ToString()); } } } #endregion #endregion } }