GM-versie: 
,

,
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:
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

.
Movement exampleDit 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:
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:
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:
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:
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:
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:
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!