[HowTo] (WinHTTP) Freebies Auslosung

01/31/2013 19:37 Achat#1
Hallo epvp!

Jeder kennt bestimmt die [Only registered and activated users can see links. Click Here To Register...] Section.
In diesem HowTo will ich euch zeigen, wie ihr mit [Only registered and activated users can see links. Click Here To Register...] einen Gewinner auslosen könnt.

Zuerst müssen wir uns mal überlegen, von wo wir die Daten bekommen.
Wir brauchen
  • Eine Liste mit e*Members, die in einem Thread gepostet haben
  • Eine zufallsgenerierte Nummer von Random.org

Nehmen wir jetzt mal an, das hier ist unser Freebies-Thread:

http://www.elitepvpers.com/forum/autoit/l1868201-tratsch-rund-um-autoit-kleinere-fragen.html

Eine Liste mit Members, die in diesem Thread gepostet haben, gibt es hier:
http://www.elitepvpers.com/forum/misc.php?do=whoposted&t=1868201

Der User übergibt uns also später exakt einen Parameter, nämlich die Thread-ID.

Diese hängen wir dann dahinter an:
Code:
http://www.elitepvpers.com/forum/misc.php?do=whoposted&t=
Mit STRG+U schauen wir uns den Quellcode der "Wer hat geschrieben?" Tabelle an.

Hier ein Ausschnitt:
Code:
<a href="members/1548344-lawliet-.html" target="_blank">Lawliet!</a>
<a href="members/4165315-achat.html" target="_blank">Achat</a>
Mit _StringBetween oder besser, mit StringRegExp lesen wir die Links / Membernames in einen Array ein.

Code:
StringRegExp($sDownload,'<a href="(members/.+\.html)" target="_blank">.+</a>', 3)
StringRegExp gibt uns ein Array, eine Tabelle zurück, die etwa so aussieht:
Element Nr.Inhalt
00members/1548344-lawliet-.html
01members/4165315-achat.html
02members/3483496-butter123.html
03members/1971139--storm-.html
04members/3089829-dr-toni.html
05members/456848-lolkop.html
06members/984054-der-eddy.html
07members/4136881-lumi-.html
08members/3383841-freddy-.html
09members/1219971-kdeluxe.html

Nun ermitteln wir einen Gewinner. Dafür muss eine zufällige Zahl von 0 bis 9 generiert werden, also von 0 bis Ubound($aRegExp)-1

Ubound($aRegExp) würde 10 zurück geben, da der Array 10 Elemente hat. Es haben in diesem Thread also 10 verschiedene Member geposted.

Das letzte Element ist aber 9, also Ubound($aRegExp)-1

Zuletzt öffnen wir das Profil des Gewinners mit
Code:
ShellExecute('http://www.elitepvpers.com/forum/' & _TrueRandom(0,Ubound($aRegExp)-1))

~~~

So, das war jetzt der logische Aufbau des Programms.
Kommen wir nun zur Benutzung von WinHttp.
Die *.au3 werde ich unten anhängen, sie enthält im Vergleich zum Original noch eine Proxy Funktion, welche aber für dieses Programm belanglos ist.
Wir benötigen Firefox und das Add-On [Only registered and activated users can see links. Click Here To Register...]

Ein Request mit WinHTTP ist meistens so aufgebaut:
Code:
	Local $hSession = _WinHttpOpen()
	Local $hConnect = _WinHttpConnect($hSession, 'ServerName')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', 'Path')

	_WinHttpCloseHandle($hConnect)
	_WinHttpCloseHandle($hSession)
Die genauen Parameter für die Funktionen erhaltet ihr, in dem ihr auf die Funktion klickt und dabei STRG+J drückt. Zurück kommt ihr mit STRG+J+SHIFT.

Öffnet jetzt LiveHttpheaders und navigiert zu
[Only registered and activated users can see links. Click Here To Register...]

Im Tab Header werdet ihr förmlich von einem Packet erschlagen,

Code:
http://www.elitepvpers.com/forum/misc.php?do=whoposted&t=1868201

GET /forum/misc.php?do=whoposted&t=1868201 HTTP/1.1
Host: www.elitepvpers.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.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
DNT: 1
[strike]
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 31 Jan 2013 21:46:20 GMT
Content-Type: text/html; charset=ISO-8859-1
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=15
Content-Encoding: gzip
Vary: Accept-Encoding
Cache-Control: private
Pragma: private
X-UA-Compatible: IE=7[/strike]
Keine Sorge, wir brauchen davon nicht alles.
Das obere ist unsere Anfrage, der untere Block die Antwort vom Server, diese fällt also schon mal weg.

Code:
	Local $hConnect = _WinHttpConnect($hSession, 'ServerName')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', 'Path')
Wir benötigen also den ServerName aka Host, den Pfad und den Typ, GET oder POST.

Code:
http://www.elitepvpers.com/forum/misc.php?do=whoposted&t=1868201

GET /forum/misc.php?do=whoposted&t=1868201 HTTP/1.1
Host: www.elitepvpers.com
1. gesamte URL, wie wir sie im Browser eingegeben haben
2. Typ des Request, nämlich GET und der Pfad.
3. Unser elite Host, elitepvpers.com, das www. brauchen wir nicht.

Code:
	Local $hConnect = _WinHttpConnect($hSession, 'elitepvpers.com')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', '/forum/misc.php?do=whoposted&t=' & $iThreadID)
Nach dem Downloaden und auslesen der Member, brauchen wir eine zufallsgenerierte Nummer. Von Random.org. Es würde auch mit Random() funktionieren, aber Random() ist nur pseudo-Random(), also qualitativ ungeeignet für uns.

Navigiert zu [Only registered and activated users can see links. Click Here To Register...]. Daraufhin bei LiveHttp Headers auf löschen klicken.

Bei Random.org gibt es den "True Random Number Generator", zwei Eingabefelder und einen Button zum generieren der Zufallszahl.

In diesem Beispiel lasse ich eine Zahl zwischen 13 und 1337 generieren, wobei 13 und 1337 inbegriffen sind.

Das Packet sieht etwa so aus:
Code:
http://www.random.org/integers/?num=1&min=13&max=1337&col=1&base=10&format=plain&rnd=new

GET /integers/?num=1&min=13&max=1337&col=1&base=10&format=plain&rnd=new HTTP/1.1
Host: www.random.org
Jetzt erfolgt einfaches Einsetzen:

Code:
	Local $hConnect = _WinHttpConnect($hSession, 'ServerName')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', 'Path')
Code:
	Local $hConnect = _WinHttpConnect($hSession, 'random.org')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', '/integers/?num=1&min=13&max=1337&col=1&base=10&format=plain&rnd=new')
Unsere 13 & 1337 ersetzen wir durch Variablen und bauen uns daraus eine Function

Code:
Func _TrueRandomNumber($iMin, $iMax)
	Local $hSession = _WinHttpOpen()
	Local $hConnect = _WinHttpConnect($hSession, 'random.org')
	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', '/integers/?num=1&min=' & $iMin & '&max=' & $iMax & '&col=1&base=10&format=plain&rnd=new')
	ClipPut($sDownload)
	_WinHttpCloseHandle($hConnect)
	_WinHttpCloseHandle($hSession)
EndFunc   ;==>_TrueRandomNumber
$sDownload lassen wir uns in die Zwischenablage kopieren, bzw über Consolewrite ausgeben.

Wir erhalten eine Zufallszahl und ein @CRLF, eine neue Zeile. Wir wollen aber nur die Zahl, diese bekommen wir mit
Int($sDownload)

Et voilà, wir sind fertig.

Zu beachten ist noch, dass wenn ihr eure Quote bei Random.org verbraucht habt [Only registered and activated users can see links. Click Here To Register...], ein String mit einer Fehlermeldung zurückgegeben wird. Int($sDownload) wird dann immer 0 zurück geben, bis sich eure Quote wieder aufgeladen hat. Bei normaler Nutzung wird die Quote aber niemals aufgebraucht.


Hier das fertige Script:
Code:
#cs ----------------------------------------------------------------------------

	AutoIt Version: 3.3.8.1
	Author:         Achat
	www.elitepvpers.com

	Script Function:
	Freebies auslosen.
	Example script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here

#include <WinHTTP.au3>

ShellExecute(_FreebiesGetWinner(1868201))

Func _FreebiesGetWinner($iThreadID)
	If Not StringIsAlNum($iThreadID) Then Return SetError(1, 0, 'Error')

	Local $hSession = _WinHttpOpen()
	Local $hConnect = _WinHttpConnect($hSession, 'elitepvpers.com')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', '/forum/misc.php?do=whoposted&t=' & $iThreadID)

	_WinHttpCloseHandle($hConnect)
	_WinHttpCloseHandle($hSession)

	Local $aRegExp = StringRegExp($sDownload, '<a href="(members/.+\.html)" target="_blank">.+</a>', 3)
	If Not IsArray($aRegExp) Then Return SetError(2, 0, 'Error')

	Local $sWinner = $aRegExp[_TrueRandomNumber(0, UBound($aRegExp) - 1)]

	Return 'http://elitepvpers.com/forum/' & $sWinner
EndFunc   ;==>_FreebiesGetWinner

Func _TrueRandomNumber($iMin, $iMax)
	Local $hSession = _WinHttpOpen()
	Local $hConnect = _WinHttpConnect($hSession, 'random.org')

	Local $sDownload = _WinHttpSimpleRequest($hConnect, 'GET', '/integers/?num=1&min=' & $iMin & '&max=' & $iMax & '&col=1&base=10&format=plain&rnd=new')

	_WinHttpCloseHandle($hConnect)
	_WinHttpCloseHandle($hSession)

	Return Int($sDownload)
EndFunc   ;==>_TrueRandomNumber
Fragen, Anregungen, Kritik etc. sind immer willkommen :)

MfG