Shared Memory Size for node.js

Discussion in 'Automobilista 2 - Help & Support' started by Pacemaker, Feb 15, 2023.

  1. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    Hi all,

    I'm wanted to starte example AMS2 into my app. One thing I am missing is the concrete size of the shared memory. With the example application I saw, that it's read via

    constSharedMemory* sharedData = (SharedMemory*)MapViewOfFile( fileHandle, PAGE_READONLY, 0, 0, sizeof(SharedMemory) )

    so basicly

    sizeof(SharedMemory)

    Has anybody an idea of the actual size (in byte) of the shared memory?


    Thanks a bunch
     
  2. mr_belowski

    mr_belowski Well-Known Member

    Joined:
    Jun 19, 2016
    Messages:
    213
    Likes Received:
    262
    20692 bytes

    so says CrewChief's code, anyway:
    Marshal.SizeOf(typeof(ams2APIStruct))
     
  3. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    Thanks! Will give it a shot and report back. Currently trying to write a node.js module, so that telemetry can also be read over there. So far I had no success finding something on Github.
     
  4. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    I get back this buffer with the above mentioned length set. Is there any list of byte offsets and encodings for the shared memory, that I can then use to actually fetch the specific data?

    I know there is the SDK für C++ in a sub directory of the AMS2 games folder, but I can't find any byte offsets and stuff defined there.
     
  5. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    Hej. I made some slight progress. Used a hex reader to get the info accordingly. The thing is, that the recent version of the struct in the AMS2-folder is puzzling me. There are zeros across the board, with no pattern to recognize or at least broken patterns.

    This is a screenshot of the first 32 bytes. I tested it with both being in the menu and being on track. Some values shift as expected, but they are on very different ppsitions.
    upload_2023-2-19_21-48-26.png

    Here my thoughts/questions:
    it seems the first 4 bytes is the shared memory version, which is reflecting what I understood correct I guess. All those first bytes I can evaluate as int32/uint32 right? Is there some clarity on which kind of ints etc. are used here across the board. I'm not super familiar with C++ and maybe I'm missing some info in the example files shipped with the games folder.

    Can you, @Renato Simioni , maybe help here or point me to someone who might provide me with some more in-depth structural info of the shared memory? Sorry for the noob questions, but I'm going with node and full-stack. :)
     
  6. mr_belowski

    mr_belowski Well-Known Member

    Joined:
    Jun 19, 2016
    Messages:
    213
    Likes Received:
    262
    from line 324 \SteamLibrary\steamapps\common\Automobilista 2\Support\SharedMemory\AMS2_SharedMemoryExampleApp\SharedMemory.h, the layout of this byte array is defined. This struct defines how the bytes map to types - uint (32bit integer) for first few, then repeating blocks of participant data (type ParticipantInfo). The first 4 bytes in this ParticipantInfo type are 0001, a uint with value 1 which is the 'mIsActive' flag. The next 64 bytes are the encoded String for that partificipant's name. The there's a few other things, and that block repeats for the next participant. There are always 64 instances of this block so if you only have 1 participant in a session there'll be a lot of zeros.

    After that there's a few IEE 754 floats - 4 bytes each mapped to a floating point number, then more String data as UTF-8 encoded text etc etc.

    Whatever language you use *should* have a way to convert 4 bytes to a 32bit int (signed or unsigned) and 32bit float, and some handling for converting an array of bytes to a String with some given encoding (utf-8 is the default). Where the struc declares a type to be boolean, i'm not sure if it's a single byte (0 / 1) or 4 bytes (0000 / 0001) - probably the former.

    For languages that don't have a concept of a Struct (the thing that's defined in the .h file), you'll need to obtain bytes from the correct parts of the shared memory array and convert them manually - I had to do this for the Android version of CC. It's simple but tedious. For languages like C# and C++ you just 'apply' the byte array to the struct and all the field values are automagically mapped from the bytes.
     
  7. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    Big thanks for the quick answer. It also took me some hours to figure it out meanwhile, but this definitely helps refining things! Especially the participants data was kind of puzzling me. For the time being, I just iterated by a fill set of over the participants data (each has 100 Bytes in total) and just got the active and names info extracted for the time being).

    Just continued to do so until I got to the info of speed and RPM and stopped here for the time being, as this is the most vital info right now. Once I'm fully finished with mapping and setting up some event emitter, I will publish the telemetry provider on Github, so that other node or full-stack devs can use it.

    @mr_belowski Can I hit you up in case of questions? Thanks again!
     
  8. mr_belowski

    mr_belowski Well-Known Member

    Joined:
    Jun 19, 2016
    Messages:
    213
    Likes Received:
    262
    Yes of course. Obviously you're welcome to refer to the cc gitlab repo. I also have a cc android repo which I keep meaning to make open source - I'll do that next week (if I remember). The cc android repo is project cars UDP data only so a bit different but it might contain some useful stuff like mapping the raw binary data to types without using a Struct
     
  9. Pacemaker

    Pacemaker New Member AMS2 Club Member

    Joined:
    Feb 2, 2020
    Messages:
    11
    Likes Received:
    0
    Cool. Sounds nice. Not sure about Android development though. My Java days are long gone and I moved on with full stack web development only. But I guess, the approaches are similar. Also first thought about using UDP, but wanted to keep the packet order/reliability out of the equation for my Windows App.

    Will update this thread, as soon, as I have something available via NPM. Still have to put everything into a node package and also read out all the remaining data. As soon as you have your repo up, drop me some lines. Will be interesting to see, how you did it.
     

Share This Page