Beispiel #1
0
 /// <summary>
 /// Notifies the User about the new page.
 /// </summary>
 void NotifyUserOfNewPage()
 {
     if (_dialogItem == null)
     {
         // Dialog has ended
         using (var pw = ServerPacket.EndChatDialog())
         {
             _user.Send(pw, ServerMessageType.GUI);
         }
     }
     else
     {
         // New page
         using (var pw = ServerPacket.SetChatDialogPage(_dialogItem.ID, GetResponsesToSkip()))
         {
             _user.Send(pw, ServerMessageType.GUI);
         }
     }
 }
Beispiel #2
0
        void RecvRequestMapEntityIndex(IIPSocket conn, BitStream r)
        {
            var index = r.ReadMapEntityIndex();

            // Get the user and their map
            User user;

            if ((user = TryGetUser(conn)) == null)
            {
                return;
            }

            Map map;

            if (!TryGetMap(user, out map))
            {
                return;
            }

            // Get the DynamicEntity
            var de = map.GetDynamicEntity(index);

            if (de == null)
            {
                // The DynamicEntity for the index was null, so tell the client to delete whatever is at that index
                using (var pw = ServerPacket.RemoveDynamicEntity(index))
                {
                    conn.Send(pw, ServerMessageType.Map);
                }
            }
            else
            {
                // A DynamicEntity does exist at that index, so tell the client to create it
                using (var pw = ServerPacket.CreateDynamicEntity(de))
                {
                    conn.Send(pw, ServerMessageType.Map);
                }
            }
        }
Beispiel #3
0
        void RecvGetFriends(IIPSocket conn, BitStream r)
        {
            var account = TryGetAccount(conn);

            if (account == null)
            {
                return;
            }

            User user;

            if ((user = TryGetUser(conn)) == null)
            {
                return;
            }

            string FriendsString = account.Friends;

            List <string> FriendsList         = FriendsString.Split(',').ToList <string>();
            string        OnlineFriendsString = "";
            string        FriendsMap          = "";

            var OnlineMembers = Server.World.GetUsers();

            foreach (var Member in OnlineMembers)
            {
                if (FriendsList.Contains(Member.Name))
                {
                    OnlineFriendsString += Member.Name + ",";
                    var parentMap = World.GetMap(Member.Map.ParentMapID);
                    FriendsMap += parentMap.Name + ",";
                }
            }

            using (var pw = ServerPacket.ReceiveFriends(OnlineFriendsString, FriendsMap, FriendsString))
            {
                user.Send(pw, ServerMessageType.GUI);
            }
        }
Beispiel #4
0
        /// <summary>
        /// When overridden in the derived class, allows for handling when the status of an <see cref="IIPSocket"/> changes.
        /// </summary>
        /// <param name="sender">The <see cref="IIPSocket"/> who's status has changed.</param>
        /// <param name="status">The new status.</param>
        /// <param name="reason">The reason for the status change.</param>
        protected override void OnReceiveStatusChanged(IIPSocket sender, NetConnectionStatus status, string reason)
        {
            base.OnReceiveStatusChanged(sender, status, reason);

            switch (status)
            {
            case NetConnectionStatus.Disconnected:
                // If there was an account on the socket, destroy it
                var acc = World.GetUserAccount(sender, false);
                if (acc != null)
                {
                    acc.Dispose();
                }
                break;

            case NetConnectionStatus.Connected:
                // Send the server time to the client
                using (var pw = ServerPacket.SetGameTime(DateTime.Now))
                {
                    sender.Send(pw, ServerMessageType.GUI);
                }
                break;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Updates the client with the changes that have been made to the UserInventory.
        /// </summary>
        public void Update()
        {
            // Don't actually grab the PacketWriter from the pool until we know we will need it
            PacketWriter pw = null;

            try
            {
                // Loop through all slots
                for (var slot = 0; slot < GameData.MaxInventorySize; slot++)
                {
                    // Skip unchanged slots
                    if (!_slotChanged[slot])
                    {
                        continue;
                    }

                    // Get the item in the slot
                    var invSlot = new InventorySlot(slot);
                    var item    = UserInventory[invSlot];

                    // Get the values to send, which depends on if the slot is empty (item == null) or not
                    GrhIndex sendItemGraphic;
                    byte     sendItemAmount;

                    if (item == null)
                    {
                        sendItemGraphic = GrhIndex.Invalid;
                        sendItemAmount  = 0;
                    }
                    else
                    {
                        sendItemGraphic = item.GraphicIndex;
                        sendItemAmount  = item.Amount;
                    }

                    // Grab the PacketWriter if we have not already, or clear it if we have
                    if (pw == null)
                    {
                        pw = ServerPacket.GetWriter();
                    }
                    else
                    {
                        pw.Reset();
                    }

                    // Pack the data and send it
                    ServerPacket.SetInventorySlot(pw, invSlot, sendItemGraphic, sendItemAmount);
                    OwnerUser.Send(pw, ServerMessageType.GUIItems);
                }
            }
            finally
            {
                // If we grabbed a PacketWriter, make sure we dispose of it!
                if (pw != null)
                {
                    pw.Dispose();
                }
            }

            // Changes complete
            _slotChanged.SetAll(false);
        }
Beispiel #6
0
        void RecvAcceptOrTurnInQuest(IIPSocket conn, BitStream r)
        {
            var providerIndex = r.ReadMapEntityIndex();
            var questID       = r.ReadQuestID();

            // Get the user
            User user;

            if ((user = TryGetUser(conn)) == null || user.Map == null)
            {
                return;
            }

            if (user.IsPeerTrading)
            {
                return;
            }

            // Get the provider
            var npc      = user.Map.GetDynamicEntity <Character>(providerIndex);
            var provider = npc as IQuestProvider <User>;

            if (provider == null)
            {
                return;
            }

            // Check the distance and state
            if (user.Map != npc.Map || user.Map == null || !npc.IsAlive || npc.IsDisposed ||
                user.GetDistance(npc) > GameData.MaxNPCChatDistance)
            {
                return;
            }

            // Get the quest
            var quest = _questManager.GetQuest(questID);

            if (quest == null)
            {
                return;
            }

            // Ensure this provider even provides this quest
            if (!provider.Quests.Contains(quest))
            {
                return;
            }

            // If the user already has the quest, try to turn it in
            if (user.ActiveQuests.Contains(quest))
            {
                // Quest already started, try to turn in
                var success = user.TryFinishQuest(quest);
                using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, false))
                {
                    user.Send(pw, ServerMessageType.GUI);
                }
            }
            else
            {
                // Quest not started yet, try to add it
                var success = user.TryAddQuest(quest);
                using (var pw = ServerPacket.AcceptOrTurnInQuestReply(questID, success, true))
                {
                    user.Send(pw, ServerMessageType.GUI);
                }
            }
        }
Beispiel #7
0
        void RecvUseWorld(IIPSocket conn, BitStream r)
        {
            var useEntityIndex = r.ReadMapEntityIndex();

            // Get the map and user
            User user;
            Map  map;

            if (!TryGetMap(conn, out user, out map))
            {
                return;
            }

            if (user.IsPeerTrading)
            {
                return;
            }

            if (!user.IsAlive)
            {
                const string errmsg = "User `{0}` tried to use world entity while dead.";
                if (log.IsInfoEnabled)
                {
                    log.InfoFormat(errmsg, user);
                }
                return;
            }

            // Grab the DynamicEntity to use
            var useEntity = map.GetDynamicEntity(useEntityIndex);

            if (useEntity == null)
            {
                const string errmsg = "UseEntity received but usedEntityIndex `{0}` is not a valid DynamicEntity.";
                Debug.Fail(string.Format(errmsg, useEntityIndex));
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, useEntityIndex);
                }
                return;
            }

            // Ensure the used DynamicEntity is even usable
            var asUsable = useEntity as IUsableEntity;

            if (asUsable == null)
            {
                const string errmsg =
                    "UseEntity received but useByIndex `{0}` refers to DynamicEntity `{1}` which does " +
                    "not implement IUsableEntity.";
                Debug.Fail(string.Format(errmsg, useEntityIndex, useEntity));
                if (log.IsErrorEnabled)
                {
                    log.WarnFormat(errmsg, useEntityIndex, useEntity);
                }
                return;
            }

            // Use it
            if (asUsable.Use(user))
            {
                // Notify everyone in the map it was used
                if (asUsable.NotifyClientsOfUsage)
                {
                    using (var pw = ServerPacket.UseEntity(useEntity.MapEntityIndex, user.MapEntityIndex))
                    {
                        map.Send(pw, ServerMessageType.Map);
                    }
                }
            }
        }
        /// <summary>
        /// Tells the skill user to start using the given <paramref name="skill"/>. This is more of a suggestion than a
        /// request since the skill user does not actually have to start casting the skill. If this skill user decides
        /// to use the skill, the CurrentCastingSkill must be set to the <paramref name="skill"/>.
        /// </summary>
        /// <param name="skill">The skill to be used.</param>
        /// <param name="target">The optional character to use the skill on. Can be null.</param>
        /// <returns>True if the <paramref name="skill"/> started being casted; otherwise false. This does not indicate
        /// whether or not the skill was or will be successfully used, just that it was attempted to be used. Common
        /// times this will return false is if there is a skill already being casted, or if the skill that was
        /// attempted to be used still needs to cool down.</returns>
        public bool TryStartCastingSkill(ISkill <SkillType, StatType, Character> skill, Character target)
        {
            if (!_character.IsAlive)
            {
                return(false);
            }

            // Check that the character knows the skill
            if (!_character.KnownSkills.Knows(skill.SkillType))
            {
                return(false);
            }

            // Don't interrupt a skill that the character is already casting
            if (IsCastingSkill)
            {
                return(false);
            }

            // Check that the group is available for usage
            if (_cooldownManager.IsCoolingDown(skill.CooldownGroup, _character.GetTime()))
            {
                return(false);
            }

            // Only allow immediate-usage skills when moving
            if (_character.Velocity != Vector2.Zero && skill.CastingTime > 0)
            {
                return(false);
            }

            if (skill.CastingTime == 0)
            {
                // The skill to use has no usage delay, so use it immediately
                UseSkill(skill, target, true);
            }
            else
            {
                // The skill does have a delay, so queue it for usage
                _currentCastingSkill = skill;
                _castingSkillTarget  = target;
                var castingTime = skill.CastingTime;
                _castingSkillUsageTime = _character.GetTime() + castingTime;

                // Tell the character the details about the skill they are casting
                if (_character is INetworkSender)
                {
                    using (var pw = ServerPacket.SkillStartCasting_ToUser(skill.SkillType, castingTime))
                    {
                        ((INetworkSender)_character).Send(pw, ServerMessageType.GUIUserStatus);
                    }
                }

                // Tell the users on the map that the character is casting
                using (var pw = ServerPacket.SkillStartCasting_ToMap(_character.MapEntityIndex, skill.SkillType))
                {
                    _character.Map.Send(pw, ServerMessageType.MapDynamicEntityProperty);
                }
            }

            return(true);
        }
Beispiel #9
0
        protected void SynchronizePercentage()
        {
            const int _updatePercentDiff = 2;

            // Check if the percentage has changed
            int maxHP = _character.ModStats[StatType.MaxHP];
            int maxMP = _character.ModStats[StatType.MaxMP];

            if (maxHP < 1)
            {
                const string errmsg = "MaxHP is less than 1 for Character `{0}`!";
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, _character);
                }
                Debug.Fail(string.Format(errmsg, _character));
                return;
            }

            var  newHPPercent = (byte)(((float)_character.HP / maxHP) * 100.0f);
            byte newMPPercent = 100;

            if (maxMP > 0)
            {
                newMPPercent = (byte)(((float)_character.MP / maxMP) * 100.0f);
            }

            var updateHP = Math.Abs(newHPPercent - _lastSentHPPercent) >= _updatePercentDiff;
            var updateMP = Math.Abs(newMPPercent - _lastSentMPPercent) >= _updatePercentDiff;

            if (!updateHP && !updateMP)
            {
                return;
            }

            _lastSentHPPercent = newHPPercent;
            _lastSentMPPercent = newMPPercent;

            // Get the map
            var map = _character.Map;

            if (map == null)
            {
                return;
            }

            // Get the users to send the update to (excluding this character)
            var users = map.Users;

            if (_isUser)
            {
                users = users.Where(x => x != _character);
            }
            if (users.Count() == 0)
            {
                return;
            }

            // Send the updates
            using (var pw = ServerPacket.GetWriter())
            {
                if (updateHP)
                {
                    pw.Reset();
                    ServerPacket.SetCharacterHPPercent(pw, _character.MapEntityIndex, newHPPercent);
                    foreach (var user in users)
                    {
                        user.Send(pw, ServerMessageType.MapCharacterSP);
                    }
                }
                if (updateMP)
                {
                    pw.Reset();
                    ServerPacket.SetCharacterMPPercent(pw, _character.MapEntityIndex, newMPPercent);
                    foreach (var user in users)
                    {
                        user.Send(pw, ServerMessageType.MapCharacterSP);
                    }
                }
            }
        }