View previous topic :: View next topic |
Author |
Message |
Vemundo Veteran
Joined: 31 Jan 2006 Posts: 1372
|
Posted: 29.04.2015 23:09 Post subject: Setetellerautomat |
|
|
gisp! wrote: |
Har du en "setetellerautomat" til overs
|
Inspirert av Gisp så jeg litt nærmere på hva som evt. lar seg gjøre og kom iallefall et stykke på vei.
En "setetellerautomat" vil kunne søke opp kamper med billetter til salgs ved å parse html fra søkesiden til billettservice:
http://www.billettservice...ties=40700
For hver kamp er det da greit å kalkulere URL for sidene med salg av billetter. F.eks. RBK-Start: http://www.billettservice...ter/438513
På kampsiden kjører en flash applikasjon som implementerer kjøp via interaktive salkart. Denne er ikke spesiell for RBK eller Lerkendal, men en generell applikasjon som ticketmaster har laget. Den lesser data (over nett) for hvordan arenaen er utformet, dvs. felt, rader og plasser, fra en fil, og data for hvilke plasser som faktisk er tilgjengelige for salg fra en annen fil.
URL for Lerkendals geometri-fil finner vi fra websiden:
"mapsellURL":"\/seatmap\/proxy\/geometry\/syst-25\/geometry\/TLD12_V07_geometry.xml"
Fra denne kan en slenge på billettservice.no foran og få faktisk URL til filen:
http://www.billettservice...ometry.xml
Denne er den samme fra kamp til kamp, så lenge de ikke endrer på hvilke plasser stadion har. Fila inneholder diverse data, men det relevante er hvordan hvert felt er bygd opp, f.eks. felt VB på REMA tribunen ser slik ut:
Code: | <composite id="REM:VB_49">
<n from="REM-VB,8,8,1,29" map_to="11,16" row_step="1" seat_step="1"/>
<n from="REM-VB,7,7,1,26" map_to="12,16" row_step="1" seat_step="1"/>
<n from="REM-VB,6,6,1,26" map_to="13,16" row_step="1" seat_step="1"/>
<n from="REM-VB,5,5,1,26" map_to="14,16" row_step="1" seat_step="1"/>
<n from="REM-VB,4,4,1,26" map_to="15,16" row_step="1" seat_step="1"/>
<n from="REM-VB,3,3,1,26" map_to="16,16" row_step="1" seat_step="1"/>
<n from="REM-VB,2,2,1,26" map_to="17,16" row_step="1" seat_step="1"/>
<n from="REM-VB,1,1,1,26" map_to="18,16" row_step="1" seat_step="1"/>
</composite>
|
Dette tilsvarer 8 rader, der de 7 første har 26 plasser og den siste har 29. Det er da lett å regne ut hvor mange plasser totalt hvert felt har. Fila inneholder også et antall "plasser" for ØØ som jeg antar styrer hvor mange billetter som kan selges der. Så herfra antar jeg at totalt antall seter til enhvert tid kan sjekkes og sammenlignes mot antall tilgjengelige for salg.
URL for RBK-Start kampens tilgjengelighets-fil finner vi fra websiden:
"availabilityURL":"\/seatmap\/proxy\/availability\/NO\/TLD0315-2015,NO-438513.xml"
Faktisk URL blir da:
http://www.billettservice...438513.xml
Hadde det vært enkelt å få informasjonen om hvilke plasser som er ledige ut av denne fila så hadde en hatt alt en trenger for å automatisere tellinga. Dessverre er det ikke fullt så enkelt. |
|
Back to top |
|
 |
Macha Veteran

Joined: 06 Nov 2008 Posts: 5305
|
Posted: 29.04.2015 23:30 Post subject: |
|
|
God innsats! Men gjør dette innlegget seg bedre under "setetellinger"-tråden?
Last edited by Macha on 29.04.2015 23:31; edited 1 time in total |
|
Back to top |
|
 |
gisp! Legende
Joined: 04 Sep 2008 Posts: 10609
|
Posted: 29.04.2015 23:31 Post subject: |
|
|
Vemundo: Jeg leser alt utenom siste setning med stor entusiasme.
Dog er det altså mulig  _________________ "Det er viktig å gå på banen for å være best mulig sjøl. Men det er langt viktigere å gå på banen for å gjøre medspillerne gode." |
|
Back to top |
|
 |
Vemundo Veteran
Joined: 31 Jan 2006 Posts: 1372
|
Posted: 29.04.2015 23:53 Post subject: |
|
|
xmlfila med tilgjengelighetsdata inneholder ett element "ev_comp", med en base64 enkodet tekststreng. Jeg dekodet denne på OS X, kommandonlinje: base64 -D "filnavn"
Den inneholder da binærkode som tolkes av flash applikasjonen. For å vite hvordan binærkoden skal tolkes må vi finne ut akkurat hva flash applikasjonen gjør med fila når den leses.
Flash applikasjonen for salkartet lastes herfra av billetservice sidene: http://www.billettservice...ISCApp.swf |
|
Back to top |
|
 |
krysstvælla Rutinert
Joined: 06 Mar 2013 Posts: 515
|
Posted: 30.04.2015 00:19 Post subject: |
|
|
Setetellingen er tatt til nye dimensjoner. |
|
Back to top |
|
 |
Vemundo Veteran
Joined: 31 Jan 2006 Posts: 1372
|
Posted: 30.04.2015 00:32 Post subject: |
|
|
Flash appen kan lastes ned og så dekompileres for å få se kildekoden. Jeg brukte http://www.showmycode.com/ for å dekompilere applikasjonen. Den første nedlastingen av kildekoden var ufullstendig, men når jeg valgte å laste ned som .zip fikk jeg tilsynelatende fullstendig versjon av koden.
Har aldri vært borte i flash, men såvidt jeg kan forstå er denne appen skrevet i ActionScript versjon 3 (http://en.wikipedia.org/w...tionScript).
Siden jeg ikke kan ActionScript er det litt slow going å finne ut akkurat hvordan tigjengelighets-fila blir behandlet. Dessuten har de "obfuskert" koden så etter dekompileringen er en del funksjonsparametre og variable erstattet med navn ala _arg1 og _local1 etc istedet for deres relle navn, så det er litt tyngre å lese. Men antar noen som er vant med flash/actionscript kan finne ut av dette relativt greit.
Hvis noen har lyst til å se nærmere på det er dette så langt jeg kom:
Klassen ISCComponent.as har en metode refreshAvailability() som trigger innlesing av tilgjengelighetsdata på nytt. ISCComponent har også registrert en extern interface metode "mapFunction" som gjør det mulig å kalle refreshAvailability fra utenfor flash applikasjonen med f.eks. javascript:
ExternalInterface.addCallback("mapFunction", this.mapFunction);
(mapFunction kaller den funksjonen en ber om, f.eks. refreshAvailability()).
refreshAvailability() får inn URL til fila og kaller requestAvailability() i klassen Request_map_data:
Code: | file_loader = new Request_map_data();
file_loader.requestAvailability(); |
Denne metoden lager en URLLoader, lager bl.a. en event listener på når fila er ferdig lest inn, og starter lesing av inn fila. Litt forenklet:
Code: | loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, this.readAvailabilityResult);
request = new URLRequest(Context.availabilityURL);
loader.load(request); |
Så når fila er ferdig lest inn antar jeg readAvailabilityResult() blir kalt. Her er det litt mer uklart for meg akkurat hva som skjer. Iallefall får den tak i URLLoaderen fra event objektet og lager et XML objekt fra de innleste data:
Code: |
loader = URLLoader(e.target);
sectionXMLData = new XML(loader.data); |
Videre ser det ut til at om det er en XML fil med "ev_comp" element, så gjør den base64 dekoding av innholdet og putter det i en byte array. Det interessante er så hva den gjør med dette byte arrayet, men her mister jeg tråden litt.
Code: | if (((sectionXMLData) && (sectionXMLData.hasOwnProperty("ev_comp")))){
try {
b64Decoder = new Base64Decoder();
b64Decoder.decode(sectionXMLData.ev_comp);
ge.ba = b64Decoder.toByteArray();
x = 1;
x = (x >> 11);
x = (x + 1);
x = (x >> 9);
x = (x + 1);
x = (x >> 7);
x = (x + 1);
x = (x >> 5);
x = (x + 1);
x = (x >> 3);
x = (x + 1);
x = (x >> 10);
x = (x + 1);
x = (x >> 8);
x = (x + 1);
x = (x >> 6);
x = (x + 1);
x = (x >> 4);
x = (x + 1);
x = (x >> 2);
x = (x + 1);
if (x == 1){
ge.ha = true;
};
|
ge er en statisk variabel definert lenger opp i fila:
Code: |
private static var ge:Class = Globals; |
I klassen Globals er ba definert:
Code: | public static var ba:ByteArray; |
I Globals er det en metode ran() som ser ut til å tolke innholdet i bytearrayet ba, uklart hvordan den blir kalt men via denne event listeneren:
Globals.as: ed.addEventListener("a_draw", ran);
Også uklart for meg akkurat hva ran() gjør, men jeg tror etter base64 dekoding av availability fila sin "ev_comp" element så er det å forstå hva denne funksjonen gjør med bytene som skal til for å kunne automatisk lese ut ledige seter ved ønske.
Code: |
private static function ran(_arg1:Event):void{
var numberBytes:* = 0;
var OM:* = 0;
var STEP:* = 0;
var VSIZE:* = 0;
var sCompress:* = 0;
var V:* = null;
var i:* = 0;
var sd:* = null;
var currByte:* = 0;
var j:* = undefined;
var e:* = _arg1;
try {
if (ba.length > 0){
numberBytes = ba.readUnsignedByte();
OM = ba.readUnsignedByte();
if ((((ba.bytesAvailable > numberBytes)) && ((OM == 1)))){
STEP = ba.readUnsignedByte();
VSIZE = ba.readUnsignedByte();
sCompress = ba.readUnsignedByte();
V = [new uint(Globals.get_errorstr(Globals.MSG_COMPRESSION_WALL_VALUE))];
i = 0;
while (i < (VSIZE - 1)) {
V.push(ba.readUnsignedByte());
i = (i + 1);
};
VSIZE = (VSIZE + 1);
Globals.ssa = (Globals.ssa + (VSIZE + 1));
sd = new ByteArray();
ba.readBytes(sd);
ba.position = 0;
ba.length = 0;
do {
Globals.ssa = sCompress;
Globals.ssa = ((Globals.ssa * V[0]) & 4194303);
j = 1;
while (j < (V.length - 1)) {
Globals.es = V[j];
Globals.ssa = (((Globals.ssa + Globals.es) * sCompress) & 4194303);
j = (j + 1);
};
Globals.ssa = (Globals.ssa + V[(V.length - 1)]);
Globals.mes = ((Globals.ssa >> 12) & 0xFF);
Globals.us = (Globals.ssa % V.length);
V[Globals.us] = (V[Globals.us] ^ sCompress);
currByte = sd.readUnsignedByte();
sd.position--;
currByte = (currByte ^ Globals.mes);
sd.writeByte(currByte);
sd.position--;
sCompress = currByte;
sd.position = (sd.position + STEP);
} while (sd.bytesAvailable > 0);
sd.position = 0;
sd.uncompress();
pa = sd.toString();
sd.position = 0;
sd.length = 0;
};
};
} catch(e:Error) {
trace(e);
pa = "error";
};
}
|
|
|
Back to top |
|
 |
Harceïde Veteran
Joined: 03 Mar 2011 Posts: 6565
|
Posted: 30.04.2015 00:35 Post subject: |
|
|
Enig..  |
|
Back to top |
|
 |
Pokie Veteran

Joined: 05 Aug 2011 Posts: 1640 Location: Trondheim
|
Posted: 30.04.2015 00:37 Post subject: |
|
|
Dette blir for komplisert for sånne som meg, som bare har hatt IT grunnkurs.. Uansett, well done, ser ut som du er inne på noe her  _________________ "I spent a lot of money on booze, birds and fast cars. The rest I just squandered."
- George Best |
|
Back to top |
|
 |
Pokie Veteran

Joined: 05 Aug 2011 Posts: 1640 Location: Trondheim
|
Posted: 30.04.2015 00:38 Post subject: |
|
|
Du er ikke foreleser i IT grunnkurs da? hehe _________________ "I spent a lot of money on booze, birds and fast cars. The rest I just squandered."
- George Best |
|
Back to top |
|
 |
Vemundo Veteran
Joined: 31 Jan 2006 Posts: 1372
|
Posted: 30.04.2015 00:40 Post subject: |
|
|
Hene, nei.
Men håpet var at noen her inne var litt vant med ActionScript, er jo såpass nerdetetthet her at oddsen er lav. |
|
Back to top |
|
 |
hello Veteran
Joined: 04 Apr 2008 Posts: 7804
|
Posted: 30.04.2015 00:41 Post subject: |
|
|
Det har blitt for ille når vi skal drive å hacke Billettservice for å få tak i salgstallene til hjemmekampene... |
|
Back to top |
|
 |
Wannebo Veteran

Joined: 15 May 2010 Posts: 1121 Location: Steinkjer
|
Posted: 30.04.2015 01:02 Post subject: |
|
|
Jeg smiler her jeg sitter. Utrolig at forumet har mennesker som viser et slikt engasjement og en vilje til å gå den ekstra mila for å vise hvor mye de bryr seg!  |
|
Back to top |
|
 |
gonnagetchaa Veteran

Joined: 19 Aug 2011 Posts: 1387 Location: Son
|
Posted: 30.04.2015 01:04 Post subject: |
|
|
hello wrote: | Det har blitt for ille når vi skal drive å hacke Billettservice for å få tak i salgstallene til hjemmekampene... |
 _________________ Kauka på meg neseblod. Må være et godt tegn.
-Shadwell  |
|
Back to top |
|
 |
apresthus Proff
Joined: 02 Sep 2007 Posts: 359 Location: Trentino, Italia
|
Posted: 30.04.2015 01:06 Post subject: |
|
|
Spennende. Jeg progger i Actionscript (og C#) til vanlig på jobben, har bare gløtta over det du har gjort til nå Vemundo, ser lovende ut dette da. Skal se når jeg får tid i løpet av helga, å se om jeg kan komme med noen innspil. |
|
Back to top |
|
 |
Zorac Forumsjef

Joined: 08 May 2005 Posts: 19484 Location: Lillestrøm
|
Posted: 30.04.2015 01:39 Post subject: |
|
|
Herregud som folk gidder å nørde og bruke tid på bagateller. Elsker dette forumet!  _________________ Influencer™ |
|
Back to top |
|
 |
Montana Veteran

Joined: 28 Dec 2012 Posts: 4809
|
Posted: 30.04.2015 03:09 Post subject: |
|
|
Om det finnes en app som kan telle ledige seter, hvordan skal gisp slippe unna husarbeid? |
|
Back to top |
|
 |
Macha Veteran

Joined: 06 Nov 2008 Posts: 5305
|
Posted: 30.04.2015 04:48 Post subject: |
|
|
 |
|
Back to top |
|
 |
OrionPax Forumsjef

Joined: 12 Aug 2011 Posts: 9562 Location: Drammen
|
Posted: 30.04.2015 06:16 Post subject: |
|
|
Kan heller ikke ActionScript, men det er mye her som er felles med mange andre språk som javascript og nevnte C#, som jeg også jobber med.
Den første kryptiske metoden ser ut som den gjør en masse bitshifting for å "dekode" base64-verdiene. Om dette mapper direkte til sete-tilgjengelighet er jeg for trøtt til å se her og nå.
Edit: Nå som jeg er litt mer våken - wth? Den setter x til 1, gjør masse gym med den, og sjekker om x er 1 etterpå. Dataene fra base64-dekoding er tilsynelatende ikke en del av det. Bare et forsøk på å forvirre folk for å unngå at de dekoder? Siden x settes til 1 i begynnelsen og ikke er avhengig av noe i base64-dataene skulle man tro at ha blir satt til samme verdi alltid.
Men koden som Vemundo har hentet frem burde kunne funke i andre programmeringsspråk med kun mindre endringer. Da kan man laste ned en XML-fil, banke den gjennom litt testkode, og se om det som kommer ut på andre siden ligner på det som er på websiden.
Jeg har ikke masse tid til å se på dette akkurat nå, men det burde absolutt la seg gjøre. Så får vi bare finne noe annet for gisp! å gjøre hvis vi får dette helautomatisert.
Uansett, bra jobba Vemundo! _________________ Rosenborg for alltid - uansett! | Troillprat.no
Last edited by OrionPax on 30.04.2015 08:20; edited 2 times in total |
|
Back to top |
|
 |
Spurven Proff

Joined: 11 Mar 2006 Posts: 474
|
Posted: 30.04.2015 08:03 Post subject: |
|
|
Haha! Fantastisk  |
|
Back to top |
|
 |
OrionPax Forumsjef

Joined: 12 Aug 2011 Posts: 9562 Location: Drammen
|
Posted: 30.04.2015 08:29 Post subject: |
|
|
Har masse å gjøre på jobben, men fuck that.
Code: | if (((sectionXMLData) && (sectionXMLData.hasOwnProperty("ev_comp")))){
try {
b64Decoder = new Base64Decoder();
b64Decoder.decode(sectionXMLData.ev_comp);
ge.ba = b64Decoder.toByteArray();
x = 1;
x = (x >> 11);
x = (x + 1);
x = (x >> 9);
x = (x + 1);
x = (x >> 7);
x = (x + 1);
x = (x >> 5);
x = (x + 1);
x = (x >> 3);
x = (x + 1);
x = (x >> 10);
x = (x + 1);
x = (x >> 8);
x = (x + 1);
x = (x >> 6);
x = (x + 1);
x = (x >> 4);
x = (x + 1);
x = (x >> 2);
x = (x + 1);
if (x == 1){
ge.ha = true;
};
|
Koden som involverer x-manipulering her mener jeg vi mer eller mindre kan se bort ifra. x settes til 1, og manipuleres ved bitshift - >> er bitwise shift right som man kan se her:
http://help.adobe.com/en_...ators.html
I tillegg legger man stadig til 1.
I sum er dette forholdsvis meningsløst, det eneste det brukes til er å sjekke om x == 1 til slutt, for å bruke det som utgangspunkt for å sette ge.ha til true eller ikke.
Poenget mitt er at all dansingen med x ALLTID vil gi samme resultat. Så meningen i all denne bitshiftingen er null - jeg kan ikke skjønne at dette er noe annet enn et litt tafatt forsøk på å lure folk til å tro at her er det avanserte decryptions (tm) som foregår som man ikke skjønner. Og det er det ikke.
Edit:
Kjørte koden i C#, og nå skal man jo ikke anta for mye, men hvis man kan anta at den bitshifter på samme måte som i ActionScript, så blir resultatet av dette alltid 1. Hele den kodebolken over her kan da byttes ut med:
Code: |
if (((sectionXMLData) && (sectionXMLData.hasOwnProperty("ev_comp")))){
try {
b64Decoder = new Base64Decoder();
b64Decoder.decode(sectionXMLData.ev_comp);
ge.ba = b64Decoder.toByteArray();
ge.ha = true;
|
Så vi må nok som Vemundo er inne på heller fokusere på der de henter ut verdiene av selve arrayen. _________________ Rosenborg for alltid - uansett! | Troillprat.no
Last edited by OrionPax on 30.04.2015 08:56; edited 1 time in total |
|
Back to top |
|
 |
gisp! Legende
Joined: 04 Sep 2008 Posts: 10609
|
Posted: 30.04.2015 08:35 Post subject: |
|
|
Hjelper deg med denne i arbeidet Vemundo
En til OrionPax også
Og Montana: Vi får kanskje lage en prokrastineringstråd i Garderoben  _________________ "Det er viktig å gå på banen for å være best mulig sjøl. Men det er langt viktigere å gå på banen for å gjøre medspillerne gode." |
|
Back to top |
|
 |
attach Forumsjef
Joined: 05 Jul 2005 Posts: 25183 Location: Rosenborg
|
Posted: 30.04.2015 08:37 Post subject: |
|
|
Dette er grunnen til at jeg har vært her i 10 år. Magisk. |
|
Back to top |
|
 |
xMegafonmannen Veteran

Joined: 20 Jul 2007 Posts: 2850
|
Posted: 30.04.2015 08:39 Post subject: |
|
|
Dette forumet imponerer til stadighet.
Og det viser hvor fantastisk klubben vår er. Hadde dette vært i molde hadde Røkke betalt noen en million for å gjøre det. ''Prosjekt tilhørighet 2.0''
Montana wrote: | Om det finnes en app som kan telle ledige seter, hvordan skal gisp slippe unna husarbeid? |
Haha! _________________ :/ |
|
Back to top |
|
 |
OrionPax Forumsjef

Joined: 12 Aug 2011 Posts: 9562 Location: Drammen
|
Posted: 30.04.2015 09:54 Post subject: |
|
|
Når det gjelder funksjonen/metoden (dårlig på hva ting heter i ActionScript gitt) ran, så kan vi jo dra ut NOEN konklusjoner basert på koden. Sikkert fler enn jeg rekker her, men i følge sjefen min må jeg visst jobbe av og til også.
Code: | numberBytes = ba.readUnsignedByte(); |
Første byte i ba (som er byte-arrayen) er en unsigned oversikt over hvor mange bytes det skal være. Altså numberBytes får den verdien. En stor del av koden blir jo kun kjørt om numberBytes er mindre enn antall bytes tilgjengelige (if-statement litt rett under).
OM blir satt til unsigned verdi av neste byte.
Her burde jeg ha lastet ned xml'en og dekodet live data. Får se hva man får til etterhvert.
if-statementet slipper oss igjennom hvis antall bytes er større enn verdien av numberBytes OG innholdet av byte nr. 2 er 1. Hva betyr OM? Vi får se.
STEP, VSIZE og sCompress blir så lest ut. V blir satt til.. er det en ny array av unsigned ints? Ukjent syntax for meg.
Så teller vi opp til VSIZE-1, og legger inn bytes i V. Nærliggende å tenke at dette har med seksjoner å gjøre.
Hva Globals.ssa er kan man jo gjette på. sa = Seats Available? Blir uansett kun gjetting.
Resten av bytene ser ut til å bli lest inn i en ny array sd (kan også være at den leser fra begynnelsen, men det virker rart).
Så looper den over verdiene og gjør litt matte på dem. Her sitter jeg med følelsen at den bygger opp en struktur på hva som finnes av plasser og om de er ledige eller ei - det er dessverre vanskelig å mene for mye om hva som foregår uten å vite innholdet i de globale variablene samt xml-fila.
De ender til slutt med en tekststreng pa som ser ut til å inneholde det vi er ute etter.
Men dere som kan litt om dette - det er kanskje ikke bare bare å debugge dette og se hva som blir assignet til pa (sd.toString()) på slutten her?
Det ville overraske meg mye om dette ikke var en tekststring som kan tolkes som antall plasser inkl. hvilke som er ledige.
Får vi tak i innholdet i alle de globale osv., så bør vi kunne kjøre denne koden og finne ut hvordan stringen ser ut. Kan vi produsere vår egen string, begynner jobben med å tolke denne. Men Vemundo kan kanskje også finne koden hvor pa blir brukt/tolket? _________________ Rosenborg for alltid - uansett! | Troillprat.no |
|
Back to top |
|
 |
denyngstelillebroren Senior

Joined: 15 Aug 2006 Posts: 230
|
Posted: 30.04.2015 10:22 Post subject: |
|
|
Husk at det er kamp klokka 20:00 i kveld!
Nerdebidrag til denne tråden inntil videre:
URL-ene for billettsalget kan forkortes ned fra
Code: | http://www.billettservice.no/event/rosenborg-start-billetter/438513 |
til
Code: | http://www.billettservice.no/event/438513 |
|
|
Back to top |
|
 |
|