Author | Message | Time |
---|---|---|
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 |