game maker
Gebruikersnaam:
Wachtwoord:
Home Info Forums Help
Welkom, Gast. Alsjeblieft inloggen of registreren.
De activerings e-mail gemist?
+  Forums
|-+  Werken met Game Maker
| |-+  Tutorials en Uitbreidingen (Moderator: Maarten Baert)
| | |-+  [Dll+Gex] Http Dll 2 - Http requests, sockets, buffers, md5, sha1, zlib en meer!
Pagina's: [1] 2 3 ... 20
« vorige volgende »
Print
Advertenties

Maarten Baert
Forumbeheerder


Offline Offline

Berichten: 4942

Gelieve quote te gebruiken als je PMs beantwoordt.


WWW
« Gepost op: 22 Oktober 2010, 19:23:18 »

GM-versie: Game Maker 6, Game Maker 7, GameMaker 8
Pro vereist: Ja
Niveau: Gevorderd-expert

Met mijn Http Dll kon je wel redelijk veel, maar het was niet echt een handige DLL om mee te werken. Daarom heb ik nu een tweede versie gemaakt. Hier is alles veel gebruiksvriendelijker en maak je minder snel fouten. Toen ik toch bezig was dacht ik dat het misschien ook wel handig zou zijn om wat functies te maken om de sockets, die ik intern gebruik, ook ter beschikking te stellen. Maar om met sockets te werken heb je eigenlijk ook buffers nodig, zoals in 39dll, dus ik heb ook maar meteen de code van mijn Buffer Dll eraan toegevoegd (na nog wat verbeteringen te hebben gemaakt). Dat betekent dat je met deze DLL nu ook online games kan maken zoals met 39dll. Deze versie gebruikt ook geen threads meer. Ik heb dat idee maar opgegeven omdat het eigenlijk niet zo veel voordelen had, en het het een stuk lastiger maakte (zowel om het te programmeren als om het te gebruiken in GM).

Features:
  • Http requests
    • Downloaden van pagina's of bestanden zonder het spel te blokkeren.
    • Stel request headers en post parameters in.
    • Lees de statuscode, response headers en natuurlijk message body.
    • Upload bestanden.
  • Sockets
    • Ondersteunt listening sockets (server) en normale sockets (client).
    • Ondersteunt IPv4 en IPv6.
    • Ondersteunt TCP en UDP.
  • Buffers: zeer gelijkaardig aan 39dll, maar met een paar extra data types.
  • MD5 en SHA-1
  • ZLib compressie
  • RC4 encryptie
  • Hexadecimaal en base64 encoding/decoding

Laatste versie:
Download Http Dll 2.3 release 6 (met source code)

Oudere versies:
Download Http Dll 2.2 (met source code)
Download Http Dll 2.1 (met source code)
Download Http Dll 2.0 (met source code)

Documentatie (Engels)

Waarom deze DLL?
Eén van de redenen dat ik dit gemaakt heb is ook dat er een fout in 39dll lijkt te zitten. Sockets kunnen niet onbeperkt informatie doorsturen, er zit een limiet op de hoeveelheid bytes die per seconde verzonden kan worden. Als je in 39dll boven die limiet gaat, verdwijnen een deel van je berichten blijkbaar gewoon. Dat is natuurlijk niet de bedoeling. De limiet is afhankelijk van hoe goed de verbinding is tussen de server en de client, dus als je lokaal test merk je het niet zo snel omdat de verbinding uitzonderlijk goed is. Maar andere spelers hebben er natuurlijk wel last van. In mijn DLL heb ik dat opgelost door wanneer het zenden niet meer werkt het deel van de data dat niet verzonden kon worden gewoon te bewaren, en het te verzenden zodra dat wel weer kan. Zo verlies je nooit berichten, en kan je zonder problemen enorme berichten doorsturen (bijvoorbeeld bestanden van een paar megabyte). Er is ook een functie waarmee je kan controleren hoeveel data er nog in de wachtrij staat om verzonden te worden.

Het zipbestand bevat een reeks voorbeelden. Dit samen met de documentatie zou genoeg moeten zijn om je op weg te helpen.

Als voorbeeld, dit is hoe je dingen kan downloaden:
GML:
var st;
httprequest = httprequest_create();
httprequest_connect(httprequest, "http://www.game-maker.nl/forums/", false);
// -> derde argument gaf aan of POST gebruikt moet worden
while true {
    httprequest_update(httprequest);
    st = httprequest_get_state(httprequest);
    if st=4 or st=5 {
        break;
    }
    sleep(10);
}
if st=5 {
    show_message("Downloaden is mislukt.");
} else {
    show_message("Downloaden is gelukt.");
    inhoud = httprequest_get_message_body(httprequest);
}
httprequest_destroy(httprequest);
Vergeleken met de oude versie is het een heel stuk simpeler Tong.



Movement example

Dit example bevat een basisengine voor een spel waarin de spelers kunnen bewegen met de pijltoetsen, en elke speler de andere spelers ook kan zien.

Over dit example ga ik wat meer uitleg geven, want het is toch redelijk ingewikkeld. Het is geen simpel example waarin de positie gewoon wordt doorgestuurd. Omdat er vaak vertraging is op internetverbindingen, geeft dat namelijk geen erg mooie resultaten. De bewegingen worden heel schokkerig. Om dit tegen te gaan heb ik een systeem toegevoegd dat de vertragingen onthoudt en de posities corrigeert, zodat de bewegingen niet meer zo schokkerig zijn. Om dit te doen moet niet alleen de positie, maar ook de snelheid worden doorgestuurd.

Het werkt door te onthouden hoeveel tijd (steps) er tussen de berichten van de server zit. Ideaal zou je één bericht moeten krijgen per step (de server stuurt alle posities in één keer door elke step). In de praktijk gebeurt het vaak dat je een step geen bericht krijgt, en de volgende step twee berichten (en het kan nog veel erger). Maar gemiddeld genomen krijg je altijd één bericht per step, tenminste zolang de server en client dezelfde fps hebben (anders werkt mijn systeem niet, dat kan je ook oplossen maar dan moet je de echte tijd gebruiken in plaats van steps, en dat is iets lastiger).

Het systeem wordt twee keer toegepast, zowel van client naar server als van server naar client. De client moet namelijk eerst zijn positie naar de server sturen, en de server stuurt het dan naar alle andere clients. Dat is twee keer storingen, dus het systeem moet twee keer toegepast worden om het te laten werken. Ik zal het uitleggen voor client naar server, het andere is exact hetzelfde maar dan omgedraaid natuurlijk.

Wanneer een client verbinding maakt met de server, doet de server dit:
GML:
client_delaystarted = false;
client_delay = 0;
client_delaystarted geeft aan of het systeem al gestart is, in het begin is dit nog niet het geval (het wordt gestart bij het eerste bericht). client_delay geeft aan hoeveel vertraging er op dit moment is. In de step event staat dan ook dit:
GML:
if client_delaystarted {
    client_delay += 1;
}
client_delay gaat dus elke step één omhoog. Maar telkens als er een bericht ontvangen wordt (een bericht voor de positie bedoel ik, niet zomaar elk bericht), wordt dit uitgevoerd:
GML:
client_delaystarted = true;
client_delay -= 1;
Het systeem wordt gestart als het nog niet gestart was, en client_delay gaat één omlaag.

Als de verbinding perfect zou zijn, zou client_delay dus gewoon altijd 0 zijn, want het gaat elke step één omhoog en bij elk bericht ook weer één omlaag. Aangezien er één bericht binnenkomt per step, blijft het op 0 staan. In de praktijk draaien server en client nooit exact even snel, dus na een tijdje kan client_delay gaan afwijken en bijvoorbeeld altijd op 3 staan. Dat is niet goed, dus dat corrigeer ik met deze code:
GML:
client_delay = max(-3, min(10, client_delay*0.95));
Dit zorgt ervoor dat client_delay langzaam terug zal gaan naar 0, zodat het niet continu op 3 of iets dergelijks kan blijven staan. Bovendien zorgt het ervoor dat client_delay niet groter dan 10 of kleiner dan -3 kan worden. In het geval van heel erge storingen is het niet de bedoeling dat de server de beweging gaat voorspellen voor de volgende seconden - dan beweegt de speler vaak door muren heen en dat ziet er niet goed uit. Vandaar dat het niet hoger mag worden dan 10. Na heel erge storingen zullen er waarschijnlijk ook weer een heleboel berichten tegelijk binnenkomen, waardoor client_delay weer heel laag zou worden, en dat is ook niet de bedoeling. Vandaar de grens van -3. Ik gebruik -3 en niet -10 omdat het meestal een paar berichten zijn die veel te laat komen, terwijl de meerderheid gewoon op het juiste moment aankomt. In zo'n geval zal client_delay af en toe heel hoog zijn, maar meestal een klein beetje negatief (-1 of -2 misschien). -10 komt in normale situaties gewoon niet voor, maar 10 wel.

Wat heb je nu aan die waarde? Wel, deze waarde geeft aan hoeveel de huidige positie voorloopt of achterloopt. 3 zou betekenen dat de positie 3 steps achterloopt, dus dat kunnen we corrigeren als we de snelheid kennen.

Wat doet de server nu met die waarde? De client stuurt elke step zijn positie en snelheid door, en die worden opgeslagen in client_x, client_y, client_hspeed, client_vspeed. In de end step event wordt daaruit de echte positie berekend:
GML:
x = client_x+client_hspeed*client_delay;
y = client_y+client_vspeed*client_delay;
Dit zorgt ervoor dat er geen plotse sprongen meer zijn als berichten vertraagd worden.

De server zal dit ook drawen:
GML:
draw_circle(client_x, client_y, 4, true);
draw_circle(x, y, 15, true);
Er worden twee cirkels getekend. De kleine cirkel geeft aan wat je zou zien zonder correctie, de grote cirkel wat je ziet met correctie. Zo zie je meteen dat de correctie wel degelijk werkt. In een echt spel gebruik je natuurlijk altijd het tweede (dus x en y, niet client_x en client_y).

Voor de berichten van de server naar de client gebeurt juist hetzelfde.



Veel succes!

« Laatste verandering: 25 April 2015, 16:42:32 door Maarten Baert »

Naar boven Gelogd

maker-bart
Gebruiker


Offline Offline

Berichten: 1133

Physica en Kunst


WWW
« Antwoord #1 Gepost op: 22 Oktober 2010, 21:44:21 »

Handig dat je nu ook online games kan maken, ga meteen even kijken wat ik er van kan maken.
Is deze DLL even snel als 39dll?

Bart

EDIT:
Is socket een soortgelijke variable zoals pid in de tutorial van BlackHawk?

EDIT2:
Ja, dus. Ik ben nu bezig met een soort van basic example zoals blackhawk hem heeft.

EDIT3:
Ik heb nu dat je kan lopen Tong Ik zal hem posten als hij klaar is.

« Laatste verandering: 22 Oktober 2010, 23:32:54 door maker-bart »

Naar boven Gelogd

Jesse
Gebruiker


Offline Offline

Berichten: 685


WWW
« Antwoord #2 Gepost op: 7 November 2010, 12:05:22 »

ik ben er dus achtergekomen dat je zo'n httprequest object maar 1 keer kan gebruiken...
maar ik maak dus een chat, waar hij om de heel weinig tijd weer alle chatberichten van internet haalt. dus per keer wordt dat dan een httprequest object. Als het is opgehaald verwijder ik hem en maak weer een nieuwe

Zit er ook een limiet op het aantal httprequest objecten?
Of is er ook een manier om meer dan 1 aanvraag op 1 request object te maken?



Naar boven Gelogd

Maarten Baert
Forumbeheerder


Offline Offline

Berichten: 4942

Gelieve quote te gebruiken als je PMs beantwoordt.


WWW
« Antwoord #3 Gepost op: 7 November 2010, 21:28:47 »

Er is normaal gezien geen enkele limiet op het aantal, behalve geheugen. Het zou wel kunnen dat Windows een limiet zet op het aantal verbindingen dat je tegelijk kan hebben, maar meestal ligt dat redelijk hoog (ik heb eens getest tot 100 en dat werkte prima). Als je van plan bent om honderden bestanden tegelijk te downloaden, is het sowieso beter om dat met maximum 2 tot 4 tegelijk te doen. Voor de snelheid maakt het niet veel verschil, als je meer dingen tegelijk download over dezelfde internetverbinding gaat het gewoon trager.


Naar boven Gelogd

Tomtiger
Gebruiker


Offline Offline

Berichten: 339

Grrrrrrrrrr..........


« Antwoord #4 Gepost op: 8 November 2010, 16:30:48 »

Ziet er goed uit (qua inhoud).
Ik kijk even wat je er verder mee kan doen.

Gr. Tomtiger


Minecraft engine proberen na te maken in GM. Later uitwerken in Java.
Naar boven Gelogd

maker-bart
Gebruiker


Offline Offline

Berichten: 1133

Physica en Kunst


WWW
« Antwoord #5 Gepost op: 12 November 2010, 15:32:08 »

Citaat van: Matrebatre
// -> tweede argument gaf aan of POST gebruikt moet worden
Hoe gebruik je die POST manier in game maker?


Naar boven Gelogd

ericlegomeer
Forumbeheerder


Offline Offline

Berichten: 9222

http://xkcd.com/386/


« Antwoord #6 Gepost op: 12 November 2010, 15:38:12 »

Hoe gebruik je die POST manier in game maker?
Met deze functie misschien?:
Citaat van: dllfunctions
function httprequest_set_post_parameter(id:real;name:string;value:string):real


Naar boven Gelogd

maker-bart
Gebruiker


Offline Offline

Berichten: 1133

Physica en Kunst


WWW
« Antwoord #7 Gepost op: 12 November 2010, 19:49:57 »

Hmm, als ik van een url download die niet bestaat:
Code:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Assertion failed!

Program: ...E~1\LOCALS~1\Temp\gm_ttt_20939\chat_server.exe
File: C:\Users\Maarten\Documents\codeblocks\...\Socket.cpp
Line: 231

Expression: state==SOCKETSTATE_CONNECTING || state==SOCKETSTATE_CONNECTED || state==SOCKETSTATE_SHUTDOWN || state==SOCKETSTATE_CLOSED || state==SOCKETSTATE_ERROR

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts

(Press Retry to debug the application - JIT must be enabled)
---------------------------
Afbreken   Opnieuw   Negeren   
---------------------------


Naar boven Gelogd

Maarten Baert
Forumbeheerder


Offline Offline

Berichten: 4942

Gelieve quote te gebruiken als je PMs beantwoordt.


WWW
« Antwoord #8 Gepost op: 12 November 2010, 20:25:04 »

Bedankt voor het melden, hier heb ik wat aan. Het zijn eigenlijk twee fouten: De eerste fout is wat er in dat bericht stond, de tweede fout is dat je dat bericht kreeg, want dat zijn debugberichten en die horen niet aanwezig te zijn in de release-versie Tong. Ik probeer het zo snel mogelijk op te lossen.

EDIT: Opgelost, als ik me niet vergis.

« Laatste verandering: 12 November 2010, 22:22:12 door Matrebatre »

Naar boven Gelogd

turbodevin
Gebruiker


Offline Offline

Berichten: 267

Rambo in de Rimboe


WWW
« Antwoord #9 Gepost op: 17 November 2010, 17:11:28 »

Hoi, is deze sneller dan 39dll, of is het niet de moeite om mijn spel (nog maar net mee bezig) om te bouwen voor het gebruik van deze dll?

Mvg Devin


Naar boven Gelogd

Maarten Baert
Forumbeheerder


Offline Offline

Berichten: 4942

Gelieve quote te gebruiken als je PMs beantwoordt.


WWW
« Antwoord #10 Gepost op: 20 November 2010, 10:22:59 »

Ik heb het nooit getest, maar ik denk dat zowel 39dll als Http Dll 2 zo weinig rekentijd vragen dat de snelheid echt niet relevant is. De echte vertraging komt van
- een trage internetverbinding: Het kost altijd tijd om dingen door te sturen naar andere computers. Dit duurt in 39dll exact even lang als in Http Dll 2. Deze tijd is meestal 50ms tot 500ms, het is sterk afhankelijk van de kwaliteit van de internetverbinding.
- de code van je server en client: als je server maar 30 keer per seconde berichten ontvangt van clients, duurt het gemiddeld 17ms voordat een bericht dat aangekomen is door je programma wordt uitgelezen. Als de client hetzelfde doet, krijg je weeral 17ms vertraging.
Beide effecten zijn veel belangrijker dan de snelheid van de DLL.

Over welke DLL je best kan gebruiken: Dit is gewoon afhankelijk van wat je zelf het makkelijkst vind. Ik vind mijn DLL handiger omdat daarin het beheer van verzonden data automatisch geregeld wordt (achter de schermen), terwijl dat bij 39dll niet gebeurt en je dus soms fouten krijgt. De functies van de twee DLL's komen zeer sterk overeen, dus ik denk dat het overstappen niet veel werk is als je spel nog niet te groot is.


Naar boven Gelogd

maker-bart
Gebruiker


Offline Offline

Berichten: 1133

Physica en Kunst


WWW
« Antwoord #11 Gepost op: 20 November 2010, 13:40:49 »

Ik ben nog steeds bezig om bij de DLL een online example (voor mezelf) te maken, maar ik wil niet letterlijk de 39dll-tutorial overnemen. Dat is volgens mij niet nodig, maar hoe creër je een speler? (domme vraag, maar ik kom er even niet uit)
Ik wil het doen door een buffer te sturen, wat bij de 39dll-tutorial ook wordt gedaan, maar dit is volgens mij overbodig. Bij het connecten van deze DLL heb je namelijk geen data verstuurd.


Naar boven Gelogd

Jolie
Gebruiker


Offline Offline

Berichten: 1304

HC Bloemendaal FTW!


« Antwoord #12 Gepost op: 21 November 2010, 09:21:12 »

Dit is echt een geweldige DLL. Fantastisch! Dit is zo ontzettend veel makkelijker dan 39DLL. Ik wil zo wel een online game maken (ga ik niet doen, heb geen beschikking over server Engel)
Je script in je beginpost klopt btw niet:
GML:
var st;
httprequest = httprequest_create();
httprequest_connect("http://www.game-maker.nl/forums/", false);
// -> tweede argument gaf aan of POST gebruikt moet worden
while true {
    httprequest_update(httprequest);
    st = httprequest_get_state(httprequest);
    if st=4 or st=5 {
        break;
    }
}
if st=5 {
    show_message("Downloaden is mislukt.");
} else {
    show_message("Downloaden is gelukt.");
    inhoud = httprequest_get_message_body(httprequest);
}
httprequest_destroy(httprequest);

In de tweede regel ben je het argument http id vergeten Rolt ogen


Naar boven Gelogd

Maarten Baert
Forumbeheerder


Offline Offline

Berichten: 4942

Gelieve quote te gebruiken als je PMs beantwoordt.


WWW
« Antwoord #13 Gepost op: 21 November 2010, 15:58:13 »

Ik ben nog steeds bezig om bij de DLL een online example (voor mezelf) te maken, maar ik wil niet letterlijk de 39dll-tutorial overnemen. Dat is volgens mij niet nodig, maar hoe creër je een speler? (domme vraag, maar ik kom er even niet uit)
Ik wil het doen door een buffer te sturen, wat bij de 39dll-tutorial ook wordt gedaan, maar dit is volgens mij overbodig. Bij het connecten van deze DLL heb je namelijk geen data verstuurd.
Als je het simpel wilt houden, kan je het best doen zoals in de tutorial van Blackhawk, dat is volgens mij veruit het simpelst.

Ik heb een hele tijd geleden gewerkt aan een online spel, en daar deed ik het zo:
  • Als een speler inlogt wordt er eerst verbinding gemaakt met de server, en daarna een bericht verstuurd met het gebruikersnaam en wachtwoord van de speler (in mijn geval was het wachtwoord gecodeerd, maar het kan ook zonder codering).
  • Wanneer de server een inkomende connectie ziet, wordt er een instantie van obj_client voor aangemaakt. Die instantie heeft een lokale variabele die het socket id bewaart.
  • Wanneer obj_client het inlogbericht ontvangt, wordt de gebruikersnaam en het wachtwoord gecontroleerd. Als het niet klopt, wordt er een bericht teruggestuurd om te zeggen dat het inloggen is mislukt. Als het wel klopt, wordt er een instantie aangemaakt van obj_player, en het id van die instantie wordt opgeslagen in obj_client. De instantie van obj_player slaat ook het id op van de instantie van obj_client waar het bij hoort. Er wordt een bericht gestuurd dat het inloggen is gelukt, en de speler zal vanaf nu speldata ontvangen. Die data wordt verzonden door obj_client, maar alleen als er al een instantie van obj_player is (m.a.w. als die lokale variabele niet 'noone' is).
  • Wanneer een speler uitlogt, wordt zijn instantie van obj_client verwijderd. De instantie van obj_player blijft bestaan, maar de lokale variabele die verwees naar de instantie van obj_client wordt op 'noone' gezet.
  • Als obj_player ziet dat de lokale variabele 'noone' is, en bepaalde voorwaarden voldaan zijn (b.v. hij is momenteel niet in gevecht met iemand anders of een monster), wordt het object obj_player ook verwijderd.
  • Als iemand inlogt, wordt er altijd eerst gecontroleerd of er nog geen instantie was van obj_player voor die account. Als die er wel was, wordt gecontroleerd wat de waarde is van de lokale variabele. Als dat 'noone' is, wordt de instantie van obj_player gekoppeld aan die van obj_client (dit gebeurt als de connectie verbroken wordt terwijl de speler nog in gevecht was, en hij meteen daarna weer inlogt). Als dat niet 'noone' is, wordt er een bericht teruggestuurd dat zegt dat de account al ingelogd is (en het inloggen mislukt dus).

Ik weet dat het systeem heel wat lastiger is dan het systeem dat meestal gebruikt wordt (het splitst clients en spelers, de andere systemen die ik heb gezien doen dat niet), maar ik vond het uiteindelijk veel praktischer Gemoedelijk.

Je script in je beginpost klopt btw niet:
<knip>
In de tweede regel ben je het argument http id vergeten Rolt ogen
Bedankt voor het melden, ik heb het aangepast.

« Laatste verandering: 21 November 2010, 16:00:08 door Matrebatre »

Naar boven Gelogd

Jolie
Gebruiker


Offline Offline

Berichten: 1304

HC Bloemendaal FTW!


« Antwoord #14 Gepost op: 22 November 2010, 12:37:49 »

Hoe werkt httprequest_set_header?
ik heb nu:
GML:
httprequest_set_header(a,"hoi","1",0)
Maar dan ontvangt mijn webserver "Array"

Naar boven Gelogd

Advertenties
« vorige volgende »
Pagina's: [1] 2 3 ... 20
Print


Topic Informatie
0 geregistreerde leden en 1 gast bekijken dit topic.

Ga naar:  

Powered by SMF 1.1.21 | SMF © 2006-2007, Simple Machines
www.game-maker.nl © 2003-2019 Nederlandse Game Maker Community