Valhalla Legends Forums Archive | Battle.net Bot Development | [VB] CheckRevision

AuthorMessageTime
JoeTheOdd
Not sure if this should go in the VB Programming forum. Please move it if it should.

Hdx and I are working on writing a VisualBasic CheckRevision() function. If anyone is interested in suggesting stuff or testing, or would like more information or something, feel free to ask. Here it is, as of right now.

[code]Public Function checkRevision( _  '// This is the CheckRevision function used for 0x51.
versionString As String, _        '// Checksum Formula recieved in 0x50.
mpqNum As Integer, _              '// MPQ Number recieved in 0x50.
Product As String) As Long        '// Product to use.

      'START JOES CODE
          '// Sample formula -- A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B
          '// TODO - Joe: Define hash codes, define files.

          Dim A As Long, B As Long, C As Long, S As Long, Splt() as String, O1 as String
          Dim O2 as String, Dim O3 as String

          A = CLng(Mid(Splt(0), 3))
          B = CLng(Mid(Splt(1), 3))
          C = CLng(Mid(Splt(2), 3))

          O1 = Mid(Splt(4), 4, 1)
          O2 = Mid(Splt(5), 4, 1)
          O2 = Mid(Splt(6), 4, 1)
      'END JOES CODE

      'START HDX'S CODE     
      A = A ^ hashCodes(mpqNum)

      For I = 0 To UBound(strFiles)
          intFile = FreeFile
          Open strFiles(I) For Binary Access Read As #intFile
              RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

          For J = 0 To RoundedSize Step 4
              strTmpData = Space(4)
              Get #intFile, J + 1, strTmpData
              S = GetDWORD(strTmpData)

              Select Case op1
                  Case "^": A = A ^ S
                  Case "-": A = A - S
                  Case "+": A = A + S
              End Select

              Select Case op2
                  Case "^": B = B ^ C
                  Case "-": B = B - C
                  Case "+": B = B + C
              End Select

              Select Case op3
                  Case "^": C = C ^ A
                  Case "-": C = C - A
                  Case "+": C = C + A
              End Select

              Select Case op4
                  Case "^": A = A ^ B
                  Case "-": A = A - B
                  Case "+": A = A + B
              End Select
          Next J
      Close #intFile
      Next I
  checkRevision = C
  '// END HDX'S CODE
End Function[/code]
April 15, 2005, 3:45 AM
Myndfyr
A couple comments, and take them with a grain of salt, as it's late and I might just be completely missing something.

1.) The Splt array seems to be unassigned.  You declare it, and then immediately use it:
[code]
'Declare it:
          Dim A As Long, B As Long, C As Long, S As Long, Splt() as String, O1 as String
' Use it
          A = CLng(Mid(Splt(0), 3))
[/code]
Is this intended?  I would think it would generate a compile-time error.

2.) I can't remember, but does VB support the ^ operator?  I thought it didn't support *any* symbolic bitwise operators -- I thought that appropriate bitwise operators were:
[code]
A = A And B
B = B Or C
C = C Xor S
[/code]
If that's the case you'll need to revise code that uses the ^ operator.  I'm too lazy to look it up right now.

Actually, the ^ operator is valid, but it means exponentiation.  See this page for more information.

3.) You repeat defining O2:
[code]
          O2 = Mid(Splt(5), 4, 1)
          O2 = Mid(Splt(6), 4, 1)
[/code]
Not being picky, just saving you that runtime debugging frustration later :)

Otherwise I think you've got a good start.
April 15, 2005, 8:49 AM
UserLoser.
Correct me if I'm wrong, but wouldn't:

((Integer * 1024) / 1024) return the same value as Integer..?
April 15, 2005, 7:06 PM
Myndfyr
[quote author=UserLoser link=topic=11286.msg108671#msg108671 date=1113591975]
Correct me if I'm wrong, but wouldn't:

((Integer * 1024) / 1024) return the same value as Integer..?
[/quote]

Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either
[code]
((Integer / 1024) * 1024)
[/code]
or:
[code]
Integer - (Integer % 1024)
[/code]
IIRC the second is more efficient, because integral division can take a long time.

You also might be able to get it faster by left-shifting (without carry) by 22 and then right-shifting it back 22 -- I believe that will fill the upper 22 bits with 0s and leave the remaining lower 10 bits as they were.

Or you could just bitwise AND it with 0x3ff, IIRC.

And on that note, should you just use a Long instead of a Double to hold the file size?  I don't think that any of Blizz's files go bigger than 2gb -- at least, not the ones you're CheckRevisioning.
April 15, 2005, 7:15 PM
UserLoser.
[quote author=MyndFyre link=topic=11286.msg108672#msg108672 date=1113592531]
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either
[/quote]

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know
April 15, 2005, 7:25 PM
Adron
[quote author=UserLoser link=topic=11286.msg108673#msg108673 date=1113593102]
[quote author=MyndFyre link=topic=11286.msg108672#msg108672 date=1113592531]
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either
[/quote]

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know
[/quote]

You should do \ 1024 then * 1024...
April 15, 2005, 7:29 PM
Adron
[quote author=MyndFyre link=topic=11286.msg108672#msg108672 date=1113592531]
[code]
Integer - (Integer % 1024)
[/code]
IIRC the second is more efficient, because integral division can take a long time.
[/quote]

I'll just point out that % implies integral division.

You do save a multiplication though.
April 15, 2005, 7:31 PM
OnlyMeat
With modern processors there isn't a performance gain doing shifts in place of multiplications/divisions anymore.

I simply did this in my vb 6.0 checkrevision implementation.

[code]
        ' Round file size
        lFileSize = Round(GetFileSize(hFile, ByVal 0&) / 1024) * 1024
[/code]

I store the result in a long (which in vb 6 is 32 bits) and worked just fine.
April 15, 2005, 7:47 PM
JoeTheOdd
MyndFyre, thanks for reminding me to fill Splt with stuff, and for reminding me about Xor. I'll just have to replace the ^ with Xor's, so I don't screw myself up big time.

UserLoser: I was wondering that myself. Thats in the Hdx's Code section, and I'll have to talk to him and find out what the hell he was thinking.
April 15, 2005, 9:11 PM
Adron
[quote author=OnlyMeat link=topic=11286.msg108679#msg108679 date=1113594477]
[code]
        ' Round file size
        lFileSize = Round(GetFileSize(hFile, ByVal 0&) / 1024) * 1024
[/code]

I store the result in a long (which in vb 6 is 32 bits) and worked just fine.
[/quote]

I'm not so sure that works reliably. Maybe it just works 50% of the cases?
April 15, 2005, 9:54 PM
HdxBmx27
#1, the ((I / 1024) * 1024) was suposto round the size to the nerest MB, but I accedently did / insted of \ :/
As for the ^ This was already descused in the original topic -.- the one i started.
Also Joe, PLEASE stop taking my code and posts from one site, and posting them on another site saying its a team project between the two of us!, I mearly wanted the input of some people on Quikness forums. Not here -.- (no offence all, but I would of posted it here myself, if i wanted help from everyone here, I like smaller forums over big ones)

Now Here is the current code:
[code]Private hashCodes(0 To 7) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal numbytes As Long)

Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub

Public Function GetDWORD(Data As String) As Long
    Dim lReturn As Long
    Call CopyMemory(lReturn, ByVal Data, 4)
    GetDWORD = lReturn
End Function

Public Function checkRevision(ByVal versionString As String, ByRef strFiles() As String, ByVal mpqNum As Integer) As Integer

        Dim tok As New clsStringTokenizer
        Call tok.SetVals(versionString, Space(1))
       
        Dim A As Long, B As Long, C As Long, S As Long
        A = Val(tok.getNextToken(3))
        B = Val(tok.getNextToken(3))
        C = Val(tok.getNextToken(3))

        tok.getNextToken
        Dim Formula As String, I As Integer, intFile As Integer, RoundedSize As Double, J As Double
        Dim op1 As String, op2 As String, op3 As String, op4 As String, strTmpData As String

        op1 = Mid(tok.getNextToken, 4, 1)
        op2 = Mid(tok.getNextToken, 4, 1)
        op3 = Mid(tok.getNextToken, 4, 1)
        op4 = Mid(tok.getNextToken, 4, 1)
       
        A = A Xor hashCodes(mpqNum)

        For I = 0 To UBound(strFiles)
            intFile = FreeFile
            Open strFiles(I) For Binary Access Read As #intFile
                RoundedSize = CDbl((LOF(intFile) \ 1024) * 1024)

            For J = 0 To RoundedSize Step 4
                strTmpData = Space(4)
                Get #intFile, J + 1, strTmpData
                S = GetDWORD(strTmpData)

                Select Case op1
                    Case "^": A = Moduls(A Xor S)
                    Case "-": A = Moduls(A - S)
                    Case "+": A = Moduls(A + S)
                End Select

                Select Case op2
                    Case "^": B = Moduls(B Xor C)
                    Case "-": B = Moduls(B - C)
                    Case "+": B = Moduls(B + C)
                End Select

                Select Case op3
                    Case "^": C = Moduls(C Xor A)
                    Case "-": C = Moduls(C - A)
                    Case "+": C = Moduls(C + A)
                End Select

                Select Case op4
                    Case "^": A = Moduls(A Xor B)
                    Case "-": A = Moduls(A - B)
                    Case "+": A = Moduls(A + B)
                End Select
            Next J
        Close #intFile
        Next I
    checkRevision = C
    End Function
   
Private Function Moduls(intOne As Long) As Long
    Moduls = CLng(intOne Mod &HFFFFFFFF)
End Function

Private Sub Form_Load()
    Call SetVars
    Dim blah(0 To 2) As String
    blah(0) = "E:\JBLS\W2BN\Warcraft II BNE.exe"
    blah(2) = "E:\JBLS\W2BN\battle.snp"
    blah(1) = "E:\JBLS\W2BN\storm.dll"
Call checkRevision("A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B", blah, 3)
End Sub[/code]
Moduls() Was suggested by both Joe, Fool, And iago. As a way to prevent overflows. But it always returns zero :/

Now does the opertation thet B.net sends refer to all Bitwise opertations (Xor, Or, And, Etc...) or there mathmatical counterparts? (+, -, /, \, ^, *, etc...)

^ was explaind to mean Xor, and so could it be assumed that + means And, and - means Or? If so it always returns zero (not using Moduls()) with no overflows.
~-~(HDX)~-~

PS: This is a strait port of iago's java code.
Also who deleyted my last post. Please don't do it again. It is varry annoying. Thanks.
April 15, 2005, 11:11 PM
UserLoser.
[quote author=Adron link=topic=11286.msg108675#msg108675 date=1113593363]
[quote author=UserLoser link=topic=11286.msg108673#msg108673 date=1113593102]
[quote author=MyndFyre link=topic=11286.msg108672#msg108672 date=1113592531]
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either
[/quote]

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know
[/quote]

You should do \ 1024 then * 1024...
[/quote]

That seems correct.  I wanted to know why he was doing it the other way
April 16, 2005, 12:19 AM
JoeTheOdd
[code]Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub[/code]

I suggest just space-delimiting them, and then calling them using Split(Hashcodes, Space(1)(MPQNum).
April 16, 2005, 2:18 AM
UserLoser.
[quote author=Joe[x86] link=topic=11286.msg108723#msg108723 date=1113617931]
[code]Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub[/code]

I suggest just space-delimiting them, and then calling them using Split(Hashcodes, Space(1)(MPQNum).
[/quote]

Why!?
April 16, 2005, 2:20 AM
JoeTheOdd
No initiation sub needs to be called beforehand.

[code]CRev() Initiated..
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
CRev() = 15061445[/code]

GG.
I lowered the mod to &HFFFFFF, because I don't remember if it was actually &HFFFFFFFF in the first place, and it works now. Not sure if it returned the correct value, but atleast it returned.

[code]Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (ByRef destination As Any, ByRef Source As Any, ByVal numbytes As Long)

Private Const HashCodes As String = "&HE7F4CB62 &HF6A14FFC &HAA5504AF " _
    & "&H871FCDC2 &H11BF6A18 &HC57292E6 &H7927D27E &H2FEC8733"

Public Function GetDWORD(Data As String) As Long
    Dim lReturn As Long
    Call CopyMemory(lReturn, ByVal Data, 4)
    GetDWORD = lReturn
End Function

Public Function checkRevision(ByVal versionString As String, ByRef strFiles() As String, ByVal mpqNum As Integer) As Currency
    '// Sample formula -- A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B
   
    Dim I1 As Integer, I2 As Integer, ToAdd As Long

    Dim A As Currency, B As Currency, C As Currency, Splt() As String, O1 As String
    Dim O2 As String, O3 As String, O4 As String, sTmpData As String
   
    Splt = Split(versionString, " ")
   
    A = CLng(Mid(Splt(0), 3))
    B = CLng(Mid(Splt(1), 3))
    C = CLng(Mid(Splt(2), 3))
   
    O1 = Mid(Splt(4), 4, 1)
    O2 = Mid(Splt(5), 4, 1)
    O3 = Mid(Splt(6), 4, 1)

    Debug.Print "CRev() Initiated.."

    A = A Xor Split(HashCodes, " ")(mpqNum - 1)

    For I1 = LBound(strFiles) To UBound(strFiles)
        intFile = FreeFile
        Open strFiles(I) For Binary Access Read As #intFile
        RoundedSize = LOF(intFile) - (LOF(intFile) Mod 4) 'RoundedSize = CDbl((LOF(intFile) \ 1024) * 1024)
        For I2 = 0 To RoundedSize Step 4
            strTmpData = Space(4)
            Get #intFile, I2 + 1, strTmpData
            ToAdd = GetDWORD(CStr(strTmpData))

            Select Case op1
                Case "^": A = A Xor ToAdd
                Case "-": A = A - S
                Case "+": A = A + S
            End Select
            Debug.Print "M(A) = " & M(A)
            A = M(A)

            Select Case op2
                Case "^": B = B Xor ToAdd
                Case "-": B = B - C
                Case "+": B = B + C
            End Select
            Debug.Print "M(B) = " & M(B)
            B = M(B)

            Select Case op3
                Case "^": C = C Xor ToAdd
                Case "-": C = C - A
                Case "+": C = C + A
            End Select
            Debug.Print "M(C) = " & M(C)
            C = M(C)

            Select Case op4
                Case "^": A = A Xor ToAdd
                Case "-": A = A - B
                Case "+": A = A + B
            End Select
            Debug.Print "M(A) = " & M(A)
            A = M(A)
           
        Next I2
        Close #intFile
    Next I1
   
    Debug.Print "CRev() = " & C
   
    checkRevision = C
End Function

Public Function M(l As Currency) As Currency

    'Dim l2 As Long
    'l2 = l
   
    'While l2 > &HFFFFFFFF
    '    l2 = l2 - &HFFFFFFFF
    'Wend
   
    'M = l2
    '// @Above: How slow can such simple code get?
   
    M = l Mod &HFFFFFF
End Function[/code]
April 16, 2005, 3:15 AM
R.a.B.B.i.T
[quote author=HdxBmx27 link=topic=11286.msg108701#msg108701 date=1113606711]
Now does the opertation thet B.net sends refer to all Bitwise opertations (Xor, Or, And, Etc...) or there mathmatical counterparts? (+, -, /, \, ^, *, etc...)

^ was explaind to mean Xor, and so could it be assumed that + means And, and - means Or? If so it always returns zero (not using Moduls()) with no overflows.
~-~(HDX)~-~
[/quote]+ is + and - is -.
April 16, 2005, 4:16 PM
iago
Incidentally, I'm not at all confident that a floating point value (which I imagine "currency" is?) will be accurate enough to do this correctly consistantly. 

And yeah, the 3 symbols used are their common usage in all real languages:
^ = xor
- = minus
+ = plus
April 16, 2005, 7:21 PM
Adron
[quote author=iago link=topic=11286.msg108798#msg108798 date=1113679262]
Incidentally, I'm not at all confident that a floating point value (which I imagine "currency" is?)
[/quote]

Currency isn't a floating point value. It's a fixed point value.
April 16, 2005, 8:22 PM
iago
[quote author=Adron link=topic=11286.msg108806#msg108806 date=1113682969]
[quote author=iago link=topic=11286.msg108798#msg108798 date=1113679262]
Incidentally, I'm not at all confident that a floating point value (which I imagine "currency" is?)
[/quote]

Currency isn't a floating point value. It's a fixed point value.
[/quote]

What's the advantage of using it, then? Isn't there a better way to get numbers that won't overflow?
April 16, 2005, 8:28 PM
Adron
[quote author=iago link=topic=11286.msg108807#msg108807 date=1113683329]
What's the advantage of using it, then? Isn't there a better way to get numbers that won't overflow?
[/quote]

The advantage, I suppose, would be to get exact calculations with decimal point numbers where roundings don't happen in any strange way. In the old days the advantage was that fixed point numbers were much faster to use than floating point numbers.

The best way of not getting an overflow error for numbers might be to tell the compiler not to generate overflow checks.... :P
April 16, 2005, 8:39 PM
iago
Can VB do that?
April 16, 2005, 8:47 PM
Adron
[quote author=iago link=topic=11286.msg108810#msg108810 date=1113684464]
Can VB do that?
[/quote]

Only when you compile your code. It's listed as an optimization.
April 16, 2005, 8:55 PM
iago
Hmm, perhaps these gentlemen should try that
April 16, 2005, 9:07 PM
JoeTheOdd
That'd be a royal pain, especially in debugging (interpreted code, not compiled).
April 16, 2005, 9:12 PM
OnlyMeat
To save you all the trouble, here is the checkrevision me and NiNe wrote. Note this has only been tested with starcraft and warcraft 2.

Cost with compiled exe and all advanced optimizations turned on (0.671 seconds). Machine stats - 1 gig DDR ram, 3.06ghz P4.

[Kp edit: killed horribly long code paste, it was ruining the thread.  On top of that, it was VB!]

It's a vb checkrevision thread, what do you expect duh!

Here is the download link kp erased:
http://mercury.walagata.com/w/ddjl/VB6CheckRevision.rar

To view the CCheckRevision class, here is a quick link:
http://mercury.walagata.com/w/ddjl/CCheckRevision.txt
April 16, 2005, 10:44 PM
iago
The point is that they were doing it for a challenge, not because they wanted an implementation of it.
April 17, 2005, 1:56 AM
Archangel
Ok this is funny,
they are having fun in a topic, like all users helping and in 1 second the fun can end because of an %$&%.

[Edit: The life can end like that soon or later too]
April 17, 2005, 2:11 PM

Search