Patcher Entwicklung

  • Moin,

    Wie im Threadtitel steht, suche ich welche die mir dabei helfen einen Patcher zu entwickeln.
    Er soll im ScriptDir die Dateien mit denen aus einer angegeben URL im Internet vergleichen zb
    ScriptDir/test.exe mit http://localhost/test.exe
    und prüfen ob diese GENAU gleich sind, wenn nicht ---> neue aus dem Internet laden.
    In einer http://localhost/patch.txt sollte stehen welche Dateien er überprüft.

    Habe mich schon mit ideas2code unterhalten, der vorgeschlagen hat das mit php zu realiseren.
    Indem das php Script die Größe ausließt und temporär cached.
    Allerdings wäre das nicht immer aktuelle und bei vielen Usern gleicht das einem DDoS.

    Ich habe schon ein bisschen herumprobiert das ganz mit InetGetSize entwickelt (stelle nachher den Source Code rein)
    allerdings bei ~1000 Usern die gleichzeit mit InetGetSize am Server sind, ebenfalls ein kleiner DDoS.

    Nach Lösungen habe ich gesucht und mir überlegt das via MD5 Summe möglich zu machen?
    Sprich er vergleicht die MD5 Summe der Dateien.
    Wäre es eine Möglichkeit? btw wie kann man so etwas wirklich realisieren?

    Oder habt ihre andere Vorschläge :)

    Danke euch schon mal!

    Gruß
    S1lver

    2 Mal editiert, zuletzt von Silverlight (28. Januar 2010 um 13:05)

  • Hey,

    du solltest auf der Seite etwas anbieten womit man erkennen kann ob ein Update bereitsteht.
    Die Updatedatei selbst zu prüfen führt dich immer wieder zu den angesprochenen Problemen, ob dabei der Server die Dateien vergleicht (php) oder der Client (download+Vergleich) ist ja egal.

    • Offizieller Beitrag

    Ich hatte eure Unterhaltung in der Shoutbox mitverfolgt und ich frage mich noch immer, was das für ein Projekt wird, bei dem 1000 User gleichzeitig den Server nach neuen Versionen abfragen. :huh:
    Aber gut, geht mich ja nicht unbedingt etwas an...

    Zum Thema: ideas2code hatte AFAIR doch vorgeschlagen, immer wenn Du eine neue Version rausbringst auch eine Liste (Textdatei) mit den MD5-Checksummen der Programme hochzuladen. Diese Liste können sich dann die Clients herunterladen und mit den lokal gespeicherten vergleichen. Wenn dann festgestellt wird, dass die Programme nicht mehr aktuell sind, dann werden sie halt gedownloadet. Diese Methode ist IMHO die ressourcenschonendste. Wenn der Server dann immer noch an seine Grenzen stößt, musst Du Dir Gedanken um eine bessere Anbindung machen. Softwaremäßig ist dann nichts mehr rauszuholen.

  • Zur Info es handelt sich dabei um ein Programm/Spiel wofür ich den Patcher brauche der es aktuell hält.
    Wenn es 1000 User haben und starten, dann sind 1000 User am Versionen abfragen :D

    Btw. Dann bräuchte man ein Script das die ganzen MD5 Summen erstellt, AutoIt müsste diese auslesen
    und mit der lokal gespeicherten Liste vergleichen?
    Allerdings wäre der Patch dann leicht manipulierbar indem man die lokale patch Datei
    dementsprechend verändert.

    MD5 Summen der Dateien auf dem Server ---> AutoIT Client ließt die Summen aus und vergleicht mit lokaler Liste.
    Könnte man anstatt der lokalen Liste nicht AutoIt die ganzen MD5 Summen der lokalen Dateien erstellen lassen, temporär speichern und dann vergleichen?

    Gruß
    S1lver

  • Server: Update -> MD5 Checksumme erstellen -> bereitstellen (als .txt z.B.)

    User: Checksumme vom Server holen -> Checksumme der lokalen .exe erstellen -> vergleichen -> neue Version ziehen (oder eben nicht)

    So ca.

  • Genau so :)

    Allerdings habe ich nicht die größte Ahnung davon und wäre sehr erfreut wenn ihr mir mit den Codes helft :D

    Was ich bisher gefunden habe :
    MD5 Checksum überprüfen
    Erstellt für eine Datei die Summe, müsste man nur noch so umschreiben das er für alle Dateien im Ordner
    die MD5 Summen errechnet & in einer txt Datei schreibt.

    Desweitern dann mit dem Überprüfen auf dem Server und runterladen.

  • Das wäre eine Funktion, um die MD5-Summen zu überprüfen, schau dir die Kommentare an für die Textdatei, die du erstellen musst. Mit einem ähnlichen Skript kannst du auch die MD5-Summen für die Dateien erstellen ;)

    Spoiler anzeigen
    [autoit]

    #include<Crypt.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Func _CheckUpdates()
    ; Author: Prog@ndy
    ;~ ; Beispielformat für die Textdatei (UTF-8 ohne BOM):
    ;~ Dateiname|MD5-Hash|Download-Adresse{@CRLF}
    ;~ test.txt|0x16f50d7f1078ae2116f3e9fa4ba25203|http:/download.com/a.txt
    ;~ temp.txt|0x0401DEFCF635DE4EAE161DC1F0F643DA|http:/download.com/b.txt
    Local $sSource = InetRead("you.url\update.txt")
    ;~ $sSource = StringToBinary("test.txt|0x16f50d7f1078ae2116f3e9fa4ba25203|http:/download.com/a.txt" & @CRLF & _
    ;~ "temp.txt|0x0401DEFCF635DE4EAE161DC1F0F643DA|http:/download.com/b.txt", 4)
    If @error Then Return SetError(1,0,0)
    $sSource = StringSplit(BinaryToString($sSource, 4), @CRLF, 1)
    Local $aFile, $sHash, $sPath = @ScriptDir&'\'
    Local $aUpdateFiles[$sSource[0]+1][4] = [[0]]
    _Crypt_Startup()
    For $i = 1 To $sSource[0]
    $aFile = StringSplit($sSource[$i], '|', 2)
    If UBound($aFile)<>3 Then ContinueLoop ; Name|MD5|URL
    $sHash = _Crypt_HashFile($sPath & $aFile[0], $CALG_MD5)
    If $aFile[1] <> $sHash Then
    $aUpdateFiles[0][0] += 1
    $aUpdateFiles[$aUpdateFiles[0][0]][0] = $aFile[0]
    $aUpdateFiles[$aUpdateFiles[0][0]][1] = $aFile[1]
    $aUpdateFiles[$aUpdateFiles[0][0]][2] = $aFile[2]
    $aUpdateFiles[$aUpdateFiles[0][0]][3] = $sHash
    EndIf
    Next
    ReDim $aUpdateFiles[$aUpdateFiles[0][0]+1][4]
    _Crypt_Shutdown()
    Return $aUpdateFiles
    ; Rückgabe:
    ;~ Dateiname|MD5-Hash|Download-Adresse|lokaler MD5{@CRLF}
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    #include<Array.au3>
    $up = _CheckUpdates()
    _ArrayDisplay($up, "Dateien zum updaten", -1, 0, '', '|', "$i|Datei|MD5-Hash (internet)|Download|lokaler MD5")

    [/autoit]
    • Offizieller Beitrag

    Zum erstellen der MD5-Checksummen kannst Du das hier verwenden:

    Spoiler anzeigen
    [autoit]


    #include <Crypt.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $sPath = @ScriptDir & '\temp\' ; MD5-Checksumme für alle Dateien aus diesem Ordner
    $sSaveFile = @ScriptDir & '\MD5List.txt' ; In dieser Datei wird die Liste gespeichert
    $aFilelist = _FileListToArray($sPath, '*', 1)
    $sMD5List = ''
    For $i = 1 To $aFilelist[0]
    $sMD5List &= $aFilelist[$i] & ' = ' & _Crypt_HashFile($sPath & $aFilelist[$i], $CALG_MD5) & @CRLF
    Next
    $hFile = FileOpen($sSaveFile, 2)
    If $hFile <> -1 Then
    FileWrite($hFile, $sMD5List)
    FileClose($hFile)
    EndIf

    [/autoit]


    Diese Liste erstellst Du jedes Mal, wenn eine neue Version rauskommt. Danach uploadest Du die Liste auf den Server. Die Clients downloaden diese, erstellen lokal ebenfalls eine Liste mit den vorhandenen Dateien und dann musst Du die Listen nur noch vergleichen.

  • Oscar bei deinem Script kommt eine Error Message in Line 8 :

    Subscript used with non-Array Variable :(

    btw progandy schaut ja schonmal nett aus danke :)

  • Habe das mal von progandy bissel gemoddet :D


    Spoiler anzeigen
    [autoit]

    #include<Crypt.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Func _CheckUpdates()
    ; Author: Prog@ndy
    ;Dateiname|MD5-Hash|Download-Adresse{@CRLF}
    ;test.txt|0x16f50d7f1078ae2116f3e9fa4ba25203|http:/download.com/a.txt
    ;temp.txt|0x0401DEFCF635DE4EAE161DC1F0F643DA|http:/download.com/b.txt
    Local $sSource = InetRead("http://localhost/patch.txt")
    ;~ $sSource = StringToBinary("test.txt|0x16f50d7f1078ae2116f3e9fa4ba25203|http:/download.com/a.txt" & @CRLF & _
    ;~"temp.txt|0x0401DEFCF635DE4EAE161DC1F0F643DA|http:/download.com/b.txt", 4)
    If @error Then Return SetError(1,0,0)
    $sSource = StringSplit(BinaryToString($sSource, 4), @CRLF, 1)
    Local $aFile, $sHash, $sPath = @ScriptDir&'\temp'
    Local $aUpdateFiles[$sSource[0]+1][4] = [[0]]
    _Crypt_Startup()
    For $i = 1 To $sSource[0]
    $aFile = StringSplit($sSource[$i], '|', 2)
    $aFilelist = _FileListToArray($sPath, '*', 1)
    $sPath = @ScriptDir & '\temp\' ; MD5-Checksumme Lokal
    If UBound($aFile)<>3 Then ContinueLoop ; Name|MD5|URL
    $sHash = _Crypt_HashFile($sPath & $aFilelist[$i], $CALG_MD5)
    If $aFile[1] <> $sHash Then
    $aUpdateFiles[0][0] += 1
    $aUpdateFiles[$aUpdateFiles[0][0]][0] = $aFile[0]
    $aUpdateFiles[$aUpdateFiles[0][0]][1] = $aFile[1]
    $aUpdateFiles[$aUpdateFiles[0][0]][2] = $aFile[2]
    $aUpdateFiles[$aUpdateFiles[0][0]][3] = $sHash
    EndIf
    Next
    ReDim $aUpdateFiles[$aUpdateFiles[0][0]+1][4]
    _Crypt_Shutdown()

    Return $aUpdateFiles
    ;Dateiname|MD5-Hash|Download-Adresse|lokaler MD5{@CRLF}
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    #include<Array.au3>
    $up = _CheckUpdates()
    _ArrayDisplay($up, "Dateien zum updaten", -1, 0, '', '|', "$i|Datei|MD5-Hash (internet)|Download|lokaler MD5")

    [/autoit]

    Allerdings gibt es es ja nur in einem Array Display wieder, wäre es nicht besser wenn er es in einer temp datei speichert? Außerdem ist da irgendwie eine Zeile 0 wo immer eine andere Zahl steht?
    Weiß jemand eine Lösung?

    Einmal editiert, zuletzt von Silverlight (29. Januar 2010 um 10:13)

  • warum willst du es denn in eine Datei speichern? Du kannst die Pfade doach auch aus dem Array auslesen und dann direkt runterladen, ohne eine Datei zu schreiben. Dann kann auch niemand die Datei verädnern und so den Patch manipulieren ;)
    Die Zahl in Array[0][0] gibt die Zahl der Dateien an, die sich geändert haben und im Array vorhanden sind. (wie bei StringSplit ;) )
    Zum Runterladen kannst du z.B so was machen, dann werden die Dateien runtergeladen.

    [autoit]

    For $i = 1 To $up[0][0]
    InetGet($up[$i][2], $Pfad&$up[$i][0], 1)
    Next

    [/autoit]
  • Naja kannst du es so schreiben das er die beiden MD5s vergleicht und dementpsrechend runterlädt?
    Btw in Zeile 0 steht immer eine 32!?
    Ich bin am verzweifeln ;(

  • Naja kannst du es so schreiben das er die beiden MD5s vergleicht und dementpsrechend runterlädt?
    Btw in Zeile 0 steht immer eine 32!?
    Ich bin am verzweifeln ;(


    Was hat denn das FileListToArray bei dir zu suchen? Die Funktion hatte ich so angedacht:
    Datei aus dem Internet laden mit Dateinamen und Hash.
    Dann für jeden Eintrag in dieser update.ini prüfen, ob die Datei geändert wurde.
    Wurde sie geändert, dann füge sie dem Array dazu.
    Das Array wird zurückgegeben

    Das Array kannst du dann in einer Schleife abarbeiten und die Dateien runterladen. Das runterladen gehört meiner Meinung nach nicht in die FUnktion mit rein, da sie nur prüfen soll, ob Updates nötig sind.

    Ich habe dir mal ein Beispiel gemacht und Kommentare dazugeschrieben. Den Download musst du selbst einbauen.

  • Danke dir, aber ich bekomm das mit den Download nicht :(


    Ein Beispiel für den Download findest du hier: https://autoit.de/index.php?page…2337#post102337
    Diese Werte musst du dann nehmen:
    Internet-Quelle: $aUpdates[$i][2]
    Ziel auf dem PC: $sZiel & $aUpdates[$i][0]
    Wenn du mit Unterordnern arbeitest, solltest du diese sicherheitshalber anlegen, falls sie noch nicht existieren:

    [autoit]

    If StringInStr($aUpdates[$i][0], '\') Then DirCreate( $sZiel & StringRegExpReplace($aUpdates[$i][0], '\\[^\\]*$', ''))

    [/autoit]
  • Gut ich bekomm das aber nicht hin :D
    MD5 Internet + Lokal MD5 + Vergleichen + runterladen + Sub Ordner.
    Ich hab keine Ahnung wie ich das auch nur im geringsten Zusammenfasse (deswegen auch in der Jobbörse)

  • Wie im Threadtitel steht, suche ich welche die mir dabei helfen einen Patcher zu entwickeln.


    Du hast von Hilfe gesprochen, nicht von komplett schreiben lassen ;)
    Das Beispiel hat ja bereits eine Schleife, in der eine MsgBox aufgeht für jede geänderte Datei. Hier musst du dann Code für den download einbauen.
    Ohne Fortschrittsanzeige sähe das dann so aus: Wie du dann den Fortschrittsbalken ainbaust, musst du selbst rausfinden.

    [autoit]

    For $i = 1 To $aUpdates[0][0]
    SplashTextOn("Download Patch", $aUpdates[$i][0] & @CRLF & "Von: " & $aUpdates[$i][2] &@CRLF & "Nach: " & $sZiel)
    If StringInStr($aUpdates[$i][0], '\') Then DirCreate( $sZiel & StringRegExpReplace($aUpdates[$i][0], '\\[^\\]*$', ''))
    InetGet($aUpdates[$i][2], $sZiel & $aUpdates[$i][0], 1)
    ;MsgBox(0, '', "z.B. Download datei..."& @CRLF & $aUpdates[$i][0] & @CRLF & "Von: " & $aUpdates[$i][2] &@CRLF & "Nach: " & $sZiel)
    SplashOff()
    Next

    [/autoit]
  • *edit am suchen*
    Finde es nett von dir, das du mir hilfst :)
    Allerdings könntest du alles in ein Dingen packen :D?
    Den Downloadbalken würd ich bestimmt hinbekommen (oder auch nicht)