opensource autofilepatchloader basic script au3

07/31/2011 04:08 UnterweltGeist#1
learning by doing

der source code hilft eingen hoffentlich zu verstehen das die dinge nicht einfach auf knopfdruck funktionieren. naja in diesem fall funktioniert es für den user wirklich auf knopfdruck für den admin eher nicht. es ist ein ziehmlich einfacher patcher. natürlich kann man ihn problemlos erweitern, dadurch wird es aber nicht weniger text. er ist im basic dialekt von autoit3 geschrieben sollte also jeder wenigstens schon von gehört haben.

der patchloader prüft und lädt alle datein die in der "files.txt" angegeben sind vom server, sind datein lokal syncron mit denen auf dem server ignoriert er sie gepflegt (prüft anzahl der bytes), die datei "files.txt" muss genauso wie "sizes.txt" und "versioninfo.txt" auf dem server liegen aber nicht in der "files.txt" eingetragen sein, wenn "sizes.txt" nicht existiert wird sie erstellt, es geht allerdings schneller wenn sie auf dem server liegt, deshalb sollte die beim testlauf erstellte size.txt auf den server übertragen werden, die datei "start.exe" wird beim klicken auf den button "start game" ausgeführt, wer im tray die 4 status icons sehen will kann sich ja selber welche machen, sie stehen für den zustand in dem sich der patcher befindet.

der patcher hat nicht den anspruch besonders raffiniert oder sicher vor manipulation zu sein. er soll einfach funktionieren, die datein aus der liste prüfen und runter laden.

files.txt beispiel
  • jede datei mit pfad ("/" www <<<< ) untereinander aufgelistet
  • die datei muss mit einer leer zeile enden
Code:
start.exe
pfad1/pfad2/datei1.txt
pfad1/datei2.txt
  • die liste kann bei großen dateimengen einfach über die konsole (ausführen cmd enter) erstellt werden, dazu könnt ihre eine batch datei erstellen mit dem folgendem befehl
fileslist.bat beispiel

Code:
dir /a /b /-p /s /o:gen > files.txt
  • alle pfade ohne dateien müssen aus der liste entfernt werden, sollten nicht so viele sein
  • die pfade müssen angepasst werden, alle \ müssen mit (suchen/ersetzen) webkonform in / umgewandelt werden
  • der hauptpfad c:/spiele/client/... muss ebenfalls durch (suchen/ersetzen) entfernt werden
  • es gibt mit sicherheit bessere lösungen, wer will kann ja eine routine dafür schreiben ^^
sizes.txt beispiel
  • die größe jeder datei untereinander aufgelistet
  • wird beim patchen erstellt, kann also einfach nach einem testlauf kopiert werden
Code:
1000
1333
1333
  • versioninfo.txt beispiel
  • die versioninfo.txt hat nur informative bedeutung
  • 1) erste versions nummer
  • 2) zweite versionsnummer
  • 3) datei anzahl
  • 4) gesamtgröße in byte (die anzahl der bytes, unterscheidet sich irgendwie von der die bei eigenschaften des ordners angezeigt wird)
Code:
1
0
3
3666
der patch source au3

Code:
#include <GUIConstants.au3>
#include <Array.au3>
#include <file.au3>

AutoItSetOption("TrayAutoPause",0)
AutoItSetOption("TrayMenuMode",1)
TraySetIcon("bluefull.ico")

global $gamename     = "Underworld"

global $serverurl    = "http://domain/dir/"
global $filestart    = "beta.exe"
global $filelist     = "files.txt"
global $filesizelist = "sizes.txt"
global $filevinfo    = "versioninfo.txt"
global $filevnow     = "versionnow.txt"
global $filepath
global $filedown
global $filesize
global $filesizelocal
global $filedata[5]=[0,0,0,0,0]
global $filedatanow[5]=[0,0,0,0,0]
global $filesall[1]
global $filessizeall[1]
global $filesallsizenow
global $infotimer1
global $infotimer2
global $dl
global $dlcount
global $dlcountinfo
global $err

global $main  = GUICreate($gamename & " - Patcher 1.2", 320, 200)
global $info1 = GUICtrlCreateLabel("Loki",297,2,50,15)


global $info1  = GUICtrlCreateLabel("",16,35,155,15)
global $info2  = GUICtrlCreateLabel("",16,50,155,15)

global $inforight1 = GUICtrlCreateLabel("",169,35,135,15,$SS_RIGHT )
global $inforight2 = GUICtrlCreateLabel("",169,50,135,15,$SS_RIGHT )

global $pdown1 = GUICtrlCreateProgress(15,65,290,10)
global $pdown2 = GUICtrlCreateProgress(15,77,290,10)
global $pdown3 = GUICtrlCreateProgress(15,89,290,17)

global $infoleft11 = GUICtrlCreateLabel("",16,115,50,15)
global $infoleft12 = GUICtrlCreateLabel("",66,115,95,15)
global $infoleft21 = GUICtrlCreateLabel("",16,130,50,15)
global $infoleft22 = GUICtrlCreateLabel("",66,130,95,15)
global $infoleft31 = GUICtrlCreateLabel("",16,145,40,15)
global $infoleft32 = GUICtrlCreateLabel("",66,145,95,15)
global $infoleft41 = GUICtrlCreateLabel("",16,160,50,15)
global $infoleft42 = GUICtrlCreateLabel("",66,160,95,15)



global $bdown      = GUICtrlCreateButton("Start Download",175,114,130,25,0)
global $bcontinue  = GUICtrlCreateButton("Continue",175,142,130,25,0)
GUICtrlSetState($bcontinue,$GUI_DISABLE)

global $bstart = GUICtrlCreateButton("Start Game",175,170,130,25,0)

GUISetState(@SW_SHOW)




_FileReadToArray($filevnow,$filedatanow)

GUICtrlSetData($infoleft11,"Version:")
GUICtrlSetData($infoleft12,$filedatanow[1] & "." & $filedatanow[2])
GUICtrlSetData($infoleft21,"Files:")
GUICtrlSetData($infoleft22,$filedatanow[3])
GUICtrlSetData($infoleft31,"Size:")
GUICtrlSetData($infoleft32,Round($filedatanow[4]/1024/1024,2) & " MB")

TrayTip("Download","Never touch a runnig system.",10,16)

global $ende=false
while $ende=false
    msg()
    downloadall()
wend

InetGet("abort")






func msg()
    
    $m = GUIGetMsg()
    Switch $m
        Case $GUI_EVENT_CLOSE
                $ende=true
                
        Case $bdown
            
            if $dl = 1 then
                InetGet("abort")
                GUICtrlSetData($bdown,"Restart Download")
                GUICtrlSetState($bcontinue,$GUI_ENABLE)
                $dl=0
                TraySetIcon("yellowhalf.ico")
            else
                InetGet("abort")
                GUICtrlSetData($bdown,"Stop")
                GUICtrlSetState($bstart,$GUI_DISABLE)
                GUICtrlSetState($bcontinue,$GUI_DISABLE)
                if checkfiles()=true Then
                    TraySetIcon("yellowfull.ico")
                    $dl=1
                    $dlcount=0
                    $dlcountinfo=0
                    $err=0
                    $filesallsizenow=0
                    GUICtrlSetData($pdown1,0)
                    GUICtrlSetData($pdown2,0)
                    GUICtrlSetData($pdown3,0)
                else
                    MsgBox(48,"Error","Filecheck faild.")
                    InetGet("abort")
                    $dl=0
                    GUICtrlSetData($bdown,"Start Download")
                endif
            endif
        
        case $bcontinue
            GUICtrlSetData($bdown,"Stop")
            GUICtrlSetState($bcontinue,$GUI_DISABLE)
            $dl=1
        
        Case $bstart
            if fileExists($filestart) then
                InetGet("abort")
                $dl=0
                $dlcount=0
                ShellExecute($filestart)
            Else
                MsgBox(0,"Not found","The file you try to excute does not exist.")
            endif
            
    EndSwitch
        
endfunc



func checkfiles()
    $f=getfilelist()
    ;if $f=0 Then
    
        $filesall=0
        $filessizeall=0
        $filedata=0
        
        If _FileReadToArray($filevinfo,$filedata) Then
            GUICtrlSetData($infoleft11,"Version:")
            GUICtrlSetData($infoleft12,$filedatanow[1] & "." & $filedatanow[2] & " > " & $filedata[1] & "." & $filedata[2])
            GUICtrlSetData($infoleft31,"Size:")
            GUICtrlSetData($infoleft32,Round($filedata[4]/1024/1024,2) & " MB")    
            If _FileReadToArray($filelist,$filesall) Then
                GUICtrlSetData($infoleft21,"Files:")
                GUICtrlSetData($infoleft22,$filesall[0])
                If $f=2 Then
                    MsgBox(48,"Error","Could not build filesizelist. Try to generate list.")
                    $file=fileopen($filesizelist,2)
                    if $file <> -1 then
                    for $i=1 to $filesall[0]
                        GUICtrlSetData($info1,$filesall[$i])
                        GUICtrlSetData($info2,"check")
                        $s=InetGetSize($serverurl & $filesall[$i])
                        FileWriteLine($file,$s)
                        GUICtrlSetData($info2,$s + "ok")
                    GUICtrlSetData($pdown1,ceiling($i * 100 / $filesall[0]))
                    next
                    fileclose($file)
                    Else
                    MsgBox(48,"Error","Generate list failed.")
                    endif
                endif
                If _FileReadToArray($filesizelist,$filessizeall) Then
                    return True
                Else
                    MsgBox(48,"Error","Could not build filesizelist.")
                    return False
                endif
            Else
                MsgBox(48,"Error","Could not build filelist.")
                return false
            endif
        Else
            MsgBox(48,"Error","Could not build versioninfolist.")
            return false
        EndIf
    ;else
        ;MsgBox(48,"Error","Load list code: " & $f)
        ;return false
    ;endif
    
endfunc



func getfilelist()
    
    InetGet("abort")
    $f=0

    GUICtrlSetData($info1,$filelist)
    
        if fileExists($filelist) Then
            fileDelete($filelist)
            GUICtrlSetData($info2,"delete")
        endif
    
        GUICtrlSetData($pdown1,25)
        GUICtrlSetData($pdown2,16)

        If InetGet($serverurl & $filelist,$filelist,1,0) = 0 Then
            MsgBox(48,"Error","Unable to download filelist.")
            $f=1
        Else
            GUICtrlSetData($info2,"ok")
        EndIf
    
        GUICtrlSetData($pdown1,100)
        GUICtrlSetData($pdown2,32)
    
    GUICtrlSetData($info1,$filesizelist)
        
        if fileExists($filesizelist) Then
            fileDelete($filesizelist)
            GUICtrlSetData($info2,"delete")
        endif
    
        GUICtrlSetData($pdown1,25)
        GUICtrlSetData($pdown2,48)

        If InetGet($serverurl & $filesizelist,$filesizelist,1,0) = 0 Then
            MsgBox(48,"Error","Unable to download filesizelist.")
            $f=$f+2
        Else
            GUICtrlSetData($info2,"ok")
        EndIf
    
        GUICtrlSetData($pdown1,100)
        GUICtrlSetData($pdown2,64)
    
    GUICtrlSetData($info1,$filevinfo)
        
        if fileExists($filevinfo) Then
            fileDelete($filevinfo)
            GUICtrlSetData($info2,"delete")
        endif
    
        GUICtrlSetData($pdown1,25)
        GUICtrlSetData($pdown2,80)
    
        If InetGet($serverurl & $filevinfo,$filevinfo,1,0) = 0 Then
            MsgBox(48,"Error","Unable to download filevinfo.")
            $f=$f+4
        else
            GUICtrlSetData($info2,"ok")
        EndIf
    
        GUICtrlSetData($pdown1,100)
        GUICtrlSetData($pdown2,100)
    
    Return $f
    
endfunc





func downloadall()
    if $dl=1 Then
        if @InetGetActive = 0 then
            if $dlcount<$filesall[0] Then
                if $dlcount>0 Then
                    Filemove("temp.txt",$filepath & $filedown,9)
                endif
                $dlcount=$dlcount+1
                if $dlcount<=$filesall[0] then
                    $filesallsizenow=$filesallsizenow+$filessizeall[$dlcount]
                    download($filesall[$dlcount],$filessizeall[$dlcount])
                endif
            Else
                Filemove($filevinfo,$filevnow,9)
                FileDelete("temp.txt")
                TraySetIcon("greenfull.ico")
                GUICtrlSetData($bdown,"Restart Download")
                GUICtrlSetState($bcontinue,$GUI_DISABLE)
                GUICtrlSetState($bstart,$GUI_ENABLE)
                $dl=0
                if $err>0 Then
                    TraySetIcon("redfull.ico")
                    MsgBox(48,"Error","While downloading it occures " & $err & " Fileerrors. Please retry downloading all.")
                endif
            endif
        endif
        downloadinfo()
    endif
endfunc




func downloadinfo()

    if timerdiff($infotimer1)>50 or $dlcountinfo<>$dlcount then
        $infotimer1=TimerInit()
        $dlcountinfo=$dlcount
        
        $s=$filesallsizenow-$filessizeall[$dlcount]+@InetGetBytesRead
        GUICtrlSetData($inforight1,$dlcount & "/" & $filesall[0])
        GUICtrlSetData($inforight2,$s & "/" & $filedata[4])
        

        GUICtrlSetData($pdown2,ceiling(($s) * 100 / $filedata[4]))
        GUICtrlSetData($pdown3,ceiling($dlcount * 100 / $filesall[0]))
        
        if timerdiff($infotimer2)>30000 then
            $infotimer2=TimerInit()
            TrayTip("Download",$gamename & @Lf & @CR & "Files: " & $dlcount & "/" & $filesall[0] & @Lf & @CR & "Size: " & Round(($filedata[4]-$s)/1024/1024) & " MB",10,16)
        EndIf    
        
        if @InetGetActive = 1 then
            GUICtrlSetData($pdown1,ceiling(@InetGetBytesRead * 100 / $filessizeall[$dlcount]))
            GUICtrlSetData($info2,Round(@InetGetBytesRead/1024) & "/" & Round($filessizeall[$dlcount]/1024) & " KB")
        endif
    endif
endfunc



func download($file,$size)
    
    if @InetGetActive = 0 then
        
        $filepath = $file
        $filedown = $file
        
        while StringInStr($filedown,"/")
            $filedown = stringtrimleft($filedown,StringInStr($filedown,"/"))
        wend
        
        if StringInStr($filepath,"/") then
            $filepath = stringtrimright($filepath,Stringlen($filedown))
            $filepath = StringReplace($filepath,"/","\")
            dircreate($filepath)
        else
            $filepath=""
        endif
        
        GUICtrlSetData($pdown1,0)
        GUICtrlSetData($info1,$filepath & $filedown)
    
        $filesizelocal=FileGetSize($filepath & $filedown)
        
        if $size <> $filesizelocal then
            If InetGet($ServerUrl & $file,"temp.txt",1,1) = 0 Then
                GUICtrlSetData($infoleft41,"Error (F):")
                GUICtrlSetData($infoleft42,$filedown)
                $err=$err+1
            else
                GUICtrlSetData($info2,Round(@InetGetBytesRead/1024) & "/" & Round($size/1024) & " KB")
            endif
        Else
            GUICtrlSetData($info2,"ok")
        endif
    
    endif
    
Endfunc
so das wars. wenn euch das programmieren interessiert, tut euch selbst einen gefallen und lest so viel source wie ihr könnt egal welche sprache. nur so kann man es verstehen und neue, gute oder schlechte sachen lernen.

ps: sry für das chaos im code :D

gg hf
07/31/2011 12:14 IgorGlock#2
Sieht nach einen Seriösen Konzept aus, nur AutoIT macht das Ganze dann unseriös. :)
07/31/2011 12:24 LordKill#3
Quote:
Originally Posted by IgorGlock View Post
Sieht nach einen Seriösen Konzept aus, nur AutoIT macht das Ganze dann unseriös. :)
wie du einfach immer etwas gegen autoit hast... tzzzzzz :D


Zurück zum Thema: sieht ganz nice aus das script, inwiefern unterscheidet sich die Anzahl? ich bin gerade nicht zu hause und kann es nicht testen also das ist jetzt auf Punkt 4 bezogen.

Der Aufbau des Script gefällt mir, paar Verbesserungen wären aber nicht schlecht, hast ja aber gesagt, dass es ein simpler Patcher sein soll.
07/31/2011 13:20 UnterweltGeist#4
wenn man sich die größe aller datein die runtergeladen werden sollen in den eigenschaften ansieht, unterscheidet sie sich von den gezählten bytes nach dem downloaden. hab vermutet das es an windows/clustergröße liegt oder an brutto/netto bytes.

würde mich nicht wundern wenn einer nen bug findet, manchmal ist man einfach geblendet für bestimmte probleme auch wenn es offensichtlich funktioniert.