Ingame-Karte des Clients *anfragen* / Request client (ingame)map

  • English / German

We've posted an important announcement regarding the current situation and the future of the game: Announcement

  • Ingame-Karte des Clients *anfragen* / Request client (ingame)map

    Huhu,

    für ein etwas größeres Projekt würde ich gerne die Karten-Daten der Spieler sammeln während sie diese erkunden. Deshalb wäre es cool wenn man per API den Client nach den Kartendaten (Bilder) des aktuellen chunks befragen könnte (könnte man dann triggern wenn der Spieler einen neuen chunk betritt) Auf dem Client könnte man in den Optionen ja sowas wie "Server erlauben Karten-Daten zu erfragen" einfügen mit denen man als Client bestimmen kann ob diese gesendet werden dürfen oder nicht.
    Red hatte mir bereits gesagt das die Karten nur clientseitig erstellt werden, daher müßte man da irgendwie ran ;)

    // -------------
    Hello,

    for a litte bigger sized project i would like to collect all that ingame-map data while players discover new lands. For this reason i would like to have an API call that requests those (image) files from the client (for example when he runs into a new chunk). On the clientside there could be an option to turn this on or off like "Allow server to request ingame-map". Red has already told me that those maps are only generated on the client, so there must be some way to fetch these ;)
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334
  • @red51 welches Format haben denn die Dateien beim Client unter RisingWorld/Map/__/mx_*_* ? Ich wollte schon mal einen POC bauen bis es möglich ist die Dateien vom Client zu "erbitten" und so auf dem Server zu verarbeiten.

    // -------------

    @red51 which file format is used for the map files in RisingWorld/Map/__/mx_*_* on the client ? I would like to build a POC until there is a way to request those client-map-files from the server via API.
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334
  • Minotorious wrote:

    Have a look here for the map file format:Map image data and file names
    oh k, did not see that thread, that helps thy.

    EDIT: Got it



    Wrote a Quick and dirty node app for this:

    JavaScript Source Code: main.ts

    1. import { readFileSync, createWriteStream } from "fs";
    2. import { Canvas, createCanvas, Image } from 'canvas';
    3. const path = __dirname + "/../mt_34_-1~";
    4. const file = readFileSync(path);
    5. let offset = 0;
    6. let index = 0;
    7. let x = 0, y = 0;
    8. const C: Canvas = createCanvas(256, 256);
    9. const ctx: CanvasRenderingContext2D = C.getContext('2d');
    10. while (offset < file.byteLength) {
    11. const red = file.readUInt8(offset + 0);
    12. const green = file.readUInt8(offset + 1);
    13. const blue = file.readUInt8(offset + 2);
    14. const alpha = file.readUInt8(offset + 3);
    15. y = Math.floor(index / 256);
    16. x = index % 256;
    17. const idata: ImageData = ctx.getImageData(x, y, 1, 1);
    18. idata.data[0] = red;
    19. idata.data[1] = green;
    20. idata.data[2] = blue;
    21. idata.data[3] = alpha;
    22. ctx.putImageData(idata, x, y);
    23. index++;
    24. offset = index*4;
    25. }
    26. const imageFileStream = createWriteStream(path + ".jpg");
    27. const stream = C.createJPEGStream({
    28. quality: 0.95,
    29. chromaSubsampling: false
    30. });
    31. stream.pipe(imageFileStream);
    32. imageFileStream.on('finish', () => console.log('The JPEG file was created.'));
    Display All
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334

    The post was edited 1 time, last by Devidian ().

  • Just a Quick & dirty POC: rw.gi.omega-zirkel.de/ no zoom levels yet, just origins.
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334
  • EN: Well, basically it would be possible to request the map files from a client, however, this would result in a lot of traffic. We don't have a separate connection for file transfers, so basically each map tile will be sent to the server as regular packets - blocking other traffic on that particular port. If the server requests too many map tiles at once, you could run into serious performance issues :( First we really have to find a better way to handle the map data on the server.

    DE: Naja, grundsätzlich wäre es möglich, die Map-Daten vom Client zu bekommen, allerdings würde das ne Menge Traffic mit sich ziehen. Wir haben leider keine separate Verbindung für Dateie-Transfers, also würde jedes Map-Tile als normale Pakete versendet werden - was gleichzeitig den anderen Traffic auf dem entsprechenden Port aufhalten würde. Wenn der Server zu viele Map-Tiels gleichzeitig anfordert, könnte das zu ernsten Performance Problemen führen :( Wir müssen wirklich erst einen besseren Weg finden, um die Map-Daten serverseitig zu verwalten.


    Devidian wrote:

    Just a Quick & dirty POC: rw.gi.omega-zirkel.de/ no zoom levels yet, just origins.
    Well done! :thumbup:
  • DE: Also ich würde so oder so diverse Mechanismen einbauen um den Traffic gering zu halten. Zunächst sollten nur die Maps um den Spieler herum angefordert werden können. Dann sollten zunächst hashwerte und Datum abgeglichen werden um zu vermeiden unnötig Updates zu schicken oder die Karte mit alten Daten zu überschreiben. Dann würde ich noch ein Limit setzen das ein map Part nur alle x Minuten aktualisiert wird. Also wenn ein map Teil von Spieler a schon übertragen wurde, wird es für x Minuten von keinem anderen Spieler angefordert.

    EN: Anyway I would implement some mechanism to reduce traffic. First of all only maps around the player should be able to be requested, then filehash and creation date should be compared to avoid updates and overrides with older map data. Then i would implement a limit per tile per x minutes to be requested. So for example if Player A has sent an update for map tile 1,1 nobody else would be requested for 1,1 for the next X minutes.
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334

    The post was edited 1 time, last by Devidian: Englisch nachgereicht ().

  • Sorry für die späte Antwort! Ich habe zwar noch etwas Sorge mit der Funktion, aber ich denke wir können sie im nächsten Update trotzdem als experimentelles Feature mit reinpacken. Die Daten werden dann 1:1 als komprimiertes byte[] übertragen, also quasi exakt so, wie die MapTiles beim User gespeichert sind (allerdings werden wir Funktionen anbieten, um dieses byte[] zumindest in ein BufferedImage umzuwandeln) ;)
  • Das klingt doch schon mal gut, meine aktuelle Lösung arbeitet auch nur mit den komprimierten original-files. Kannst du kurz erläutern wie du es genau implementiert hast wenn du Zeit findest @red51? Meine aktuelle Lösung (Server) merkt sich datum und hash der Dateien und vergleicht erst vor einer Übertragung um Daten zu reduzieren. Und mein aktueller Client sendet onfilechange hash und erstell datum an den Server zum Abgleich bis dieser dann ein ok für die Übertragung gibt.
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334
  • Das Player-Objekt erhält eine neue Funktion, um ein "raw" Map Tile anzufordern. Dazu kannst du die X und Y Koordinaten angeben (so, wie auch die Map Tiles beim Client unterteilt sind) sowie einen optionalen MD5 Hash. Zusätzlich definierst du noch einen Callback, welcher aufgerufen wird, sobald entweder alle Bytes des Map Tiles auf den Server übertragen wurden (i.d.R. müssen die Map-Tiles auf mehrere Pakete aufgeteilt werden).

    Der Funktionskopf sieht in der API so aus: Player.requestMapTileRaw(int x, int y, String controlHash, Callback<byte[]> callback)

    Also "controlHash" kann wie gesagt entweder ein MD5 Hash des komprimierten byte[] angegeben werden, oder null wenn keine Hash-Prüfung stattfinden soll.

    Das byte[], welches an das Callback übergeben wird, ist entweder null (wenn das Map Tile beim Client nicht existiert oder wenn die Checksumme identisch ist), oder es handelt sich um die komprimierten Map Tile Daten.

    Im Code würde das zB so aussehen:

    Java Source Code

    1. player.requestMapTileRaw(x, y, null, (byte[] data) -> {
    2. if(data == null){
    3. // Map Tile nicht vorhanden
    4. }
    5. else{
    6. // Map Tile vorhanden, kann nun dekomprimiert werden
    7. byte[] mapData = Utils.ByteUtils.decompress(data);
    8. // Nun können die Map-Daten weiterverarbeitet werden, zB in ein
    9. // BufferedImage umgewandelt werden o.ä.
    10. BufferedImage img = Utils.ImageUtils.byteArrayToBufferedImage(mapData);
    11. }
    12. });
    Display All
  • Super, damit kann ich dann ein Plugin schreiben das meine Fake API ersetzt, werde wohl aber einfach die raw files auf dem server speichern und meine rendering-app dementsprechend anpassen, das diese auf Änderungen im raw Verzeichnis reagiert und dann on-the-fly dekomrimiert und die bilder in allen zoomstufen aktualisiert.

    Clientseitig würde ich noch einen Flag in den Einstellungen einbauen (default true), mit dem Spieler der API das anfordern erlauben kann oder nicht (falls jemand Probleme mit seiner Internetleitung und dem feature hat). bei false würde die API immer null senden, fertig.
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334
  • Hört sich gut an :thumbup:

    Wir können so eine Einstellung sicherheitshalber noch hinzufügen. Generell muss man aber mal in der Praxis sehen, wie sich diese neue Funktion tatsächlich verhält - also ob es Probleme gibt, oder doch alles geschmeidiger läuft als erwartet. Es wird denselben Port für den Versand nutzen der auch für Bilder usw. verwendet wird. Ich würde gerne einen separaten Port für sowas einrichten, aber das wird dann möglicherweise wieder problematisch bis alle Hoster diese Änderung vorgenommen haben :/
  • PatrickBronke wrote:

    Du willst eine Live-Map erstellen, die man im Internet aufrufen kann. (Wie Dynmap)
    Finde ich persönlich sehr gut. Fehlt nur noch, dass dann die Spieler ihre aktuelle Position gezeigt werden.
    Das steht schon auf der ToDo Liste

    RW Online-Map Project [WIP]
    Gamer aus Leidenschaft
    (Web) Entwickler aus Leidenschaft
    <3 Vater aus Leidenschaft <3
    (prio in aufsteigender Sortierung ;) )

    ~~~~~~~~~~~~~~~~~
    1. Entweder man macht etwas richtig oder lässt es bleiben!
    2. Egal wie lange etwas dauert, Hauptsache es wird fertig (irgendwann)
    ------------------------
    Discord: Devidian#1334