예제 #1
0
파일: World.cs 프로젝트: saroque/server
        private void PacketHandler_0x3A_DialogUse(Object obj, ClientPacket packet)
        {
            var user = (User) obj;
            if (user.CheckSquelch(0x38, null))
            {
                Logger.InfoFormat("{0}: squelched (dialog use)", user.Name);
                return;
            }

            var header = packet.ReadDialogHeader();
            var objectType = packet.ReadByte();
            var objectID = packet.ReadUInt32();
            var pursuitID = packet.ReadUInt16();
            var pursuitIndex = packet.ReadUInt16();

            Logger.DebugFormat("objectType {0}, objectID {1}, pursuitID {2}, pursuitIndex {3}",
                objectType, objectID, pursuitID, pursuitIndex);

            Logger.DebugFormat("active dialog via state object: pursuitID {0}, pursuitIndex {1}",
                user.DialogState.CurrentPursuitId, user.DialogState.CurrentPursuitIndex);

            if (pursuitID == user.DialogState.CurrentPursuitId && pursuitIndex == user.DialogState.CurrentPursuitIndex)
            {
                // If we get a packet back with the same index and ID, the dialog has been closed.
                Logger.DebugFormat("Dialog closed, resetting dialog state");
                user.DialogState.EndDialog();
                return;
            }

            if ((pursuitIndex > user.DialogState.CurrentPursuitIndex + 1) ||
                (pursuitIndex < user.DialogState.CurrentPursuitIndex - 1))
            {
                Logger.ErrorFormat("Dialog index is outside of acceptable limits (next/prev)");
                return;
            }

            WorldObject wobj;

            if (user.World.Objects.TryGetValue(objectID, out wobj))
            {
                VisibleObject clickTarget = wobj as VisibleObject;
                // Was the previous button clicked? Handle that first
                if (pursuitIndex == user.DialogState.CurrentPursuitIndex - 1)
                {
                    Logger.DebugFormat("Handling prev: client passed index {0}, current index is {1}",
                        pursuitIndex, user.DialogState.CurrentPursuitIndex);

                    if (user.DialogState.SetDialogIndex(clickTarget, pursuitID, pursuitIndex))
                    {
                        user.DialogState.ActiveDialog.ShowTo(user, clickTarget);
                        return;
                    }
                }

                // Is the active dialog an input or options dialog?

                if (user.DialogState.ActiveDialog is OptionsDialog)
                {
                    var paramsLength = packet.ReadByte();
                    var option = packet.ReadByte();
                    var dialog = user.DialogState.ActiveDialog as OptionsDialog;
                    dialog.HandleResponse(user, option, clickTarget);
                }

                if (user.DialogState.ActiveDialog is TextDialog)
                {
                    var paramsLength = packet.ReadByte();
                    var response = packet.ReadString8();
                    var dialog = user.DialogState.ActiveDialog as TextDialog;
                    dialog.HandleResponse(user, response, clickTarget);
                }

                // Did the handling of a response result in our active dialog sequence changing? If so, exit.

                if (user.DialogState.CurrentPursuitId != pursuitID)
                {
                    Logger.DebugFormat("Dialog has changed, exiting");
                    return;
                }

                if (user.DialogState.SetDialogIndex(clickTarget, pursuitID, pursuitIndex))
                {
                    Logger.DebugFormat("Pursuit index is now {0}", pursuitIndex);
                    user.DialogState.ActiveDialog.ShowTo(user, clickTarget);
                    return;
                }
                else
                {
                    Logger.DebugFormat("Sending close packet");
                    var p = new ServerPacket(0x30);
                    p.WriteByte(0x0A);
                    p.WriteByte(0x00);
                    user.Enqueue(p);
                    user.DialogState.EndDialog();
                }
            }
        }
예제 #2
0
파일: World.cs 프로젝트: saroque/server
        private void PacketHandler_0x39_NPCMainMenu(Object obj, ClientPacket packet)
        {
            var user = (User) obj;

            if (user.CheckSquelch(0x38, null))
            {
                Logger.InfoFormat("{0}: squelched (NPC main menu)", user.Name);
                return;
            }

            // We just ignore the header, because, really, what exactly is a 16-bit encryption 
            // key plus CRC really doing for you
            var header = packet.ReadDialogHeader();
            var objectType = packet.ReadByte();
            var objectId = packet.ReadUInt32();
            var pursuitId = packet.ReadUInt16();

            Logger.DebugFormat("main menu packet: ObjectType {0}, ID {1}, pursuitID {2}",
                objectType, objectId, pursuitId);

            // Sanity checks
            WorldObject wobj;

            if (Game.World.Objects.TryGetValue(objectId, out wobj))
            {
                // Are we handling a global sequence?
                DialogSequence pursuit;
                VisibleObject clickTarget = wobj as VisibleObject;

                if (pursuitId < Constants.DIALOG_SEQUENCE_SHARED)
                {
                    // Does the sequence exist in the global catalog?
                    try
                    {
                        pursuit = Game.World.GlobalSequences[pursuitId];
                    }
                    catch
                    {
                        Logger.ErrorFormat("{0}: pursuit ID {1} doesn't exist in the global catalog?",
                            wobj.Name, pursuitId);
                        return;
                    }
                }
                else if (pursuitId >= Constants.DIALOG_SEQUENCE_HARDCODED)
                {
                    if (!(wobj is Merchant))
                    {
                        Logger.ErrorFormat("{0}: attempt to use hardcoded merchant menu item on non-merchant",
                            wobj.Name, pursuitId);
                        return;
                    }

                    var menuItem = (MerchantMenuItem) pursuitId;
                    var merchant = (Merchant) wobj;
                    MerchantMenuHandler handler;

                    if (!merchantMenuHandlers.TryGetValue(menuItem, out handler))
                    {
                        Logger.ErrorFormat("{0}: merchant menu item {1} doesn't exist?",
                            wobj.Name, menuItem);
                        return;
                    }

                    if (!merchant.Jobs.HasFlag(handler.RequiredJob))
                    {
                        Logger.ErrorFormat("{0}: merchant does not have required job {1}",
                            wobj.Name, handler.RequiredJob);
                        return;
                    }

                    handler.Callback(user, merchant, packet);
                    return;
                }
                else
                {
                    // This is a local pursuit
                    try
                    {
                        pursuit = clickTarget.Pursuits[pursuitId - Constants.DIALOG_SEQUENCE_SHARED];
                    }
                    catch
                    {
                        Logger.ErrorFormat("{0}: local pursuit {1} doesn't exist?", wobj.Name, pursuitId);
                        return;
                    }
                }
                Logger.DebugFormat("{0}: showing initial dialog for Pursuit {1} ({2})",
                    clickTarget.Name, pursuit.Id, pursuit.Name);
                user.DialogState.StartDialog(clickTarget, pursuit);
                pursuit.ShowTo(user, clickTarget);
            }
            else
            {
                Logger.WarnFormat("specified object ID {0} doesn't exist?", objectId);
                return;
            }

        }