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"); }
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); }
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); }
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); }
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}"); }
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); }
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); } } } } } } ); }
public void Enter(NecClient client) { _logger.Info($"Entering Map: {Id}", client); ClientLookup.Add(client); client.Map = this; }
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"); } }