Imports System.IO Imports System.Net Imports System.Net.Sockets Namespace Query Class RCONQuery Private qSocket As Socket Private address As IPAddress Private _port As Integer = 0 Private _password As String = Nothing Private results As String() = New String(49) {} Private _count As Integer = 0 Public Sub New(IP As String, port As Integer, password As String) qSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) qSocket.SendTimeout = 5000 qSocket.ReceiveTimeout = 5000 Try address = Dns.GetHostAddresses(IP)(0) Catch End Try _port = port _password = password End Sub Public Function Send(command As String) As Boolean Try Dim endpoint As New IPEndPoint(address, _port) Using stream As New MemoryStream() Using writer As New BinaryWriter(stream) writer.Write("SAMP".ToCharArray()) Dim SplitIP As String() = address.ToString().Split("."C) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(0)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(1)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(2)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(3)))) writer.Write(CUShort(_port)) writer.Write("x"C) writer.Write(CUShort(_password.Length)) writer.Write(_password.ToCharArray()) writer.Write(CUShort(command.Length)) writer.Write(command.ToCharArray()) End Using If qSocket.SendTo(stream.ToArray(), endpoint) > 0 Then Return True End If End Using Catch Return False End Try Return False End Function Public Function Rceive() As Integer Try For i As Integer = 0 To results.GetLength(0) - 1 results.SetValue(Nothing, i) Next _count = 0 Dim endpoint As EndPoint = New IPEndPoint(address, _port) Dim rBuffer As Byte() = New Byte(499) {} Dim count As Integer = qSocket.ReceiveFrom(rBuffer, endpoint) Using stream As New MemoryStream(rBuffer) Using reader As New BinaryReader(stream) If stream.Length <= 11 Then Return _count End If reader.ReadBytes(11) Dim len As Short Try While (InlineAssignHelper(len, reader.ReadInt16())) <> 0 results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(Convert.ToInt32(len))) End While Catch Return _count End Try End Using End Using Catch Return _count End Try Return _count End Function Public Function Store(count As Integer) As String() Dim rString As String() = New String(count - 1) {} Dim i As Integer = 0 While i < count AndAlso i < _count rString(i) = results(i) i += 1 End While _count = 0 Return rString End Function Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T target = value Return value End Function End Class Class Query Private qSocket As Socket Private address As IPAddress Private _port As Integer = 0 Private results As String() Private _count As Integer = 0 Private timestamp As DateTime() = New DateTime(1) {} Public Sub New(IP As String, port As Integer) qSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) qSocket.SendTimeout = 5000 qSocket.ReceiveTimeout = 5000 Try address = Dns.GetHostAddresses(IP)(0) Catch End Try _port = port End Sub Public Function Send(opcode As Char) As Boolean Try Dim endpoint As EndPoint = New IPEndPoint(address, _port) Using stream As New MemoryStream() Using writer As New BinaryWriter(stream) writer.Write("SAMP".ToCharArray()) Dim SplitIP As String() = address.ToString().Split("."C) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(0)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(1)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(2)))) writer.Write(Convert.ToByte(Convert.ToInt32(SplitIP(3)))) writer.Write(CUShort(_port)) writer.Write(opcode) If opcode = "p"C Then writer.Write("8493".ToCharArray()) End If timestamp(0) = DateTime.Now End Using If qSocket.SendTo(stream.ToArray(), endpoint) > 0 Then Return True End If End Using Catch Return False End Try Return False End Function Public Function Receive() As Integer Try _count = 0 Dim endpoint As EndPoint = New IPEndPoint(address, _port) Dim rBuffer As Byte() = New Byte(3401) {} qSocket.ReceiveFrom(rBuffer, endpoint) timestamp(1) = DateTime.Now Using stream As New MemoryStream(rBuffer) Using reader As New BinaryReader(stream) If stream.Length <= 10 Then Return _count End If reader.ReadBytes(10) Select Case reader.ReadChar() Case "i"C ' Information If True Then results = New String(5) {} results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadByte()) results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadInt16()) results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadInt16()) Dim hostnamelen As Integer = reader.ReadInt32() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(hostnamelen)) Dim gamemodelen As Integer = reader.ReadInt32() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(gamemodelen)) Dim mapnamelen As Integer = reader.ReadInt32() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(mapnamelen)) Return _count End If Case "r"C ' Rules If True Then Dim rulecount As Integer = reader.ReadInt16() results = New String(rulecount * 2 - 1) {} For i As Integer = 0 To rulecount - 1 Dim rulelen As Integer = reader.ReadByte() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(rulelen)) Dim valuelen As Integer = reader.ReadByte() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(valuelen)) Next Return _count End If Case "c"C ' Client list If True Then Dim playercount As Integer = reader.ReadInt16() results = New String(playercount * 2 - 1) {} For i As Integer = 0 To playercount - 1 Dim namelen As Integer = reader.ReadByte() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(namelen)) results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadInt32()) Next Return _count End If Case "d"C ' Detailed player information If True Then Dim playercount As Integer = reader.ReadInt16() results = New String(playercount * 4 - 1) {} For i As Integer = 0 To playercount - 1 results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadByte()) Dim namelen As Integer = reader.ReadByte() results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = New String(reader.ReadChars(namelen)) results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadInt32()) results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = Convert.ToString(reader.ReadInt32()) Next Return _count End If Case "p"C ' Ping If True Then results = New String(0) {} results(System.Math.Max(System.Threading.Interlocked.Increment(_count),_count - 1)) = timestamp(1).Subtract(timestamp(0)).Milliseconds.ToString() Return _count End If Case Else Return _count End Select End Using End Using Catch Return _count End Try End Function Public Function Store(count As Integer) As String() Dim rString As String() = New String(count - 1) {} Dim i As Integer = 0 While i < count AndAlso i < _count rString(i) = results(i) i += 1 End While _count = 0 Return rString End Function End Class End Namespace