Neuling hat einige Fragen

  • Hallo Community,

    wie man recht schnell erkennen wird, bin ich nicht nur hier im Forum neu. Vor etwa zwei Wochen habe ich begonnen mich mit AutoIT zu beschäftigen. Auch was alles andere in Richtung Programmierung angeht, bin ich sozusagen jungfreulich. Also bitte verzeiht mir auch offensichtliche Fehler.

    Ich habe für ein Onlinegame in kleines Programm gebaut, welches mir bisher lediglich zwei Werte aus dem Speicher auslesen soll. Soweit funktioniert das auch, aber mit ein paar Punkten bin ich nicht ganz zufrieden. Nun aber erstmal den Code, das dürfte ggf. helfen.

    [autoit]

    #include <GUIConstants.au3>
    #include <MemoryMod.au3>
    #include <String.au3>

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

    Opt("TrayAutoPause", 0)
    Opt("TrayMenuMode", 1)
    Opt("GUIOnEventMode", 1)
    GUICreate("Window", 200, 88)

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

    $varName = IniRead("ZenyWatch.ini", "Address", "Name", "NotFound")
    $varGeld = IniRead("ZenyWatch.ini", "Address", "Geld", "NotFound")
    $pid = WinGetProcess("Ragnarok")
    GUISetOnEvent($GUI_EVENT_CLOSE, "Close_Or_Quit_Clicked")
    $quitButton = GUICtrlCreateButton ( "Cancel",148,60,50)
    GUICtrlSetOnEvent($quitButton, "Close_Or_Quit_Clicked")
    GUICtrlCreateLabel("Name: ", 5, 10)
    GUICtrlCreateLabel("Zeny: ", 5, 30)

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

    While 1
    $info = _MemoryOpen($pid)
    $varName_read = _MemoryRead($varName, $info)
    $varGeld_read = _MemoryRead_dword($varGeld, $info)
    $varGeld_format = _StringAddComma ($varGeld_read)
    _MemoryClose($pid)

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

    GUICtrlCreateLabel($varName_read, 45, 10)
    GUICtrlCreateLabel($varGeld_format, 45, 30)
    TraySetToolTip("Window")
    GUISetState(@SW_SHOW)
    Sleep(5000)
    Wend

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

    Func Close_Or_Quit_Clicked()
    Exit
    EndFunc

    [/autoit]

    Diese MemoryMod.au3 basiert fast ausschliesslich auf dieser UDF. Ich habe nur eine weitere _MemoryRead Funktion hinzugefügt um 'dword' und 'char[]' zu unterscheiden.

    Nun aber zu meinen zu lösenden Aufgaben, Probleme sagt man ja nicht weil das so negativ ist. Das erste was mir Kopfzerbrechen bereitet ist, das das Programm nach längerer Laufzeit zunehmend Prozessorlast verursacht. Vielleicht hat es auch etwas damit zu tun, wenn es minimiert ist bzw. im Hintergrund läuft. In diesem Zustand glaube ich auch, pausiert es, läuft es mir verminderter Leistung oder soetwas, aber das ist lediglich eine Vermutung. Weiter habe ich bisher keine Lösung finden können für die Tatsache, das bei jedem Durchlauf wenn die Werte neu geschrieben werden, die Anzeige flackert. Die _MemoryRead die den 'char[]' bearbeitet ist im Moment fest definiert auf 21, was natürlich nur bedingt sinnvoll ist. Ist der Wert länger wird er gekürzt und ich habe keine Idee wie ich das verbessern kann.

    Nun ich denke das reicht für meinen ersten Beitrag hier im Forum und ich hoffe ihr könnt mir helfen. Wobei ihr das schon habt, ohne diese klasse Community wäre ich nie so weit gekommen. Natürlich sind auch Verbesserungsvorschläge darüber hinaus herzlich willkommen.


    Danke und Mfg

  • Moin MisterBill,

    erstens schau mal auf die Startseite, da steht was über die Hilfe bei Bots (oder Trainern ;) ).
    Außerdem sieht es verdammt so aus als seist du nicht ganz so 'jungfräulich' wie du sagst.
    Also wenn dein Programm funktioniert dann freu dich doch (die Jungs bei Ragnarok tuen's bestimmt nicht :thumbdown: ).

  • Wo mein Programm bitte ein Bot oder Trainer sein soll, musst du mir dann aber schon mal erklären. Aufgrund der Tatsache das es das nicht ist, denke ich bin ich hier schon genau richtig. Darüber hinaus verstehe ich nicht, was für ein Problem die Jungs in Ragnark mit einem solchen Programm haben sollten. Ich nehme keinerlei Veränderungen am Client oder den Werten im Speicher vor, zumal das nichts bringen würde aufgrund der Arbeitsweise des Games.

    Und doch, ich bin jungfräulich im Bereich der Programmierung. Das ich soweit gekommen bin, verdanke ich der Fähigkeit google.de bedienen zu können und diesem Forum. Viele ähnliche Probleme wurden hier schon gelöst aus denen ich für mich notwendiges ableiten konnte. Und klar freue ich mich, das das Programm soweit läuft, für meine Verhältnisse gut wie ich finde. Dennoch würde ich es gerne weiter verbessern.


    Ich bin also über produktive Beiträge sehr dankbar. Mfg

  • Es liest den Namen des Charakter und den Geldbetrag, welcher dann in einem kleinen Fenster angezeigt wird. Da ich im Vollbildmodus spiele für mich praktisch wenn ich im Windows bin, da ich so mitbekomme wenn sich was getan hat. Im Bezug auf ein Onlinegame ist das für mich keinesfalls ein Bot da es auf Informationen aus dem Spiel nicht im Spiel reagiert, es ändert lediglich die Anzeige in meinem kleinen Fenster im Windows. Trainer ist es ebenfalls keiner, da ich keine Werte manipuliere.

    Wie genau ich das nun klassifiziern soll, weiss ich nicht.

  • Okay MisterBill dann will ich dir mal glauben ;)
    Dein Problem ist das du jedes mal die Controls neu erstellst (GUICtrlCreateLabel).
    Das machst du nur einmal vor der While-Schleife und dann setzt du die Werte mit 'GUICtrlSetData' ein.
    Das spart eine Menge Prozessorleistung.

  • Ich habe zwar von der Funktion jetzt keine Plan, aber muss die Zeile:

    _MemoryClose($pid)

    nicht:

    _MemoryClose($info)

    heißen ?

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Zuerst einmal danke für die Antworten. Gestern konnte ich mich nur kurz mit dem Thema beschäftigen, bin aber nicht dahinter gekommen, wie ich das mit 'GUICtrlSetData' anstellen soll. Könntest du mir JanSchmidt bitte noch etwas mehr auf die Sprünge helfe?


    Danke vorab und Mfg.

  • Moin MisterBill,

    bitteschön :)


    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <MemoryMod.au3>
    #include <String.au3>

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

    Opt("TrayAutoPause", 0)
    Opt("TrayMenuMode", 1)
    Opt("GUIOnEventMode", 1)
    GUICreate("Window", 200, 88)

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

    $varName = IniRead("ZenyWatch.ini", "Address", "Name", "NotFound")
    $varGeld = IniRead("ZenyWatch.ini", "Address", "Geld", "NotFound")
    $pid = WinGetProcess("Ragnarok")
    GUISetOnEvent($GUI_EVENT_CLOSE, "Close_Or_Quit_Clicked")
    $quitButton = GUICtrlCreateButton ( "Cancel",148,60,50)
    GUICtrlSetOnEvent($quitButton, "Close_Or_Quit_Clicked")
    GUICtrlCreateLabel("Name: ", 5, 10)
    GUICtrlCreateLabel("Zeny: ", 5, 30)
    $ControlName = GUICtrlCreateLabel("", 45, 10)
    $ControlGeld = GUICtrlCreateLabel("", 45, 30)

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

    While 1
    $info = _MemoryOpen($pid)
    $varName_read = _MemoryRead($varName, $info)
    $varGeld_read = _MemoryRead_dword($varGeld, $info)
    $varGeld_format = _StringAddComma ($varGeld_read)
    _MemoryClose($info)

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

    GUICtrlSetData( $ControlName, $varName_read )
    GUICtrlSetData( $ControlGeld, $varGeld_format )
    TraySetToolTip("Window")
    GUISetState(@SW_SHOW)
    Sleep(5000)
    Wend

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

    Func Close_Or_Quit_Clicked()
    Exit
    EndFunc

    [/autoit]

    Der Hinweis von Micha_he ist auch schon drin ;)

  • Danke Micha_he und JanSchmidt, bin heute endlich mal dazu gekommen eure Verbesserungen zu testen. Prozessorlast scheint nun in Ordnung zu sein und das Problem mit dem flackern ist bisher auch nicht mehr aufgetreten. Danke nochmal dafür, aber es gibt auch eine neue Schwierigkeit.

    [autoit]


    $ControlName = GUICtrlCreateLabel("", 45, 10)
    $ControlZeny = GUICtrlCreateLabel("", 45, 30)

    [/autoit]

    Diese kürzen mir offensichtlich die Ausgabe, denn es wird lediglich jeweils nur die erste Position angezeigt. Bsp. Charaktername: 'Novice', Anzeige: 'N'. Und wegen und 'char[]' wollte ich auch nochmal nachfragen.

    [autoit]


    Func _MemoryRead($iv_Address, $ah_Handle, $sv_Type = 'char[21]')

    [/autoit]


    (aus der UDF)

    Gibt es da die Möglichkeit, die Länge des ausgelesenen Wertes zu bestimmen, weil das auf 21 zu fixieren macht natürlich keinen Sinn. Leider waren meine Bemühungen in dieser Richtung bisher vergebens.


    Danke vielmals im voraus

  • nimm einfach 500, dann passt das schon :)
    Gib für die Labels auch noch width an un leg es auf 200 fest :)

  • Moin MisterBill,

    also progandy meinte folgendes :

    [autoit]

    GUICtrlCreateLabel("Name: ", 5, 10, 200)
    GUICtrlCreateLabel("Zeny: ", 5, 30, 200)

    [/autoit]


    und dann werden die Texte nicht mehr abgeschnitten.
    Damit du einen Text aus dem Speicher auslesen kannst brauchst du ein char-Array. Normalerweise nimmt man eine Größe von 255 Zeichen als Buffer. Bei einem Namen reichen aber locker 63 aus. Wenn du die Länge der Rückgabe von '_MemoryRead()' mit 'StringLen()' abfragst müsste eigentlich die richtige Länge rauskommen.

  • Soweit alles mal umgesetzt und bin auch recht zufrieden damit, danke bis dahin. Nun habe ich aber eine weiter Frage, die mit 'WinGetProcess' zutun hat. Damit lese ich ja die 'pid' des Fensters aus was aber problematisch wird, wenn zwei davon geöffnet sind. Ich habe mir zwar schon 'ProcessList' angeschaut, werde aber nicht ganz schlau daraus. Vorstellen tue ich mir das folgendermassen, sobald mehrere Fenster mit dem gleichen Namen offen sind, gibt es im Programm zB. mit 'GUICtrlCreateCombo ' eine Auswahl, wo man die 'pid' wählen kann.

    Geht das überhaupt wie ich mir das vorstelle, kann man über 'GUICtrlCreateCombo' eine solche Auswahl in Abhängikeit aus- bzw. einblenden oder muss diese immer da sein? Und könnt ihr mir bei der Lösung helfen? Danke wie immer und Mfg

  • Schalte ein Fenster mit der Auswahl dazwischen, wenn du mehrere PIDs hast.
    Also z.B. so:

    Spoiler anzeigen
    [autoit]

    $prozess = InputBox("Prozess","Prozessname angeben","explorer.exe")
    $array = ProcessList($prozess)
    If @error Then
    Exit
    ElseIf $array[0][0] = 0 Then
    Exit MsgBox(0,$prozess,"Kein Prozess mit diesem Name")
    ElseIf $array[0][0] = 1 Then
    MsgBox(0, $prozess, "1 Prozess gefunden mit PID = "&$array[1][1])
    Else
    MsgBox(0, $prozess, "Mehrere Prozesse gefunden! Anzahl:" &$array[0][0] & @CRLF &@CRLF & "Hier die GUI mit ComboBox machen :)")
    EndIf

    [/autoit]
  • Über ein zusätzliches Fenster will ich das nicht machen, sondern es in das bestehende integrieren. Ich habe auch schon etwas gefunden, einen Process_Selector der von der Funktionalität wahrscheinlich passen würde. Leider bekomme ich das nicht auf meine Bedürfnisse angepasst und eingebaut. Mit 'ProcessList' kann ich mir ja die besagten gleichen Prozesse auslesen. Ich bekomme die Werte dann aber nicht in die Liste.

    [autoit]

    For $i = 1 to $Process_List[0][0]
    $Combo_List &= "|" & $Process_List[$i][0]
    Next

    GUICtrlSetData($Process_Box, $Combo_List)

    [/autoit]

    Vermute mal das ist diese Stelle hier. Danach muss ich doch theoretisch mit 'GUICtrlRead' nur noch den ausgewählten Prozess übergeben. Muss ich das auch komplett als Funktion machen oder kann ich diesen Process_Selector soweit herunterkürzen auf das Benötigte?

    Wenn ihr mir helfen könntet wäre das klasse, bevor ich total verzweifle. Mfg

  • Ich habe mir inzwischen noch etwas Gedanken über die Funktionsweise gemacht und auch einige Versuche gestartet, leider aber ohne den gewünschten Effekt. Ich bekomme die ComboBox bzw. die ganze Funktion um das auswählen mit der ComboBox nicht in mein kleines Programm eingebaut.

    Gedacht habe ich mir das so, das ich für den ersten Durchlauf die Pid mit WinGetProcess hole und danach in der Schleife dann immer mit ProcessList auf das spezielle Programm und dessen Pids prüfe, anzeige und zur Wahl über die ComboBox stelle. Vielleicht hat jemand eine Idee, wie ich das umsetzten kann.


    Vielen Danke und Mfg

  • Kann mir wohl keiner bei dem Problem mit 'GUICtrlCreateCombo' helfen, scheint auch schwierig zu sein. Ich komme aber auch auf keinerlei Idee wie ich das angehen kann. Wie auch immer, danke an alle die mir bis hier her geholfen haben.


    Mfg

  • Hat mich zwar einige Zeit und vor allem Nerven gekostet, aber prinzipiell funktioniert die Sache nun wie gedacht. Ich lese die unterschiedlichen PIDs der gleichen Anwendung aus und kann sie dann über die ComboBox auswählen. Leider gibt es nun aber weitere Schwierigkeiten. Die Pause(Sleep) ist aktuell auf 100, soll aber eigentlich auf 5000 doch wenn ich das machen, gibt es keine Reaktion mehr vom Programm. Darüber hinaus hat der Cancel Knopf offensichtlich keine Funktion mehr, ich kann mir aber nicht erklären warum.

    Ich würde mich freuen, wenn ihr euch die Sache mal anschauen könntet und vielleicht Lösungen oder auch allgemeine Verbesserungen habt für mich. Folgend der aktuelle Code.

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #include <NomadMemory.au3>
    #include <String.au3>
    #NoTrayIcon

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

    Local $processList, $comboList, $i, $pid, $quitButton

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

    Opt("TrayAutoPause", 0)
    Opt("TrayMenuMode", 1)
    Opt("GUIOnEventMode", 0)
    $Gui = GUICreate("Watch", 200, 104)

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

    $varName = IniRead("Watch.ini", "Address", "Name", "NotFound")
    $varGeld = IniRead("Watch.ini", "Address", "Geld", "NotFound")
    $pid = WinGetProcess("...")
    GUISetOnEvent($GUI_EVENT_CLOSE, "Close_Or_Quit_Clicked")
    $quitButton = GUICtrlCreateButton("Cancel", 148, 76, 50)
    GUICtrlSetOnEvent($quitButton, "Close_Or_Quit_Clicked")
    GUICtrlCreateLabel("Name: ", 5, 10)
    GUICtrlCreateLabel("Geld: ", 5, 30)
    GUICtrlCreateLabel("Prozess: ", 5, 60)
    $text = GUICtrlCreateLabel("", 55, 60, 50)
    $comboBox = GUICtrlCreateCombo("", 5, 80, 110, 200, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL))
    $controlName = GUICtrlCreateLabel("", 45, 10, 200)
    $controlGeld = GUICtrlCreateLabel("", 45, 30, 200)
    GUISetState(@SW_SHOW)

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

    $processList = ProcessList("...")

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

    For $i = 1 to $processList[0][0]
    $comboList &= "|" & $processList[$i][1]
    Next

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

    GUICtrlSetData($comboBox, $comboList)

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

    While 1
    $Msg = GUIGetMsg()
    Switch $Msg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $comboBox
    $pid = GUICTRLRead($comboBox)
    GUICTRLSetData($text, $pid)
    EndSwitch

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

    $info = _MemoryOpen($pid)
    $varName_read = _MemoryRead("0x" & $varName, $info)
    $varGeld_read = _MemoryRead_dword("0x" & $varGeld, $info)
    $varGeld_format = _StringAddComma($varGeld_read)
    _MemoryClose($info)

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

    GUICtrlSetData($controlName, $varName_read)
    GUICtrlSetData($controlGeld, $varGeld_format)

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

    Sleep(100)
    WEnd

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

    Func Close_Or_Quit_Clicked()
    Exit
    EndFunc

    [/autoit]

    Vielen Dank und einen schönen Sonntag noch. Mfg

    • Offizieller Beitrag

    Hallo,

    Du musst dich schon entscheiden ob Du im MessageLoop-Modus oder im OnEvent-Modus arbeiten willst. Im moment Arbeit dein Programm im MessageLoop-Modus da kann der Cancel-Button nicht funktionieren weil er nicht abgefragt wird.

    einfach die Zeile:

    [autoit]

    Case $GUI_EVENT_CLOSE

    [/autoit]

    ersetzen durch

    [autoit]

    Case $GUI_EVENT_CLOSE, $quitButton

    [/autoit]

    dann sollte der Cancel Button auch funktionieren. Die Zeilen mit GUISetOnEvent(.....) und die Funktion Close_Or_Quit_Clicked kannst Du dann löschen, die werden nur im OnEvent-Modus benötigt.

    Was soll ein Sleep(5000) bringen?