public static void DisplayGumpResponse(NetState state, CircularBufferReader reader)
        {
            var serial   = reader.ReadUInt32();
            var typeID   = reader.ReadInt32();
            var buttonID = reader.ReadInt32();

            foreach (var gump in state.Gumps)
            {
                if (gump.Serial != serial || gump.TypeID != typeID)
                {
                    continue;
                }

                var buttonExists = buttonID == 0; // 0 is always 'close'

                if (!buttonExists)
                {
                    foreach (var e in gump.Entries)
                    {
                        if (e is GumpButton button && button.ButtonID == buttonID)
                        {
                            buttonExists = true;
                            break;
                        }

                        if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID)
                        {
                            buttonExists = true;
                            break;
                        }
                    }
                }

                if (!buttonExists)
                {
                    state.WriteConsole("Invalid gump response, disconnecting...");
                    state.Dispose();
                    return;
                }

                var switchCount = reader.ReadInt32();

                if (switchCount < 0 || switchCount > gump.m_Switches)
                {
                    state.WriteConsole("Invalid gump response, disconnecting...");
                    state.Dispose();
                    return;
                }

                var switches = new int[switchCount];

                for (var j = 0; j < switches.Length; ++j)
                {
                    switches[j] = reader.ReadInt32();
                }

                var textCount = reader.ReadInt32();

                if (textCount < 0 || textCount > gump.m_TextEntries)
                {
                    state.WriteConsole("Invalid gump response, disconnecting...");
                    state.Dispose();
                    return;
                }

                var textEntries = new TextRelay[textCount];

                for (var j = 0; j < textEntries.Length; ++j)
                {
                    int entryID    = reader.ReadUInt16();
                    int textLength = reader.ReadUInt16();

                    if (textLength > 239)
                    {
                        state.WriteConsole("Invalid gump response, disconnecting...");
                        state.Dispose();
                        return;
                    }

                    var text = reader.ReadBigUniSafe(textLength);
                    textEntries[j] = new TextRelay(entryID, text);
                }

                state.RemoveGump(gump);

                var prof = GumpProfile.Acquire(gump.GetType());

                prof?.Start();

                gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries));

                prof?.Finish();

                return;
            }

            if (typeID == 461)
            {
                // Virtue gump
                var switchCount = reader.ReadInt32();

                if (buttonID == 1 && switchCount > 0)
                {
                    var beheld = World.FindMobile(reader.ReadUInt32());

                    if (beheld != null)
                    {
                        EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld);
                    }
                }
                else
                {
                    var beheld = World.FindMobile(serial);

                    if (beheld != null)
                    {
                        EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID);
                    }
                }
            }
        }
Esempio n. 2
0
    public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, int packetLength)
    {
        var serial   = (Serial)reader.ReadUInt32();
        var typeID   = reader.ReadInt32();
        var buttonID = reader.ReadInt32();

        foreach (var gump in state.Gumps)
        {
            if (gump.Serial != serial || gump.TypeID != typeID)
            {
                continue;
            }

            var buttonExists = buttonID == 0; // 0 is always 'close'

            if (!buttonExists)
            {
                foreach (var e in gump.Entries)
                {
                    if (e is GumpButton button && button.ButtonID == buttonID)
                    {
                        buttonExists = true;
                        break;
                    }

                    if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID)
                    {
                        buttonExists = true;
                        break;
                    }
                }
            }

            if (!buttonExists)
            {
                state.LogInfo("Invalid gump response, disconnecting...");
                var exception = new InvalidGumpResponseException($"Button {buttonID} doesn't exist");
                exception.SetStackTrace(new StackTrace());
                NetState.TraceException(exception);
                state.Mobile?.SendMessage("Invalid gump response.");

                // state.Disconnect("Invalid gump response.");
                return;
            }

            var switchCount = reader.ReadInt32();

            if (switchCount < 0 || switchCount > gump.m_Switches)
            {
                state.LogInfo("Invalid gump response, disconnecting...");
                var exception = new InvalidGumpResponseException($"Bad switch count {switchCount}");
                exception.SetStackTrace(new StackTrace());
                NetState.TraceException(exception);
                state.Mobile?.SendMessage("Invalid gump response.");

                // state.Disconnect("Invalid gump response.");
                return;
            }

            var switches = new int[switchCount];

            for (var i = 0; i < switches.Length; ++i)
            {
                switches[i] = reader.ReadInt32();
            }

            var textCount = reader.ReadInt32();

            if (textCount < 0 || textCount > gump.m_TextEntries)
            {
                state.LogInfo("Invalid gump response, disconnecting...");
                var exception = new InvalidGumpResponseException($"Bad text entry count {textCount}");
                exception.SetStackTrace(new StackTrace());
                NetState.TraceException(exception);
                state.Mobile?.SendMessage("Invalid gump response.");

                // state.Disconnect("Invalid gump response.");
                return;
            }

            var textEntries = new TextRelay[textCount];

            for (var i = 0; i < textEntries.Length; ++i)
            {
                int entryID    = reader.ReadUInt16();
                int textLength = reader.ReadUInt16();

                if (textLength > 239)
                {
                    state.LogInfo("Invalid gump response, disconnecting...");
                    var exception = new InvalidGumpResponseException($"Text entry {i} is too long ({textLength})");
                    exception.SetStackTrace(new StackTrace());
                    NetState.TraceException(exception);
                    state.Mobile?.SendMessage("Invalid gump response.");

                    // state.Disconnect("Invalid gump response.");
                    return;
                }

                var text = reader.ReadBigUniSafe(textLength);
                textEntries[i] = new TextRelay(entryID, text);
            }

            state.RemoveGump(gump);

            var prof = GumpProfile.Acquire(gump.GetType());

            prof?.Start();

            gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries));

            prof?.Finish();

            return;
        }

        if (typeID == 461)
        {
            // Virtue gump
            var switchCount = reader.Remaining >= 4 ? reader.ReadInt32() : 0;

            if (buttonID == 1 && switchCount > 0)
            {
                var beheld = World.FindMobile((Serial)reader.ReadUInt32());

                if (beheld != null)
                {
                    EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld);
                }
            }
            else
            {
                var beheld = World.FindMobile(serial);

                if (beheld != null)
                {
                    EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID);
                }
            }
        }
    }