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); } } } }
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); } } } }