ich möchte mit euch nach und nach ein eignen Browsergame bot in C# Basteln.
ich habe mir jetzt irgendein Browsergame genommen und dachte mir das für den Anfang Shakes und Fidget ganz gut ist da es schon viele Bots dazu gibt.
mein ziel ist es in diesen Kapitel sich einloggen zu können und auch sich wieder auszuloggen.
da werden wir mit unter analysieren wie wir vorgehen müssen und und anschauen was so alles passiert wenn wir und im Browser einloggen.
ich benutze dafür Mozilla Firefox und das addon Live HTTP Header 0.17, wahrscheinlich, wenn ihr das liest, gibt es schon neuere Versionen.
__________________________________________________ _____
Einloggen mit den Browser.
Jeder kennt das sicherlich, man sieht dieses kleine Feldchen einloggen, und man soll irgendwas eingeben....aber nur was?
ich würde vermuten wir erstellen einfach ein neuen Account und versuchen dann es mit diesen Daten.
Mein Charakter den ich erstellt habe heißt ShaShu123 und das Passwort ist 123456.(dieser ist nur ein Beispiel)
bevor wir uns aber einloggen öffnen wir unser neuen schönes addon HTTP headers:
und dann taucht auch schon ein Fenster auf, da werden so ziemlich alle Informationen gezeigt die unser Browser mit den Server austauscht.
ich logge mich mit ShaShu123 ein und es werden sehr viele Informationen Angefragt wie ihr seht.
__________________________________________________ _____
Wie baue ich das mit meinen eignen Bot nach?
dazu müssen wir jetzt analysieren was da überhaupt übersendet wurde.
der erste Befehl den der Browser zum Server gesendet hat war:
http://s1.sfgame.de/request.php?req=0000000000000000000000000000000000 2ShaShu123%3Be10adc3949ba59abbe56e057f20f883e%3Bv1 .60&random=%2&rnd=815509581349780834661
und diesen gilt jetzt auseinander zu nehmen.
versucht am besten etwas zu überlegen bevor ihr weiter macht.
für mich auf den ersten blick sieht das http://s1.sfgame.de für mich wie der Server aus den wir benutzen. das kann also auch s2 oder s8 oder gar s9.sfgame.to sein.
das request.php?req= steht dafür das unser Browser seine anfrage gemacht zu einen bestimmten Punkt.
das 00000000000000000000000000000000002 kann ich nur vermuten das der Server als ziel angegeben ist und mit 00000000000000000000000000000000001 der Client(Browser) angesprochen wird.
jetzt wird es interessant, ShaShu123 ist unser Name den wir verschickt haben, wir wissen schon mal an welcher stelle dieser ist und können den vielleicht austauschen.
%3B und %3 Sind anscheindend die angeben wo das passwort anfängt und endet.
was ist mit unseren Passwort passiert? es sieht so komisch aus aus wirren Buchstaben und zahlen: 3Be10adc3949ba59abbe56e057f20f883e.
dies finden wir später heraus.
danach wird unsere Flash Version übersendet mit Bv1.60.
mit &random=%2&rnd= wird beschied gesagt das dieser eine zufällige zahl übersendet: 815509581349780834661
phew das war eine ganze menge Arbeit für so ein kurzes Stück Text.
wenn ihr wollt könnt ihr euch ausloggen und versuchen mit den gleichen Link den ihr zum einloggen benutzt habt einfach in den Browser eingeben.
ihr werdet verblüfft sein was ihr seht. (dies brauchen wir später noch)
__________________________________________________ __
Erstellung eines Programmes
Wir haben jetzt den Link und deren Bestandteile um sich einloggen zu können.
Nun machen wir auch das Programm dazu, ich öffne in Visual Studio ein neues C# Projekt und Mache eine Windows-Form Anwendung.
ich habe mir zu Hilfe ein paar snippets rausgesucht aus dem Internet, dieser sollte uns helfen.
GetUrlResponse, das fragt auf der Angegebenden internetseite informationen ab.
Code:
public static string GetUrlResponse(string url, string username, string password)
{
string content = null;
WebRequest webRequest = WebRequest.Create(url);
if (username == null || password == null)
{
NetworkCredential networkCredential = new NetworkCredential(username, password);
webRequest.PreAuthenticate = true;
webRequest.Credentials = networkCredential;
}
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII);
StringBuilder contentBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
contentBuilder.Append(sr.ReadLine());
contentBuilder.Append("\r\n");
}
content = contentBuilder.ToString();
return content.ToString();
}
Code:
static string getMd5Hash(string input)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SFBot
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string GetUrlResponse(string url, string username, string password)
{
string content = null;
WebRequest webRequest = WebRequest.Create(url);
if (username == null || password == null)
{
NetworkCredential networkCredential = new NetworkCredential(username, password);
webRequest.PreAuthenticate = true;
webRequest.Credentials = networkCredential;
}
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII);
StringBuilder contentBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
contentBuilder.Append(sr.ReadLine());
contentBuilder.Append("\r\n");
}
content = contentBuilder.ToString();
return content.ToString();
}
}
}
Nun zum eigentlichen, wir haben ja unser Weblogin auseinander genommen und können nun mithilfe
Wenn der Knopf gedrückt wurde soll der die abfrage machen, also erstellen wir ein Ereignis für denk Knopf.
ich möchte das der label den wir hinzugefügt haben das Ergebnis unseres Login Versuches ausgibt, also:
label1.Text = GetUrlResponse("http://s1.sfgame.de/request.php?req=0000000000000000000000000000000000 2ShaShu123%3Be10adc3949ba59abbe56e057f20f883e%3Bv1 .60&random=%2&rnd=815509581349780834661","","");
das ganze sieht bei mir jetzt so aus:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SFBot
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = GetUrlResponse("http://s1.sfgame.de/request.php?req=00000000000000000000000000000000002ShaShu123%3Be10adc3949ba59abbe56e057f20f883e%3Bv1.60&random=%2&rnd=815509581349780834661","","");
}
public static string GetUrlResponse(string url, string username, string password)
{
string content = null;
WebRequest webRequest = WebRequest.Create(url);
if (username == null || password == null)
{
NetworkCredential networkCredential = new NetworkCredential(username, password);
webRequest.PreAuthenticate = true;
webRequest.Credentials = networkCredential;
}
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII);
StringBuilder contentBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
contentBuilder.Append(sr.ReadLine());
contentBuilder.Append("\r\n");
}
content = contentBuilder.ToString();
return content.ToString();
}
}
}
falls das nicht der Fall ist dann ist an euren Link was falsch.
Meine Projektdaten bis zu den Zeitpunkt:

__________________________________________________ __
Ich will mich aber mit ein anderen Charakter einloggen!
ich erstelle für die Form 2 neue Textboxen für Name und Passwort.
bei mir sieht das momentan so aus:
jetzt wird das an der zeit das wir die schöne lange URL im Script auseinander nehmen.
wir hatten das ja schon bei der Analyse gemacht und nun verwirklichen wir das, indem wir bei unseren GetUrlResponse das auch einsetzen.
für das Passwort brauchen wir unser getMd5Hash um es in MD5 umzuwandeln.
ich habe es jetzt bei mir so zu stehen:
label1.Text = GetUrlResponse("http://s1.sfgame.de/request.php?req=0000000000000000000000000000000000 2" + textBox1.Text + "%3B" + getMd5Hash(textBox2.Text) + "%3Bv1.60&random=%2&rnd=815509581349780834661","", "");
wenn ich mich jetzt versuche einzuloggen über unsere Form Zeigt der mir alles Korrekt an.
wer möchte kann jetzt ein anderen Account zum einloggen benutzen.
mein gesammtes Script zu den zeitpunkt:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SFBot
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = GetUrlResponse("http://s1.sfgame.de/request.php?req=00000000000000000000000000000000002" + textBox1.Text + "%3B" + getMd5Hash(textBox2.Text) + "%3Bv1.60&random=%2&rnd=815509581349780834661", "", "");
}
public static string GetUrlResponse(string url, string username, string password)
{
string content = null;
WebRequest webRequest = WebRequest.Create(url);
if (username == null || password == null)
{
NetworkCredential networkCredential = new NetworkCredential(username, password);
webRequest.PreAuthenticate = true;
webRequest.Credentials = networkCredential;
}
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream(), Encoding.ASCII);
StringBuilder contentBuilder = new StringBuilder();
while (-1 != sr.Peek())
{
contentBuilder.Append(sr.ReadLine());
contentBuilder.Append("\r\n");
}
content = contentBuilder.ToString();
return content.ToString();
}
static string getMd5Hash(string input)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
}
}
Alles was hier glänzt ist das Virtuelle Silber und Gold!
Ich möchte ein Grund haben warum wir uns einloggen, wie ihr euch vielleicht euch schon denken könnt ist das ich sehen möchte wie viel Gold und Silber mein Charakter hat.
Wenn wir uns einloggen bekommen wir eine ganz interessante Sache zurück von unser GetUrlResponse, das sind nämlich alle Informationen die unser Charakter so hat, das kann zum Beispiel sein Level sein, die id des Clans wo dieser drinnen ist.
Bis Jetze haben wir uns die liste in den label auf der Form anzeigen lassen. Unser weg ist jetzt heraus zu finden wie wir drankommen.
dafür Übergeben wir jetze den wert anstatt den label jetze einen string und teilen diesen bei jeden "/". das mach ich mit:
Code:
string Response;
string[] Werte;
private void button1_Click(object sender, EventArgs e)
{
Response = GetUrlResponse("http://s1.sfgame.de/request.php?req=00000000000000000000000000000000002" + textBox1.Text + "%3B" + getMd5Hash(textBox2.Text) + "%3Bv1.60&random=%2&rnd=815509581349780834661", "", "");
Werte = Response.Split(new Char[] { '/' }); // index 13 ist gold
label1.Text = "Der Charakter hat: " + Werte[13] + " Silber";
}
Meine Projektdaten bis zu den Zeitpunkt:

__________________________________________________ __
Ausloggen!
Nachdem wir gesehen haben wie viel Gold wir haben wollen wir uns vielleicht auch ausloggen.
dazu erstellen wir auf der form einen neuen Knopf und machen ein Click Ereignis dahinter.
So jetze kommen wir nun zu Events in Shakes und Fidget. Wer jetze sich ein wenig bereits mit HTTP Headers rumprobiert hat und versucht hat eigne Aktionen gebaut hat werden einige uffäligkeiten gekommen sein.
ich habe mich jetze mit ShaShu123 5 mal ausgelogt und geschaut was bei HTTP Headers passeiert:





Es sieht stark ähnlich aus wie beim einloggen doch ist einiges immer anders. Ich mache das mal hier etwas farblich:
http://s1.sfgame.de/request.php?req=413S061tOkcA5578ez2273u682h2WD51535&random=%2&rnd=18995102901349883080567
http://s1.sfgame.de/request.php?req=42O4039lE573499vBu67115195FCTP73535&random=%2&rnd=4244337341349883141874
http://s1.sfgame.de/request.php?req=5236JT508eG4L0n3W89b4q93Mi71016Q535&random=%2&rnd=117011131349883197148
http://s1.sfgame.de/request.php?req=sC3VD15v5Y8Q15314gV8Y6877i212n2N535&random=%2&rnd=18435726571349883245595
http://s1.sfgame.de/request.php?req=75v8Gk6oi229zcs13Z21141q836EG70r535&random=%2&rnd=1456184931349883272782
die anfrage an
schickt die SessionID mit der aufgabe mit der zufalszahl.Zum Glück wissen wir das meiste schon was wir brauch damit sich der Charakter ausloggen kann, zum einen den Server, den wir ja mit hand eintragen. Die Aufgabe bekommen wir überall heraus wenn wir Einfach die verschiedenen Knöpfe mit HTTP Headers abfragen, Hier für das ausloggen haben wir die 535. Dann noch die zufahlszahl, wo völlig egal ist was da steht. Und die SessionId haben wir aus dem Letzten Kapitel, Stichwort string[] Werte.
Diesen hole ich mir mit:
Code:
string[] SessionIDFilter;
private void button1_Click(object sender, EventArgs e)
{
Response = GetUrlResponse("http://s1.sfgame.de/request.php?req=00000000000000000000000000000000002" + textBox1.Text + "%3B" + getMd5Hash(textBox2.Text) + "%3Bv1.60&random=%2&rnd=815509581349780834661", "", "");
Werte = Response.Split(new Char[] { '/' }); //index 13 ist gold //Index 511 SessionID noch nicht gesplittet
SessionIDFilter = Werte[511].Split(new Char[] { ';' }); //SessionID ist index 2
label1.Text = "Der Charakter hat: " + Werte[13] + " Silber";
}
Mein Script für den 2. Knopf sieht wie folgt aus:
Code:
private void button2_Click(object sender, EventArgs e)
{
label1.Text = "Charakter Ausgeloggt! Debug: " + GetUrlResponse("http://s1.sfgame.de/request.php?req=" + SessionIDFilter[2] + "535" + "&random=%2&rnd=18995102901349883080567", "", "");
}
Meine Projektdaten bis zu den Zeitpunkt:

__________________________________________________ __
ich hoffe ihr konntet etwas durchsehen und könnt vielleicht das für andere Browsergames auch machen und nachvollziehen.
Vieleicht Macht ihr daraus einen richtigen großen bot mit allen Funktionen und einer großen Übersicht des Charakters. oder ihr nutzt dieses Beispiel für das Spiel Kickerstars was genauso einfach ist.
Bei Rechtschreibfehler oder Verbesserungsvorschläge mir einfach eine PM schicken
Mit freundlichen Grüßen Noa3 von Dev-Unit.de







