public static void PollInfo(NetState ns, CircularBufferReader reader, ref int packetLength) { var version = reader.ReadByte(); if (_token != null) { unsafe { byte *tok = stackalloc byte[_token.Length]; var span = new Span <byte>(tok, _token.Length); reader.Read(span); if (!span.SequenceEqual(_token)) { ns.Disconnect("Invalid token sent for ConnectUO"); return; } } } ns.LogInfo($"ConnectUO (v{version}) is requesting stats."); if (version > ConnectUOProtocolVersion) { Utility.PushColor(ConsoleColor.Yellow); ns.LogInfo("Warning! ConnectUO (v{version}) is newer than what is supported."); Utility.PopColor(); } ns.SendServerPollInfo(); }
public static void EncodedCommand(NetState state, CircularBufferReader reader, ref int packetLength) { var e = World.FindEntity((Serial)reader.ReadUInt32()); int packetId = reader.ReadUInt16(); var ph = IncomingPackets.GetEncodedHandler(packetId); if (ph == null) { reader.Trace(state); return; } if (ph.Ingame && state.Mobile == null) { state.LogInfo( "Sent in-game packet (0xD7x{0:X2}) before being attached to a mobile", packetId ); state.Disconnect($"Sent in-game packet (0xD7x{packetId:X2}) before being attached to a mobile."); } else if (ph.Ingame && state.Mobile.Deleted) { state.Disconnect($"Sent in-game packet(0xD7x{packetId:X2}) but mobile is deleted."); } else { ph.OnReceive(state, e, new EncodedReader(reader)); } }
public static void DisplayGumpResponse(NetState state, CircularBufferReader reader, ref 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); } } } }
public static void TextCommand(NetState state, CircularBufferReader reader, ref int packetLength) { var from = state.Mobile; if (from == null) { return; } int type = reader.ReadByte(); var command = reader.ReadAscii(); switch (type) { case 0xC7: // Animate { EventSink.InvokeAnimateRequest(from, command); break; } case 0x24: // Use skill { var tokenizer = command.Tokenize(' '); if (!tokenizer.MoveNext() || !int.TryParse(tokenizer.Current, out var skillIndex)) { break; } Skills.UseSkill(from, skillIndex); break; } case 0x43: // Open spellbook { if (!int.TryParse(command, out var booktype)) { booktype = 1; } EventSink.InvokeOpenSpellbookRequest(from, booktype); break; } case 0x27: // Cast spell from book { var tokenizer = command.Tokenize(' '); var spellID = (tokenizer.MoveNext() ? Utility.ToInt32(tokenizer.Current) : 0) - 1; var serial = tokenizer.MoveNext() ? (Serial)Utility.ToUInt32(tokenizer.Current) : Serial.MinusOne; EventSink.InvokeCastSpellRequest(from, spellID, World.FindItem(serial)); break; } case 0x58: // Open door { EventSink.InvokeOpenDoorMacroUsed(from); break; } case 0x56: // Cast spell from macro { var spellID = Utility.ToInt32(command) - 1; EventSink.InvokeCastSpellRequest(from, spellID, null); break; } case 0xF4: // Invoke virtues from macro { var virtueID = Utility.ToInt32(command) - 1; EventSink.InvokeVirtueMacroRequest(from, virtueID); break; } case 0x2F: // Old scroll double click { /* * This command is still sent for items 0xEF3 - 0xEF9 * * Command is one of three, depending on the item ID of the scroll: * - [scroll serial] * - [scroll serial] [target serial] * - [scroll serial] [x] [y] [z] */ break; } default: { state.LogInfo("Unknown text-command type 0x{0:X2}: {1}", state, type, command); break; } } }