This is the connection code:
Private Sub cmdConn_Click()
If cmdConn.Caption = "Connect" Then
AddC vbWhite, "Connecting to port " & bnetport & " at the " & bnetserver & " server..."
BNET.Connect bnetserver, bnetport
cmdConn.Caption = "Disconnect"
Else
cmdConn.Caption = "Connect"
BNETDiscReq = True
AddC vbWhite, "Disconnected."
BNET.Close
End If
End Sub
Private Sub BNET_Connect()
AddC vbWhite, "Connected!"
AddC vbWhite, "Initating packetage..."
P0x01
P0x50
End Sub
This is the 0x01 packet code:
Public Sub P0x01()
AddC vbWhite, "Notifying server of emulation..."
DMBot.BNET.SendData Chr(&H1) 'Send 0x01 packet
AddC vbWhite, "0x01 protocol packet sent."
AddC vbWhite, "Server notification done."
End Sub
This is the 0x51 packet code:
Public Sub P0x50()
AddC vbWhite, "Assembling 0x50 Protocol packet..."
With PacketBuf
.InsertDWORD &H0 'This can be left as 0.
.InsertNonNTString "68XI" & bnetclient 'Intel x86, client abrv
.InsertDWORD &HCD
'Verbyte, changes with product upgrade.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertNTString "USA" 'Abbrev. of country
.InsertNTString "United States" 'Name of country
.SendPacket DMBot.BNET, &H50 'Send 0x50 packet
End With
AddC vbWhite, "0x50 SID_AUTH_INFO packet sent."
End Sub
This is the DataArrival code:
Private Sub bnet_DataArrival(ByVal bytesTotal As Long)
Static PktBuff As String 'Packet Buffer
Dim Incoming As String
Dim PacketLength As Long
BNET.GetData Incoming, vbString
PktBuff = PktBuff & Incoming
AddC vbWhite, "Data recieved."
AddC vbWhite, "Dumping packet..."
AddC vbGreen, PktBuff
AddC vbWhite, "End of packet dump."
End Sub
This is the BNET socket close code:
Private Sub BNET_Close()
If BNETDiscReq = True Then
AddC vbRed, "Local Disconnect Confirmation."
Else
AddC vbRed, "Server aborted connection!"
End If
End Sub
And this is what the bot outputs to the textbox:
DMBot activated at [9/10/2005 7:45:43 PM] .
Loading configuration...
Username: Kyro[DM]
Password: ********
CDKey: *************
Client: Starcraft: Brood War
Client VerByte: CD
BNET Server: useast.battle.net
BNET Port: 6112
BNET Default Channel: op Kyro[DM]
Config loaded.
Connecting to port 6112 at the useast.battle.net server...
Connected!
Initating packetage...
Notifying server of emulation...
0x01 protocol packet sent.
Server notification done.
Assembling 0x50 Protocol packet...
0x50 SID_AUTH_INFO packet sent.
Server aborted connection!
I'm using Dark Minion's PacketBuffer class to handle the assemblage of packets. If you'd like to see the code to that as well, please let me know.
As you can see from above, just after I send the 0x50 packet, the server does a hard abort without responding to the packet whatsoever. I can only assume I made a mistake in the 0x50 packet structure, but I'm not sure since the BNET Docs show that the structure is correct:
Quote(DWORD) Protocol ID (0)
(DWORD) Platform ID
(DWORD) Product ID
(DWORD) Version Byte
(DWORD) Product language
(DWORD) Local IP for NAT compatibility*
(DWORD) Time zone bias*
(DWORD) Locale ID*
(DWORD) Language ID*
(STRING) Country abreviation
(STRING) Country
Any input, suggestions, and ideas would be appreciated! Thanks in advance for any help given, or if not that, for at least reading this!
Take care!
[Edit: Corrected typos, moved a question to separate topic, modified subject of this topic]
WoW, most of that is useless. And you forgot to post the 1 thing that matters.
.InsertNonNTString "68XI" & bnetclient 'Intel x86, client abrv
That should actually be 2 lines.
.InsertDWORD &H49583836 'IX86
.InsertDWORD &H53455850 'SEXP
0x52535441 = STAR
Considering everything in your packet is hard coded.. it seems that your 'bnetclient' is a fault. Also Start handeling DWORDs as DWORDs not "NonNTString"s
~-~(HDX)~-~
That solution works- the server doesn't disconnect this time.
QuoteAnd you forgot to post the 1 thing that matters.
What do you mean by that? What did I forget to post?
[Edit: Figured out how HdxBmx27 got the hex values, and removed the question regarding it.]
I asked initially how you knew STAR and SEXP was those hex values-- then I decided to see if I could figure out how you knew it. I did some experimenting, and converted each character of SEXP into hex, and got this:
53 45 58 50
S E X P
So now I get how to know what to put in for it. But how would I make it so that it's not hard coded? I tried doing this:
.InsertDWORD StrToHex("IX86")
.InsertDWORD StrToHex(bnetclient)
.InsertDWORD StrToHex(VerByte)
In this case, bnetclient's value is "SEXP" and VerByte's value is "CD".
Here's the StrToHex function-- I cannot take credit for this function-- R.A.B.B.I.T. coded this function:
Public Function StrToHex(ByVal string1 As String) As String
Dim strTemp As String, strReturn As String, i As Long
For i = 1 To Len(string1)
strTemp = Hex(Asc(Mid(string1, i, 1)))
If Len(strTemp) = 1 Then strTemp = "0" & strTemp
strReturn = strReturn & " " & strTemp
Next i
StrToHex = strReturn
End Function
You say everything is hard-coded- how so? So far, I've been trying to keep it soft-coded, but I'm always open to constructive criticism-- so if you have more information on that, it'd be appreciated.
Also, what's the best way to handle DataArrivals? IIRC, the packets can be separated by popping all incoming data into buffer, and passing packet along to a parser upon getting FF, and that the two bits next to FF is the length of the packet, although AFAIK, wouldn't it be easier to just wait til next FF, and then parse, instead of check to see if the buffer has reached that length and pass it along to parser?
Also, I'd like to apologize in advance if I seem dense- it's my first time coding a binary bot-- once again, thanks in advance for the advice!!! :-)
Hard-coded = the value dont change. meaning your setting everything to 0 insted of taking the time to find out the correct values. This can be done easily with a few APi calls.
And I was refering to the content of bnetclient vareable.
And reading all the reply, ifbnetclient = "SEXP" when you were trying to ad it in the 1st place, then thats the problem.
as for the code you posted, theres a few problems. InsertDWORD() is passed a numeric value, not a string, Witch StrtoHex() outputs.
So the correct way of doing it would be:
.InsertDWORD Val("&H" & Replace(StrToHex("IX86"), Space(1), vbNullString))
.InsertDWORD Val("&H" & Replace(StrToHex(bnetclient), Space(1), vbNullString))
.InsertDWORD Val("&H" & VerByte)
That would output the correct information. What you do is convert it to hex, remove the spaces, and get the numeric value of the hex string.
~-~(HDX)~-~
Public Sub P0x50()
AddC vbWhite, "Assembling 0x50 Protocol packet..."
With PacketBuf
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD CLng("&H" & Replace(StrToHex("IX86"), " ", "")) 'IX86
.InsertDWORD CLng("&H" & Replace(StrToHex(bnetclient), " ", "")) 'SEXP
.InsertDWORD CLng("&H" & VerByte)
'Verbyte, changes with product upgrade.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD &H0 'This can be left as 0.
.InsertNTString "USA" 'Abbrev. of country
.InsertNTString "United States" 'Name of country
.SendPacket DMBot.BNET, &H50 'Send 0x50 packet
End With
AddC vbWhite, "0x50 SID_AUTH_INFO packet sent."
End Sub
Like that? And where can I find the information on those APIs you're referring to, if you're willing to say? If you're not willing to refer me to the API information, what keywords should I use for google to find it myself? I put those at null because I assumed they were not needed- what uses are there for those, if any? Thanks for the such prompt response!
theres a reason I used "Val" insed to "CLng"
also here are some APIs that are used to get most of the information for the packet (Google for there declarations)
GetLocaleInfoA 'Used to get Country abbrv & full name.
GetSystemTime 'Used to get TimeZone Bias
SystemTimeToFileTime 'Used to get TimeZone Bias
GetLocalTime 'Used to get TimeZone Bias
GetUserDefaultLCID 'Locale ID
GetUserDefaultLangID 'Language ID
You can get the local IP by using the .LocalIP property of your winsock.
And the reasons it's good to get the information is cuz it more-accuratly emulates the client. Also the country determnins what channels the bot starts in, and the timezone bias effect a few things that the server sends you.
~-~(HDX)~-~
You say there's a reason you used Val instead of CLng-- what's the reason if I may ask?
Also, does any of the following require a specific format:
(DWORD) Product language
(DWORD) Local IP for NAT compatibility*
(DWORD) Time zone bias*
(DWORD) Locale ID*
(DWORD) Language ID*
For example, can I just do:
.InsertDWORD BNET.LocalIP 'Where BNET is the winsocket
Or does it need to be in a specific format?
Also what can I do about product language? Or do I leave that one at null since it's optional? The help you've been giving is most excellent and also very useful, thank you!!!
Nvm, Clng works.. I thoguht it caused an error when passed a string. But ti dosent matter.
As for spacific format. the IP has to be in network byte order.
AE each section of the ip address is a char. EXA: 198.0.0.1 = Chr(198) & Chr(0) & chr(0) & chr(1)
The timeZone Bias is in munites not hrs. EXA WST (-8, My time zone) would be -480.
everything else is regular. You can basically pass it directly from the API to the InsertDWORD.
Also, I havent found a way to get the product language. But unless your client is being used in GreatBrittin, it will always be "USeg" (Great Britin is "GBeg")
~-~(HDX)~-~
It took me a while to figure it out, but I managed to write a function on my own to convert an ip address to network byte order as you described... The function works pretty good... If there's a way to improve the function, I'm open to suggestions.
'Converts an IP address to network byte order.
Public Function IP2NBO(IpAddress As String)
Dim Section(3) As String
Section(0) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
IpAddress = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
Section(1) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
IpAddress = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
Section(2) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
Section(3) = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
IP2NBO = Chr(Section(0)) & Chr(Section(1)) & Chr(Section(2)) & Chr(Section(3))
End Function
I also managed to obtain a function from ALLAPI.NET that'd pull up information such as LOCALE_SENGCOUNTRY- credit goes to them for the function:
Public Function GetInfo(ByVal lInfo As Long) As String
Dim Buffer As String, Ret As String
Buffer = String$(256, 0)
Ret = GetLocaleInfo(LOCALE_USER_DEFAULT, lInfo, Buffer, Len(Buffer))
If Ret > 0 Then
GetInfo = Left$(Buffer, Ret - 1)
Else
GetInfo = ""
End If
End Function
And here's the 0x50 code I have figured out so far:
With PacketBuf
.InsertDWORD &H0 'This can be left as 0.
.InsertDWORD CLng("&H" & Replace(StrToHex("IX86"), " ", vbNullString)) 'IX86
.InsertDWORD CLng("&H" & Replace(StrToHex(bnetclient), " ", vbNullString)) 'SEXP
.InsertDWORD CLng("&H" & VerByte) 'Verbyte, changes with product upgrade.
.InsertDWORD &H0 'Product Language
.InsertDWORD CLng("&H" & Replace(StrToHex(IP2NBO(DM.BNET.LocalIP)), " ", vbNullString)) 'Local IP for NAT compatibility
.InsertDWORD &H0 'Time Zone bias
.InsertDWORD GetUserDefaultLCID() 'Locale ID
.InsertDWORD GetUserDefaultLangID 'Language ID
.InsertNTString GetInfo(LOCALE_SABBREVCTRYNAME) 'Abbrev. of country
.InsertNTString GetInfo(LOCALE_SENGCOUNTRY) 'Name of country
.SendPacket DMBot.BNET, &H50 'Send 0x50 packet
End With
Took me quite a while to get this far, but I'd have never had gotten this far without your help! Thanks! If you don't mind elaborating a bit more info, it'd be very much appreciated.
I've been struggling at the time zone bias, and I still can't understand how to implement that one. It involves three API's, and in spite of this following information:
QuoteTimezone bias
The difference, in minutes, between UTC and local time. The client calculates this value by subtracting the Local Time from the System Time, having converted both to Filetime structures, and then converting the resultant offset to minutes by diving it by 600,000,000. If you wish to understand the mechanism involved, read Microsoft's documentation on File times.
I still can't figure out how to implement it. I did manage to get the API declarations for those three APIs:
Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long
Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
But that's as far as I got. I couldn't understand how exactly to perform the described operation...
As for the Product Language, do I just do:
.InsertDWORD CLng("&H" & Replace(StrToHex("USeg"), " ", vbNullString)) 'Product Language
Or does that need to be done another way?
Also, there's a problem with the LocalIP variable-- while it does contain the correct IP-- it contains the computer's IP, not my actual IP. You see, my computer is part of a network, there's two devices connected to my network; my laptop, and my videophone. The router holds the actual public IP, and assigns private IPs to devices that connect to the network. Will this be a problem? If so, is there a way to get around this problem?
[Edit: Cleaned up code]
@ your IP2BO function.. You could jsut use split.. Insted of lots of mid() calls
@ your current 0x50 sub, Looking good. More detailed then most bots out there.
As always jsut ask what you want me to elaborate on and I will.
@ TimeZone. I forgot to mention youll need the API CopyMemory
What you need to do is use GetSystemTime to get the UTC time. Then use SystemTimeToFileTime to convert to a file time, then use copymemory to copy the filetime struct to a long, remember that filetime struct is 2 longs so use 8 for the number of bytes (Long=4, 4*2=8)
Do the same thing for GetLocalTime. Then use the below UnsignedSubtract to subtract Local from system to get the bias.
Below code was writtin by Lordy-poo and I was given permission long time ago when he was drunk :P
Public Function UnsignedSubtract(ByVal number1 As Long, ByVal number2 As Long) As Long
UnsignedSubtract = DToL(CDbl(number1) - CDbl(number2))
End Function
Public Function DToL(ByVal num As Double) As Long
While num > &H7FFFFFFF
num = num - 4294967296#
Wend
While num < &H80000000
num = num + 4294967296#
Wend
DToL = CLng(num)
End Function
@ prod Lang, Looks fine to me.
KK sleep time, I'll read this again in the morning.
~-~(HDX)~-~
@Split- thanks-- wish I knew that one sooner-- that'll save me alot of time in the future-- thanks!!
@0x50 looking good-- I owe that to you. :-) Still not done-- there's still the time zone bias...
@Prod Lang-- cool, thanks. It's put in code now.
@TimeZone-- still struggling. Here's where I am:
' System time structure
Public Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long
Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numBytes As Long)
DIM SysUTCTime1 as Date, SysUTCTime2 as Long, SysFTime as long
Dim Result As String * 8
Dim t As SYSTEMTIME
GetSystemTime t
SysUTCTime = DateSerial(t.wYear, t.wMonth, t.wDay) + TimeSerial(t.wHour, t.wMinute, t.wSecond) + t.wMilliseconds / 86400000#
FTime = SystemTimeToFileTime(UTCTime, FTime)
CopyMemory ByVal Result, FTime, 8
FTime2 = Result
'Got lost at about this point.
I got lost and wasn't able to make heads nor tails of it... Looks like the TimeZone is the most difficult part of the 0x50 packet... What am I doing wrong? I wish I could make sense of this... Thanks for your help thus far! Do you think you could assist me further in this TimeZone Bias stuff? If so, thanks in advance once again! If not, thanks anyhow- you were of huge help!
Quote from: Kyro on September 11, 2005, 02:30 AMIt took me a while to figure it out, but I managed to write a function on my own to convert an ip address to network byte order as you described... The function works pretty good... If there's a way to improve the function, I'm open to suggestions.
'Converts an IP address to network byte order.
Public Function IP2NBO(IpAddress As String)
Dim Section(3) As String
Section(0) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
IpAddress = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
Section(1) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
IpAddress = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
Section(2) = Mid(IpAddress, 1, InStr(1, IpAddress, ".") - 1)
Section(3) = Mid(IpAddress, InStr(1, IpAddress, ".") + 1)
IP2NBO = Chr(Section(0)) & Chr(Section(1)) & Chr(Section(2)) & Chr(Section(3))
End Function
Consider using instead inet_pton(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_pton.3.html), htonl(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/htonl.3.html), and ntohl(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/ntohl.3.html) for IP addresses (both IPv4 and IPv6). Use htons(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/htons.3.html) and ntohs(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/ntohs.3.html) for port numbers. inet_pton(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_pton.3.html) supercedes inet_aton(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_aton.3.html), which can only handle IPv4 addresses. Note that certain broken implementations of the socket library (such as Microsoft's) fail to provide inet_pton(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_pton.3.html)
or inet_aton(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_aton.3.html). The recommended workaround for this deficiency is to stop using Microsoft's socket library. If you are unable to do so, you may be able to get some functionality by using the deprecated inet_addr(3) (http://homepages.cwi.nl/~aeb/linux/man2html/man3/inet_addr.3.html) function instead. This function is deprecated because you cannot distinguish between an error condition and a valid broadcast address.
DIM stSysTime as SYSTEMTIME, ftSysTime as FILETIME, UTCTime as long
Dim Result As long
GetSystemTime stSysTime
Result = SystemTimeToFileTime(stSysTime, ftSysTime)
CopyMemory UTCTime, ByVal ftSysTime, 8
'Got lost at about this point.
That is what I was talking about.
Do the same for LocalTime
@ KP's post. Do as Kp says. Thats the more accurate way of doing it. I'm jsut not well versed i it. (I've done it before, just not much)
So does anyone have a way of determining the Product Language? I'd assume get the system lnguage, and if it's GBeg use that, else use USeg?
~-~(HDX)~-~
@HdxBmx27
Public Function GetTimeZoneBias() As Long
Dim stSysTime As SYSTEMTIME, ftSysTime As FILETIME, SysUTCTime As Long
Dim stLocalTime As SYSTEMTIME, ftLocalTime As FILETIME, LocalUTCTime As Long
Dim Result As Long
GetSystemTime stSysTime
Result = SystemTimeToFileTime(stSysTime, ftSysTime)
CopyMemory ByVal SysUTCTime, ftSysTime, 8
GetLocalTime stSysTime
Result = SystemTimeToFileTime(stLocalTime, ftLocalTime)
CopyMemory ByVal LocalUTCTime, ftLocalTime, 8
GetTimeZoneBias = UnsignedSubtract(LocalUTCTime, SysUTCTime)
End Function
That causes VB to crash. I assume incorrectly coded the CopyMemory lines since I know using memory functions incorrectly will either yield corrupted data or crash vb without an error, woe unto those who didn't save their work before testing. *kicks self* Had to rewrite the function again, just to show you what I had. Heh. In any case, can you tell me what's wrong with that code?
Also, I got curious about those lines:
QuoteDim Result As Long
Result = SystemTimeToFileTime(stSysTime, ftSysTime)
Result = SystemTimeToFileTime(stLocalTime, ftLocalTime)
I don't see a reason for having the Result variable, since we do no work with it other than store whatever SystemTimeToFileTime returns. Could it be done like this:
SystemTimeToFileTime(stSysTime, ftSysTime)
SystemTimeToFileTime(stLocalTime, ftLocalTime)
@Kp- got a suggestion of a good winsocket class/library that's better than the vb winsock?
Quote from: Kyro on September 11, 2005, 02:11 PM@Kp- got a suggestion of a good winsocket class/library that's better than the vb winsock?
No, but then I never suggested that you should use Windows sockets at all. The address utility functions I mentioned are present in glibc as of several years ago, and probably in the userland libraries for most other systems too. Windows is the only system I've found that
doesn't have it. :)
Hurm Someone deleted my post...
I dont feel ike writing the code again so.
Theres an API called GetTimeZoneInformation.
It gets passed a "TIME_ZONE_INFORMATION" struct, and In that struct is a "Bias" property.
After Calling the API the .Bias value will be the EXACT OPPISIT of what it truly is. So jsut subtract it from 0 to get the right info (Correct = 0 - .Bias)
I found this API using google <3
as for the error, its cuz I put the ByVal in the wrong place, it should be on the 2nd argument of CopyMemory not the 1st.
~-~(HDX)~-~
You're not the only one-- my post in response to your post got deleted too... >.<
I don't feel like retyping everything either, so I'll just sum up what I said--
Here's the C->S 0x50 packet sub in its final form, thoughts?
Public Sub P0x50()
AddC vbWhite, "Assembling 0x50 Protocol packet..."
If (bnetclient = "" Or VerByte = "") Then
AddC vbRed, "Error! Missing bnet/verbyte values!"
AddC vbRed, "Connection aborted locally."
BNETDiscReq = True
Call DMBot.BNET_Close
Else
With PacketBuf
.InsertDWORD &H0 'BNET Protocol ID (Currently zero.)
.InsertDWORD CLng("&H" & Replace(StrToHex("IX86"), " ", vbNullString)) 'IX86
.InsertDWORD CLng("&H" & Replace(StrToHex(bnetclient), " ", vbNullString)) 'SEXP
.InsertDWORD CLng("&H" & VerByte) 'Verbyte, changes with product upgrade.
.InsertDWORD CLng("&H" & Replace(StrToHex("USeg"), " ", vbNullString)) 'Product Language
.InsertDWORD CLng("&H" & Replace(StrToHex(IP2NBO(DMBot.BNET.LocalIP)), " ", vbNullString)) 'Local IP for NAT compatibility
.InsertDWORD GetTimeZoneBias 'Time Zone bias
.InsertDWORD GetUserDefaultLCID() 'Locale ID
.InsertDWORD GetUserDefaultLangID 'Language ID
.InsertNTString GetInfo(LOCALE_SABBREVCTRYNAME) 'Abbrev. of country
.InsertNTString GetInfo(LOCALE_SENGCOUNTRY) 'Name of country
.SendPacket DMBot.BNET, &H50 'Send 0x50 packet
End With
AddC vbWhite, "0x50 SID_AUTH_INFO packet sent."
End If
End Sub
And the code you gave for the GetTimeZoneBias() is here:
Declare Function GetTimeZoneInformation Lib "kernel32.dll" (lpTimeZoneInformation As TIME_ZONE_INFORMATION) As Long
Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long
Declare Sub GetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type TIME_ZONE_INFORMATION
Bias As Long
StandardName(0 To 31) As Integer
StandardDate As SYSTEMTIME
StandardBias As Long
DaylightName(0 To 31) As Integer
DaylightDate As SYSTEMTIME
DaylightBias As Long
End Type
Public Function GetTimeZoneBias() As Long
Dim tziInfo As TIME_ZONE_INFORMATION
GetTimeZoneInformation tziInfo
GetTimeZoneBias = 0 - tziInfo.Bias
End Function
And I also mentioned in my post (the one that deleted) that AFAIK, product languages are usually stored in resource strings that can be easily viewed using a resource viewer- resource strings are usually stored in either an EXE or a DLL, usually a DLL. I remember that much from using a resource viewer to poke around in various executables and DLLs to see if they had anything interesting within. I haven't poked around in the SC executables nor DLL files, but I'll do that as soon as I download a resource viewer to see if my theory is right.
[Edit: Decided to retype everything after all. Heh.]
Quote from: Kp on September 11, 2005, 03:01 PM
Quote from: Kyro on September 11, 2005, 02:11 PM@Kp- got a suggestion of a good winsocket class/library that's better than the vb winsock?
No, but then I never suggested that you should use Windows sockets at all. The address utility functions I mentioned are present in glibc as of several years ago, and probably in the userland libraries for most other systems too. Windows is the only system I've found that doesn't have it. :)
And unfortunately that library is absent on the rather large majority of user desktop systems. :P
Quote from: MyndFyre on September 11, 2005, 03:23 PMAnd unfortunately that library is absent on the rather large majority of user desktop systems. :P
That would be the fault of the system's administrator for installing and/or continuing to use a known-defective system.