Browsergame Automatisieren

08/31/2017 10:52 S u n#1
Hallo Epvp'ler,

Ich spiele zur Zeit das Broswergame "Die Stämme".
Da ich seit einiger Zeit während meins Studiums die Sprache C lerne, hab ich mir überlegt, eine "erleichterung" für das Browsergame zu basteln.

Grundlegendes Problem:

In diesem Spiel kann man NPC gesteuerte Dörfer angreifen, um sich die Ressourcen anzueignen. Dies geht am schnellsten über den sogenannten Farmassistentent. Die Dörfer werden untereinander aufgelistet, und können dann per Mausklick auf ein Symbol dahinter, angegriffen werden.
Mit diesem Schema geht man eine Liste von belibig vielen Dörfern durch, bis keine Truppen mehr untätig sind.
Zur Zeit mache ich das ganze von Hand. Durch das Fortschreiten im Spiel, und durchs erobern neuer Dörfer, kommen immer mehr Truppen hinzu. Mittlerweile bin ich bei über 2000 NPC Dörfern, die nacheinander von meinen Truppen angegriffen werden können. Dementsprechend zieht sich ein einmaliges Durchklicken aller Dörfer auf fast 30 Minuten bis zu einer Stunde hinaus.

Gibt es eine möglichkeit, eventuell sogar mit der verwendung von C, diese Vorgänge zu Automatisieren? Nach jedem klick, muss man die Maus ein stück nach unten bewegen, daher eignet sich ein "Auto-clicker" nicht.

Zum Schluss, sollte das grundlegende Programm funktionieren, möchte ich noch eine Art "Pixelscan" einbauen, der bei der Meldung "Es sind nicht genügend Truppen vorhanden, um den Angriff durchzuführen", selbstständig durch die Taste "d", das Dorf wechselt.


Das Browsergame besitzt folgende Sicherheitskontrollen:
-Nicht mehr als 5 Angriffe pro Sekunde abschicken
-Nach einer bestimmten Zeit wird ein Captcha Feld geöffnet

Da ich dieses Programm nicht durchgehend laufen lassen möchte, sondern nur, wenn ich eh am PC sitze, kann ich den Captcha dann per Hand ausfüllen.


Zur Hilfe noch ein Bild vom Aufbau des farmassistenten. :)


Hat jemand Ideen, wie und womit man soetwas programmieren könnte?
Ich bin in C noch nicht weiter, als zu Konsolenanwendungen gekommen. Ist sowas überhaupt mit C möglich?
Ich freue mich über jeden Tipp, und jede Idee!
/Sunliight
08/31/2017 11:03 florian0#2
Klar geht das auch mit C.

Maus bewegen [Only registered and activated users can see links. Click Here To Register...]
Maus klicken [Only registered and activated users can see links. Click Here To Register...]
Pixel farbe [Only registered and activated users can see links. Click Here To Register...]


Alternativ kannst du auch einfach AutoIt Funktionen per Bibliothek verwenden. Wie das geht wird hier erklärt: [Only registered and activated users can see links. Click Here To Register...]
08/31/2017 11:06 S u n#3
Sehr cool! Danke!
Ich schau mir alles mal an. :)

Gibt es irgendwas zu beachten? Kann ich das ganze In VS programmieren? :)
08/31/2017 13:33 gebunden#4
Klar, Visual Studio ist nur eine IDE, ein Editor mit vielen tollen Zusatzfunktionen.
Du könntest das ganze auch in Notepad programmieren und dann selbst kompilieren :P
08/31/2017 19:44 S u n#5
Quote:
Originally Posted by florian0 View Post
Klar geht das auch mit C.

Maus bewegen [Only registered and activated users can see links. Click Here To Register...]
Maus klicken [Only registered and activated users can see links. Click Here To Register...]
Pixel farbe [Only registered and activated users can see links. Click Here To Register...]


Alternativ kannst du auch einfach AutoIt Funktionen per Bibliothek verwenden. Wie das geht wird hier erklärt: [Only registered and activated users can see links. Click Here To Register...]

Ich sehe grade, deine Links oben sind für C++, ich kenne bis jetzt nur Standard C..
Und der AutoIt link klappt nicht.. :D



Quote:
Originally Posted by gebunden View Post
Klar, Visual Studio ist nur eine IDE, ein Editor mit vielen tollen Zusatzfunktionen.
Du könntest das ganze auch in Notepad programmieren und dann selbst kompilieren :P
Haben bis jetzt da nur Konsolenanwendungen geschrieben. :D
Habe noch nie etwas sinnvolles damit angestellt.. :D
08/31/2017 23:11 Red_John#6
In "Die Stämme" würde es sich anbieten, dass ganze mit HTTP Requests abzuwickeln.
08/31/2017 23:53 S u n#7
Quote:
Originally Posted by Red_John View Post
In "Die Stämme" würde es sich anbieten, dass ganze mit Paketen abzuwickeln.
Hast du zufällig dafür ein "Guide"?
Kann mit dem Begriff nichts anfangen...
09/01/2017 00:48 florian0#8
Quote:
Originally Posted by The Sunliight View Post
Ich sehe grade, deine Links oben sind für C++, ich kenne bis jetzt nur Standard C..
Und der AutoIt link klappt nicht.. :D

Haben bis jetzt da nur Konsolenanwendungen geschrieben. :D
Habe noch nie etwas sinnvolles damit angestellt.. :D
Ja, die WinAPI (daher stammen die ganzen Funktionen) ist problemlos in C nutzbar.
Den AutoIt Link hat das Board zensiert ... jedenfalls gibts von AutoIt eine Include-Datei für C (und C++), damit kannst du all die Sachen wie Tasten drücken, Maus bewegen, Pixel suchen, etc. einfach in C verwenden. AU3_API oder so heißt die. Habs auch noch nie verwendet, sah aber einfach aus.

"Mit Paketen arbeiten" heißt in dem Fall, das du statt Mausklicks und Pixelsuche einfach die Daten an den Webserver schickst, die dein Browser senden würde, wenn du den Button drückst. Das ist aber noch ne ganze Ecke komplizierter wie Pixel und Maus, noch dazu in als Anfänger in C.
09/07/2017 09:18 S u n#9
So! :)
Das Programm hab ich jetzt Grundlegend fertig.
Folgendes "kann" es schon:
-Bildschirmgröße einlesen
-Berechnen wo die Button (bei richtiger Browserauflösung 50%) sind
-25 Button klicken
-runter scrollen
-das ganze 4 mal wiederholen
-Seite Wechseln zu den nächsten 100 Dörfern
-weiter machen

Gelöst habe ich das ganze etwas "anfängerhaft" mit SetCursorPos(); und GetCursorPos();, und ein paar while btw. for schleifen.

Jetzt möchte ich eine neue Erweiterung einbringen.
Das Programm soll nur solange laufen, wie ich oder bis ich eine Taste drrücke. Dann soll eine Abfrage kommen ob ich weiter machen möchte, oder ob ich es beenden will. Zur Zeit klickt er 300 mal, und beendet dann erst das Program. Nicht ganz so Ideal.
Ich habe es versucht durch scanf etc zu regeln, und auch etwas rum gegoogelt. Leider finde ich keine gute lösung, bei der das Programm weiterläuft..
Die Abfrage ansich ist einfach. Aber das Programm nur bis zu einem Tastendruck laufen zu lassen, und es dann zu unterbrechen bekomme ich nicht hin..

Gibt es in C eine funktion bzw einen header den ich dafür verwenden kann?

Quote:
Originally Posted by florian0 View Post
.
Quote:
Originally Posted by Red_John View Post
.
Quote:
Originally Posted by gebunden View Post
.
09/07/2017 10:14 florian0#10
Also mit RegisterHotKey ([Only registered and activated users can see links. Click Here To Register...]) kannst du schonma en Hotkey machen.

Jetzt brauchst du nur noch ne Methode dein Programm an beliebiger Stelle zu unterbrechen ... hmm ...


Ich würde ehrlichgesagt zum State-Machine-Pattern greifen. Klingt für mich zwar echt nach Overkill, aber mir fällt gerade keine bessere Methode ein, bei der man nicht in jeder zweiten Zeile den Hotkey prüfen müsste.

Das Konzept ist eigentlich einfach. Du zerlegst dein Programm in Teilschritte. z.B. Eine Seite komplett Abarbeiten wird ein Zustand; und Seite wechseln wird ein Zustand.
Nachdem eine Seite abgearbeitet wurde, wechselt der Zustand auf "Seite wechseln". Wenn die Seite gewechselt wurde gehts weiter mit "Angreifen"; falls es die letze Seite war, wechselst du in den "Ende Zustand".

Nach jedem Zustand wird der globale Hotkey abgefragt.

Bei zwei States kann man natürlich noch nicht an jeder Stelle unterbrechen. Immer nur beim Wechsel zwischen zwei Zuständen. Wenn du noch an weiteren Stellen unterbrechen willst, musst du noch weitere Zustände erstellen.

Code:
enum STATES {
	STATE_ATTACK, STATE_NEXT_PAGE, STATE_END
};


state = STATE_ATTACK;

while (state != STATE_END) {
	
	switch(state) {
		case STATE_ATTACK:

			// komplette Seite abarbeiten

			state = STATE_NEXT_PAGE;
			break;

		case STATE_NEXT_PAGE:
			

			if (aktuelleSeite == letzeSeite) {
				state = STATE_END;
				break;
			}

			// seite wechseln

			// Wieder angreifen			
			state = STATE_ATTACK;

			break;
	}

	// Prüfe ob Hotkey gedrückt
	if (hotkey) {
		// MessageBox (y/n)
		if (msgbox == no) {
			// programm beenden
		}
	}

}
Hoffe, das hat dich jetzt nich umgehauen :S

Gruß
florian0
09/07/2017 10:22 Vloxxity#11
Ich glaub am wirklich einfachsten geht es durch nen Browserplugin?!
ich hab mir vor ner weile mal nen Chrome Plugin für My Free Farm programmiert wo der automatisch ein Feld bepflanzt anstatt dass ich da 120 mal klicken muss pro Feld!
Vor allem irg welche Bots die deine Maus bewegen würden somit ja deinen kompletten PC lahm legen was ja schwachsinnig ist!
09/07/2017 11:12 S u n#12
Quote:
Originally Posted by florian0 View Post
Uff.. Ich verstehe das Grundprinzip. Mit Switch habe ich acuh schon gearbeitet. Ich werde mal versuchen das ganze einzubinden. :D Vielleicht klappt es ja so wie geplant.
Meine Idee war eine Abfrage ähgnlich wie scanf.
So aller !"while(1 != scanf("%d", &unterbrechen) && Sleep(3000))".
Die Idee wäre, er fragt nach 10 Angriffen nach einer eingabe. bei der Eingabe der Zahl 1 als bsp geht er wieder in eine Grundabfrage (10 Dörfer angreifen?, Bot beenden?, Seite wechsel?). Wenn 3 Sekunden lang nichts eingegeben wurde, dann greift er die nächsten 10 Dörfer an.

Ich versuche mich mal weiter. Hab noch so viel, was das Programm können soll, aber nur ein Semester Erfahrung mit C.



Quote:
Originally Posted by Vloxxity View Post
Ich glaub am wirklich einfachsten geht es durch nen Browserplugin?!
ich hab mir vor ner weile mal nen Chrome Plugin für My Free Farm programmiert wo der automatisch ein Feld bepflanzt anstatt dass ich da 120 mal klicken muss pro Feld!
Vor allem irg welche Bots die deine Maus bewegen würden somit ja deinen kompletten PC lahm legen was ja schwachsinnig ist!
Klar KANN es durch so ein Plugin einfacher gehen, klar könnte man es auch im Hintergrund laufen lassen..
Allerdings bin ich erst seit einem Semester überhaupt in C unterwegs. Davor nie Erfahrungen mit sowas gesammelt.
Ich versuche mögflichst viel durch meine "eigenen" Ideen zu basteln, und bin froh wenn es überhaupt irgendwas macht.
Wenn ich ein Programm schrieben könnte, welches im Hintergrund, durchgehend farmt, dann müsste ich auch das Auslesen der meldung fehlender Truppen, den Capcha und noch ein paar andere Sachen irgendwie lösen.. :D
Ich arbeite dran besser zu werden..
09/07/2017 12:24 warfley#13
Quote:
Originally Posted by The Sunliight View Post
while(1 != scanf("%d", &unterbrechen) && Sleep(3000))".
Zunächst einmal wird das so nicht funktionieren, da Sleep 0 zurückgibt falls es erfolgreich war, und sonst die Anzahl an MS zurück gibt die nicht gesleept wurden (falls unterbrochen wurde).
Falls du deine Abbruchbedingung nicht von dem Ergebnis von sleep abhängig machen möchtest kannst du die Komma syntax verwenden
Code:
while(1 != scanf("%d", &unterbrechen) && (Sleep(3000), 1))
Als nächstes möchte ich dich noch zu deinem besten, und zum besten der gesamten Programmierwelt darum bitten, diese Syntax direkt wieder zu vergessen. Im if gehören keine Ausführungen, nur abfragen. Alles andere macht den Code nur unübersichtlich und Fehleranfällig. Außerdem bitte vergiss auch direkt wieder den Tipp mit der Komma Syntax, die ist auch nur Gift für einen schönen wartbaren Code.

Quote:
Die Idee wäre, er fragt nach 10 Angriffen nach einer eingabe. bei der Eingabe der Zahl 1 als bsp geht er wieder in eine Grundabfrage (10 Dörfer angreifen?, Bot beenden?, Seite wechsel?). Wenn 3 Sekunden lang nichts eingegeben wurde, dann greift er die nächsten 10 Dörfer an.

Ich versuche mich mal weiter. Hab noch so viel, was das Programm können soll, aber nur ein Semester Erfahrung mit C.
Dafür musst du über Polling abfragen ob ein Keydown im Konsolenpuffer liegt. Das habe ich vor einiger Zeit mal gemacht, allerdings in Pascal. Der Code sollte sich allerdings sehr einfach in C übertragen lassen:
Code:
function ReadChar(Blocking: boolean = True): char;
var
  hstdin: HANDLE;
  irInputRecord: INPUT_RECORD;
  dwEventsRead: DWORD;
  r: DWORD;
begin
  hStdin := GetStdHandle(STD_INPUT_HANDLE); // get handle from STDIn
  GetNumberOfConsoleInputEvents(hstdin, r); // get number of pending events
  if Blocking or (r > 0) then // if there is a event pending (or blocking)
    while ReadConsoleInputA(hStdin, irInputRecord, 1, dwEventsRead) do
      if (irInputRecord.EventType = KEY_EVENT) and
        (irInputRecord.Event.KeyEvent.wVirtualKeyCode <> VK_SHIFT) and
        (irInputRecord.Event.KeyEvent.wVirtualKeyCode <> VK_MENU) and
        (irInputRecord.Event.KeyEvent.wVirtualKeyCode <> VK_CONTROL) then // check if the event is a key press, and if the key is no shift, alt or control key
      begin
        Result := irInputRecord.Event.KeyEvent.AsciiChar; // get the Keycode
        ReadConsoleInputA(hStdin, irInputRecord, 1, dwEventsRead); // remove from pending list
        Exit; // return
      end
      else if not Blocking then // if no event pending, and not blocking
        break; // return
  Result := #0;
end;
Ich habe den Code für dich auch noch kommentiert. Blocking bezeichnet hierbei einfach, ob falls kein Key gedrückt wurde so lange gewartet werden soll bis einer gedrückt wurde, oder falls blocking false ist, wird dann 0 zurückgegeben. Somit kann erkannt werden ob ein Key gedrückt wurde oder nicht.


Ansonsten würde ich es wie florian0 vorgeschlagen hat als Statemachine realisieren. Natürlich kann man das noch schöner machen mit Funktionszeigern und einer generischen Transition Funktion, aber grundlegend sollte das die übersichtlichste Variante darstellen.


Zu guter Letzt noch ein Tipp: Verwende kein C dafür, C lutscht. Auch wenn du für die Uni C lernen musst, würde ich dir empfehlen Privat eine andere Sprache zu verwenden. Zum einen macht es dir das Leben deutlich einfacher, zum anderen lernst du damit auch verschiedene Paradigmen, und das macht es dir einfacher in andere Sprachen zu finden.

Und noch ein Tipp: verwende wirklich HTTP Requests (Warum ein Vorposten die Pakete genannt hat ist mir etwas fremd, Pakete bezeichnet eigentlich die low level Implementierung auf TCP/UDP/IP Basis, du kannst aber einfach eine HTTP Bibliothek verwenden). [Only registered and activated users can see links. Click Here To Register...] bietet sich dafür zum Beispiel an.
09/08/2017 14:39 Warnuk3r#14
Für Stämme habe ich mir immer alles mit JavaScript über Tampermonkey und Greasemonkey oder wie die Addons heißen realisiert. Da kannste einfach das Klickevent eines Buttons abfeuern und generell einige Updates einbauen, weil man mit der Seite machen kann was man möchte.
09/09/2017 00:23 DiiViiSioN#15
Hast ne PN. Achja hab dort eines vergessen: C#! :D