private void HandleDisconnected(ITcpSocket socket)
        {
            NecClient client;

            lock (_lock)
            {
                if (!_clients.ContainsKey(socket))
                {
                    _logger.Error(socket, $"[{_identity}] Disconnected client does not exist in lookup");
                    return;
                }

                client = _clients[socket];
                _clients.Remove(socket);
                _logger.Debug($"[{_identity}] Clients Count: {_clients.Count}");
            }

            Action <NecClient> onClientDisconnected = ClientDisconnected;

            if (onClientDisconnected != null)
            {
                try
                {
                    onClientDisconnected.Invoke(client);
                }
                catch (Exception ex)
                {
                    _logger.Exception(client, ex);
                }
            }

            _logger.Info(client, $"[{_identity}] Client disconnected");
        }
Example #2
0
        protected override void HandleDisconnected(ITcpSocket socket)
        {
            NecConnection connection;

            lock (_lock)
            {
                if (!_connections.ContainsKey(socket))
                {
                    _Logger.Error(socket, $"[{_serverType}] Disconnected client does not exist in lookup");
                    return;
                }

                connection = _connections[socket];
                _connections.Remove(socket);
                _Logger.Debug($"[{_serverType}] Clients Count: {_connections.Count}");
            }

            Action <NecConnection> onClientDisconnected = clientDisconnected;

            if (onClientDisconnected != null)
            {
                try
                {
                    onClientDisconnected.Invoke(connection);
                }
                catch (Exception ex)
                {
                    _Logger.Exception(connection, ex);
                }
            }

            _Logger.Info(connection, $"[{_serverType}] Client disconnected");
        }
        public override void HandleRequest(NecClient client, SendCmdExecRequest request)
        {
            string command = request.CommandString();

            for (int i = 0; i < command.Length; i++)
            {
                char c = command[i];
                if (c < 32 || c > 126)
                {
                    // outside of printable ascii range, cut off bad characters for safety
                    if (i <= 0)
                    {
                        // first character already bad, exit
                        _Logger.Info(client, "Command will not be executed due to bad character");
                        return;
                    }

                    command = command.Substring(0, i - 1);
                    break;
                }
            }

            server.chat.commandHandler.HandleCommand(client, command);
            // IBuffer res = BufferProvider.Provide();
            // res.WriteInt32(0);
            // Router.Send(client, (ushort) AreaPacketId.recv_cmd_exec_r, res, ServerType.Area);
        }
Example #4
0
        public override void Handle(NecConnection connection, NecPacket packet)
        {
            string accountName = packet.data.ReadCString();
            string password    = packet.data.ReadCString();
            string macAddress  = packet.data.ReadCString();
            int    unknown     = packet.data.ReadInt16();

            _Logger.Info($"Account:{accountName} Password:{password} Unknown:{unknown}");

            Account account = database.SelectAccountByName(accountName);

            if (account == null)
            {
                if (settings.requireRegistration)
                {
                    _Logger.Error(connection, $"AccountName: {accountName} doesn't exist");
                    SendResponse(connection, null);
                    connection.socket.Close();
                    return;
                }

                string bCryptHash = BCrypt.Net.BCrypt.HashPassword(password, NecSetting.B_CRYPT_WORK_FACTOR);
                account = database.CreateAccount(accountName, accountName, bCryptHash);
            }

            if (!BCrypt.Net.BCrypt.Verify(password, account.hash))
            {
                _Logger.Error(connection, $"Invalid password for AccountName: {accountName}");
                SendResponse(connection, null);
                connection.socket.Close();
                return;
            }

            NecClient client = new NecClient();

            client.account        = account;
            client.authConnection = connection;
            connection.client     = client;
            client.UpdateIdentity();
            server.clients.Add(client);

            SendResponse(connection, account);

            //if client did not send a hardbeat within 75 seconds, something went wrong. remove the client. Thats enough time for 4 heartbeats.
            Task.Delay(TimeSpan.FromSeconds(75)).ContinueWith
                (t1 =>
            {
                if (client != null)
                {
                    if (client.heartBeat == 0)
                    {
                        server.clients.Remove(client);
                        _Logger.Error($"Initial heartbeat missed. disconnecting client. Server.clientCount is now {server.clients.GetCount()}");
                    }
                }
            }
                );
        }
        public override void Handle(NecClient client, NecPacket packet)
        {
            uint selectedWorld = packet.Data.ReadUInt32();

            Logger.Info($"Selected World: {selectedWorld}");


            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(0);
            res.WriteCString(Settings.DataMsgIpAddress);
            res.WriteInt32(Settings.MsgPort);
            Router.Send(client, (ushort)AuthPacketId.recv_base_select_world_r, res, ServerType.Auth);
        }
        public override void Handle(NecConnection connection, NecPacket packet)
        {
            uint major = packet.data.ReadUInt32();
            uint minor = packet.data.ReadUInt32();

            _Logger.Info($"{major} - {minor}");

            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(0);
            res.WriteUInt32(major);
            res.WriteUInt32(minor);

            router.Send(connection, (ushort)AuthPacketId.recv_base_check_version_r, res);
        }
Example #7
0
        public override void Handle(NecConnection connection, NecPacket packet)
        {
            string accountName = packet.Data.ReadCString();
            string password    = packet.Data.ReadCString();
            string macAddress  = packet.Data.ReadCString();
            int    unknown     = packet.Data.ReadInt16();

            Logger.Info($"Account:{accountName} Password:{password} Unknown:{unknown}");

            Account account = Database.SelectAccountByName(accountName);

            if (account == null)
            {
                if (Settings.RequireRegistration)
                {
                    Logger.Error(connection, $"AccountName: {accountName} doesn't exist");
                    SendResponse(connection, null);
                    connection.Socket.Close();
                    return;
                }

                string bCryptHash = BCrypt.Net.BCrypt.HashPassword(password, NecSetting.BCryptWorkFactor);
                account = Database.CreateAccount(accountName, accountName, bCryptHash);
            }

            if (!BCrypt.Net.BCrypt.Verify(password, account.Hash))
            {
                Logger.Error(connection, $"Invalid password for AccountName: {accountName}");
                SendResponse(connection, null);
                connection.Socket.Close();
                return;
            }

            NecClient client = new NecClient();

            client.Account        = account;
            client.AuthConnection = connection;
            connection.Client     = client;
            client.UpdateIdentity();
            Server.Clients.Add(client);

            SendResponse(connection, account);
        }
        public override void Handle(NecClient client, NecPacket packet)
        {
            string      soulName = packet.data.ReadCString();
            List <Soul> souls    = database.SelectSoulsByAccountId(client.account.id);

            foreach (Soul soul in souls)
            {
                if (soul.name == soulName)
                {
                    client.soul = soul;
                    break;
                }
            }

            IBuffer res = BufferProvider.Provide();

            if (client.soul == null)
            {
                _Logger.Error(client, $"Soul with name: '{soulName}' not found");
                res.WriteInt32(1); // 0 = OK | 1 = Failed to return to soul selection
                router.Send(client, (ushort)MsgPacketId.recv_soul_select_r, res, ServerType.Msg);
                client.Close();
                return;
            }

            res.WriteInt32(0); // 0 = OK | 1 = Failed to return to soul selection
            if (client.soul.password == null)
            {
                _Logger.Info(client, "Password not set, initiating set password");
                res.WriteByte(0); // bool - 0 = Set New Password | 1 = Enter Password
            }
            else
            {
                res.WriteByte(1); // bool - 0 = Set New Password | 1 = Enter Password
            }


            router.Send(client, (ushort)MsgPacketId.recv_soul_select_r, res, ServerType.Msg);
        }
        public override void Handle(NecClient client, NecPacket packet)
        {
            uint unknown = packet.Data.ReadByte();

            Logger.Info($"Unknown: {unknown}");

            byte bonusPoints;


            int rangeDetermination = Util.GetRandomNumber(0, 10000);

            // ^^ generate a number between 0 and 10000 to determinate the bonus points range

            if (rangeDetermination >= 9980)
            {
                bonusPoints = (byte)Util.GetRandomNumber(21, 30);
            }
            else if (rangeDetermination >= 9880)
            {
                bonusPoints = (byte)Util.GetRandomNumber(16, 20);
            }
            else if (rangeDetermination >= 9680)
            {
                bonusPoints = (byte)Util.GetRandomNumber(10, 15);
            }
            else
            {
                bonusPoints = (byte)Util.GetRandomNumber(1, 10);
            }

            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(0);
            res.WriteByte(bonusPoints); // Number of points

            Router.Send(client, (ushort)MsgPacketId.recv_chara_draw_bonuspoint_r, res, ServerType.Msg);
        }
        public override void Handle(NecClient client, NecPacket packet)
        {
            byte   unknown  = packet.Data.ReadByte();
            string soulName = packet.Data.ReadCString();

            Soul soul = new Soul();

            soul.Name      = soulName;
            soul.AccountId = client.Account.Id;
            if (!Database.InsertSoul(soul))
            {
                Logger.Error(client, $"Failed to create SoulName: {soulName}");
                client.Close();
                return;
            }

            client.Soul = soul;
            Logger.Info($"Created SoulName: {soulName}");

            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(0);
            Router.Send(client, (ushort)MsgPacketId.recv_soul_create_r, res, ServerType.Msg);
        }
Example #11
0
        public override void Handle(NecClient client, NecPacket packet)
        {
            byte   character_slot_id = packet.Data.ReadByte();
            string character_name    = packet.Data.ReadCString();
            uint   race_id           = packet.Data.ReadUInt32();
            uint   sex_id            = packet.Data.ReadUInt32();

            byte hair_id       = packet.Data.ReadByte();
            byte hair_color_id = packet.Data.ReadByte();
            byte face_id       = packet.Data.ReadByte();

            uint alignment_id = packet.Data.ReadUInt32();

            ushort strength     = packet.Data.ReadUInt16();
            ushort vitality     = packet.Data.ReadUInt16();
            ushort dexterity    = packet.Data.ReadUInt16();
            ushort agility      = packet.Data.ReadUInt16();
            ushort intelligence = packet.Data.ReadUInt16();
            ushort piety        = packet.Data.ReadUInt16();
            ushort luck         = packet.Data.ReadUInt16();

            uint class_id  = packet.Data.ReadUInt32();
            uint unknown_a = packet.Data.ReadUInt32();


            //-------------------------------------
            // Send Character Creation packets to Database for laster use.

            if (!Maps.TryGet(Map.NewCharacterMapId, out Map map))
            {
                Logger.Error($"New character map not found MapId: {Map.NewCharacterMapId}");
                client.Close();
            }

            Character character = new Character();

            Server.Instances.AssignInstance(character);
            character.MapId   = map.Id;
            character.X       = map.X;
            character.Y       = map.Y;
            character.Z       = map.Z;
            character.Heading = (byte)map.Orientation;

            character.AccountId = client.Account.Id;
            character.SoulId    = client.Soul.Id;
            character.Slot      = character_slot_id;
            character.Name      = character_name;

            character.Raceid       = race_id;
            character.Sexid        = sex_id;
            character.HairId       = hair_id;
            character.HairColorId  = hair_color_id;
            character.FaceId       = face_id;
            character.Alignmentid  = alignment_id;
            character.Strength     = strength;
            character.vitality     = vitality;
            character.dexterity    = dexterity;
            character.agility      = agility;
            character.intelligence = intelligence;
            character.piety        = piety;
            character.luck         = luck;
            character.ClassId      = class_id;
            CreateShortcutBars(client, character, class_id);

            //----------------------------------------------------------
            // Character Slot ID

            if (!Database.InsertCharacter(character))
            {
                Logger.Error(client, $"Failed to create CharacterSlot: {character_slot_id}");
                client.Close();
                return;
            }

            CreateSkillTreeItems(client, character, class_id);

            client.Character = character;
            Logger.Info($"Created CharacterSlot: {character_slot_id}");
            Logger.Info($"Created CharacterName: {character_name}");
            Logger.Info($"Created race: {race_id}");
            Logger.Info($"Created sex: {sex_id}");
            Logger.Info($"Created hair: {hair_id}");
            Logger.Info($"Created hair color: {hair_color_id}");
            Logger.Info($"Created faceid: {face_id}");
            Logger.Info($"Created alignment_id: {alignment_id}");
            Logger.Info($"Created strength: {strength}");
            Logger.Info($"Created vitality: {vitality}");
            Logger.Info($"Created dexterity: {dexterity}");
            Logger.Info($"Created agility: {agility}");
            Logger.Info($"Created intelligence: {intelligence}");
            Logger.Info($"Created piety: {piety}");
            Logger.Info($"Created luck: {luck}");
            Logger.Info($"Created class_id: {class_id}");

            //-------------------------------------------------------------------------------
            Server.Characters.Add(character);
            //-------------------------------------------------------------------------------


            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(0);
            res.WriteInt32(character.Id); //CharacterId

            Router.Send(client, (ushort)MsgPacketId.recv_chara_create_r, res, ServerType.Msg);
        }
 public NecSqLiteDb(string databasePath)
 {
     _databasePath = databasePath;
     _Logger.Info($"Database Path: {_databasePath}");
 }
Example #13
0
        public override void Handle(NecClient client, NecPacket packet)
        {
            byte   characterSlotId = packet.data.ReadByte();
            string characterName   = packet.data.ReadCString();
            uint   raceId          = packet.data.ReadUInt32();
            uint   sexId           = packet.data.ReadUInt32();

            byte hairId        = packet.data.ReadByte();
            byte hairColorId   = packet.data.ReadByte();
            byte faceId        = packet.data.ReadByte();
            byte faceArrangeId = packet.data.ReadByte();
            byte voiceId       = packet.data.ReadByte();

            uint alignmentId = packet.data.ReadUInt32();

            ushort strength     = packet.data.ReadUInt16(); //bonus stat, not base
            ushort vitality     = packet.data.ReadUInt16(); //bonus stat, not base
            ushort dexterity    = packet.data.ReadUInt16(); //bonus stat, not base
            ushort agility      = packet.data.ReadUInt16(); //bonus stat, not base
            ushort intelligence = packet.data.ReadUInt16(); //bonus stat, not base
            ushort piety        = packet.data.ReadUInt16(); //bonus stat, not base
            ushort luck         = packet.data.ReadUInt16(); //bonus stat, not base

            uint classId    = packet.data.ReadUInt32();
            int  errorCheck = packet.data.ReadInt32();
            byte unknown    = packet.data.ReadByte();


            //-------------------------------------
            // Send Character Creation packets to Database for laster use.

            if (!maps.TryGet(Map.NEW_CHARACTER_MAP_ID, out Map map))
            {
                _Logger.Error($"New character map not found MapId: {Map.NEW_CHARACTER_MAP_ID}");
                client.Close();
            }

            Character character = new Character();
            Attribute attribute = new Attribute();

            attribute.DefaultClassAtributes(raceId);

            character.mapId   = map.id;
            character.x       = map.x;
            character.y       = map.y;
            character.z       = map.z;
            character.heading = map.orientation;

            character.accountId = client.account.id;
            character.soulId    = client.soul.id;
            character.slot      = characterSlotId;
            character.name      = characterName;

            character.raceId        = raceId;
            character.sexId         = sexId;
            character.hairId        = hairId;
            character.hairColorId   = hairColorId;
            character.faceId        = faceId;
            character.faceArrangeId = faceArrangeId;
            character.voiceId       = voiceId;
            character.hp.SetMax(attribute.hp);
            character.hp.SetCurrent(attribute.hp);
            character.mp.SetMax(attribute.mp);
            character.mp.SetCurrent(attribute.mp);
            character.strength     = (ushort)(strength + attribute.str);
            character.vitality     = (ushort)(vitality + attribute.vit);
            character.dexterity    = (ushort)(dexterity + attribute.dex);
            character.agility      = (ushort)(agility + attribute.agi);
            character.intelligence = (ushort)(intelligence + attribute.@int);
            character.piety        = (ushort)(piety + attribute.pie);
            character.luck         = (ushort)(luck + attribute.luck);
            character.classId      = classId;
            character.level        = 1;

            //----------------------------------------------------------
            // Character Slot ID

            if (!database.InsertCharacter(character))
            {
                _Logger.Error(client, $"Failed to create CharacterSlot: {characterSlotId}");
                client.Close();
                return;
            }

            //after the DB instert, so Character has a valid ID.
            server.instances.AssignInstance(character);
            client.character = character;


            CreateSkillTreeItems(client, character, classId);
            CreateShortcutBars(client, character, classId);
            CreateEquipmentItems(client, character, classId);

            _Logger.Info($"Created CharacterSlot: {characterSlotId}");
            _Logger.Info($"Created CharacterName: {characterName}");
            _Logger.Info($"Created race: {raceId}");
            _Logger.Info($"Created sex: {sexId}");
            _Logger.Info($"Created hair: {hairId}");
            _Logger.Info($"Created hair color: {hairColorId}");
            _Logger.Info($"Created faceid: {faceId}");
            _Logger.Info($"Created alignment_id: {alignmentId}");
            _Logger.Info($"Created strength: {strength}");
            _Logger.Info($"Created vitality: {vitality}");
            _Logger.Info($"Created dexterity: {dexterity}");
            _Logger.Info($"Created agility: {agility}");
            _Logger.Info($"Created intelligence: {intelligence}");
            _Logger.Info($"Created piety: {piety}");
            _Logger.Info($"Created luck: {luck}");
            _Logger.Info($"Created class_id: {classId}");

            IBuffer res = BufferProvider.Provide();

            res.WriteInt32(errorCheck);
            res.WriteInt32(character.id); //CharacterId

            router.Send(client, (ushort)MsgPacketId.recv_chara_create_r, res, ServerType.Msg);
        }
Example #14
0
        public void Enter(NecClient client, MapPosition mapPosition = null)
        {
            if (client.map != null)
            {
                client.map.Leave(client);
            }
            client.map = this;

            _Logger.Info(client, $"Entering Map: {id}:{fullName}");
            // If position is passed in use it and set character position, if null then use map default coords
            // If this isn't set here, the wrong coords are in character until send_movement_info updates it.
            if (mapPosition != null)
            {
                client.character.x       = mapPosition.x;
                client.character.y       = mapPosition.y;
                client.character.z       = mapPosition.z;
                client.character.heading = mapPosition.heading;
            }
            //set character coords to default map entry coords If arriving form another map.
            else if (client.character.mapId != id)
            {
                client.character.x       = x;
                client.character.y       = y;
                client.character.z       = z;
                client.character.heading = orientation;
            }

            client.character.mapId     = id;
            client.character.mapChange = false;
            clientLookup.Add(client);
            _Logger.Debug($"Client Lookup count is now : {clientLookup.GetAll().Count}  for map  {id} ");
            _Logger.Debug($"Character State for character {client.character.name} is {client.character.state}");
            //Send your character data to the other living or dead players on the map.

            //on successful map entry, update the client database position
            if (!_server.database.UpdateCharacter(client.character))
            {
                _Logger.Error("Could not update the database with current known player position");
            }
            if (!_server.database.UpdateSoul(client.soul))
            {
                _Logger.Error("Could not update the database with soul details ");
            }

            //ToDo  move all this rendering logic to Send_Map_Entry.   We dont need a copy of this logic on every map instance.
            RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.character, client.soul.name);

            //dead
            //you are dead here.  only getting soul form characters. sorry bro.
            if (client.character.state.HasFlag(CharacterState.SoulForm))
            {
                foreach (NecClient otherClient in clientLookup.GetAll())
                {
                    if (otherClient == client)
                    {
                        continue;
                    }
                    if (otherClient.character.state.HasFlag(CharacterState.SoulForm))
                    {
                        _server.router.Send(myCharacterData, otherClient);
                    }
                }
            }
            else //Bro, you alive! You gon see living characters!
            {
                foreach (NecClient otherClient in clientLookup.GetAll())
                {
                    if (otherClient == client)
                    {
                        continue;
                    }
                    if (otherClient.character.state.HasFlag(CharacterState.SoulForm))
                    {
                        continue;
                    }
                    _server.router.Send(myCharacterData, otherClient);
                }
            }

            if (client.union != null)
            {
                RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.character, client.union.name);
                _server.router.Send(this, myUnionData, client);
            }

            Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith
                (t1 =>
            {
                foreach (MonsterSpawn monsterSpawn in monsterSpawns.Values)
                {
                    if (monsterSpawn.active)
                    {
                        monsterSpawn.spawnActive = true;
                        if (!monsterSpawn.taskActive)
                        {
                            MonsterTask monsterTask = new MonsterTask(_server, monsterSpawn);
                            if (monsterSpawn.defaultCoords)
                            {
                                monsterTask.monsterHome = monsterSpawn.monsterCoords[0];
                            }
                            else
                            {
                                monsterTask.monsterHome = monsterSpawn.monsterCoords.Find(x => x.coordIdx == 64);
                            }
                            monsterTask.Start();
                        }
                        else
                        {
                            if (monsterSpawn.monsterVisible)
                            {
                                _Logger.Debug($"MonsterTask already running for [{monsterSpawn.name}]");
                                RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn);
                                _server.router.Send(monsterData, client);
                                if (!monsterSpawn.GetAgro())
                                {
                                    monsterSpawn.MonsterMove(_server, client, monsterSpawn.monsterWalkVelocity, 2,
                                                             0);
                                }
                            }
                        }
                    }
                }
            }
                );
        }
Example #15
0
 public void Enter(NecClient client)
 {
     _logger.Info($"Entering Map: {Id}", client);
     ClientLookup.Add(client);
     client.Map = this;
 }
Example #16
0
        public void Enter(NecClient client, MapPosition mapPosition = null)
        {
            if (client.Map != null)
            {
                client.Map.Leave(client);
            }

            Logger.Info(client, $"Entering Map: {Id}:{FullName}");
            // If position is passed in use it and set character position, if null then use map default coords
            // If this isn't set here, the wrong coords are in character until send_movement_info updates it.
            if (mapPosition != null)
            {
                client.Character.X       = mapPosition.X;
                client.Character.Y       = mapPosition.Y;
                client.Character.Z       = mapPosition.Z;
                client.Character.Heading = mapPosition.Heading;
            }
            else
            {
                client.Character.X       = this.X;
                client.Character.Y       = this.Y;
                client.Character.Z       = this.Z;
                client.Character.Heading = this.Orientation;
            }

            client.Map                 = this;
            client.Character.MapId     = Id;
            client.Character.mapChange = false;
            ClientLookup.Add(client);
            Logger.Debug($"Client Lookup count is now : {ClientLookup.GetAll().Count}  for map  {this.Id} ");

            RecvDataNotifyCharaData myCharacterData = new RecvDataNotifyCharaData(client.Character, client.Soul.Name);

            _server.Router.Send(this, myCharacterData, client);
            if (client.Union != null)
            {
                RecvDataNotifyUnionData myUnionData = new RecvDataNotifyUnionData(client.Character, client.Union.Name);
                _server.Router.Send(this, myUnionData, client);
            }

            foreach (MonsterSpawn monsterSpawn in this.MonsterSpawns.Values)
            {
                if (monsterSpawn.Active == true)
                {
                    monsterSpawn.SpawnActive = true;
                    if (!monsterSpawn.TaskActive)
                    {
                        MonsterTask monsterTask = new MonsterTask(_server, monsterSpawn);
                        if (monsterSpawn.defaultCoords)
                        {
                            monsterTask.monsterHome = monsterSpawn.monsterCoords[0];
                        }
                        else
                        {
                            monsterTask.monsterHome = monsterSpawn.monsterCoords.Find(x => x.CoordIdx == 64);
                        }
                        monsterTask.Start();
                    }
                    else
                    {
                        if (monsterSpawn.MonsterVisible)
                        {
                            Logger.Debug($"MonsterTask already running for [{monsterSpawn.Name}]");
                            RecvDataNotifyMonsterData monsterData = new RecvDataNotifyMonsterData(monsterSpawn);
                            _server.Router.Send(monsterData, client);
                            if (!monsterSpawn.GetAgro())
                            {
                                monsterSpawn.MonsterMove(_server, client, monsterSpawn.MonsterWalkVelocity, (byte)2,
                                                         (byte)0);
                            }
                        }
                    }
                }
            }

            //on successful map entry, update the client database position
            if (!_server.Database.UpdateCharacter(client.Character))
            {
                Logger.Error("Could not update the database with current known player position");
            }
        }