Click to See Complete Forum and Search --> : COD4 Rcon tool udp packets issue
rush001
Apr 9th, 2010, 01:48 PM
hi everybody
this is my first post in this forum although i have been using it for my knowledge for quite some time..
I know a similar thread has been opened in this forums a long time ago but is dead atm, and i cant seem to find it too.
Anyway, i have been trying to make an Rcon tool for my clan, and i know many people have done it so it shouldnt be very hard but i am DEAD STUCK in half way....more like 75% of the way :D
COD 4 accepts only UDP connections so i made a Visual Basic prog with UDPclient. It can send the commands ok and also receives response from the server but it seems to get only upto 1302 characters of the response.
I learnt that it was due to the response being fragmented into packets and i only got one of those packets. So, how do i get around it? is there a code or any way that would let me receive all the packets? maybe a code that lets me continue receiving packets from the point where the first one got fragmented??
PLZ HELP!!:(
Shaggy Hiker
Apr 9th, 2010, 01:57 PM
With UDP, there is no guarantee that you even WILL get all the packets. The packet may have some kind of number in it that tells you that it is packet X, or packet X of N. Documentation may have something about that. Still, if you are getting one packet, then you are probably getting them all. You could show us how you do the receive, as that might tell us something.
Also, I had a couple threads on UDP over in the Networking section. One of them has 7 posts in it, the last couple of which include complete classes I am using for UDP communication. The title of the thread is not likely to be meaningful, but there aren't all that many UDP threads anyways. In that final UDP class, I had the listener running in a background thread. When a packet was received, the payload was removed, enqueued for other users (running on the UI thread), then the listener was re-started to await the next incoming message. That may be of interest to you.
rush001
Apr 9th, 2010, 02:58 PM
ok i just found a thread in this forum that talks about similar problem..same, to be honest (soz for not searching properly :P) So, i will just use the same code as he seems to be doing the same way as i did:
orts System
Imports System.Collections.Generic
Imports System.Text
Imports System.Net.Sockets
Imports System.Net
Namespace iarcon
Friend Class RCON
Public Function sendCommand(ByVal rconCommand As String, ByVal gameServerIP As String, ByVal password As String, ByVal gameServerPort As Integer) As String
On Error Resume Next
Dim client As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
client.Connect(IPAddress.Parse(gameServerIP), gameServerPort)
Dim command As String
command = "rcon " & password & " " & rconCommand
Dim bufferTemp() As Byte = Encoding.ASCII.GetBytes(command)
Dim bufferSend(bufferTemp.Length + 5 - 1) As Byte
'intial 5 characters as per standard
bufferSend(0) = Byte.Parse("255")
bufferSend(1) = Byte.Parse("255")
bufferSend(2) = Byte.Parse("255")
bufferSend(3) = Byte.Parse("255")
bufferSend(4) = Byte.Parse("02")
Dim j As Integer = 5
For i As Integer = 0 To bufferTemp.Length - 1
bufferSend(j) = bufferTemp(i)
j += 1
Next i
'send rcon command and get response
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
client.Send(bufferSend, SocketFlags.None)
'big enough to receive response
Dim bufferRec(64999) As Byte
client.Receive(bufferRec)
Return Encoding.ASCII.GetString(bufferRec)
End Function
End Class
End Namespace
if you could just add that cool :P feature (making the thread wait for second/more packets by reusing the connection) you talk about in those threads, in this code, thats good enough for me :) . so.. can you? plzzz?? :D
rush001
May 5th, 2010, 11:50 AM
Ok, i have found the solution and i am pretty sure it will be useful to anybody who's gonna try and make an RCON tool in the future so i will tell you how i solved this issue.
I learnt that its true that the message was being fragmented into different packets but i was using only one udpclient.RECEIVE which receives only one packet regardless of how many packets there are in the message queue i.e even if i did get all the packets properly, i am only retrieving one packet.
All i had to do was make more udpclient.receive for the remaining packets.
Jeremin
Jun 15th, 2010, 07:35 AM
hi rush001
as you, i am working on a rcon tool for cod4 (written in c++, but this seems to be an UDP problem) and i have the same problem.
i also tried what you say, i am able to recieve different packets with different lengths, but i dont know, when i have to stop recieving.
hope you understand what i mean, my english is really not that good :D
jeremin
rush001
Jun 17th, 2010, 10:10 AM
I have seen two ways to set a limit for receiving.
1) each slot occupies about 105 bytes. So you can stop receiving when the bytes received in one receiving is less than that.. meaning there was no data sent. If the server does send data other than the player stats like 'disconnect' or 'incorrect password', they will be less than 105 bytes too causing the receive function to stop.
2) create a loop around the receive part. Make the loop continue until the receiving process takes more than 0 seconds. This means that as long as you receive data, it will take more than 0 seconds hence continuing the loop. If you dont receive any data, the receive funtion completes at 0 seconds hence stopping the loop and completing the receive process.
I have used the second method but the first one should do the work too. The first one is a bit easier to do i think but the second one is a fail-safe :D Do tell me if you dont understand any of my explanations... my english isnt that good either :D
Jeremin
Jun 17th, 2010, 02:07 PM
i also used the second method, it was realy a fail of mine ;)
i just didnt understand what my code is doing, but now i understand it and it works how it should.
first i tried to solve it with the first method, but because, at least for me, the sizes of packets are variable, just every second packet has the lenght of 1303 characters, it fails.
and i really didnt succeed to work out the right way to find the point to stop recieving.
now, for me everything works fine, thank you :D
rush001
Jun 18th, 2010, 12:43 AM
glad to be of help. I still remember how hard it was to find any helpful source for this part...
Anyway,I have moved on upto the point where you tabulate the data. So, if you get stuck anywhere in between, maybe i can be of help..
Good Luck xD
Also wanted to add that 105 bytes is the size of ONE slot.. since you are getting datagrams for all the slots(obviously more than one), you get more than just 105 bytes but since the datagrams get fragmented every 1500 bytes(I dont know the details but thats the MTU(Maximum Transmission Unit) ), you only get about 1303 bytes at ONE time. Not too sure why its not exactly 1500 bytes that you receive at a time tho :P
SLeePYG72786
Nov 9th, 2010, 07:31 AM
I know this is kind of a dead thread, but I'm trying to do the exact same thing. There just isn't much about this on the 'net at this point, even though the game has been out for over 3 years. :sigh:
If anyone has ANY additional information about this, please please post something.
Jeremin
Nov 10th, 2010, 07:39 AM
perhaps you should say, where exactly is your problem.
in my opinion, the safest way to recieve everything, is recieving until you get a timeout by the socket. but i don't know how to solve that in VB.
(in c++, my code works fine for me, send me a message if you want to get it)
greetings
rush001
Nov 11th, 2010, 08:08 AM
yes, pointing out where exactly your problem is will make it a lot easier for both you and the helpers :D
BTW, Jeremin, have you completed your rcon tool yet?
I haven't, cause i had to stop. I was taking too much time for this tool and the clan matters needed me more than this tool :P . Also , i just kept on adding new features to the tool without actually completing the code, which made it even longer to finish.
I HAVE completed the whole thing but only on my notebook. And then i just lost interest lol
Jeremin
Nov 11th, 2010, 12:08 PM
@rush001
i released a kind of a beta, it worked quite fine and i got nice feedbacks.
i started to work on a better version with multiple servers, but now, my studies started 1,5 months ago and i had to make a break.
i hope, i will get time to work on this tool around cristmas, maybe i'm even able to include black ops ;)
PS: if you want, i can send you my beta file, but it's in german.
SLeePYG72786
Nov 11th, 2010, 03:51 PM
I downloaded the file from post #16 in this thread:
http://www.vbforums.com/showthread.php?t=518401&highlight=udpclient
My problem is trying to figure out how to close the UDPclient before I go to open another connection to a different server.
My clan has 7 CoD4 servers, with the ability to add 3 more. Right now we're using a VB6-based Rcon. It uses radio buttons to connect to each server. So we have 7 radio buttons, and when we click on one it's coded to close any open connections, then open the connection to that server, and automatically sends the "status" command as well, which then puts the output to a large multi-line text box.
EDIT > I have no idea about C++. I only have experience in VB6 and VB.Net 4 (Visual Studio 2010)
Shaggy Hiker
Nov 11th, 2010, 04:30 PM
You never have to close UDPClients because there is no connection. If you want to start listening to a different port, you may just be able to change the port. Alternatively, you could destroy the UDPClient and create another one.
SLeePYG72786
Nov 11th, 2010, 07:49 PM
My problem is getting it to even connect. I have no clue on how to get it to call the UdpClient.Connect command. If I type in:
UdpClient.
it only shows:
Equals
ReferenceEquals
Where is "connect"? How do I make it connect to a certain IP? On the MSDN site it shows it has a Connect, so why can't I use it?
I understand this isn't VB6, but dang. I've been looking everywhere, and everything either leads to a dead end or shows nothing to do with what I need. =X
rush001
Nov 12th, 2010, 03:13 AM
@rush001
PS: if you want, i can send you my beta file, but it's in german.
Although i won't be able to understand any German, I think it would be helpful if i had a look at your beta file :D
rush001
Nov 12th, 2010, 03:25 AM
My problem is getting it to even connect. I have no clue on how to get it to call the UdpClient.Connect command. If I type in:
UdpClient.
it only shows:
Equals
ReferenceEquals
Where is "connect"? How do I make it connect to a certain IP? On the MSDN site it shows it has a Connect, so why can't I use it?
I understand this isn't VB6, but dang. I've been looking everywhere, and everything either leads to a dead end or shows nothing to do with what I need. =X
If you have a look at the code on the 3rd post, on line 13:
client.Connect(IPAddress.Parse(gameServerIP), gameServerPort)
That is a typical way of creating a new (Socket) connection. You can use either UDPClient or Socket (both have slightly different syntaxes and usage methods).
As a fail safe ,use socket command. I forgot the syntax for UDPClient ;) or maybe UDPClient doesn't allow you to specify the IP and port. (?) Once again, As a fail safe ,use socket command :D
If you follow the example above(which is similar to the file you downloaded),
Just copy paste the sendcommand function (line 10) into the class RCON. you can make 7 public functions and name them sendcommand1, sendcommand2 etc each with their own IP and passes. I think that would be the easiest and safest way.
good luck :D
SLeePYG72786
Nov 14th, 2010, 12:20 AM
I've got it going now. Thanks for the help everyone.
rush001
Nov 14th, 2010, 08:48 AM
NICE !
I love it when things work :)
If you get stuck further, don't forget to ask.
Good Luck with your adventure :D
SLeePYG72786
Nov 15th, 2010, 05:39 PM
Ok, I have another issue now. When I get the response from the server in the multi-line textbox, it always shows:
????print
at the top. Is there a way to remove that?
Another question as well, which is very similar, and the solution will probably work for both questions. When I connect to a server with the "status" command, I can see the people in the server (their names, IP's, GUID, etc.), but if they're using color codes in their name (^1 , ^2 , etc.), it shows that in their name. How would I go about removing those 2 characters from the response? Like I said, I'm sure the solution will work for both of these questions.
Thanks again.
rush001
Nov 16th, 2010, 09:06 AM
This problem is not a very big one.
1) All you have to do is remove the "????print" using the following code:
Replace(STRING, "???print", "")
where STRING is the output(response from the server)
"???print" is the string you are looking for
"" means you replace the found string with "" i.e nothing/blank
2) Similarly, place 10 replace functions for each colour.
Replace(STRING, "^0", "")
Replace(STRING, "^1", "")
Replace(STRING, "^2", "")
Replace(STRING, "^3", "")
Replace(STRING, "^4", "")
Replace(STRING, "^5", "")
Replace(STRING, "^6", "")
Replace(STRING, "^7", "")
Replace(STRING, "^8", "")
Replace(STRING, "^9", "")
Note: these functions will make any number of substitutions possible. You can limit the number of substitutions too.
Replace(STRING, "string to find", "replace with", "no. of replacements")
SLeePYG72786
Nov 16th, 2010, 10:50 AM
It's still not working for me. *ugh*
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
On Error Resume Next
Dim rcon As New QuakeRcon.RCON
Dim Response As String = rcon.sendCommand("status", "IP", "Password", "Port")
'Replacing \n with \r\n so that it could be treated as Enter in text area
Response = Response.Replace(Constants.vbLf, Constants.vbCrLf)
txtResponse.Text = Response
Replace(txtResponse.Text, "???print", "")
Replace(Response, "^0", "")
Replace(Response, "^1", "")
Replace(Response, "^2", "")
Replace(Response, "^3", "")
Replace(Response, "^4", "")
Replace(Response, "^5", "")
Replace(Response, "^6", "")
Replace(Response, "^7", "")
Replace(Response, "^8", "")
Replace(Response, "^9", "")
End Sub
I don't understand....
I had tried using the replace command last night several different way, this way included, but to no avail.
=?
SLeePYG72786
Nov 16th, 2010, 11:43 AM
Response.Replace("????print", "")
Doesn't work either.....
=X
rush001
Nov 17th, 2010, 12:21 AM
I can't be too sure without seeing the whole code.
Also, what error or output do you get?
As far as i can see from your code, you haven't declared "Response"
Try that first and if that doesn't help, post the output too so that i can look at it further.
Kennix
Aug 13th, 2011, 07:46 AM
herewith some code, maybe a long time ago for the last comment in this forum, but still may be usefull:
Public Function RCON(ByVal strCommand As String)
Dim udpClient As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim strSendData As String
Dim bytSendData() As Byte
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
Dim bytReturnData(intUDPClientRecievelength) As Byte
Dim strReturnData As String
strReturnData = ""
strSendData = ""
Try
frmMain.lblStatus.Text = "Sending Data ..."
udpClient.ReceiveTimeout = intUDPClientReceiveTimeout
strSendData = Chr(255) & Chr(255) & Chr(255) & Chr(255) & "rcon " & strRconPass & " " & strCommand
bytSendData = Encoding.GetEncoding("Windows-1252").GetBytes(strSendData)
udpClient.Connect(strRconHostName, intRconPort)
udpClient.Send(bytSendData, bytSendData.Length, SocketFlags.None)
frmMain.lblStatus.Text = "Receiving Data ..."
Do
'Wait for new data to arrive, or on the timeout
udpClient.Receive(bytReturnData, SocketFlags.None)
'Convert bytes to a text string
strReturnData = strReturnData & "*" & Replace(Encoding.GetEncoding("Windows-1252").GetString(bytReturnData), Chr(0), "")
'Remove last empty line in strReturnData
strReturnData = strReturnData.TrimEnd(vbNewLine.ToArray)
'Clearing bytReturnData
ReDim bytReturnData(intUDPClientRecievelength)
'Wait a specific amount of time to allow new data being send and received
Call Wait(intUDPClientSendDelay)
Loop
Catch Err As Net.Sockets.SocketException
'timeout error
If 10060 = Err.ErrorCode Then
'Replacing LineFeeds with CarrierReturnLineFeeds
strReturnData = Replace(strReturnData, vbLf, vbCrLf)
'Check on if any data has arrived
If strReturnData Is Nothing Then
strReturnData = "No data returned from server"
Else
'Removing ˙˙˙˙print
strReturnData = Replace(strReturnData, "˙˙˙˙print" & vbCrLf, "")
'if not more than ˙˙˙˙print is returned, but command is executed
strReturnData = Replace(strReturnData, "˙˙˙˙print", "Command received by server")
'Removing color codes
strReturnData = Replace(strReturnData, "^0", "")
strReturnData = Replace(strReturnData, "^1", "")
strReturnData = Replace(strReturnData, "^2", "")
strReturnData = Replace(strReturnData, "^3", "")
strReturnData = Replace(strReturnData, "^4", "")
strReturnData = Replace(strReturnData, "^5", "")
strReturnData = Replace(strReturnData, "^6", "")
strReturnData = Replace(strReturnData, "^7", "")
strReturnData = Replace(strReturnData, "^8", "")
strReturnData = Replace(strReturnData, "^9", "")
End If
Else
MsgBox("Error Code: " & Err.ErrorCode & " Error Description: " & Err.Message)
End If
End Try
'Close Socket
udpClient.Close()
frmMain.lblStatus.Text = "Data transfer Finished"
RCON = strCommand & vbCrLf & strReturnData
Call TextOutputToLog(RCON)
End Function
please note the & "*" & in the do loop above
at that location i am joining to udp sets of data together. However, i am losing 1 sign all the time. But cannot find the reason for that.
13-8-2011 14:18:13
status
*map: mp_toujane
num score ping guid name lastmsg address qport rate
--- ----- ---- ------ --------------- ------- --------------------- ----- -----
0 0 63 0 Gallier-Kennix 0 81.71.$$$.33:-1964 1500 25000
4 0 CNCT 0 Rune 76750 81.71.$$$.33:-15867 27752 1500
5 0 CNCT 0 Rune 73950 81.71.$$$.33:-15731 28520 1500
7 0 CNCT 0 Rune 70550 81.71.$$$.33:-15780 29544 1500
8 0 CNCT 0 Rune 67500 81.71.$$$.33:-15729 30056 1500
10 0 CNCT 0 Senne 46400 81.71.$$$.33:-15741 6250 1500
11 0 CNCT 0 Senne 45800 81.71.$$$.33:-15726 6506 1500
12 43 53 0 G.I.O. 0 88.78.56.$$$:28962 2706 25000
13 13 118 0 Mirotvorac 0 93.141.2.$$$:-13539 9477 25000
14 0 999 0 Sibe 0 89.204.83.$$$:28960 1866 5000
16 55 75 0 Chapaev 0 94.228.$$$.140:28960 3419 25000
17 40 73 0 Noob number: 455<DUPE> 0 89.$$$.91.21:28960 1492 25000
18 0 32 0 ~~~~ 0 192.$$$.1.24:28960 2109 5000
19 7 78 0 *1|Feca 0 145.236.$$$.80:28960 3866 25000
20 38 53 0 metaldemon 0 81.$$$.66.53:28960 3067 25000
13-8-2011 14:18:25
status
No data returned from server
13-8-2011 14:18:37
status
*map: mp_toujane
num score ping guid name lastmsg address qport rate
--- ----- ---- ------ --------------- ------- --------------------- ----- -----
0 0 53 0 Gallier-Kennix 0 81.71.109.33:-1964 1500 25000
1 0 CNCT 0 Kobe 20450 81.71.$$$.33:-15782 28008 1500
2 0 CNCT 0 Kobe 17700 81.71.$$$.33:-15719 28776 1500
3 0 CNCT 0 Kobe 9800 81.71.$$$.33:-15744 29800 1500
4 0 CNCT 0 Rune 100850 81.71.$$$.33:-15867 27752 1500
5 0 CNCT 0 Rune 98050 81.71.$$$.33:-15731 28520 1500
6 0 CNCT 0 Kobe 8050 81.71.$$$.33:-15717 30312 1500
7 0 CNCT 0 Rune 94650 81.71.$$$.33:-15780 29544 1500
8 0 CNCT 0 Rune 91600 81.71.$$$.33:-15729 30056 1500
10 0 CNCT 0 Senne 70500 81.71.$$$.33:-15741 6250 1500
11 0 CNCT 0 Senne 69900 81.71.$$$.33:-15726 6506 1500
12 43 50 0 G.I.O. 0 88.78.56.$$$:28962 2706 25000
13 13 120 0 Mirotvorac 0 93.141.2.$$$:-13539 9477 25000
14 0 999 0 Sibe *6350 89.204.83.$$$:28960 1866 5000
16 56 70 0 Chapaev 0 94.228.201.$$$:28960 3419 25000
17 40 74 0 Noob number: 455<DUPE> 0 89.$$$.91.21:28960 1492 25000
18 0 32 0 ~~~~ 0 192.168.1.24:28960 2109 5000
19 7 83 0 |Feca 0 145.236.$$$.80:28960 3866 25000
20 39 51 0 metaldemon 0 81.$$$.66.53:28960 3067 25000
maybe someone that knows the trick? i have noticed this also in an other vb6 program written by someone else
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.