private void AreaClientDisconnected(NecConnection connection) { NecClient client = connection.client; if (client == null) { return; } //Try to update the character stats. if (!database.UpdateCharacter(client.character)) { _Logger.Error("Could not update the database with character details before disconnect"); } if (!database.UpdateSoul(client.soul)) { _Logger.Error("Could not update the database with soul details before disconnect"); } clients.Remove(client); //I disconnected while my dead body was being carried around by another player if (client.character.hasDied) { DeadBody deadBody = instances.GetInstance(client.character.deadBodyInstanceId) as DeadBody; if (deadBody.salvagerId != 0) { NecClient mySalvager = clients.GetByCharacterInstanceId(deadBody.salvagerId); if (mySalvager != null) { deadBody.x = mySalvager.character.x; deadBody.y = mySalvager.character.y; deadBody.z = mySalvager.character.z; deadBody.mapId = mySalvager.character.mapId; deadBody.connectionState = 0; mySalvager.bodyCollection.Remove(deadBody.instanceId); mySalvager.map.deadBodies.Add(deadBody.instanceId, deadBody); RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { router.Send(mySalvager.map, cBodyData.ToPacket(), client); } //must occur after the charaBody notify. RecvCharaBodySalvageEnd recvCharaBodySalvageEnd = new RecvCharaBodySalvageEnd(deadBody.instanceId, 5); router.Send(mySalvager, recvCharaBodySalvageEnd.ToPacket()); } } } //while i was dead and being carried around, the player carrying me disconnected foreach (NecClient collectedBody in client.bodyCollection.Values) { DeadBody deadBody = instances.GetInstance(collectedBody.character.deadBodyInstanceId) as DeadBody; RecvCharaBodySelfSalvageEnd recvCharaBodySelfSalvageEnd = new RecvCharaBodySelfSalvageEnd(3); router.Send(collectedBody, recvCharaBodySelfSalvageEnd.ToPacket()); deadBody.x = client.character.x; deadBody.y = client.character.y; deadBody.z = client.character.z; collectedBody.character.x = client.character.x; collectedBody.character.y = client.character.y; collectedBody.character.z = client.character.z; //ToDo add Town checking. if map.ID.toString()[0]==1 skip deadbody rendering deadBody.mapId = client.character.mapId; client.map.deadBodies.Add(deadBody.instanceId, deadBody); RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { router.Send(client.map, cBodyData.ToPacket()); } //send your soul to all the other souls runnin around RecvDataNotifyCharaData cData = new RecvDataNotifyCharaData(collectedBody.character, collectedBody.soul.name); foreach (NecClient soulStateClient in client.map.clientLookup.GetAll()) { if (soulStateClient.character.state == CharacterState.SoulForm) { router.Send(soulStateClient, cData.ToPacket()); } } } Map map = client.map; //If i was dead, toggle my deadBody to a Rucksack if (map != null) { if (map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { map.deadBodies.TryGetValue(client.character.deadBodyInstanceId, out DeadBody deadBody); deadBody.connectionState = 0; RecvCharaBodyNotifySpirit recvCharaBodyNotifySpirit = new RecvCharaBodyNotifySpirit(client.character.deadBodyInstanceId, (byte)RecvCharaBodyNotifySpirit.ValidSpirit.DisconnectedClient); router.Send(map, recvCharaBodyNotifySpirit.ToPacket()); Task.Delay(TimeSpan.FromSeconds(600)).ContinueWith (t1 => { if (map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { RecvObjectDisappearNotify recvObjectDisappearNotify = new RecvObjectDisappearNotify(client.character.deadBodyInstanceId); router.Send(client.map, recvObjectDisappearNotify.ToPacket(), client); map.deadBodies.Remove(client.character.deadBodyInstanceId); } } ); } } if (map != null) { map.Leave(client); } Union union = client.union; if (union != null) { union.Leave(client); } Character character = client.character; if (character != null) { instances.FreeInstance(character); character.characterActive = false; } }
public override void Handle(NecClient client, NecPacket packet) { IBuffer res = BufferProvider.Provide(); res.WriteInt32(0); //error check. must be 0 res.WriteByte(0); //Bool - play cutscene. 1 yes, 0 no? //to-do, play a cutscene on first time map entry router.Send(client, (ushort)AreaPacketId.recv_map_enter_r, res, ServerType.Area); if (client.map.deadBodies.ContainsKey(client.character.deadBodyInstanceId)) { _Logger.Debug($"found dead body of {client.character.name} already on map. Hope you didn't lose your loot!"); DeadBody deadBody = server.instances.GetInstance(client.character.deadBodyInstanceId) as DeadBody; deadBody.connectionState = 1; RecvCharaBodyNotifySpirit recvCharaBodyNotifySpirit = new RecvCharaBodyNotifySpirit(client.character.deadBodyInstanceId, (byte)RecvCharaBodyNotifySpirit.ValidSpirit.ConnectedClient); router.Send(client.map, recvCharaBodyNotifySpirit.ToPacket()); } else if (client.character.state.HasFlag(CharacterState.SoulForm)) { DeadBody deadBody = server.instances.GetInstance(client.character.deadBodyInstanceId) as DeadBody; deadBody.x = client.character.x; deadBody.y = client.character.y; deadBody.z = client.character.z; deadBody.heading = client.character.heading; deadBody.beginnerProtection = (byte)client.character.beginnerProtection; deadBody.charaName = client.character.name; deadBody.soulName = client.soul.name; deadBody.equippedItems = client.character.equippedItems; deadBody.raceId = client.character.raceId; deadBody.sexId = client.character.sexId; deadBody.hairId = client.character.hairId; deadBody.hairColorId = client.character.hairColorId; deadBody.faceId = client.character.faceId; deadBody.faceArrangeId = client.character.faceArrangeId; deadBody.voiceId = client.character.voiceId; deadBody.level = client.character.level; deadBody.classId = client.character.classId; deadBody.equippedItems = client.character.equippedItems; deadBody.connectionState = 1; client.map.deadBodies.Add(deadBody.instanceId, deadBody); RecvDataNotifyCharaBodyData cBodyData = new RecvDataNotifyCharaBodyData(deadBody); if (client.map.id.ToString()[0] != "1"[0]) //Don't Render dead bodies in town. Town map ids all start with 1 { router.Send(client.map, cBodyData.ToPacket(), client); } router.Send(client, cBodyData.ToPacket()); } //Re-do all your stats ItemService itemService = new ItemService(client.character); router.Send(client, itemService.CalculateBattleStats(client)); //added delay to prevent crash on map entry. Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith (t1 => { client.character.ClearStateBit(CharacterState.InvulnerableForm); RecvCharaNotifyStateflag recvCharaNotifyStateflag = new RecvCharaNotifyStateflag(client.character.instanceId, (ulong)client.character.state); router.Send(client.map, recvCharaNotifyStateflag.ToPacket()); } ); }