/// <summary> /// Attempts to check the database verson via the database to see if it's valid for use. /// </summary> /// <param name="client">The client providing the connection to database.</param> /// <returns>Returns true if valid; false if not.</returns> public object Execute(SqlDatabaseClient client) { client.AddParameter("sver", Program.Version.ToString()); string dbResult = (string)client.ExecuteQuery( "SELECT database_version FROM versioning; " + "UPDATE versioning SET server_version = @sver;"); Version required = new Version(1, 0, 3100); Version dbVersion = Version.Parse(dbResult); if (dbVersion < required) { return(false); } return(true); }
/// <summary> /// Loads the item defitions from mysql database and stores in a local array. /// </summary> /// <param name="destination">The array to store data to.</param> public static void Load() { // The largest item id value in the item_definitions table. int largestValue = 0; // The defitions storage. ItemDefinition[] definitions = null; // The raw definitions from mysql database. DataRow[] rows = null; try { using (SqlDatabaseClient client = GameServer.Database.GetClient()) { // Find the highest id value so we can make an array based on that value. largestValue = (short)client.ExecuteQuery("SELECT MAX(id) FROM item_definitions;"); // Get raw definitions. rows = client.ReadDataTable("SELECT * FROM item_definitions").Select(); } /* * Create the array with specified largest value + 1 (because items start at 0). */ definitions = new ItemDefinition[largestValue + 1]; // Parse definitions. foreach (DataRow row in rows) { // General definitions. short id = Convert.ToInt16(row[0]); string name = Convert.ToString(row[1]); string examine = Convert.ToString(row[2]); short equipId = Convert.ToInt16(row[3]); bool stackable = Convert.ToBoolean(row[4]); bool tradable = Convert.ToBoolean(row[5]); bool noted = Convert.ToBoolean(row[6]); short noteId = Convert.ToInt16(row[7]); // Price definitions. int[] prices = new int[3]; prices[0] = Convert.ToInt32(row[8]); // Minimum price. prices[1] = Convert.ToInt32(row[9]); // Normal price. prices[2] = Convert.ToInt32(row[10]); // Maximum price. // Bonus definitions. short[] bonuses = new short[16]; bonuses[0] = Convert.ToInt16(row[11]); // Attack Stab Bonus bonuses[1] = Convert.ToInt16(row[12]); // Attack Slash Bonus bonuses[2] = Convert.ToInt16(row[13]); // Attack Crush Bonus bonuses[3] = Convert.ToInt16(row[14]); // Attack Magic Bonus bonuses[4] = Convert.ToInt16(row[15]); // Attack Ranged Bonus bonuses[5] = Convert.ToInt16(row[16]); // Defence Stab Bonus bonuses[6] = Convert.ToInt16(row[17]); // Defence Slash Bonus bonuses[7] = Convert.ToInt16(row[18]); // Defence Crush Bonus bonuses[8] = Convert.ToInt16(row[19]); // Defence Magic Bonus bonuses[9] = Convert.ToInt16(row[20]); // Defence Ranged Bonus bonuses[10] = Convert.ToInt16(row[21]); // Defence Summoning Bonus bonuses[11] = Convert.ToInt16(row[22]); // Strength Bonus bonuses[12] = Convert.ToInt16(row[23]); // Prayer Bonus // Configure definition. definitions[id] = new ItemDefinition(id, name, examine, equipId, noted, noteId, stackable, tradable, prices, bonuses); } /* * This must be done so no errors are caused if there * are null items. If the player does somehow spawn * a null item, they'll recieve drawf remains instead. */ for (int i = 0; i < definitions.Length; i++) { if (definitions[i] == null) { definitions[i] = definitions[0]; } } //Program.Logger.WriteInfo("Loaded " + rows.Length + " item definitions."); } catch (Exception ex) { Program.Logger.WriteException(ex); } ItemDefinition.definitions = definitions; }
/// <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; } } } }