예제 #1
0
        /// <summary>
        /// Occurs when the party invitation gets accepted
        /// </summary>
        private void CM_PARTYINVITATIONACCEPT(CMSG_PARTYINVITATIONACCEPT cpkt)
        {
            //FORWARD A OKAY MESSAGE TO THE SENDER AND RECIEVER OF THE INIVATION
            PartySession party = this.character.sessionParty;
            if (party != null)
            {
                if (cpkt.Status == 1)
                {
                    //Has accepted the party invitation
                    {
                        SMSG_PARTYINVITATIONRESULT spkt = new SMSG_PARTYINVITATIONRESULT();
                        spkt.Result = 0;
                        spkt.SessionId = party.PartyLeader.id;
                        party.PartyLeader.client.Send((byte[])spkt);
                    }
                    //Send over a new party
                    if (this.character.sessionParty.Count == 1)
                    {
                        SMSG_PARTYMEMBERINFO spkt = new SMSG_PARTYMEMBERINFO();
                        spkt.Leader = party.PartyLeader.id;
                        spkt.LeaderIndex = 1;
                        spkt.Setting1 = this.character.sessionParty.LootSettings;
                        spkt.Setting2 = this.character.sessionParty.ExpSettings;
                        spkt.Setting3 = 0;
                        if (this.character.sessionParty.ItemLeader != null)
                            spkt.Setting4 = this.character.sessionParty.ItemLeader.id;
                        spkt.AddMemberInfo(party.GetCharacters());
                        spkt.SessionId = party.PartyLeader.id;
                        spkt.Result = 1;
                        party.PartyLeader.client.Send((byte[])spkt);
                    }

                    //Forwards new party member information to all existing players
                    this.character.sessionParty.Add(this.character);
                    int index = party.IndexOf(this.character) + 1;

                    //Process character adding
                    foreach (Character target in party.GetCharacters())
                    {
                        //Send a new character to other party members
                        if (target.id != character.id)
                        {
                            SMSG_PARTYNEWMEMBER spkt2 = new SMSG_PARTYNEWMEMBER();
                            spkt2.Index = 1;
                            spkt2.ActorId = this.character.id;
                            spkt2.Unknown = 1;
                            spkt2.Name = this.character.Name;
                            spkt2.SessionId = target.id;
                            target.client.Send((byte[])spkt2);
                        }
                        //Send a complete list to yourself
                        else
                        {
                            SMSG_PARTYMEMBERINFO spkt7 = new SMSG_PARTYMEMBERINFO();
                            spkt7.Leader = party.PartyLeader.id;
                            spkt7.LeaderIndex = 1;
                            spkt7.Setting1 = this.character.sessionParty.LootSettings;
                            spkt7.Setting2 = this.character.sessionParty.ExpSettings;
                            spkt7.Setting3 = 0;
                            if (this.character.sessionParty.ItemLeader != null)
                                spkt7.Setting4 = this.character.sessionParty.ItemLeader.id;
                            spkt7.Result = 1;
                            spkt7.SessionId = this.character.id;
                            spkt7.AddMemberInfo(party.GetCharacters());
                            this.Send((byte[])spkt7);
                        }
                    }

                    //Forwards new party member location and HP/SP
                    //informations
                    foreach (Character target in party.GetCharacters())
                    {
                        if (target.id == character.id) continue;

                        //Send over target to myself
                        SMSG_PARTYUNKNOWN spkt4 = new SMSG_PARTYUNKNOWN();
                        spkt4.ActorID = target.id;
                        spkt4.Unsure = 1;
                        spkt4.Unknown = (byte)(this.character.map + 0x65);
                        spkt4.Race = 0;
                        spkt4.Map = target.map;
                        spkt4.HP = target.HP;
                        spkt4.HPmax = target.HPMAX;
                        spkt4.SP = target.SP;
                        spkt4.SPmax = target.SPMAX;
                        spkt4.LP = target._status.CurrentLp;
                        spkt4.CharLvl = target._level;
                        spkt4.Job = target.job;
                        spkt4.JobLvl = target.jlvl;
                        spkt4.SessionId = this.character.id;
                        this.Send((byte[])spkt4);

                        //Send my self to target
                        SMSG_PARTYUNKNOWN spkt3 = new SMSG_PARTYUNKNOWN();
                        spkt3.ActorID = this.character.id;
                        spkt3.Unsure = 1;
                        spkt3.Unknown = (byte)(this.character.map + 0x65);
                        spkt3.Race = 0;
                        spkt3.Map = this.character.map;
                        spkt3.HP = this.character.HP;
                        spkt3.HPmax = this.character.HPMAX;
                        spkt3.SP = this.character.SP;
                        spkt3.SPmax = this.character.SPMAX;
                        spkt3.LP = this.character._status.CurrentLp;
                        spkt3.CharLvl = this.character._level;
                        spkt3.Job = this.character.job;
                        spkt3.JobLvl = this.character.jlvl;
                        spkt3.SessionId = target.id;
                        target.client.Send((byte[])spkt3);

                        //Process positon update
                        if (target.map == this.character.map)
                        {
                            SMSG_PARTYMEMBERLOCATION spkt6 = new SMSG_PARTYMEMBERLOCATION();
                            spkt6.Index = 1;
                            spkt6.ActorId = target.id;
                            spkt6.X = target.Position.x;
                            spkt6.Y = target.Position.y;
                            spkt6.SessionId = this.character.id;
                            this.Send((byte[])spkt6);

                            SMSG_PARTYMEMBERLOCATION spkt5 = new SMSG_PARTYMEMBERLOCATION();
                            spkt5.Index = 1;
                            spkt5.ActorId = this.character.id;
                            spkt5.X = this.character.Position.x;
                            spkt5.Y = this.character.Position.y;
                            spkt5.SessionId = target.id;
                            target.client.Send((byte[])spkt5);
                        }
                    }
                }
                else
                {
                    Character PartyLeader = this.character.sessionParty.PartyLeader;
                    SMSG_PARTYINVITATIONRESULT spkt = new SMSG_PARTYINVITATIONRESULT();
                    spkt.Result = (byte)PartyErrors.DENIED;
                    spkt.SessionId = PartyLeader.id;
                    PartyLeader.client.Send((byte[])spkt);

                    try
                    {
                        uint TargetActorId = (uint)this.character.Tag;
                        Character TargetActor = null;
                        if (LifeCycle.TryGetById(TargetActorId, out TargetActor))
                        {
                            TargetActor.Tag = null;
                            if (TargetActor.sessionParty._Characters.Count <= 1)
                                TargetActor.sessionParty = null;
                        }
                    }
                    catch (InvalidCastException)
                    {
                        Trace.TraceWarning("Cannot retrieve actor information");
                    }

                    if (this.character.sessionParty.Count <= 1)
                        this.character.sessionParty = null;
                    this.character.Tag = null;
                }
            }
            //FORWARD A DENIAL MESSAGE TO THE RECIEVER OF THE INVITATION
            else
            {
                SMSG_PARTYINVITATIONRESULT spkt = new SMSG_PARTYINVITATIONRESULT();
                spkt.Result = (byte)PartyErrors.DENIED;
                spkt.SessionId = this.character.id;
                this.Send((byte[])spkt);
                this.character.sessionParty = null;
            }
        }
예제 #2
0
        /// <summary>
        /// Checks for position updates.
        /// </summary>
        /// <remarks>
        /// First we'll check to see if we could see, actor x from
        /// our old position. After that we'll check if can see actor x
        /// from our new position. If we can see him, we'll forward our movement
        /// packet. If we can't see him we'll sent a actor disappearance packet.
        ///
        /// Once that's done, we'll check if we can see a non-former visible actor
        /// is now visible in our new position. Which will cause us to invoke a appearance
        /// packet.
        /// </remarks>
        /// <param name="cpkt"></param>
        private void CM_CHARACTER_MOVEMENTSTOPPED(CMSG_MOVEMENTSTOPPED cpkt)
        {
            if (this.isloaded == false) return;
            //If character was previous walking/running
            if (!this.character.IsMoving)
            {
                this.character.LastPositionTick = Environment.TickCount;
                return;
            }
            else
            {
                //Sending packet to late
                int time = Environment.TickCount - this.character.LastPositionTick;
                if (time > 10000)
                {
                    CommonFunctions.Warp(this.character, this.character.Position, this.character.currentzone);
                    this.character.LastPositionTick = Environment.TickCount;
                    return;
                }
                else
                {
                    this.character.LastPositionTick = Environment.TickCount;
                }
            }

            // GENERATE NEW PACKETS, WE PREPROCESS
            SMSG_MOVEMENTSTOPPED spkt = new SMSG_MOVEMENTSTOPPED();
            spkt.ActorID = this.character.id;
            spkt.speed = cpkt.Speed;
            spkt.X = cpkt.X;
            spkt.Y = cpkt.Y;
            spkt.Z = cpkt.Z;
            spkt.yaw = cpkt.Yaw;
            spkt.TargetActor = this.character._targetid;
            spkt.DelayTime = cpkt.DelayTime;

            //Get new actors for next-tick
            Point oldP = this.character.Position;
            Point newP = new Point(cpkt.X, cpkt.Y, cpkt.Z);

            this.character.stance = (byte)StancePosition.Stand;
            this.character.Position = newP;
            Regiontree.UpdateRegion(this.character);
            Regiontree tree = this.character.currentzone.Regiontree;

            try
            {
                foreach (MapObject regionObject in tree.SearchActors(this.character, SearchFlags.Npcs | SearchFlags.Characters | SearchFlags.MapItems))
                {
                    bool CanSeePrev = Point.IsInSightRangeByRadius(regionObject.Position, oldP);
                    bool CanSeeNext = Point.IsInSightRangeByRadius(regionObject.Position, newP);
                    if (CanSeeNext && !CanSeePrev)
                    {
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            this.character.ShowObject(current);
                        }

                        regionObject.ShowObject(this.character);
                        regionObject.Appears(this.character);
                    }
                    else if (CanSeePrev && !CanSeeNext)
                    {
                        //Hide Object to other characters
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            this.character.HideObject(current);
                        }

                        //Hide Object to myself
                        regionObject.HideObject(this.character);
                        regionObject.Disappear(this.character);
                    }
                    else if (CanSeeNext && CanSeePrev)
                    {
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            if (current.client.isloaded == false) continue;
                            spkt.SessionId = current.id;
                            current.client.Send((byte[])spkt);
                        }
                    }
                }
            }
            catch (Exception)
            {
                Trace.WriteLine("Error network code");
            }
            finally
            {
                if (this.character.sessionParty != null)
                {
                    foreach (Character target in this.character.sessionParty._Characters)
                    {
                        try
                        {
                            if (target.id == this.character.id) continue;
                            SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION();
                            spkt3.Index = 1;
                            spkt3.ActorId = this.character.id;
                            spkt3.SessionId = target.id;
                            spkt3.X = (this.character.Position.x / 1000);
                            spkt3.Y = (this.character.Position.y / 1000);
                            target.client.Send((byte[])spkt3);
                        }
                        catch (SocketException)
                        {
                            Trace.WriteLine("Network error");
                        }
                        catch (Exception)
                        {
                            Trace.WriteLine("Unknown error");
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Notifies the client to load start sending all pre-cached and yet to be
        /// processed packets.
        ///
        /// See the above method
        /// </summary>
        /// <remarks>
        /// Due the nature of this method we'll be invoking a notification on
        /// our "assumed" to be pending LoadMap method. We'll process all Moveable
        /// objects in the sightrange here.
        ///
        /// We cannot do this when we're precaching because suppose the client takes
        /// 10 minutes  to load, all the moveable monsters and characters can be gone
        /// already. And thus sending outdated information.
        /// </remarks>
        private void CM_CHARACTER_MAPLOADED()
        {
            try
            {
                #region Internal

                //Register on the new map
                this.character.currentzone.Regiontree.Subscribe(this.character);

                //GET NEW Z-POS
                float z = character.Position.z + 100;

                //Refresh Personal Requests
                CommonFunctions.RefreshPersonalRequests(this.character);
                Regiontree.UpdateRegion(this.character);
                isloaded = false;

                #endregion Internal

                #region Actor infromation

                {
                    /*
                     * Send actor information
                     *
                     * This packet makes a actor appear on the screen. Just like character information
                     * It defines automaticly which actor is your actor.
                     */

                    SMSG_ACTORINFO spkt = new SMSG_ACTORINFO();
                    spkt.ActorID = this.character.id;
                    spkt.X = this.character.Position.x;
                    spkt.Y = this.character.Position.y;
                    spkt.Z = this.character.Position.z;
                    spkt.race = this.character.race;
                    spkt.face = this.character.FaceDetails;
                    spkt.ActiveWeaponIndex = (byte)this.character.weapons.ActiveWeaponIndex;
                    spkt.InventoryContainerSize = (byte)this.character.container.Capacity;
                    spkt.StorageContainerSize = (byte)this.character.STORAGE.Capacity;
                    spkt.UnlockedWeaponCount = this.character.weapons.UnlockedWeaponSlots;
                    spkt.Unknown = 0;
                    spkt.PrimaryWeaponByIndex = this.character.weapons.PrimaryWeaponIndex;
                    spkt.SeccondairyWeaponByIndex = this.character.weapons.SeconairyWeaponIndex;
                    spkt.Name = this.character.Name;
                    spkt.SessionId = this.character.id;
                    this.Send((byte[])spkt);
                }

                #endregion Actor infromation

                #region Battle Stats

                {
                    CommonFunctions.SendBattleStatus(this.character);
                }

                #endregion Battle Stats

                #region Extend Stats

                {
                    /*
                     * Sends over the status points attributes
                     *
                     */

                    SMSG_EXTSTATS spkt2 = new SMSG_EXTSTATS();
                    spkt2.base_stats_1 = character.stats.BASE;
                    spkt2.base_stats_2 = character.stats.CHARACTER;
                    spkt2.base_stats_jobs = character.stats.EQUIPMENT;
                    spkt2.base_stats_bonus = character.stats.ENCHANTMENT;
                    spkt2.statpoints = character.stats.REMAINING;
                    spkt2.SessionId = character.id;
                    this.Send((byte[])spkt2);
                }

                #endregion Extend Stats

                if (IsFirstTimeLoad)
                {
#if THREADING
                    WaitCallback FireTimeLoginCallback = delegate(object a)
                    {
#else
                    {
#endif

                        #region Equipment List

                        {
                            /*
                             * Sends a list of all Equiped Equipment
                             */

                            SMSG_EQUIPMENTLIST spkt = new SMSG_EQUIPMENTLIST();
                            for (int i = 0; i < 16; i++)
                            {
                                Rag2Item item = this.character.Equipment[i];
                                if (item != null) spkt.AddItem(item, item.active, i);
                            }

                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Equipment List

                        #region Weaponary List

                        {
                            /*
                             * Sends a list of all weapons
                             */

                            SMSG_WEAPONLIST spkt = new SMSG_WEAPONLIST();
                            spkt.SessionId = this.character.id;
                            for (int i = 0; i < 5; i++)
                            {
                                Weapon current = this.character.weapons[i];
                                spkt.AddWeapon(current);
                            }

                            this.Send((byte[])spkt);
                        }

                        #endregion Weaponary List

                        #region Unlock Weaponary

                        {
                            /*
                             * This packet unlocks the selected slots
                             */

                            SMSG_ADDITIONLIST spkt = new SMSG_ADDITIONLIST();
                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Unlock Weaponary

                        #region Character Status

                        {
                            /*
                             * Send Character status
                             *
                             * This updates the characters status, this defines which job you're using
                             * the experience you have. The experience is expressed in absolute values
                             * so it doesn't represent a relative value for exp required.
                             *
                             * It also contains the definitions of how many LC, LP, HP, SP you have.
                             * Note: LC represents the amount of breath capacity.
                             */

                            SMSG_CHARSTATUS spkt = new SMSG_CHARSTATUS();
                            spkt.Job = this.character.job;
                            spkt.Exp = this.character.Cexp;
                            spkt.JobExp = this.character.Jexp;
                            spkt.LC = this.character._status.CurrentOxygen;
                            spkt.MaxLC = this.character._status.MaximumOxygen;
                            spkt.HP = this.character.HP;
                            spkt.MaxHP = this.character.HPMAX;
                            spkt.SP = this.character.SP;
                            spkt.MaxSP = this.character.SPMAX;
                            spkt.LP = this.character._status.CurrentLp;
                            spkt.MaxLP = 7;
                            spkt.FieldOfSight = 0;
                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Character Status

                        #region Battle Skills

                        {
                            /*
                             * Region Send all battle skills
                             *
                             * Also known as all active skills, heals, buffs included
                             */

                            List<Skill> list = this.character.learnedskills;
                            SMSG_BATTLESKILL battleskills = new SMSG_BATTLESKILL(list.Count);
                            foreach (Skill skill in list)
                                battleskills.AddSkill(skill.Id, skill.Experience);
                            battleskills.SessionId = this.character.id;
                            this.Send((byte[])battleskills);
                        }

                        #endregion Battle Skills

                        #region Special Skills

                        {
                            /*
                             * Sends over an list of special skills
                             *
                             */

                            SMSG_LISTSPECIALSKILLS spkt = new SMSG_LISTSPECIALSKILLS();
                            for (int i = 0; i < 16; i++)
                            {
                                Skill skill = character.SpecialSkills[i];
                                if (skill != null)
                                {
                                    spkt.AddSkill(skill.info.skillid, skill.Experience, (byte)i);
                                }
                            }
                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Special Skills

                        #region Update Zeny

                        {
                            /*
                             * Send Money
                             *
                             * This sets the money of a player to a absolute value. For instance if you
                             * say 500, it would mean the player gets 500 rufi. There are no relative
                             * values for TakeMoney or GiveMoney.
                             */

                            SMSG_SENDZENY spkt = new SMSG_SENDZENY();
                            spkt.Zeny = this.character.ZENY;
                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Update Zeny

                        #region Send Quest List

                        {
                            SMSG_QUESTINFO spkt3 = new SMSG_QUESTINFO();
                            spkt3.SessionId = this.character.id;
                            foreach (QuestBase Quest in this.character.QuestObjectives)
                            {
                                List<Saga.Quests.Objectives.ObjectiveList.StepInfo> Steps =
                                    QuestBase.GetSteps(this.character, Quest.QuestId);
                                spkt3.AddQuest(Quest.QuestId, (byte)Steps.Count);
                                for (int i = 0; i < Steps.Count; i++)
                                {
                                    Saga.Quests.Objectives.ObjectiveList.StepInfo currentStep = Steps[i];
                                    uint nextstep = (i + 1 < Steps.Count) ? Steps[i + 1].StepId : 0;
                                    spkt3.AddQuestStep(currentStep.StepId, currentStep.State, nextstep, Quest.isnew);
                                }
                            }
                            this.Send((byte[])spkt3);

                            foreach (QuestBase Quest in this.character.QuestObjectives)
                            {
                                List<Saga.Quests.Objectives.ObjectiveList.StepInfo> Steps =
                                    QuestBase.GetSteps(this.character, Quest.QuestId);

                                for (int i = 0; i < Steps.Count; i++)
                                {
                                    Saga.Quests.Objectives.ObjectiveList.StepInfo currentStep = Steps[i];
                                    if (currentStep.State == 1)
                                    {
                                        Predicate<Saga.Quests.Objectives.ObjectiveList.SubStep> Findsubstep = delegate(Saga.Quests.Objectives.ObjectiveList.SubStep objective)
                                        {
                                            return objective.Quest == Quest.QuestId
                                            && objective.StepId == currentStep.StepId;
                                        };

                                        List<Quests.Objectives.ObjectiveList.SubStep> Substeps =
                                            this.character.QuestObjectives.Substeps.FindAll(Findsubstep);

                                        foreach (Saga.Quests.Objectives.ObjectiveList.SubStep substep in Substeps)
                                        {
                                            if (substep.current > 0)
                                            {
                                                SMSG_QUESTSUBSTEPUPDATE spkt = new SMSG_QUESTSUBSTEPUPDATE();
                                                spkt.Unknown = 1;
                                                spkt.SubStep = (byte)substep.SubStepId;
                                                spkt.StepID = substep.StepId;
                                                spkt.QuestID = substep.Quest;
                                                spkt.Amount = (byte)substep.current;
                                                spkt.SessionId = this.character.id;
                                                this.Send((byte[])spkt);
                                            }
                                        }

                                        break;
                                    }
                                }
                            }
                        }

                        #endregion Send Quest List

                        #region Send Way Points

                        {
                            foreach (QuestBase Quest in this.character.QuestObjectives)
                            {
                                SMSG_SENDNAVIGATIONPOINT spkt2 = new SMSG_SENDNAVIGATIONPOINT();
                                spkt2.SessionId = this.character.id;
                                spkt2.QuestID = Quest.QuestId;

                                foreach (Saga.Quests.Objectives.ObjectiveList.Waypoint waypoint in QuestBase.UserGetWaypoints(this.character, Quest.QuestId))
                                {
                                    Predicate<MapObject> IsNpc = delegate(MapObject match)
                                    {
                                        return match.ModelId == waypoint.NpcId;
                                    };

                                    MapObject myObject = this.character.currentzone.Regiontree.SearchActor(IsNpc, SearchFlags.Npcs);
                                    if (myObject != null)
                                    {
                                        spkt2.AddPosition(waypoint.NpcId, myObject.Position.x, myObject.Position.y, myObject.Position.z);
                                    }
                                }
                                this.Send((byte[])spkt2);
                            }
                        }

                        #endregion Send Way Points

                        #region Addition List

                        {
                            SMSG_ADDITIONLIST spkt = new SMSG_ADDITIONLIST();
                            spkt.SessionId = this.character.id;
                            foreach (AdditionState state in character._additions)
                            {
                                if (state.CanExpire)
                                {
                                    spkt.Add(state.Addition, state.Lifetime);
                                }
                                else
                                {
                                    spkt.Add(state.Addition, 0);
                                }
                            }
                            this.Send((byte[])spkt);
                        }

                        #endregion Addition List

                        #region Scenario

                        {
                            QuestBase scenarioQuest = this.character.QuestObjectives.Quests[3];
                            if (scenarioQuest != null)
                            {
                                SMSG_INITIALIZESCENARIO spkt = new SMSG_INITIALIZESCENARIO();
                                spkt.Scenario1 = scenarioQuest.QuestId;
                                List<Saga.Quests.Objectives.ObjectiveList.StepInfo> list;
                                if (this.character.QuestObjectives.ScenarioSteps.TryGetValue(scenarioQuest.QuestId, out list))
                                    if (list.Count > 0)
                                    {
                                        spkt.Scenario2 = list[0].StepId;
                                        spkt.StepStatus = 1;
                                        spkt.Enabled = 0;
                                    }

                                spkt.SessionId = this.character.id;
                                this.Send((byte[])spkt);
                            }
                            else
                            {
                                QuestBase qbase;
                                if (Singleton.Quests.TryFindScenarioQuest(1, out qbase))
                                {
                                    qbase.OnStart(character.id);
                                }
                            }
                        }

                        #endregion Scenario

                        #region Mail

                        {
                            int count = Singleton.Database.GetInboxUncheckedCount(this.character.Name);
                            SMSG_MAILARRIVED spkt = new SMSG_MAILARRIVED();
                            spkt.Amount = (uint)count;
                            spkt.SessionId = this.character.id;
                            this.Send((byte[])spkt);
                        }

                        #endregion Mail

                        #region Inventory List

                        {
                            SMSG_INVENTORYLIST spkt5 = new SMSG_INVENTORYLIST((byte)this.character.container.Count);
                            spkt5.SessionId = this.character.id;
                            foreach (Rag2Item c in this.character.container)
                                spkt5.AddItem(c);
                            this.Send((byte[])spkt5);
                        }

                        #endregion Inventory List

                        #region Friendlist

                        {
                            WaitCallback FriendlistLogin = delegate(object state)
                            {
                                //Look through all friends lists of logged on players and if they are friends then
                                // notify them that the user logged on.
                                SMSG_FRIENDSLIST_NOTIFYLOGIN spkt = new SMSG_FRIENDSLIST_NOTIFYLOGIN();
                                spkt.name = this.character.Name;
                                foreach (Character characterTarget in LifeCycle.Characters)
                                {
                                    lock (characterTarget)
                                    {
                                        if (characterTarget.id != this.character.id)
                                            if (character._friendlist.Contains(this.character.Name))
                                            {
                                                spkt.SessionId = characterTarget.id;
                                                characterTarget.client.Send((byte[])spkt);
                                            }
                                    }
                                }
                            };

                            ThreadPool.QueueUserWorkItem(FriendlistLogin);
                        }

                        #endregion Friendlist

#if THREADING
                    };
                    ThreadPool.QueueUserWorkItem(FireTimeLoginCallback);
#else
                    }
#endif
                }
                else
                {
                    //Always ubsubcribe from the respawn manager in case
                    //we forget to do it.
                    Tasks.Respawns.Unsubscribe(this.character);
                }

                #region Dynamic Objects

                {
                    try
                    {
                        Regiontree tree = this.character.currentzone.Regiontree;

#if THREADING
                        WaitCallback FindCharactersActors = delegate(object a)
                        {
#else
                        {
#endif
                            foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters))
                            {
                                try
                                {
                                    if (Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position))
                                    {
                                        regionObject.ShowObject(this.character);
                                        if (this.character.id != regionObject.id)
                                        {
                                            this.character.ShowObject(regionObject);
                                        }

                                        regionObject.Appears(this.character);
                                    }
                                }
                                catch (SocketException)
                                {
                                    Trace.WriteLine("Network eror");
                                }
                                catch (Exception e)
                                {
                                    Trace.WriteLine(e.Message);
                                }
                            }
#if THREADING
                        };
#else
                        }
#endif

#if THREADING
                        WaitCallback FindNpcActors = delegate(object a)
                        {
#else
                        {
#endif
                            foreach (MapObject regionObject in tree.SearchActors(this.character, SearchFlags.MapItems | SearchFlags.Npcs))
                            {
                                try
                                {
                                    if (Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position))
                                    {
                                        regionObject.ShowObject(this.character);
                                        regionObject.Appears(this.character);
                                    }
                                }
                                catch (SocketException)
                                {
                                    Trace.WriteLine("Network eror");
                                }
                                catch (Exception e)
                                {
                                    Trace.WriteLine(e.Message);
                                }
                            }

#if THREADING
                        };
#else
                        }
#endif

#if THREADING
                        ThreadPool.QueueUserWorkItem(FindCharactersActors);
                        ThreadPool.QueueUserWorkItem(FindNpcActors);
#endif
                    }
                    catch (Exception e)
                    {
                        Trace.WriteLine(e.Message);
                    }
                }

                #endregion Dynamic Objects

                #region Time Weather

                CommonFunctions.UpdateTimeWeather(this.character);

                #endregion Time Weather

                #region Map Info

                {
                    SMSG_SHOWMAPINFO spkt2 = new SMSG_SHOWMAPINFO();
                    spkt2.SessionId = this.character.id;
                    spkt2.ZoneInfo = this.character.ZoneInformation;
                    this.Send((byte[])spkt2);
                }

                #endregion Map Info

                #region Return Points

                {
                    /*
                     * Send Resturn points
                     * Return points define which map you'll be send to when you
                     * use your promise stone or die
                     */

                    WorldCoordinate lpos = this.character.lastlocation.map > 0 ? this.character.lastlocation : this.character.savelocation;
                    WorldCoordinate spos = this.character.savelocation;
                    if (spos.map == this.character.currentzone.Map)
                    {
                        this.character.stance = (byte)StancePosition.Stand;
                        SMSG_RETURNMAPLIST spkt = new SMSG_RETURNMAPLIST();
                        spkt.ToMap = lpos.map;
                        spkt.FromMap = this.character.currentzone.CathelayaLocation.map;
                        spkt.IsSaveLocationSet = (lpos.map > 0) ? (byte)1 : (byte)0;
                        spkt.SessionId = this.character.id;
                        this.Send((byte[])spkt);
                    }
                    else
                    {
                        this.character.stance = (byte)StancePosition.Stand;
                        SMSG_RETURNMAPLIST spkt = new SMSG_RETURNMAPLIST();
                        spkt.ToMap = spos.map;
                        spkt.FromMap = this.character.currentzone.CathelayaLocation.map;
                        spkt.IsSaveLocationSet = (spos.map > 0) ? (byte)1 : (byte)0;
                        spkt.SessionId = this.character.id;
                        this.Send((byte[])spkt);
                    }
                }

                #endregion Return Points

                #region Job Levels

                {
                    SMSG_JOBLEVELS spkt2 = new SMSG_JOBLEVELS();
                    spkt2.SessionId = this.character.id;
                    spkt2.jobslevels = this.character.CharacterJobLevel;
                    this.Send((byte[])spkt2);
                }

                #endregion Job Levels

                #region Change Actors state

                {
                    /*
                     * Change the actors state
                     *
                     * This is used to change the actors state to a non-active-battle position.
                     * Note we will not warp the player back on their x and y coords if they were dead.
                     * This would result in double loading a map. This should be handeld before processing
                     * the character.
                     */

                    this.character.stance = (byte)StancePosition.Reborn;
                    this.character.ISONBATTLE = false;
                    SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE();
                    spkt.ActorID = this.character.id;
                    spkt.SessionId = this.character.id;
                    spkt.Stance = this.character.stance;
                    spkt.State = (this.character.ISONBATTLE) ? (byte)1 : (byte)0;
                    this.Send((byte[])spkt);
                }

                #endregion Change Actors state

                #region Party Update

                if (this.character.sessionParty != null)
                {
                    foreach (Character partyTarget in this.character.sessionParty._Characters)
                    {
                        //Only process if we're on the same map
                        if (partyTarget.id != this.character.id)
                            if (partyTarget.map == this.character.map)
                            {
                                //Retrieve positions people that are loaded
                                SMSG_PARTYMEMBERLOCATION spkt2 = new SMSG_PARTYMEMBERLOCATION();
                                spkt2.Index = 1;
                                spkt2.ActorId = partyTarget.id;
                                spkt2.SessionId = this.character.id;
                                spkt2.X = (partyTarget.Position.x / 1000);
                                spkt2.Y = (partyTarget.Position.y / 1000);
                                this.Send((byte[])spkt2);

                                //Update the position of myself to loaded characters
                                SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION();
                                spkt3.Index = 1;
                                spkt3.ActorId = this.character.id;
                                spkt3.SessionId = partyTarget.id;
                                spkt3.X = (this.character.Position.x / 1000);
                                spkt3.Y = (this.character.Position.y / 1000);
                                partyTarget.client.Send((byte[])spkt3);
                            }
                    }
                }

                #endregion Party Update

                #region Static Objects

                try
                {
                    //SEND OVER ALL CHARACTERS THAT ARE ALWAYS VISIBLE
                    foreach (MapObject regionObject in this.character.currentzone.Regiontree.SearchActors(SearchFlags.StaticObjects))
                    {
                        Console.WriteLine("Show object: {0}", regionObject.ToString());
                        regionObject.ShowObject(this.character);
                        regionObject.Appears(this.character);
                    }
                }
                catch (Exception)
                {
                    //Do nothing
                }

                #endregion Static Objects
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                this.Close();
            }
            finally
            {
                this.character.ISONBATTLE = false;
                isloaded = true;
                IsFirstTimeLoad = false;
                this.character.LastPositionTick = Environment.TickCount;
            }
        }
예제 #4
0
        /// <summary>
        /// Checks for position updates.
        /// </summary>
        /// <remarks>
        /// First we'll check to see if we could see, actor x from
        /// our old position. After that we'll check if can see actor x
        /// from our new position. If we can see him, we'll forward our movement
        /// packet. If we can't see him we'll sent a actor disappearance packet.
        ///
        /// Once that's done, we'll check if we can see a non-former visible actor
        /// is now visible in our new position. Which will cause us to invoke a appearance
        /// packet.
        /// </remarks>
        /// <param name="cpkt"></param>
        private void CM_CHARACTER_MOVEMENTSTART(CMSG_MOVEMENTSTART cpkt)
        {
            if (this.isloaded == false)
            {
                return;
            }

            //If character was previous walking/running
            if (this.character.IsMoving)
            {
                long time = (long)((uint)Environment.TickCount) - (long)((uint)this.character.LastPositionTick);

                //Sending packet to late
                if (time > 10000)
                {
                    CommonFunctions.Warp(this.character, this.character.Position, this.character.currentzone);
                    this.character.LastPositionTick = Environment.TickCount;
                    return;
                }
                else
                {
                    this.character.LastPositionTick = Environment.TickCount;
                }
            }
            else
            {
                this.character.LastPositionTick = Environment.TickCount;
            }

            //CALCULATE CURRENT MOVING SPEED
            ushort speed = (ushort)this.character._status.WalkingSpeed;
            if (cpkt.MovementType != 1)
            {
                if (speed > 0) speed /= 2;
            }

            //Get new actors for next-tick

            uint delay = cpkt.DelayTime;
            byte movement = cpkt.MovementType;
            float ax = cpkt.AccelerationX;
            float ay = cpkt.AccelerationY;
            float az = cpkt.AccelerationZ;

            Point oldP = this.character.Position;
            Point newP = new Point(cpkt.X, cpkt.Y, cpkt.Z);

            this.character.stance = (byte)StancePosition.Walk;
            this.character.Yaw = cpkt.Yaw;
            Regiontree tree = this.character.currentzone.Regiontree;

            try
            {
                foreach (MapObject regionObject in tree.SearchActors(this.character, SearchFlags.Npcs | SearchFlags.Characters | SearchFlags.MapItems, newP))
                {
                    bool CanSeePrev = Point.IsInSightRangeByRadius(regionObject.Position, oldP);
                    bool CanSeeNext = Point.IsInSightRangeByRadius(regionObject.Position, newP);
                    if (CanSeeNext && !CanSeePrev)
                    {
                        //Show object to other characters
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            this.character.ShowObject(current);
                        }

                        //Show object to self
                        regionObject.ShowObject(this.character);
                        regionObject.Appears(this.character);
                    }
                    else if (CanSeePrev && !CanSeeNext)
                    {
                        //Hide Object to other characters
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            this.character.HideObject(current);
                        }

                        //Hide Object to myself
                        regionObject.HideObject(this.character);
                        regionObject.Disappear(this.character);
                    }
                    else if (CanSeeNext && CanSeePrev)
                    {
                        //Update movment
                        if (MapObject.IsPlayer(regionObject))
                        {
                            Character current = (Character)regionObject;
                            if (current.client.isloaded == false) continue;

                            SMSG_MOVEMENTSTART spkt = new SMSG_MOVEMENTSTART();
                            spkt.SourceActorID = this.character.id;
                            spkt.Speed = speed;
                            spkt.X = oldP.x;
                            spkt.Y = oldP.y;
                            spkt.Z = oldP.z;
                            spkt.Yaw = this.character.Yaw;
                            spkt.MovementType = movement;
                            spkt.Delay0 = delay;
                            spkt.TargetActor = this.character._targetid;
                            spkt.AccelerationX = ax;
                            spkt.AccelerationY = ay;
                            spkt.AccelerationZ = az;
                            spkt.SessionId = current.id;
                            current.client.Send((byte[])spkt);
                        }

                        //Console.WriteLine("Disappear: {0}", regionObject.ToString());
                    }
                }
            }
            catch (Exception)
            {
                Trace.WriteLine("Error on local region");
            }
            finally
            {
                if (this.character.sessionParty != null)
                {
                    foreach (Character target in this.character.sessionParty._Characters)
                    {
                        try
                        {
                            if (target.id == this.character.id) continue;
                            SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION();
                            spkt3.Index = 1;
                            spkt3.ActorId = this.character.id;
                            spkt3.SessionId = target.id;
                            spkt3.X = (this.character.Position.x / 1000);
                            spkt3.Y = (this.character.Position.y / 1000);
                            target.client.Send((byte[])spkt3);
                        }
                        catch (SocketException)
                        {
                            Trace.WriteLine("Party network error");
                        }
                        catch (Exception)
                        {
                            Trace.WriteLine("Unknown error");
                        }
                    }
                }
            }

            this.character.Position = newP;
            Regiontree.UpdateRegion(this.character);
            QuestBase.UserCheckPosition(this.character);
        }
예제 #5
0
    public static bool Warp(Character target, Point destination, Zone NewZoneInstance)
    {
        if (target.client.isloaded == true)
        {
            if (target.map > 0 && NewZoneInstance.Map > 0)
            {
                if (target.map != NewZoneInstance.Map)
                {
                    #region Not the same Zone

                    if (target.currentzone.Type != ZoneType.Dungeon)
                    {
                        WorldCoordinate worldcoord;
                        worldcoord.coords = target.Position;
                        worldcoord.map = target.currentzone.Map;
                        target.lastlocation = worldcoord;
                    }

                    //Start loading
                    target.client.isloaded = false;
                    Zone currentZone = target.currentzone;
                    target.currentzone.OnLeave(target);

                    lock (target)
                    {
                        //Unregister
                        currentZone.Regiontree.Unsubscribe(target);

                        //Set position to the new location
                        target.map = NewZoneInstance.Map;

                        //Set new position
                        target.Position = new Point(
                                destination.x,
                                destination.y,
                                destination.z
                        );
                    }

                    //Update party members
                    if (target.sessionParty != null)
                        foreach (Character partyTarget in target.sessionParty)
                        {
                            //switch the map
                            SMSG_PARTYMEMBERMAPCHANGE spkt4 = new SMSG_PARTYMEMBERMAPCHANGE();
                            spkt4.Index = 1;
                            spkt4.ActorId = target.id;
                            spkt4.Unknown = (byte)(target.map + 0x065);
                            spkt4.Zone = target.map;
                            spkt4.SessionId = partyTarget.id;
                            partyTarget.client.Send((byte[])spkt4);
                        }

                    //Set zone instance
                    target.currentzone = NewZoneInstance;

                    //Send over load packet
                    SMSG_SENDSTART spkt = new SMSG_SENDSTART();
                    spkt.SessionId = target.id;
                    spkt.X = destination.x;
                    spkt.Y = destination.y;
                    spkt.Z = destination.z;
                    spkt.MapId = NewZoneInstance.Map;
                    spkt.Unknown = (byte)(target.map + 0x65);
                    spkt.Channel = 1;
                    target.client.Send((byte[])spkt);
                    return true;

                    #endregion Not the same Zone
                }
                else
                {
                    #region Notify People That Actor Disapears

                    Point origin = target.Position;

                    Regiontree tree;
                    tree = target.currentzone.Regiontree;
                    foreach (MapObject c in tree.SearchActors(target, SearchFlags.DynamicObjects))
                    {
                        bool insightrangeold = Point.IsInSightRangeByRadius(origin, c.Position);
                        bool insightrangenew = Point.IsInSightRangeByRadius(destination, c.Position);
                        if (c.id == target.id) continue;

                        //If vible from old postion but not from new position hide
                        if (insightrangeold && !insightrangenew)
                        {
                            double distance = Point.GetDistance3D(destination, c.Position);
                            //CROSS NOTIFY PLAYERS ACTORS DISAPPPEARS
                            if (MapObject.IsPlayer(c))
                            {
                                Character targetChar = c as Character;
                                targetChar.HideObject(target);
                            }

                            c.HideObject(target);
                            c.Disappear(target);
                        }
                    }

                    #endregion Notify People That Actor Disapears

                    #region Update Region

                    target.Position = new Point(destination.x, destination.y, destination.z);
                    Regiontree.UpdateRegion(target);

                    #endregion Update Region

                    #region Teleport

                    SMSG_ACTORTELEPORT spkt = new SMSG_ACTORTELEPORT();
                    spkt.SessionId = target.id;
                    spkt.x = destination.x;
                    spkt.y = destination.y;
                    spkt.Z = destination.z;
                    target.client.Send((byte[])spkt);

                    #endregion Teleport

                    #region Reset State

                    target.ISONBATTLE = false;
                    target.stance = (byte)StancePosition.Reborn;
                    target._targetid = 0;

                    SMSG_ACTORCHANGESTATE spkt4 = new SMSG_ACTORCHANGESTATE();
                    spkt4.SessionId = target.id;
                    spkt4.Stance = target.stance;
                    spkt4.TargetActor = target._targetid;
                    spkt4.State = (target.ISONBATTLE == true) ? (byte)1 : (byte)0;
                    spkt4.ActorID = target.id;
                    target.client.Send((byte[])spkt4);

                    #endregion Reset State

                    #region Notify People That the Actor Appears

                    tree = target.currentzone.Regiontree;
                    foreach (MapObject myObject in tree.SearchActors(target, SearchFlags.DynamicObjects))
                    {
                        bool insightrangeold = Point.IsInSightRangeByRadius(origin, myObject.Position);
                        bool insightrangenew = Point.IsInSightRangeByRadius(destination, myObject.Position);

                        double distance = Point.GetDistance3D(destination, myObject.Position);

                        //If visible from new postion but not from old postion
                        if (insightrangenew && !insightrangeold)
                        {
                            myObject.ShowObject(target);
                            myObject.Appears(target);

                            if (MapObject.IsPlayer(myObject))
                            {
                                Character current = (Character)myObject;
                                if (current.client.isloaded == false) continue;
                                target.ShowObject(current);
                            }
                        }
                    }

                    #endregion Notify People That the Actor Appears

                    #region Notify Party Members

                    if (target.sessionParty != null)
                    {
                        foreach (Character partyTarget in target.sessionParty)
                        {
                            if (partyTarget.id == target.id) continue;
                            SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION();
                            spkt3.Index = 1;
                            spkt3.ActorId = target.id;
                            spkt3.SessionId = partyTarget.id;
                            spkt3.X = (destination.x / 1000);
                            spkt3.Y = (destination.y / 1000);
                            partyTarget.client.Send((byte[])spkt3);
                        }
                    }

                    #endregion Notify Party Members

                    return true;
                }
            }
            else
            {
                Trace.TraceError("Warping player {0} to unsupported map {1}", target.Name, 0);
                return false;
            }
        }
        else
        {
            return false;
        }
    }