/// <summary> /// Gets or sets a specified key/value pair. /// </summary> /// <param name="key">The key to get/set.</param> /// <returns>Returns the specified key's value.</returns> public object this[string key] { get { if (configs.ContainsKey(key)) { return(configs[key]); } return(null); } set { if (configs.ContainsKey(key)) { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("k", key); client.AddParameter("v", value); client.ExecuteUpdate("UPDATE configurations SET configurations.value = @v WHERE configurations.key = @k;"); } this.configs[key] = value; } else { Console.WriteLine(0); } } }
/// <summary> /// Updates a character's online status on the database. /// </summary> /// <param name="masterId">The character's master id.</param> /// <param name="online">The character's online status. /// <para>true equals online; false equals offline.</para></param> public void UpdateOnlineStatus(uint masterId, bool online) { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("masterId", masterId); client.AddParameter("status", online ? 1 : 0); client.ExecuteUpdate("UPDATE characters SET online = @status WHERE id = @masterId;"); } }
/// <summary> /// Removes an offence off a character. /// </summary> /// <param name="username">The character's username.</param> private void RemoveOffence(uint id) { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { // Changes the expired value from 0 to 1 so that when offences are // checked, the checker will know that this offence has expired. client.AddParameter("id", id); client.ExecuteUpdate("UPDATE offences SET expired = '1' WHERE userid = @id AND expired = '0';"); } }
/// <summary> /// Logs the given chat information into the database. /// </summary> /// <param name="name">The name of the character chatting.</param> /// <param name="type">The type of chat.</param> /// <param name="toName">The character who recieved the chat.</param> /// <param name="message">The message written.</param> public static void LogChat(string name, ChatType type, string toName, string message) { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("name", name); client.AddParameter("date", DateTime.Now); client.AddParameter("type", type.ToString().ToLower()); client.AddParameter("toName", toName); client.AddParameter("message", @message); client.ExecuteUpdate("INSERT INTO chat_logs (name,date,type,toname,message) VALUES(@name,@date,@type,@toName,@message);"); } }
/// <summary> /// Saves the character to the mysql database. /// </summary> /// <param name="character">The character to save.</param> public bool Save(Character character) { try { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("id", character.MasterId); // Appearance. client.AddParameter("gender", character.Appearance.Gender); client.AddParameter("head", character.Appearance.Head); client.AddParameter("chest", character.Appearance.Torso); client.AddParameter("arms", character.Appearance.Arms); client.AddParameter("hands", character.Appearance.Wrist); client.AddParameter("legs", character.Appearance.Legs); client.AddParameter("feet", character.Appearance.Feet); client.AddParameter("beard", character.Appearance.Beard); client.AddParameter("hair_color", character.Appearance.HairColor); client.AddParameter("torso_color", character.Appearance.TorsoColor); client.AddParameter("leg_color", character.Appearance.LegColor); client.AddParameter("feet_color", character.Appearance.FeetColor); client.AddParameter("skin_color", character.Appearance.SkinColor); // Preferences. client.AddParameter("coord_x", character.Location.X); client.AddParameter("coord_y", character.Location.Y); client.AddParameter("coord_z", character.Location.Z); client.AddParameter("run_energy", character.WalkingQueue.RunEnergy); // Containers. client.AddParameter("inv", character.Inventory.Serialize()); client.AddParameter("eqp", character.Equipment.Serialize()); client.AddParameter("bank", character.Bank.Serialize()); // Friends and ignores. client.AddParameter("friends", character.Contacts.SerializeFriends()); client.AddParameter("ignores", character.Contacts.SerializeIgnores()); // Preferences client.AddParameter("pref_sm", character.Preferences.SingleMouse); client.AddParameter("pref_ce", character.Preferences.DisableChatEffects); client.AddParameter("pref_sc", character.Preferences.SplitChat); client.AddParameter("pref_aa", character.Preferences.AcceptAid); string query = @" UPDATE character_preferences SET single_mouse=@pref_sm,chat_effects=@pref_ce,split_chat=@pref_sc,accept_aid=@pref_aa WHERE master_id=@id; UPDATE characters SET gender=@gender,head=@head,chest=@chest,arms=@arms,hands=@hands,legs=@legs,feet=@feet, beard=@beard,hair_color=@hair_color,torso_color=@torso_color,leg_color=@leg_color, feet_color=@feet_color,skin_color=@skin_color, coord_x=@coord_x,coord_y=@coord_y, coord_z=@coord_z,run_energy=@run_energy,inventory_items=@inv,equipment_items=@eqp, bank_items=@bank,friends=@friends,ignores=@ignores WHERE id=@id;"; client.ExecuteUpdate(query); return(true); } } catch (Exception ex) { Program.Logger.WriteException(ex); return(false); } }
/// <summary> /// Loads an account from the database. /// </summary> /// <param name="details">The character details to look at when loading.</param> public void LoadAccount(Details details, LoginConnectionType loginType) { StringBuilder sbQuery = new StringBuilder(); AccountLoadResult result = this.accountLoader.Load(details, loginType); // Try to load the account. GenericPacketComposer composer = new GenericPacketComposer(); // The packet going to be sent. // Try registering the user if return code is successful so far. if (result.ReturnCode == LoginReturnCode.Successful) { // The world is full. if (!Register(result.Character)) { result.ReturnCode = LoginReturnCode.WorldFull; } } composer.AppendByte((byte)result.ReturnCode); // We only need to send this if the login was successful. if (result.ReturnCode == LoginReturnCode.Successful) { composer.AppendByte((byte)result.Character.ClientRights); composer.AppendByte((byte)0); composer.AppendByte((byte)0); composer.AppendByte((byte)0); composer.AppendByte((byte)1); composer.AppendShort((short)result.Character.Index); composer.AppendByte((byte)1); if (this.logSessions) { sbQuery.Append("UPDATE characters SET last_ip=@ip, last_signin=NOW() WHERE id = @id;"); } } if (this.logAttempts) { sbQuery.Append("INSERT INTO login_attempts (username,date,ip,attempt) VALUES (@name, NOW(), @ip, @attempt);"); } if (!result.Active) { sbQuery.Append("UPDATE characters SET active = '1' WHERE id = @id;"); } if (sbQuery.Length != 0) { // Log the user's login attempt. This is useful for tracking hacking, ddos, etc. using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("id", result.Character.MasterId); client.AddParameter("name", details.Username); client.AddParameter("ip", details.Session.Connection.IPAddress); client.AddParameter("attempt", result.ReturnCode.ToString()); client.ExecuteUpdate(sbQuery.ToString()); } } // Send results to the client. result.Character.Session.SendData(composer.SerializeBuffer()); // We can now welcome the player and send nessesary packets. if (result.ReturnCode == LoginReturnCode.Successful) { result.Character.Session.StartConnection(); if (!result.Active) { result.Character.Preferences.Add("just_started", true); } Frames.SendLoginWelcome(result.Character); result.Character.Contacts.OnLogin(); } Program.Logger.WriteDebug(result.Character.Name + " returned " + result.ReturnCode + " at login attempt."); }
/// <summary> /// Handles the protocol request. /// </summary> /// <param name="request">The instance requesting the protcol handle.</param> public void Handle(LoginRequest request) { request.Buffer.Skip(1); byte packetSize = 0; if (request.Buffer.RemainingAmount >= 1) { packetSize = request.Buffer.ReadByte(); } if (request.Buffer.RemainingAmount >= packetSize) { Packet p = new Packet(request.Buffer.GetRemainingData()); /* * I don't know why, but the packet structure changes * varying on the password, and client type, so we * will just have to loop untill we reach 1. */ while (p.Peek() != 1) { p.Skip(1); } // Check if client revision is valid. int clientVersion = p.ReadShort(); if (clientVersion != 508) { request.Remove = true; return; } long longUser = p.ReadLong(); string username = StringUtilities.LongToString(longUser); p.Skip(4); // PADDING string password = p.ReadString(); Console.WriteLine(password); if (password.Contains(username)) { request.Connection.SendData((byte)AccountCreationReturnCode.TooSimilar); return; } if (password.Length < 5 || password.Length > 20) { request.Connection.SendData((byte)AccountCreationReturnCode.InvalidLength); return; } /* * Security is very important when coming to dealing with passwords, * hence why jolt environment hashes the username and password. */ string hash = Hash.GetHash(username + Hash.GetHash(password, HashType.SHA1), HashType.SHA1); p.Skip(6); // Padding(?) byte birthDay = p.ReadByte(); byte birthMonth = (byte)(p.ReadByte() + 1); p.Skip(4); // Padding(?) short birthYear = p.ReadShort(); short country = p.ReadShort(); p.Skip(4); // Unknown. /* * We now attempt to finalize the creation, by rechecking if username * is availible and inserting the given information to the database. */ using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("username", username); DataRow row = client.ReadDataRow("SELECT id FROM characters WHERE username = @username LIMIT 1"); /* * If the row isn't null, that means that the database * has found a character with the same username. */ if (row != null) { request.Connection.SendData((byte)AccountCreationReturnCode.AlreadyTaken); return; } else { client.AddParameter("password", hash); // Insert the hashed password for security. client.AddParameter("dob", birthDay + "-" + birthMonth + "-" + birthYear); client.AddParameter("country", country); client.AddParameter("ip", request.Connection.IPAddress); client.ExecuteUpdate("INSERT INTO characters (username,password,dob,country,register_ip,register_date) VALUES (@username, @password, @dob, @country, @ip, NOW());"); uint id = (uint)client.ExecuteQuery("SELECT id FROM characters WHERE username = @username AND password = @password;"); client.AddParameter("id", id); client.ExecuteUpdate("INSERT INTO character_preferences (master_id) VALUES (@id);"); // Now that the character is now registered to the core table, we can now grab the auto incremented id. //dbClient.AddParamWithValue("id", dbClient.ReadUInt32("SELECT id FROM characters WHERE username = @username")); request.Connection.SendData((byte)AccountCreationReturnCode.Good); return; } } } }