コード例 #1
0
ファイル: Connection.cs プロジェクト: DomGrieco/server
 public static void RegisterClient(Client client)
 {
     Logger.DebugFormat("RegisterConnection: {0}", client.ConnectionId);
     ConnectedClients[client.ConnectionId] = client;
     if (client.ServerType == ServerTypes.World)
         WorldClients[client.ConnectionId] = client;
 }
コード例 #2
0
ファイル: Login.cs プロジェクト: DomGrieco/server
        private void PacketHandler_0x02_CreateA(Client client, ClientPacket packet)
        {
            var name = packet.ReadString8();
            var password = packet.ReadString8();
            var email = packet.ReadString8();

            // This string will contain a client-ready message if the provided password
            // isn't valid.
            byte passwordErr = 0x0;

            if (Game.World.PlayerExists(name))
            {
                client.LoginMessage("That name is unavailable.", 3);
            }
            else if (name.Length < 4 || name.Length > 12)
            {
                client.LoginMessage("Names must be between 4 to 12 characters long.", 3);
            }
            else if (!ValidPassword(password, out passwordErr))
            {
                client.LoginMessage(GetPasswordError(passwordErr), 3);
            }
            else if (Regex.IsMatch(name, "^[A-Za-z]{4,12}$"))
            {
                client.NewCharacterName = name;
                client.NewCharacterPassword = HashPassword(password);
                client.LoginMessage("\0", 0);
            }
            else
            {
                client.LoginMessage("Names may only contain letters.", 3);
            }
        }
コード例 #3
0
ファイル: Server.cs プロジェクト: DomGrieco/server
 public virtual void AcceptConnection()
 {
     if (TcpListener.Pending())
     {             
         var socket = TcpListener.AcceptSocket();
         var client = new Client(socket, this);
         client.Begin();
     }
 }
コード例 #4
0
ファイル: Connection.cs プロジェクト: DomGrieco/server
 public static void DeregisterClient(Client client)
 {
     ((IDictionary)ConnectedClients).Remove(client.ConnectionId);
     // Send a control message to clean up after World users; Lobby and Login handle themselves
     if (client.ServerType == ServerTypes.World)
     {
         ((IDictionary)WorldClients).Remove(client.ConnectionId);
         // This will also handle removing the user from WorldClients if necessary
         World.MessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.CleanupUser, client.ConnectionId));
     }
 }
コード例 #5
0
ファイル: Login.cs プロジェクト: DomGrieco/server
 private void PacketHandler_0x4B_RequestNotification(Client client, ClientPacket packet)
 {
     var x60 = new ServerPacket(0x60);
     x60.WriteByte(0x01);
     x60.WriteUInt16((ushort)Game.Notification.Length);
     x60.Write(Game.Notification);
     client.Enqueue(x60);
 }
コード例 #6
0
ファイル: Login.cs プロジェクト: DomGrieco/server
        // Chart for all error password-related error codes were provided by kojasou@ on
        // https://github.com/hybrasyl/server/pull/11.
        private void PacketHandler_0x26_ChangePassword(Client client, ClientPacket packet)
        {
            var name = packet.ReadString8();
            var currentPass = packet.ReadString8();
            // Clientside validation ensures that the same string is typed twice for the new
            // password, and the new password is only sent to the server once. We can assume
            // that they matched if 0x26 request is sent from the client.
            var newPass = packet.ReadString8();

            // TODO: REDIS

            IDatabase cache = World.DatastoreConnection.GetDatabase();
            var myPerson = cache.Get(name);

            if (myPerson == null)
            {
                client.LoginMessage(GetPasswordError(0x0E), 0x0E);
                Logger.DebugFormat("Password change attempt on invalid player `{0}`", name);
                
            }

            var player = JsonConvert.DeserializeObject(myPerson as String) as User;
            if (player.VerifyPassword(currentPass))
            {

                // Check if the password is valid.
                byte err = 0x00;
                if (ValidPassword(newPass, out err))
                {
                    player.Password.Hash = HashPassword(newPass);
                    player.Password.LastChanged = DateTime.Now;
                    player.Password.LastChangedFrom = ((IPEndPoint) client.Socket.RemoteEndPoint).Address.ToString();
                    player.Save();
                    // Let the user know the good news.
                    client.LoginMessage("Your password has been changed successfully.", 0x0);
                    Logger.InfoFormat("Password successfully changed for `{0}`", name);
                }
                else
                {
                    client.LoginMessage(GetPasswordError(err), err);
                    Logger.ErrorFormat("Invalid new password proposed during password change attempt for `{0}`", name);
                }
            }
                // The current password is incorrect. Don't allow any changes to happen.
            else
            {
                client.LoginMessage(GetPasswordError(0x0F), 0x0F);
                Logger.ErrorFormat("Invalid current password during password change attempt for `{0}`", name);
            }
        }
コード例 #7
0
ファイル: Login.cs プロジェクト: DomGrieco/server
        private void PacketHandler_0x10_ClientJoin(Client client, ClientPacket packet)
        {
            var seed = packet.ReadByte();
            var keyLength = packet.ReadByte();
            var key = packet.Read(keyLength);
            var name = packet.ReadString8();
            var id = packet.ReadUInt32();

            var redirect = ExpectedConnections[id];
            if (redirect.Matches(name, key, seed))
            {
                ((IDictionary)ExpectedConnections).Remove(id);

                client.EncryptionKey = key;
                client.EncryptionSeed = seed;

                if (redirect.Source is Lobby)
                {
                    var x60 = new ServerPacket(0x60);
                    x60.WriteByte(0x00);
                    x60.WriteUInt32(Game.NotificationCrc);
                    client.Enqueue(x60);
                }
            }

        }
コード例 #8
0
ファイル: Login.cs プロジェクト: DomGrieco/server
        private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet)
        {
            if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword))
                return;

            var hairStyle = packet.ReadByte();
            var sex = packet.ReadByte();
            var hairColor = packet.ReadByte();

            if (hairStyle < 1)
                hairStyle = 1;

            if (hairStyle > 17)
                hairStyle = 17;

            if (hairColor > 13)
                hairColor = 13;

            if (sex < 1)
                sex = 1;

            if (sex > 2)
                sex = 2;

            if (!Game.World.PlayerExists(client.NewCharacterName))
            {
                var newPlayer = new User();
                newPlayer.Name = client.NewCharacterName;
                newPlayer.Sex = (Sex) sex;
                newPlayer.Location.Direction = Direction.South;
                newPlayer.Location.MapId = 136;
                newPlayer.Location.X = 10;
                newPlayer.Location.Y = 10;
                newPlayer.HairColor = hairColor;
                newPlayer.HairStyle = hairStyle;
                newPlayer.Class = Class.Peasant;
                newPlayer.Level = 1;
                newPlayer.Experience = 1;
                newPlayer.Level = 1;
                newPlayer.Experience = 0;
                newPlayer.AbilityExp = 0;
                newPlayer.Gold = 0;
                newPlayer.Ability = 0;
                newPlayer.Hp = 50;
                newPlayer.Mp = 50;
                newPlayer.BaseHp = 50;
                newPlayer.BaseMp = 50;
                newPlayer.BaseStr = 3;
                newPlayer.BaseInt = 3;
                newPlayer.BaseWis = 3;
                newPlayer.BaseCon = 3;
                newPlayer.BaseDex = 3;
                newPlayer.Login.CreatedTime = DateTime.Now;
                newPlayer.Password.Hash = client.NewCharacterPassword;
                newPlayer.Password.LastChanged = DateTime.Now;
                newPlayer.Password.LastChangedFrom = ((IPEndPoint) client.Socket.RemoteEndPoint).Address.ToString();

                IDatabase cache = World.DatastoreConnection.GetDatabase();
                var myPerson = JsonConvert.SerializeObject(newPlayer);
                    cache.Set(String.Format("{0}:{1}", User.DatastorePrefix, newPlayer.Name), myPerson);

//                    Logger.ErrorFormat("Error saving new player!");
  //                  Logger.ErrorFormat(e.ToString());
    //                client.LoginMessage("Unknown error. Contact [email protected]", 3);
      //          }
                client.LoginMessage("\0", 0);
            }
        }
コード例 #9
0
ファイル: Login.cs プロジェクト: DomGrieco/server
        private void PacketHandler_0x03_Login(Client client, ClientPacket packet)
        {
            var name = packet.ReadString8();
            var password = packet.ReadString8();
            Logger.DebugFormat("cid {0}: Login request for {1}", client.ConnectionId, name);

            User loginUser;

            if (!World.TryGetUser(name, out loginUser))
            {
                client.LoginMessage("That character does not exist", 3);
                Logger.InfoFormat("cid {0}: attempt to login as nonexistent character {1}", client.ConnectionId, name);

            }
            else if (loginUser.VerifyPassword(password))
            {
                Logger.DebugFormat("cid {0}: password verified for {1}", client.ConnectionId, name);

                if (Game.World.ActiveUsersByName.ContainsKey(name))
                {
                    Logger.InfoFormat("cid {0}: {1} logging on again, disconnecting previous connection",
                        client.ConnectionId, name);
                    World.MessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.LogoffUser, name));
                }

                Logger.DebugFormat("cid {0} ({1}): logging in", client.ConnectionId, name);
                client.LoginMessage("\0", 0);
                client.SendMessage("Welcome to Hybrasyl!", 3);
                Logger.DebugFormat("cid {0} ({1}): sending redirect to world", client.ConnectionId, name);

                var redirect = new Redirect(client, this, Game.World, name, client.EncryptionSeed,
                    client.EncryptionKey);
                Logger.InfoFormat("cid {0} ({1}): login successful, redirecting to world server",
                    client.ConnectionId, name);
                client.Redirect(redirect);
                loginUser.Login.LastLogin = DateTime.Now;
                loginUser.Login.LastLoginFrom = ((IPEndPoint) client.Socket.RemoteEndPoint).Address.ToString();
                loginUser.Save();
            }
            else
            {
                Logger.WarnFormat("cid {0} ({1}): password incorrect", client.ConnectionId, name);
                client.LoginMessage("Incorrect password", 3);
                loginUser.Login.LastLoginFailure = DateTime.Now;
                loginUser.Login.LoginFailureCount++;
                loginUser.Save();
            }
        }
コード例 #10
0
ファイル: World.cs プロジェクト: saroque/server
        private void ProcessSlashCommands(Client client, ClientPacket packet)
        {

        }
コード例 #11
0
ファイル: Packet.cs プロジェクト: DomGrieco/server
        public void Encrypt(Client client)
        {
            var length = Data.Length - 3;

            var rand = new Random();
            var bRand = (ushort)(rand.Next() % 65277 + 256);
            var sRand = (byte)(rand.Next() % 155 + 100);

            var key = (UseDefaultKey) ? client.EncryptionKey : client.GenerateKey(bRand, sRand);

            for (var i = 0; i < length; i++)
            {
                Data[i] ^= key[i % key.Length];
                Data[i] ^= SaltTable[client.EncryptionSeed][(i / key.Length) % SaltTable[client.EncryptionSeed].Length];
                if ((i / key.Length) % SaltTable[client.EncryptionSeed].Length != Ordinal)
                {
                    Data[i] ^= SaltTable[client.EncryptionSeed][Ordinal];
                }
            }

            Data[length] = (byte)(bRand % 256 ^ 0x74);
            Data[length + 1] = (byte)(sRand ^ 0x24);
            Data[length + 2] = (byte)((bRand >> 8) % 256 ^ 0x64);
        }
コード例 #12
0
ファイル: Login.cs プロジェクト: saroque/server
        // Chart for all error password-related error codes were provided by kojasou@ on
        // https://github.com/hybrasyl/server/pull/11.
        private void PacketHandler_0x26_ChangePassword(Client client, ClientPacket packet)
        {
            var name = packet.ReadString8();
            var currentPass = packet.ReadString8();
            // Clientside validation ensures that the same string is typed twice for the new
            // password, and the new password is only sent to the server once. We can assume
            // that they matched if 0x26 request is sent from the client.
            var newPass = packet.ReadString8();

            using (var ctx = new hybrasylEntities(Constants.ConnectionString))
            {
                var player = ctx.players.Where(p => p.name == name).SingleOrDefault();

                // Check that `name` exists. If not, return a message indicating that to the user.
                if (player == null)
                {
                    client.LoginMessage(GetPasswordError(0x0E), 0x0E);
                    Logger.DebugFormat("Password change attempt on invalid player `{0}`", name);
                }
                // If the player does exist, validate the current and new passwords before updating.
                else
                {
                    // Check that the current password is correct and the new password is different
                    // than the current password.
                    if (VerifyPassword(currentPass, player))
                    {
                        // Check if the password is valid.
                        byte err = 0x00;
                        if (ValidPassword(newPass, out err))
                        {
                            player.password_hash = HashPassword(newPass);
                            ctx.SaveChanges();

                            // Let the user know the good news.
                            client.LoginMessage("Your password has been changed successfully.", 0x0);
                            Logger.InfoFormat("Password successfully changed for `{0}`", name);
                        }
                        else
                        {
                            client.LoginMessage(GetPasswordError(err), err);
                            Logger.ErrorFormat("Invalid new password proposed during password change attempt for `{0}`", name);
                        }
                    }
                    // The current password is incorrect. Don't allow any changes to happen.
                    else
                    {
                        client.LoginMessage(GetPasswordError(0x0F), 0x0F);
                        Logger.ErrorFormat("Invalid current password during password change attempt for `{0}`", name);
                    }
                }
            }
        }
コード例 #13
0
ファイル: Login.cs プロジェクト: saroque/server
        private void PacketHandler_0x04_CreateB(Client client, ClientPacket packet)
        {
            if (string.IsNullOrEmpty(client.NewCharacterName) || string.IsNullOrEmpty(client.NewCharacterPassword))
                return;

            var hairStyle = packet.ReadByte();
            var sex = packet.ReadByte();
            var hairColor = packet.ReadByte();

            if (hairStyle < 1)
                hairStyle = 1;

            if (hairStyle > 17)
                hairStyle = 17;

            if (hairColor > 13)
                hairColor = 13;

            if (sex < 1)
                sex = 1;

            if (sex > 2)
                sex = 2;

            if (!Game.World.PlayerExists(client.NewCharacterName))
            {
                using (var ctx = new hybrasylEntities(Constants.ConnectionString))
                {
                    player newplayer = new player
                    {
                        name = client.NewCharacterName,
                        password_hash = client.NewCharacterPassword,
                        sex = (Sex) sex,
                        hairstyle = hairStyle,
                        haircolor = hairColor,
                        map_id = 136,
                        map_x = 10,
                        map_y = 10,
                        direction = 1,
                        class_type = 0,
                        level = 1,
                        exp = 0,
                        ab = 0,
                        gold = 0,
                        ab_exp = 0,
                        max_hp = 50,
                        max_mp = 50,
                        cur_hp = 50,
                        cur_mp = 35,
                        str = 3,
                        @int = 3,
                        wis = 3,
                        con = 3,
                        dex = 3,
                        inventory = "[]",
                        equipment = "[]",
                        created_at = DateTime.Now
                    };
                    try
                    {
                        ctx.players.Add(newplayer);
                        ctx.SaveChanges();
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorFormat("Error saving new player!");
                        Logger.ErrorFormat(e.ToString());
                        client.LoginMessage("Unknown error. Contact [email protected]", 3);
                    }
                    client.LoginMessage("\0", 0);
                }
            }
        }
コード例 #14
0
ファイル: Login.cs プロジェクト: saroque/server
        private void PacketHandler_0x03_Login(Client client, ClientPacket packet)
        {
            var name = packet.ReadString8();
            var password = packet.ReadString8();
            Logger.DebugFormat("cid {0}: Login request for {1}", client.ConnectionId, name);

            using (var ctx = new hybrasylEntities(Constants.ConnectionString))
            {

                var result = ctx.players.Where(player => player.name == name).SingleOrDefault();

                if (result == null)
                {
                    client.LoginMessage("That character does not exist", 3);
                    Logger.InfoFormat("cid {0}: attempt to login as nonexistent character {1}", client.ConnectionId, name);
                }
                else
                {
                    if (VerifyPassword(password, result))
                    {
                        Logger.DebugFormat("cid {0}: password verified for {1}", client.ConnectionId, name);

                        if (Game.World.ActiveUsersByName.ContainsKey(name))
                        {
                            Logger.InfoFormat("cid {0}: {1} logging on again, disconnecting previous connection",
                                client.ConnectionId, name);
                            World.MessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.LogoffUser, name));
                        }

                        Logger.DebugFormat("cid {0} ({1}): logging in", client.ConnectionId, name);
                        client.LoginMessage("\0", 0);
                        client.SendMessage("Welcome to Hybrasyl!", 3);
                        Logger.DebugFormat("cid {0} ({1}): sending redirect to world", client.ConnectionId, name);

                        var redirect = new Redirect(client, this, Game.World, name, client.EncryptionSeed,
                            client.EncryptionKey);
                        Logger.InfoFormat("cid {0} ({1}): login successful, redirecting to world server",
                            client.ConnectionId, name);
                        client.Redirect(redirect);
                    }
                    else
                    {
                        Logger.WarnFormat("cid {0} ({1}): password incorrect", client.ConnectionId, name);
                        client.LoginMessage("Incorrect password", 3);
                    }
                }
            }
        }
コード例 #15
0
ファイル: Login.cs プロジェクト: DomGrieco/server
 private void PacketHandler_0x68_RequestHomepage(Client client, ClientPacket packet)
 {
     var x03 = new ServerPacket(0x66);
     x03.WriteByte(0x03);
     x03.WriteString8("http://www.hybrasyl.com");
     client.Enqueue(x03);
 }
コード例 #16
0
ファイル: Server.cs プロジェクト: DomGrieco/server
 public Redirect(Client client, Server source, Server destination, string name, byte seed, byte[] key)
 {
     Id = id++;
     Client = client;
     Source = source;
     Destination = destination;
     Name = name;
     EncryptionSeed = seed;
     EncryptionKey = key;
 }
コード例 #17
0
ファイル: Packet.cs プロジェクト: DomGrieco/server
        public void Decrypt(Client client)
        {
            var length = Data.Length - 3;

            var bRand = (ushort)((Data[length + 2] << 8 | Data[length]) ^ 0x7470);
            var sRand = (byte)(Data[length + 1] ^ 0x23);

            var key = (UseDefaultKey) ? client.EncryptionKey : client.GenerateKey(bRand, sRand);

            for (var i = 0; i < length; i++)
            {
                Data[i] ^= key[i % key.Length];
                Data[i] ^= SaltTable[client.EncryptionSeed][(i / key.Length) % SaltTable[client.EncryptionSeed].Length];
                if ((i / key.Length) % SaltTable[client.EncryptionSeed].Length != Ordinal)
                {
                    Data[i] ^= SaltTable[client.EncryptionSeed][Ordinal];
                }
            }
        }