Question About Server Data
devicenull
Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
(I'm guessing I will come back and find this moved, but I dunno where it will go)
Okay, I am trying to get server player info from HL servers in VB.
I've got it mostly figured out, but I have to figure out the difference between total frags and time on server.
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
°= 176
£= 163
X= 88
E= 69 <!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
That is what I have, the number on the right is the ASCII # of the char..
Somehow this should be the time on the server and frags.
from the SDK, on server info:
<!--QuoteBegin--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->"players"
Server responds with the following packet:
(int32) -1
(byte) ASCII 'D' (players response, S2A_PLAYER)
(byte) active client count
for each active client
(byte) client number / index
(string) player name
(int32) client's frag total
(float32) client's total time in-game<!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->
So how do I get the difference between frag and in game time?
How are they sent..
The player was on for about 50m:50s (time is about for seconds)
The player had 0 score at the time (this is all what hlla told me)
Please DO NOT reply if you are just saying, use another program, such as ASE or .hlla, I dont want to, so dont bother
Okay, I am trying to get server player info from HL servers in VB.
I've got it mostly figured out, but I have to figure out the difference between total frags and time on server.
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
°= 176
£= 163
X= 88
E= 69 <!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
That is what I have, the number on the right is the ASCII # of the char..
Somehow this should be the time on the server and frags.
from the SDK, on server info:
<!--QuoteBegin--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> </td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->"players"
Server responds with the following packet:
(int32) -1
(byte) ASCII 'D' (players response, S2A_PLAYER)
(byte) active client count
for each active client
(byte) client number / index
(string) player name
(int32) client's frag total
(float32) client's total time in-game<!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->
So how do I get the difference between frag and in game time?
How are they sent..
The player was on for about 50m:50s (time is about for seconds)
The player had 0 score at the time (this is all what hlla told me)
Please DO NOT reply if you are just saying, use another program, such as ASE or .hlla, I dont want to, so dont bother
Comments
Can't you simply cast the string to the proper type? For instace, use Cint(left$(Number,0,2)) then cdbl(mid$(Number,5,8))
If not you can convert manually,,, To convert from number to text, simply use (256^3)* right-most digit + (256^2) * ASCII code of next digit + 256 * ascii value of next digit + last digit
So for instance ABCD would be 1094861636
For doubles: do same but use eight digits, and divide result by 1000 (maybe?)
the part after Code: is what the server sends in response to the command to get players.
I have figured out most of it, just 2 things confuse me.
<b>How do I get the time online?
How do I get the total frags?</b>
Both should be in the Code: section, I just cannot decode them.
-----
(Not in any way related to my question, reply to above)
If I was converting text to numbers I would use this:
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
Redim preserve numstring(1 to Len(textstring))
For i = 1 to Len(textstring)
numstring(i) = Asc(Mid(textstring,1,i))
Next i
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
Wouldnt that work easier?
Take the very first byte after the string representing the players name, and treat it like you treat any other byte... the right portion in your CODE section. Get that ASCII value and store it in a variable, and call that variable Total. Take the next byte after that, and convert it into the ASCII decimal value. Don't overwrite your variable Total yet, just store it in another temp variable. Now take this temp variable and multiply it by 256. Add the product of that to your variable Total. Take the next byte after that and do the same thing except multiply by the temp variable 65536. Finally take the fourth byte and do the same thing except multiply by 16777216. The value in Total (the true int32 value of those four bytes) is going to be your frag total.
So in pseudoish code.... fragtotal = asc(byte1) + asc(byte2) * 256 + asc(byte3) * 65536 + asc(byte4) * 16777216
I'm sure there's a much easier and cleaner way to do this in VB, but I've never seriously used that language. Floats are a little weirder, and I'd have to do some experimentation to get the right code for it, but this should get you going hopefully.
<a href='http://dev.kquery.com/index.php?article=4' target='_blank'>http://dev.kquery.com/index.php?article=4</a>
dataminushead = Right(datavar, Len(datavar) - 5)
totalplayers = Asc(Left(dataminushead, 1))
dataminushead = Right(datavar, Len(datavar) - 1)
ReDim Preserve Players(1 To totalplayers)
For a = 1 To totalplayers
Players(a).cnum = Asc(Left(dataminushead, 1))
Players(a).pname = Mid(dataminushead, 2, 12)
Players(a).frags = Mid(dataminushead, 13, 3)
Players(a).intime = Mid(dataminushead, 16, 1)
dataminushead = Right(dataminushead, 17)
temp1 = Asc(Mid(Players(a).frags, 1, 1))
temp2 = Asc(Mid(Players(a).frags, 2, 1)) * 256
temp3 = Asc(Mid(Players(a).frags, 3, 1)) * 65536
temp4 = Asc(Mid(Players(a).frags, 4, 1)) * 16777216
Players(a).frag = temp1 * temp2 * temp3 * temp4
Next a<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
That dosent work, it gives overflow errors, should those be other numbers?
Does that seem like what you meant?
dataminushead is the full string minus the header..
Now a really stupid question,
You know how most server browsers have a list box with multiple collumns.. how do I do that in vb..
That kquery site was close, but I need to know how to get the chars from chars to an actual number
The guy who makes KQuery <b>may</b> be able to help you, he's often in #kquery on irc.hashnet.org, his name's K
Edit: He's often v. busy so don't hassle him, just ask nicely <!--emo&:)--><img src='http://www.unknownworlds.com/forums/html/emoticons/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif'><!--endemo-->
I cannot understand, I must not... NOOOOOOOOOOOO <!--emo&:D--><img src='http://www.unknownworlds.com/forums/html/emoticons/biggrin.gif' border='0' style='vertical-align:middle' alt='biggrin.gif'><!--endemo-->
Ugh, vb. I'd rather use java. Doing strange UI things in either usually involves either faking it or getting a newer version of vb.
That dosent work, it gives overflow errors, should those be other numbers?
Does that seem like what you meant?
dataminushead is the full string minus the header..
Now a really stupid question,
You know how most server browsers have a list box with multiple collumns.. how do I do that in vb..
<!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->
This line is your problem:
Players(a).frag = temp1 * temp2 * temp3 * temp4
Change it to:
Players(a).frag = temp1 + temp2 + temp3 + temp4
Also, this section:
dataminushead = Right(datavar, Len(datavar) - 5)
totalplayers = Asc(Left(dataminushead, 1))
dataminushead = Right(datavar, Len(datavar) - 1)
Doesn't seem correct. You are moving back into the initial int32 value when you do that. I believe the second dataminushead assignment should be like so:
dataminushead = Right( dataminushead, Len(dataminushead) - 1)
This will remove the first byte from your data buffer (the total player count) which is I believe what you're trying to do.
I do not believe player names are of fixed length. Thus, you cannot assume anything about the length of the player's name. If I recall correctly, the HL server will send over a player's name as a NULL-terminated sequence of characters. This means the buffer will indicate when the string has finished by sending a single byte with an ASCII value of zero (0.) You're currently assuming the player's name will be 12 bytes... definitely not good. Here's some new code for that entire section, with the aforementioned changes:
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
dim iPosition
dataminushead = Right(datavar, Len(datavar) - 5)
totalplayers = Asc(Left(dataminushead, 1))
dataminushead = Right( dataminushead, Len(dataminushead) - 1)
ReDim Preserve Players(1 To totalplayers)
iPosition = 1 ' Start
For a = 1 To totalplayers
Players(a).cnum = Asc(Mid(dataminushead, iPosition, 1))
iPosition = iPosition + 1
' Keep looping until you find the NULL terminator
while( Asc(Mid(dataminushead, iPosition, 1)) <> 0 )
Players(a).pname = Players(a).pname + Mid(dataminushead, iPosition, 1)
iPosition = iPosition + 1
wend
iPosition = iPosition + 1 ' Move past the NULL character
Players(a).frags = Mid(dataminushead, iPosition, 4) ' Note the change here!
iPosition = iPosition + 4
Players(a).intime = Mid(dataminushead, iPosition, 4) 'Note the change here!
iPosition = iPosition + 4
temp1 = Asc(Mid(Players(a).frags, 1, 1))
temp2 = Asc(Mid(Players(a).frags, 2, 1)) * 256
temp3 = Asc(Mid(Players(a).frags, 3, 1)) * 65536
temp4 = Asc(Mid(Players(a).frags, 4, 1)) * 16777216
Players(a).frag = temp1 + temp2 + temp3 + temp4
' Note.... do not do anything with dataminushead at this point... let iPosition be your guide
next a
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
In terms of the data you'll be receiving from HLDS, note that int32 and float32 values are 4 bytes in length. This is fixed and unchanging. Strings, however, have an undefined length. You cannot do anything to determine their length automatically, you must iterate through the buffer until you find the terminating character. Make no assumption about how many or how few bytes you'll receive. This should apply to each and every string you encounter when deciphering the various packets you'll receive back from HLDS.
Let me know how this goes...
I actually understand what you did there too, and it makes more sense then what I was doing.
I have almost finished what I was doing..I will upload the compiled exe and source when I get it done.
I also discovered that parts of my code were horrible, its working nice now, THX
Now, it seems that if the player has above 3 frags, I get overflow errors :/
This hasent been a problem up until now, when the people i was testing it on actually had a posistive score.
As to what this is doing:
I am taking the player info, and writing it to my commandmenu file..
this way, I can kick/gag/llama people without opening my console
BTW:
Is there an easier way to do this:
"1" "Kick" "admin_kick player" <-- to a file
I use this:
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
Print #2, Chr(quoteasc) & "1" & Chr(quoteasc) & " " & Chr(quoteasc) & "Kick" & Chr(quoteasc) & " " & Chr(quoteasc) & "admin_kick " & playername & Chr(quoteasc)
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
Ugh:
VB strips all the quotation marks from the file.. Any way to avoid this?
I open the files for Input/Output FYI
<a href='http://aezay.dk/aezay/other/HLLoader/' target='_blank'>Half-Life Loader</a>
As the title say, it's more of a loader for Half-Life, but it can also query servers for their current status, well... at least some servers, cant get it to work on all servers, dont know why.
<a href='http://aezay.dk/aezay/other/HLLoader/' target='_blank'>Half-Life Loader</a>
As the title say, it's more of a loader for Half-Life, but it can also query servers for their current status, well... at least some servers, cant get it to work on all servers, dont know why. <!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->
Um, you know there is a file in the HL sdk about getting info from the servers?
If you didnt, and you want it, tell me
Anyone know how to make vb not be a pain?
(With this file stuff)
Anyone know how to make vb not be a pain?
(With this file stuff) <!--QuoteEnd--></td></tr></table><span class='postcolor'><!--QuoteEEnd-->
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
if( language = VB ) then
GiveUpHope()
end if
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
I used "Line Input" instead of "Input"
I am now making it so it looks nice, and so you can change everything I hardcoded for the various stuff
Anyway, what it does is this:
Every x seconds, it querys the server about the players,
then, if it has the data it needs, it opens a file "pwcommandmenu.txt", at the same time the file "commandmenu.txt" is opened in the same directory..
It reads through "pwcommandmenu.txt" untill it finds the line "//COMMAND: PLAYER INFO"
It then writes all the player data to commandmenu.txt, like this:
<!--c1--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>CODE</b> </td></tr><tr><td id='CODE'><!--ec1-->
"2" "Manwe"
{
"1" "Kick" "admin_kick Manwe"
"2" "Llama" "admin_llama Manwe"
"3" "Unllama" "admin_unllama Manwe"
"4" "Gag" "admin_gag 0 Manwe"
"5" "Ungag" "admin_ungag Manwe"
}
<!--c2--></td></tr></table><span class='postcolor'><!--ec2-->
So that when you open your commandmenu in NS, you have the option to preform various commands without opening your console..
Possibly I may add the option to choose what commands you want, but that will be later, after everything is working nicely.
Edit: Here we go:
Source: <a href='http://pages.cthome.net/useless/server_src.zip' target='_blank'>server_src.zip</a> MD5:
19410004c98d81173f9336e5fe59fdb9 *server_src.zip
Exe: <a href='http://pages.cthome.net/useless/server_exe.zip' target='_blank'>server_exe.zip</a> MD5: af0a9616a067939f67497ae034408b67 *server_exe.zip
It was created in VB 5, requires mswinsock.dll, lemme know if you need it
Should be no problems, it even strips off [No C-D] and [Old C-D] tags
Updated v1.0.1 Fixed minor bug
Edit: It worked fine <!--emo&:)--><img src='http://www.unknownworlds.com/forums/html/emoticons/smile.gif' border='0' style='vertical-align:middle' alt='smile.gif'><!--endemo-->
Any comments/suggestions for this?
I want to get the serverlist working, but that will wait until I get more data from the server.
Come on, I know somone will come up with something good