コード例 #1
0
 /// <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);
         }
     }
 }
コード例 #2
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;");
     }
 }
コード例 #3
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);");
     }
 }
コード例 #4
0
        /// <summary>
        /// Gets any offences that the character may have caused from the database.
        /// </summary>
        /// <param name="username">The character's username.</param>
        /// <returns>The offense type.</returns>
        public OffenceType GetOffence(uint id)
        {
            DataRow row;

            using (SqlDatabaseClient client = GameServer.Database.GetClient())
            {
                client.AddParameter("id", id);
                row = client.ReadDataRow("SELECT type,expire_date FROM offences WHERE userid = @id AND expired = '0' LIMIT 1;");
            }

            try
            {
                if (row != null)
                {
                    if (DateTime.Now >= (DateTime)row[1])
                    {
                        RemoveOffence(id);
                        return(OffenceType.None);
                    }
                    Console.WriteLine(row[0]);
                    return((OffenceType)row[0]);
                }
            }
            catch (Exception ex)
            {
                Program.Logger.WriteException(ex);
            }
            return(OffenceType.None);
        }
コード例 #5
0
 /// <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';");
     }
 }
コード例 #6
0
        /// <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);
            if (request.Buffer.RemainingAmount >= 4)
            {
                long   longName = request.Buffer.ReadLong();
                string name     = StringUtilities.LongToString(longName);

                bool availible = false;

                // Check if the entered name is availible.
                using (SqlDatabaseClient client = GameServer.Database.GetClient())
                {
                    client.AddParameter("name", name);
                    DataRow row = client.ReadDataRow("SELECT id FROM characters WHERE username = @name LIMIT 1");

                    if (row == null)
                    {
                        availible = true;
                    }
                }

                // Check if the world allows account creation.
                if (GameEngine.World.AccountCreationEnabled)
                {
                    // Name lengths must be valid.
                    if (name != null && name.Length > 0 && name.Length < 13 && !name.ContainsBadWord())
                    {
                        if (availible)
                        {
                            request.Connection.SendData((byte)AccountCreationReturnCode.Good);
                        }
                        else
                        {
                            request.Connection.SendData((byte)AccountCreationReturnCode.AlreadyTaken);
                        }
                    }
                    else
                    {
                        request.Connection.SendData((byte)AccountCreationReturnCode.InvalidUsername);
                    }
                }
                else
                {
                    request.Connection.SendData((byte)AccountCreationReturnCode.Disabled);
                }
            }
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <summary>
        /// Checks whether a character is online from the database.
        /// </summary>
        /// <param name="username">The username to check for.</param>
        /// <returns>Returns true if the character is online; false if offline.</returns>
        public bool OnlineByDatabase(string username)
        {
            DataRow result = null;

            using (SqlDatabaseClient client = GameServer.Database.GetClient())
            {
                client.AddParameter("username", username);
                result = client.ReadDataRow("SELECT online FROM characters WHERE username = @username LIMIT 1;");
            }

            if (result != null)
            {
                return((bool)result[0]);
            }
            return(false);
        }
コード例 #9
0
        /// <summary>
        /// Constructs a new world.
        ///
        ///     <para>With the given world id, it will find the configurations
        ///     set in the database, and configure this world using them. This
        ///     allows you to create multiple worlds, yet connect to the same
        ///     world, with the same players etc.</para>
        /// </summary>
        /// <param name="worldId">The id of this world.</param>
        public GameWorld(uint worldId)
        {
            // World initializations
            this.Id = worldId;

            DataRow vars;

            // Grab the rest of the world-specific variables from the database.
            using (SqlDatabaseClient client = GameServer.Database.GetClient())
            {
                client.AddParameter("id", worldId);
                vars = client.ReadDataRow(
                    "SELECT * FROM worlds WHERE world_id = @id LIMIT 1;" +
                    "UPDATE characters SET online = '0' WHERE online = '1';" +
                    "UPDATE worlds SET startup_time = NOW() WHERE world_id = @id;");
            }

            if (vars != null)
            {
                this.Name           = (string)vars["world_name"];
                this.WelcomeMessage = (string)vars["welcome_message"];
                string[] coords = vars["spawn_point"].ToString().Split(',');
                this.SpawnPoint = Location.Create(
                    short.Parse(coords[0]),
                    short.Parse(coords[1]),
                    byte.Parse(coords[2]));
                this.Motw                   = (string)vars["motw"];
                this.ExperienceRate         = (int)vars["exp_rate"];
                this.AccountCreationEnabled = true;
                this.IdlingEnabled          = (bool)vars["enable_idling"];
            }
            else
            {
                throw new ArgumentException("No existing world with id '" + worldId + "'.");
            }

            // Load bad words.
            BadWords.Load();
        }
コード例 #10
0
        /// <summary>
        /// Handles connection requests.
        /// </summary>
        /// <param name="async">The asynchronous handle result.</param>
        public void OnConnectionRequest(IAsyncResult result)
        {
            try
            {
                Socket socket = this.listener.EndAcceptSocket(result);
                StandBy();

                if (this.CheckBlacklist)
                {
                    using (SqlDatabaseClient client = GameServer.Database.GetClient())
                    {
                        client.AddParameter("ip", socket.RemoteEndPoint.ToString().Split(':')[0]);
                        DataRow row = client.ReadDataRow("SELECT * FROM blacklist WHERE ip_address = @ip LIMIT 1;");

                        if (row != null)
                        {
                            Program.Logger.WriteDebug("Connection attempt from " + socket.RemoteEndPoint + " denied.");
                            socket.Close();
                            socket = null;
                        }
                    }
                }

                Node node = this.factory.Create(socket);
                if (node != null)
                {
                    this.manager.HandleNewConnection(node);
                }
            }
            catch (ObjectDisposedException)
            {
            }
            catch (Exception ex)
            {
                Program.Logger.WriteException(ex);
            }
        }
コード例 #11
0
        /// <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);
            }
        }
コード例 #12
0
        /// <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.");
        }
コード例 #13
0
        /// <summary>
        /// Loads an account from the mysql database using the given character details.
        /// </summary>
        /// <param name="details">The details used to load the account.</param>
        /// <returns>Returns the account load result.</returns>
        public AccountLoadResult Load(Details details, LoginConnectionType loginType)
        {
            AccountLoadResult result = new AccountLoadResult();

            if (GameEngine.World.SystemUpdate)
            {
                result.Character  = new Character(details, 0);
                result.ReturnCode = LoginReturnCode.SystemUpdate;
            }
            try
            {
                DataRow data = null;
                using (SqlDatabaseClient client = GameServer.Database.GetClient())
                {
                    /*
                     * Checks if the character exists in the database. It also
                     * checks if the given password matches the stored password.
                     */
                    client.AddParameter("username", details.Username);
                    client.AddParameter("password", details.Password);
                    data = client.ReadDataRow("SELECT * FROM characters LEFT JOIN (character_preferences) ON (characters.id = character_preferences.master_id) WHERE username = @username AND password = @password LIMIT 1;");
                }

                if (data != null) // Meaning the character exists, and the password is correct.
                {
                    result.Character = new Character(details, (uint)data[0]);

                    // If a character is offensive, set the proper penalties.
                    OffenceType offence = (OffenceType)GameEngine.World.OffenseManager.GetOffence(result.Character.MasterId);
                    if (offence == OffenceType.Banned) // If the character is banned, flag and end this request.
                    {
                        result.ReturnCode = LoginReturnCode.AccountDisabled;
                    }
                    if (offence == OffenceType.Muted) // If the character is muted, we will mute this character.
                    {
                        result.Character.Muted = true;
                    }

                    /*
                     * Only check if it's a new connection, as reconnections try
                     * connnecting to the server before the older session is removed,
                     * so we must ignore whether or not the character is online.
                     */
                    if (loginType != LoginConnectionType.Reconnection && (bool)data[5])
                    {
                        result.ReturnCode = LoginReturnCode.AlreadyOnline;
                    }

                    /*
                     * We only want to assign the character details loaded from
                     * the database if the player has passed though security.
                     */
                    if (result.ReturnCode == LoginReturnCode.Successful)
                    {
                        // Core info.
                        result.Character.ClientRights = (ClientRights)data[3];
                        result.Character.ServerRights = (ServerRights)data[4];
                        result.Active = (bool)data[6];

                        // Appearance.
                        result.Character.Appearance.Gender     = (Gender)data[14];
                        result.Character.Appearance.Head       = (short)data[15];
                        result.Character.Appearance.Torso      = (short)data[16];
                        result.Character.Appearance.Arms       = (short)data[17];
                        result.Character.Appearance.Wrist      = (short)data[18];
                        result.Character.Appearance.Legs       = (short)data[19];
                        result.Character.Appearance.Feet       = (short)data[20];
                        result.Character.Appearance.Beard      = (short)data[21];
                        result.Character.Appearance.HairColor  = (byte)data[22];
                        result.Character.Appearance.TorsoColor = (byte)data[23];
                        result.Character.Appearance.LegColor   = (byte)data[24];
                        result.Character.Appearance.FeetColor  = (byte)data[25];
                        result.Character.Appearance.SkinColor  = (byte)data[26];

                        // Location.
                        result.Character.Location = Location.Create((short)data[27], (short)data[28], (byte)data[29]);

                        // Energy.
                        result.Character.WalkingQueue.RunEnergy = (byte)data[30];

                        // Containers.
                        if (data[31] is string)
                        {
                            result.Character.Inventory.Deserialize((string)data[31]);
                        }
                        if (data[32] is string)
                        {
                            result.Character.Equipment.Deserialize((string)data[32]);
                        }
                        if (data[33] is string)
                        {
                            result.Character.Bank.Deserialize((string)data[33]);
                        }

                        // Friends and ignores
                        if (data[34] is string)
                        {
                            string friends = (string)data[34];
                            if (friends != string.Empty)
                            {
                                result.Character.Contacts.DeserializeFriends(friends);
                            }
                        }
                        if (data[35] is string)
                        {
                            string ignores = (string)data[35];
                            if (ignores != string.Empty)
                            {
                                result.Character.Contacts.DeserializeIgnores((string)data[35]);
                            }
                        }

                        // Preferences.
                        result.Character.Preferences.SingleMouse        = (bool)data[37];
                        result.Character.Preferences.DisableChatEffects = (bool)data[38];
                        result.Character.Preferences.SplitChat          = (bool)data[39];
                        result.Character.Preferences.AcceptAid          = (bool)data[40];
                    }
                }
                else // User doesn't exist or password is wrong.
                {
                    result.Character  = new Character(details, 0);
                    result.ReturnCode = LoginReturnCode.WrongPassword;
                }
            }
            catch (Exception ex)
            {
                Program.Logger.WriteException(ex);
                result.Character  = new Character(details, 0);
                result.ReturnCode = LoginReturnCode.BadSession;
            }
            return(result);
        }
コード例 #14
0
        /// <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;
                    }
                }
            }
        }