Question About Server Data

devicenulldevicenull 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

Comments

  • zebFishzebFish Join Date: 2003-08-15 Member: 19760Members
    I don't understand your question *but* if it's about converting text strings to numbers...


    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?)
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    Okay, If I wasnt clear I'm sorry lemme try again:
    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?
  • EvisceratorEviscerator Join Date: 2003-02-24 Member: 13946Members, Constellation
    Everything is going to come across to you in bytes. VB isn't exactly designed to work with binary data effeciently, but you should be able do it easily. I'm a C++ coder, so this is just a little hack from memory. It should work (?)

    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.
  • MintmanMintman Join Date: 2003-05-30 Member: 16866Members
    I believe this is what you are looking for (under the HL section if that wasn't obvious)

    <a href='http://dev.kquery.com/index.php?article=4' target='_blank'>http://dev.kquery.com/index.php?article=4</a>
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    <!--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-->
    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
  • MintmanMintman Join Date: 2003-05-30 Member: 16866Members
    edited September 2003
    Pattern matching from the returned string perhaps?

    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-->
  • Sucky_DuckySucky_Ducky Join Date: 2003-05-04 Member: 16043Members
    Omg, my head just exploded... Don't post server-code-thingy in general discussion :s
    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-->
  • taboofirestaboofires Join Date: 2002-11-24 Member: 9853Members
    The code you put up uses pretty standard methods of compressing data. If you overflowed, the problem is much more likely the data sizes in your program rather than the example.

    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.
  • EvisceratorEviscerator Join Date: 2003-02-24 Member: 13946Members, Constellation
    <!--QuoteBegin--devicenull+Sep 3 2003, 06:40 PM--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> (devicenull @ Sep 3 2003, 06:40 PM)</td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->
    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...
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    Cool, that worked really nicely..
    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
  • EvisceratorEviscerator Join Date: 2003-02-24 Member: 13946Members, Constellation
    Glad to see you got it working! What exactly is your program going to do?
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    Okay it was working
    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
  • AezayAezay Join Date: 2003-04-19 Member: 15660Members
    You made me remember, all the time I spend analyzing the data HL servers send back to me, but I finally figured it out, and wrote this little application...

    <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.
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    <!--QuoteBegin--Aezay+Sep 6 2003, 09:51 PM--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> (Aezay @ Sep 6 2003, 09:51 PM)</td></tr><tr><td id='QUOTE'><!--QuoteEBegin--> You made me remember, all the time I spend analyzing the data HL servers send back to me, but I finally figured it out, and wrote this little application...

    <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)
  • EvisceratorEviscerator Join Date: 2003-02-24 Member: 13946Members, Constellation
    edited September 2003
    <!--QuoteBegin--devicenull+Sep 8 2003, 12:44 PM--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td><b>QUOTE</b> (devicenull @ Sep 8 2003, 12:44 PM)</td></tr><tr><td id='QUOTE'><!--QuoteEBegin-->
    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-->
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    Actually I figured it out,
    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
  • EnemyWithinEnemyWithin Join Date: 2002-11-03 Member: 5572Members
    Very interesting idea. Have you tested this on large servers (20+ players)? With VB6, I had problems retrieving query data from the server if it didn't fit into the winsock buffer. It would receive the 2nd packet of data, but I would always lose some of the data at the end of the first packet. Very annoying <!--emo&:(--><img src='http://www.unknownworlds.com/forums/html/emoticons/sad.gif' border='0' style='vertical-align:middle' alt='sad.gif'><!--endemo-->
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    edited September 2003
    Yes, tried it on Guns4Back2School, 24 / 24 it worked fine... I just never went near the end of the playerlist though, lemme try it again

    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.
  • devicenulldevicenull Join Date: 2003-04-30 Member: 15967Members, NS2 Playtester, Squad Five Blue
    No suggestions?
    Come on, I know somone will come up with something good
Sign In or Register to comment.