Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
        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());
            }
                );
        }