39 dll: Dateien Verschicken

  • GM 7
  • 39 dll: Dateien Verschicken

    Hallo!
    Ich möchte, dass man in dem Spiel ein Profilbild laden kann, das automatisch auf 128*128px komprimiert wird.
    Das ist ja soweit kein Problem, aber jetzt möchte ich, dass der Mitspieler (Multiplayer) dieses Bild auch sieht.
    Also muss ich das 128px*128px große Bild verschicken. Am liebsten ist es mir, dass auch per 3ßdll zu machen, um nicht unnötig viele Dlls dabei packen zu müssen.
    Ich habe mal hier im Forum gesucht und bin schließlich auf diesen Thread gestoßen: klick
    Da wird damit die Datei verschickt:
    Spoiler anzeigen

    GML-Quellcode

    1. clearbuffer();
    2. writebyte(1);
    3. f=fileopen("datei.bmp",0);
    4. fileread(f,filesize(f));
    5. fileclose(f);
    6. sendmessage(global.otherplayer);

    Und damit empfangen:
    Spoiler anzeigen

    GML-Quellcode

    1. file = fileopen("datei.bmp",1);
    2. filewrite(file);
    3. fileclose(file);

    Laut Megm sollte der Code funktionieren. doch nur mit kleinen Dateien unter 8kB.
    Jetzt habe ich das so versucht:

    Senden:
    Spoiler anzeigen

    GML-Quellcode

    1. clearbuffer();
    2. writebyte(0);
    3. writetestring("");
    4. sendmessage(global.otherplayer);
    5. file = fileopen(rc);
    6. i=0;
    7. while(i<filesize(rc))
    8. {
    9. clearbuffer();
    10. writebyte(1);
    11. fileread(file,1);
    12. sendmessage(global.otherplayer);
    13. i+=1;
    14. }
    15. fileclose(file);
    16. clearbuffer();
    17. writebyte(2);
    18. writetestring("");
    19. sendmessage(global.otherplayer);
    Alles anzeigen

    Empfangen:
    Spoiler anzeigen

    GML-Quellcode

    1. switch (messageid)
    2. {
    3. case 0:
    4. //empfangen start
    5. f=fileopen("datei.bmp");
    6. break;
    7. case 1:
    8. //empfang vorgang
    9. filewrite(f);
    10. break;
    11. case 2:
    12. //empfangen ende
    13. fileclose(f);
    14. break;
    15. }
    Alles anzeigen

    Doch gamemaker sagt mir schon von Anfang an folgende Fehlermeldung:
    Spoiler anzeigen
    ERROR in
    action number 1
    of Step Event
    for object obj_recieve

    In script fileopen:
    Error in line 1:
    /*
    Opens or creates a file for reading or writing.
    Argument0 = Filename.
    Argument1 = mode. 0 = reading, 1 = writing, 2 = both reading and writing
    Returns a file id.
    */
    return external_call(global._FilA, argument0, argument1);

    At position 208: Unknown variable _FilA
    Der Fehler kommt übrigens sowohl bei Sender als auch Empfänger.

    Ich hoffe mir kann jemand helfen.
    LG
    -Tobi

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Tobi ()

  • Nein eben nicht. Das war mein allererster Gedanke.. :S
    Ich werde mir das morgen nocheinmal angucken und wenn es dann nicht funktioniert, werde ich mal die zwei "Programme" (Host, Client) mit hochladen.
    Nur heute schaff ich's nicht mehr. (Und wenn morgen, dann auch nur morgen Abend)

    Aber danke für den schnellen Versuch.
    LG
    -Tobi
  • Der Fehler liegt an der Initialisierung der Dll. du musst beide Zusatzdienste aktivieren, tust du aber nicht.
    Also nebenbei dass dieser Fehler kommt würde ich noch zwei unterschiedliche IDs verwenden beim Senden. Da steht zweimal

    GML-Quellcode

    1. writebyte(0)

    Außerdem musst du mit dem Senden der Datei warten, bis feststeht ob und dass der Server die Nachricht erhalten hat also, dass der Server einen OK-befehl gibt wenn er die nachricht bekommen hat und dann der Client erst die Datei sendet.

    © 2008 by Teamgrill Productions
  • Danke für die schnelle Antwort :thumbup:
    Ok ich glaub das writebyte(0) war nur ein tippfehler beim Beispiel.
    Der Fehler liegt an der Initialisierung der Dll. du musst beide Zusatzdienste aktivieren, tust du aber nicht.
    Meinst du das?

    GML-Quellcode

    1. dllinit(0, true, false);

    Muss da dann true, true hin?
    lg
    -Tobi


    €dit:
    Okay danke es funktioniert :thumbup:
    Jetzt hab ich noch eine Frage:
    Ist die Funktion zum Senden der Datei auf eine maximale Byte-Zahl beschränkt?
    Bzw. Wie mache ich das bei Bildern?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Tobi ()

  • Nein, aber es ist schlauer mehrere kleine Pakete zu senden.
    Du liest sagen wir 1024 byte aus der Datei, sendest sie an den Client, der schreibt diese in eine Datei und sendet dem Server dass er es empfangen hat. Beim eintreffen der Nachricht liest der Server die nächsten 1024 byte aus und sendet sie usw. Bis eben alles gesendet wurde.

    © 2008 by Teamgrill Productions
  • okay danke.
    Aber wenn ich erstmal versuche das Bild als ein Paket zu verschicken (ist nur ein Bild von 128*128 mit 17 kB), kommt es mit maximal 10,7kB an und kann nicht geöffnet werden.
    Und wenn ich das mit Paketen mache, muss ich dann am Anfang einmal f=fileopen(filename,1) und bei jedem neuen paket mit filewrite(f) die Daten in die Datei schreiben und dann wieder am Ende mit fileclose(f) schließen?
    So hab ich das nämlich versucht. Und dann noch im Klienten:
    Am Anfang:
    f=fileopen(filename,0)

    Dann für jedes Paket:
    fileread(f,1024);

    Und dann am Ende
    fileclose(f);

    Oder muss ich für jedes Paket die Position des "Cursors" in der Datei um 1024 erhöhen oder macht der das automatisch?
    Aber irgendwie kommt dann nur eine Datei von 1,70kB an.
    Könntest du eventuell einen Beispielcode posten?

    LG
    -iBot
  • es sollte schon funktionieren.
    1. Zuerst sendet der, der die Datei schickt, dem anderen, dass dieser eine bestimmte Datei zum schreiben öffnen soll und öffnet selbst die zuvor ausgewählte Datei zum Lesen.
    2. Der andere empfängt den Befehl, die Datei zu öffnen, öffnet diese zum schreiben und sendet ein OK.
    3. Der Sender empfängt das OK und sendet einen Teil der Datei zum Empfänger.
    4. Dieser empfängt die Daten und schreibt sie in die Datei, sendet wieder ein OK.
    5. Wiederholung von Schritt 3 und 4 bis Zeigerposition der Datei am Ende ist, ist dies der Fall sendet der Sender einen Endbefehl und schließt die Datei.
    6. der Empfänger empfängt den Befehl und schließt die Datei.

    Zwecks Lese bzw schreibposition gibt es nichts zu erwähnen. Hier wär allerdings mal ein Code um einen Teil der Datei zu senden.

    GML-Quellcode

    1. // Bei Empfang der OK-Nachricht
    2. // sendfile ist die ausgewählte Datei
    3. // sendsize ist die menge der zu übertragenden bytes (zb 1024)
    4. if (filepos(sendfile)<filesize(sendfile))
    5. {
    6. clearbuffer()
    7. writebyte(datenid)
    8. if (filepos(sendfile)<filesize(sendfile)-sendsize)
    9. fileread(sendfile,sendsize)
    10. else
    11. fileread(sendfile,filesize(sendfile)-filepos(sendfile))
    12. sendmessage(global.otherplayer)
    13. }
    Alles anzeigen

    © 2008 by Teamgrill Productions