C++ cUrl Eingeloggt bleiben

Jonas Meyer

Mitglied
Hallo,
ich habe ein kleines Programm erstellt wo ich ein Browsergame(travian.de) ein bisschen einlese also mich einlogge und dann Werte auslese leider komm ich nicht weiter und zwar möchte ich eine neue Url öffnen und dann bin ich nicht mehr eingeloggt. Die Cookies habe ich an glaub ich zu mindestens.

Der Code:

C++:
 #include <string> 
 #include <iostream> 
 #include <fstream>
 #include <curl.h>

using namespace std; 

static char errorBuffer[CURL_ERROR_SIZE]; 
 

static string buffer; 

void Build(int id);
void StundeProdie(static string buffer);
void EinheitenAusgabe(static string buffer);
void AusgabeRohstofffelder(static string buffer);


static int writer(char *data, size_t size, size_t nmemb, string *buffer) 
 { 
 int result = 0; 
 if (buffer != NULL) 
 { 
 buffer->append(data, size * nmemb); 
 result = size * nmemb; 
 }
 return result; 
} 

 CURL *curl; 
 CURLcode result; 

 int main(int argc, char* argv[]) 
 { 

 string useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0";
 
 curl = curl_easy_init();
 

 if (curl) 
 { 

	 // Config
	 curl_easy_setopt(curl, CURLOPT_URL, "http://ts2.travian.de/dorf1.php");
	 curl_easy_setopt(curl, CURLOPT_USERAGENT,useragent.c_str()); 
	 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=NAME&password=PASSWORT&s1=Einloggen&w=1366%3A768&login=1352499815"); 
	 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 
	 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
	 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
	 curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1 );
	 curl_easy_setopt(curl, CURLOPT_REFERER, "http://ts2.travian.de/");
	 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "" );
	 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "" );


	 result = curl_easy_perform(curl); 

	 if (result == CURLE_OK) 
	 { 
		 fstream datei;
		 datei.open("travTest.html", ios::out);
		 datei << buffer << endl;
		 datei.close();
	 }

	 EinheitenAusgabe(buffer);
	 StundeProdie(buffer);
	 AusgabeRohstofffelder(buffer);
	 Build(1);
 } 
 curl_easy_cleanup(curl); 
 system("PAUSE");
 return 0;
 } 

 void AusgabeRohstofffelder(static string buffer){
	 int begin		= 0;
	 int exit		= 0;
	 int anfang		= 0;
	 int ende		= 0;
	 int length     = 0;
	 char ausgabe[128];

	 begin		= buffer.find("class=\"village1\"><map name=\"rx\"");
	 exit		= buffer.find("</map>", begin);

	 ende = begin;

	 for(int i = 0; i < 18; i++){
		 anfang = buffer.find("alt=\"", ende);
		 ende   = buffer.find("\"/>",anfang);
		 length	= buffer.copy(ausgabe, (ende - (anfang+5)), anfang+5);
		 ausgabe[length]	= '\0';
		 cout << ausgabe << endl;
	 }
 }

 void Build(int id){

 CURL *curl; 
 CURLcode result;
 string buffer2;


 string useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0";
 
 curl = curl_easy_init(); 
 if (curl) 
 { 
	 char urladresse[256] = "http://ts2.travian.de/build.php?id=1";

	 curl_easy_setopt(curl, CURLOPT_URL, urladresse);
	 curl_easy_setopt(curl, CURLOPT_USERAGENT,useragent.c_str()); 
	 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 
	 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer2);
	 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
	 curl_easy_setopt(curl, CURLOPT_REFERER, "http://ts2.travian.de/dorf1.php");
	 curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1 );
	 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
	 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "");

 
	 result = curl_easy_perform(curl); 


	 if (result == CURLE_OK) 
	 { 
		 fstream datei2;
		 datei2.open("travTestBau.html", ios::out);
		 datei2 << buffer2 << endl;
		 datei2.close();
	 }else{
		 cout << "error!" << endl;
	 }
	}
 }

 void StundeProdie(static string buffer){
	 int	rohstoffe			= 0;
	 int	res					= 0;
	 int	ende				= 0;
	 int	length				= 0;
	 char	nameRohstoff[64];
	 char	nameAusgabe[64];
	 char	anzahlRohstoff[30];

	 rohstoffe					= buffer.find("Produktion pro Stunde:");
	 
	 for(int i = 0; i < 4; i++)
	 {
		 res					= buffer.find("\"num\">", rohstoffe);
		 if(res == string::npos)
			 break;
		 ende					= buffer.find("</td>", res);
		 if(ende == string::npos)
			 break;
		 length					= buffer.copy(nameRohstoff, (ende - (res+6)), res+6);
		 nameRohstoff[length]	= '\0';
		 int j = 0;
		 int l = 0;
		 for(; l < 64; l++){
			 if((nameRohstoff[l] != '	')&&(nameRohstoff[i] != '\n')){
				 nameAusgabe[j] = nameRohstoff[l];
				 j++;
			 }
		 }


		 switch(i){
		 case 0:
			 cout << "Holz: ";
			 break;
		 case 1:
			 cout << "Lehm: ";
			 break;
		 case 2:
			 cout << "Eisen: ";
			 break;
		 case 3:
			 cout << "Getreide: ";
			 break;
		 default:
			 cout << "Error in StundeProdie(); " << endl;
			 break;
		 }
		 int Result;
		 Result = atoi(nameAusgabe);

		 rohstoffe = ende;
		 cout << Result << endl;
	 }
			 
 }

 void EinheitenAusgabe(static string buffer)
{
	 int	einheiten			= 0;
	 int	numEinheitenAnfang	= 0;
	 int	numEinheitenEnde	= 0;
	 int	naEinheitenAnfang	= 0;
	 int	naEinheitenEnde		= 0;
	 int	length				= 0;
	 char	einheitenAnzahl[26];
	 char	einheitenName[25];

	 einheiten					= buffer.find("Einheiten");

	 while(einheiten != -1)
	 {
		 numEinheitenAnfang			= buffer.find("\"num\">", einheiten);
		 if(numEinheitenAnfang == string::npos)
			 break;
		 numEinheitenEnde			= buffer.find("</td>", numEinheitenAnfang);
		 //if(numEinheitenEnde == string::npos)
			// break;
		 length						= buffer.copy(einheitenAnzahl,(numEinheitenEnde - (numEinheitenAnfang+6)) , numEinheitenAnfang+6);
		 einheitenAnzahl[length]	= '\0';

		 naEinheitenAnfang			= buffer.find("\"un\">", einheiten);
		 //if(naEinheitenAnfang == string::npos)
			// break;
		 naEinheitenEnde			= buffer.find("</td>", naEinheitenAnfang);
		 //if(naEinheitenEnde == string::npos)
			// break;
		 length						= buffer.copy(einheitenName,(naEinheitenEnde - (naEinheitenAnfang+5)) , naEinheitenAnfang+5);
		 einheitenName[length]		= '\0';

		 cout << einheitenName;
		 cout << ": " << einheitenAnzahl << endl;

		 einheiten = naEinheitenEnde;
	}
}
 
Zuletzt bearbeitet von einem Moderator:
Die Cookies habe ich an glaub ich zu mindestens.

C++:
	 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "" );
	 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "" );

Eben nicht. Du musst da einen absoluten Pfad für das Cookie-File eintragen. Denn wie schon die Doku sagt:

CURLOPT_COOKIEFILE

Tell libcurl to activate the cookie engine, and to read the initial set of cookies from the given file. Read-only.

CURLOPT_COOKIEJAR

Tell libcurl to activate the cookie engine, and when the easy handle is closed save all known cookies to the given cookiejar file. Write-only.

Wenn libcurl nicht weiß, wohin die Cookies gespeichert werden sollen, kann es keine Cookies speichern ;-)
 
Zuletzt bearbeitet von einem Moderator:
Also muss ich da schreiben: curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "MyCookie" ); oder muss ich ne Variable erstellen? Von welchen Typ oder kann ich das in einer Txt speichern. Das habe ich nirgendwo gefunden. Und irgendwo stand bei "" macht er das von alleine.
 
Also muss ich da schreiben: curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "MyCookie" ); oder muss ich ne Variable erstellen? Von welchen Typ oder kann ich das in einer Txt speichern. Das habe ich nirgendwo gefunden. Und irgendwo stand bei "" macht er das von alleine.

Hmm, ich muss zugeben, ich hab damit noch nichts gemacht, aber das Manual ist eindeutig. Du müsstest als Paramter (wo du "MyCookie" hingeschrieben hast) den Pfad zu einer Datei schreiben, in der die Cookie-Daten abgelegt werden sollen. So wie es jetzt geschrieben steht, würde libcurl versuchen, eine Datei mit dem Namen "MyCookie" im aktuellen Verzeichnis (wo auch immer das gerade ist) zu suchen oder zu schreiben. Besser wäre es, einen Pfad vorzugeben. Ob das eine .txt ist, dürfte egal sein.
 
Ok,
das knapp immer noch nicht.
C++:
 #include <string> 
 #include <iostream> 
 #include <fstream>
 #include <curl.h>

using namespace std; 

static char errorBuffer[CURL_ERROR_SIZE]; 
 

static string buffer; 

void Build(int id);
void StundeProdie(static string buffer);
void EinheitenAusgabe(static string buffer);
void AusgabeRohstofffelder(static string buffer);


static int writer(char *data, size_t size, size_t nmemb, string *buffer) 
 { 
 int result = 0; 
 if (buffer != NULL) 
 { 
 buffer->append(data, size * nmemb); 
 result = size * nmemb; 
 }
 return result; 
} 

 CURL *curl; 
 CURLcode result; 

 int main(int argc, char* argv[]) 
 { 

 string useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0";
 
 curl = curl_easy_init();
 

 if (curl) 
 { 

	 // Config
	 curl_easy_setopt(curl, CURLOPT_URL, "http://ts2.travian.de/dorf1.php");
	 curl_easy_setopt(curl, CURLOPT_USERAGENT,useragent.c_str()); 
	 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=Craftplorer&password=032659&s1=Einloggen&w=1366%3A768&login=1352499815"); 
	 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 
	 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
	 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
	 curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1 );
	 curl_easy_setopt(curl, CURLOPT_REFERER, "http://ts2.travian.de/");
	 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "MyCookies.txt" );
	 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "MyCookies.txt" );


	 result = curl_easy_perform(curl); 

	 if (result == CURLE_OK) 
	 { 
		 fstream datei;
		 datei.open("travTest.html", ios::out);
		 datei << buffer << endl;
		 datei.close();
	 }

	 EinheitenAusgabe(buffer);
	 StundeProdie(buffer);
	 AusgabeRohstofffelder(buffer);
	 Build(1);
 } 
 curl_easy_cleanup(curl); 
 system("PAUSE");
 return 0;
 } 

 void AusgabeRohstofffelder(static string buffer){
	 int begin		= 0;
	 int exit		= 0;
	 int anfang		= 0;
	 int ende		= 0;
	 int length     = 0;
	 char ausgabe[128];

	 begin		= buffer.find("class=\"village1\"><map name=\"rx\"");
	 exit		= buffer.find("</map>", begin);

	 ende = begin;

	 for(int i = 0; i < 18; i++){
		 anfang = buffer.find("alt=\"", ende);
		 ende   = buffer.find("\"/>",anfang);
		 length	= buffer.copy(ausgabe, (ende - (anfang+5)), anfang+5);
		 ausgabe[length]	= '\0';
		 cout << ausgabe << endl;
	 }
 }

 void Build(int id){

 CURL *curl; 
 CURLcode result;
 string buffer2;


 string useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0";
 
 curl = curl_easy_init(); 
 if (curl) 
 { 
	 char urladresse[256] = "http://ts2.travian.de/build.php?id=1";

	 curl_easy_setopt(curl, CURLOPT_URL, urladresse);
	 curl_easy_setopt(curl, CURLOPT_USERAGENT,useragent.c_str()); 
	 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 
	 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer2);
	 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
	 curl_easy_setopt(curl, CURLOPT_REFERER, "http://ts2.travian.de/dorf1.php");
	 curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1 );
	 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "MyCookies.txt");
	 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "MyCookies.txt");

 
	 result = curl_easy_perform(curl); 


	 if (result == CURLE_OK) 
	 { 
		 fstream datei2;
		 datei2.open("travTestBau.html", ios::out);
		 datei2 << buffer2 << endl;
		 datei2.close();
	 }else{
		 cout << "error!" << endl;
	 }
	}
 }

 void StundeProdie(static string buffer){
	 int	rohstoffe			= 0;
	 int	res					= 0;
	 int	ende				= 0;
	 int	length				= 0;
	 char	nameRohstoff[64];
	 char	nameAusgabe[64];
	 char	anzahlRohstoff[30];

	 rohstoffe					= buffer.find("Produktion pro Stunde:");
	 
	 for(int i = 0; i < 4; i++)
	 {
		 res					= buffer.find("\"num\">", rohstoffe);
		 if(res == string::npos)
			 break;
		 ende					= buffer.find("</td>", res);
		 if(ende == string::npos)
			 break;
		 length					= buffer.copy(nameRohstoff, (ende - (res+6)), res+6);
		 nameRohstoff[length]	= '\0';
		 int j = 0;
		 int l = 0;
		 for(; l < 64; l++){
			 if((nameRohstoff[l] != '	')&&(nameRohstoff[i] != '\n')){
				 nameAusgabe[j] = nameRohstoff[l];
				 j++;
			 }
		 }


		 switch(i){
		 case 0:
			 cout << "Holz: ";
			 break;
		 case 1:
			 cout << "Lehm: ";
			 break;
		 case 2:
			 cout << "Eisen: ";
			 break;
		 case 3:
			 cout << "Getreide: ";
			 break;
		 default:
			 cout << "Error in StundeProdie(); " << endl;
			 break;
		 }
		 int Result;
		 Result = atoi(nameAusgabe);

		 rohstoffe = ende;
		 cout << Result << endl;
	 }
			 
 }

 void EinheitenAusgabe(static string buffer)
{
	 int	einheiten			= 0;
	 int	numEinheitenAnfang	= 0;
	 int	numEinheitenEnde	= 0;
	 int	naEinheitenAnfang	= 0;
	 int	naEinheitenEnde		= 0;
	 int	length				= 0;
	 char	einheitenAnzahl[26];
	 char	einheitenName[25];

	 einheiten					= buffer.find("Einheiten");

	 while(einheiten != -1)
	 {
		 numEinheitenAnfang			= buffer.find("\"num\">", einheiten);
		 if(numEinheitenAnfang == string::npos)
			 break;
		 numEinheitenEnde			= buffer.find("</td>", numEinheitenAnfang);
		 //if(numEinheitenEnde == string::npos)
			// break;
		 length						= buffer.copy(einheitenAnzahl,(numEinheitenEnde - (numEinheitenAnfang+6)) , numEinheitenAnfang+6);
		 einheitenAnzahl[length]	= '\0';

		 naEinheitenAnfang			= buffer.find("\"un\">", einheiten);
		 //if(naEinheitenAnfang == string::npos)
			// break;
		 naEinheitenEnde			= buffer.find("</td>", naEinheitenAnfang);
		 //if(naEinheitenEnde == string::npos)
			// break;
		 length						= buffer.copy(einheitenName,(naEinheitenEnde - (naEinheitenAnfang+5)) , naEinheitenAnfang+5);
		 einheitenName[length]		= '\0';

		 cout << einheitenName;
		 cout << ": " << einheitenAnzahl << endl;

		 einheiten = naEinheitenEnde;
	}
}
Mit Pfad geht das gar nicht bei mir.

Cookie.txt
Code:
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This file was generated by libcurl! Edit at your own risk.

ts2.travian.de	FALSE	/	FALSE	0	sess_id	cb509ffe4c79a7278235d2d9bddd383f
#HttpOnly_ts2.travian.de	FALSE	/	FALSE	0	lowRes	0
#HttpOnly_ts2.travian.de	FALSE	/	FALSE	0	T3E	3MWN0YmYwMWZhpjM1UTO2cjOxITMzQjO3YDMzUjNyUzMxoDM6UTMmdTMldjZ1IWZlZzM2QjN3EGOyUTNyYDZ5YGN4YGOjNmZ0MjMxkjOyVmcvxGc0ZWYyNkOxcTOxQjOwMCMjEzN5EDN

Live HTTP Header Mitschnitt

Code:
http://ts2.travian.de/build.php?id=1

GET /build.php?id=1 HTTP/1.1
Host: ts2.travian.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://ts2.travian.de/dorf1.php
Cookie: CAD=108827066%23%23%23%23%23%23; __gads=ID=88abe4a0b25db528:T=1352561991:S=ALNI_MZwNdo8LtWRiEJvuIzZoakfzXbjsg; sess_id=9458870f30ed658f1c05e6c2b597f2af; lowRes=0; T3E=hlDOjJjYkF2NyoTM5UTO2cjOxYTNxQjO1MTMzUjNyUzMxoDM6UTMmdTMldjZ1IWZlZzM2QjN3EGOyUTNyYDZ5YGN4YGOjNmZ0MjMxkjOyVmcvxGc0ZWYyNkOxcTOxQjOwMCMjEzN5EDN

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 11 Nov 2012 16:59:03 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Vary: Accept-Encoding
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Sun, 11 Nov 2012 16:59:02 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
----------------------------------------------------------

Mir ist aufgefallen das beim Einloggen ein Post Packet benutzt wird und bei den Bauen ein GET Packet. Wie stelle ich das denn ein das es GET ist ich hab auf der cUrl Seite mal geschaut aber da gab es nicht mit GET. Post heißst ja "CURLOPT_POSTFIELDS" und muss ich das für GET auch machen?

mfG
 
Zuletzt bearbeitet von einem Moderator:
Ich kann mich ja einloggen aber wenn ich dann ein weitern Link öffne( in der Build Funktion) dann bin ich halt nicht mehr eingeloggt bzw bekomme als Antwort nur die einlogg Seite. Und ich habe ja halt die Cookies gespeichert.
 
Zuletzt bearbeitet:
Ich habe das an beiden stellen im Code so geändert.
C++:
	 if (result == CURLE_OK) 
	 { 
		 fstream datei;
		 datei.open("travTest.html", ios::out);
		 datei << buffer << endl;
		 datei.close();
	 }else{
		 cout << errorBuffer << endl;
	 }

Warum mir die beiden Cookies fehlen kannst du mir nicht sagen oder?
Ich versteh das gar nicht wieso bekomme ich die Cookies denn nicht?
Muss ich noch irgendwas mitschicken das der Server weiß das ich Cookies haben will oder so?

Hab mal die Firefox Cookies gelöscht und dann Mitgeschnitten.
Code:
http://ts2.travian.de/build.php?id=16

GET /build.php?id=16 HTTP/1.1
Host: ts2.travian.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://ts2.travian.de/dorf1.php
Cookie: sess_id=bd5a308c83610509a8bf5bfcc512137b; lowRes=0; T3E=yATNxYTZyQjYmpjMwMjM3cjO0QTM2EjOyMzN4UjNyUzMxoDM6UTMmdTMldjZ1IWZlZzM2QjN3EGOyUTNyYDZ5YGN4YGOjNmZ0MjMxkjOyVmcvxGc0ZWYyNkOxcTOxQjOwMCMjEzN5EDN

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 11 Nov 2012 18:32:49 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Vary: Accept-Encoding
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Sun, 11 Nov 2012 18:32:49 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
----------------------------------------------------------

Diesmal sind es auch nur 3 Cookies.
 
Zuletzt bearbeitet von einem Moderator:
Aha! Das bedeutet, dass der Server die vorderen Cookie-Daten nur unter bestimmten Bedinungen mit schickt. Vermutlich musst du einen Haken setzen, um eingeloggt zu bleiben? Wenn das so ist, musst du beim Einloggen über curl den Wert mit schicken, der auch mitgesendet wird, wenn du den Login über Browser machen würdest. Gibt es einen solchen Haken?

Ich kenne Travian nicht...
 

Neue Beiträge

Zurück