Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 635691
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T20:25:56+00:00 2026-05-13T20:25:56+00:00

I want to know how to read a struct within a struct via php’s

  • 0

I want to know how to read a struct within a struct via php’s unpack function. When I get an IS_MCI packet, I check it’s Type to make sure it’s equal to ISP_MCI, and then I check NumC to find out how many CompCar structs there are within this packet. The problem is trying to unpack these contents into an array via a single function. I always get a undefined offset. So, i’m looking for some fresh eyes on the matter.

How would you handle this packet?

The struct in question is this:

struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of these is sent
{
    byte    Size;       // 4 + NumC * 28
    byte    Type;       // ISP_MCI
    byte    ReqI;       // 0 unless this is a reply to an TINY_MCI request
    byte    NumC;       // number of valid CompCar structs in this packet

    CompCar Info[8];    // car info for each player, 1 to 8 of these (NumC)
};

struct CompCar // Car info in 28 bytes - there is an array of these in the MCI (below)
{
    word    Node;       // current path node
    word    Lap;        // current lap
    byte    PLID;       // player's unique id
    byte    Position;   // current race position : 0 = unknown, 1 = leader, etc...
    byte    Info;       // flags and other info - see below
    byte    Sp3;
    int     X;          // X map (65536 = 1 metre)
    int     Y;          // Y map (65536 = 1 metre)
    int     Z;          // Z alt (65536 = 1 metre)
    word    Speed;      // speed (32768 = 100 m/s)
    word    Direction;  // direction of car's motion : 0 = world y direction, 32768 = 180 deg
    word    Heading;    // direction of forward axis : 0 = world y direction, 32768 = 180 deg
    short   AngVel;     // signed, rate of change of heading : (16384 = 360 deg/s)
};
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T20:25:56+00:00Added an answer on May 13, 2026 at 8:25 pm
    $msg = 
       chr(0x20) // Size = 32 (4+1*28)
      . chr(0x1) // Type = 1
      . chr(0x0) // ReqI=0
      . chr(0x1) // NumC=1
        . chr(0x1) . chr(0x0) // node=1
        . chr(0x2) . chr(0x0)  // lap=2
        . chr(0x3) // puid=3
        . chr(0x5) // pos=5
        . chr(0x10) // info=16
        . chr(0x0) //sp3=0
        . chr(0x0) . chr(0x0) . chr(0x1) . chr(0x0) // x=65536
        . chr(0x0) . chr(0x0) . chr(0x2) . chr(0x0) // y=65536*2
        . chr(0x0) . chr(0x0) . chr(0x3) . chr(0x0)  // z=65536*3
        . chr(0x0) . chr(0x20) // speed=8192
        . chr(0x0) . chr(0x10) // dir=4096
        . chr(0x0) . chr(0x8) // heading=2048
        . chr(0x0) . chr(0x4) // AngVel=1024
    ;
    
    $IS_MCI = unpack('CSize', $msg);
    if ( strlen($msg) < $IS_MCI['Size'] ) {
      die("not enough data");
    }
    $IS_MCI += unpack('CType/CReqI/CNumC', substr($msg, 1));
    $IS_MCI['Info'] = array();
    
    for($i=0; $i<$IS_MCI['NumC']; $i++) {
      $data = substr($msg, 4+($i*28), 28);
      $IS_MCI['Info'][] = unpack('vNode/vLap/CPLID/CPosition/CInfo/CSp3/lX/lY/lZ/vSpeed/vDirection/vHeading/sAngVel', $data);
    }
    print_r($IS_MCI);
    

    prints

    Array
    (
        [Size] => 32
        [Type] => 1
        [ReqI] => 0
        [NumC] => 1
        [Info] => Array
            (
                [0] => Array
                    (
                        [Node] => 1
                        [Lap] => 2
                        [PLID] => 3
                        [Position] => 5
                        [Info] => 16
                        [Sp3] => 0
                        [X] => 65536
                        [Y] => 131072
                        [Z] => 196608
                        [Speed] => 8192
                        [Direction] => 4096
                        [Heading] => 2048
                        [AngVel] => 1024
                    )
    
            )
    
    )
    

    Now, that code makes some assumptions that you might not want to take for granted (i.e. add a lot more error/read-data handling).

    • It assumes the packet ($msg) has been completely read before the code runs. You might want to read only the parts you currently need (no need for substr() then). Or least be prepared that the message can arrive in several chunks.
    • It also takes the size/num parameters for granted, i.e. it doesn’t check if the values are feasible and enough data is available. That’s definitely something you have to change. Size must be between 0…228, NumC must be between 0…8 and both values must fit together and so on.
    • Also take a closer look at the format identifiers I’ve used in unpack(). For wordI’ve used v which stands for “unsigned short (always 16 bit, little endian byte order). But for int I’ve used l: “signed long (always 32 bit, machine byte order)”. That’s ok on my machine. But search the documentation of the protocol for the endianness of the data.

    The testdata in $msg has been taken from the result of

    __declspec(align(1)) struct CompCar // Car info in 28 bytes - there is an array of these in the MCI (below)
    {
        word    Node;       // current path node
        word    Lap;        // current lap
        byte    PLID;       // player's unique id
        byte    Position;   // current race position : 0 = unknown, 1 = leader, etc...
        byte    Info;       // flags and other info - see below
        byte    Sp3;
        int     X;          // X map (65536 = 1 metre)
        int     Y;          // Y map (65536 = 1 metre)
        int     Z;          // Z alt (65536 = 1 metre)
        word    Speed;      // speed (32768 = 100 m/s)
        word    Direction;  // direction of car's motion : 0 = world y direction, 32768 = 180 deg
        word    Heading;    // direction of forward axis : 0 = world y direction, 32768 = 180 deg
        short   AngVel;     // signed, rate of change of heading : (16384 = 360 deg/s)
    };
    
    __declspec(align(1)) struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of these is sent
    {
        byte    Size;       // 4 + NumC * 28
        byte    Type;       // ISP_MCI
        byte    ReqI;       // 0 unless this is a reply to an TINY_MCI request
        byte    NumC;       // number of valid CompCar structs in this packet
    
        CompCar Info[1];    // example: one element, fixed
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      struct IS_MCI mci = {
        32, 1, 0, 1,
        { 1, 2, 3, 5, 16, 0, 65536, 65536*2, 65536*3, 8192, 4096, 2048, 1024 }
      };
    
      WSADATA wsaData;
      WORD wVersionRequested = MAKEWORD( 2, 2 );
       int err = WSAStartup( wVersionRequested, &wsaData );
      if ( err != 0 ) {
          /* Tell the user that we could not find a usable */
          /* WinSock DLL.                                  */
          return 1;
      }
    
      SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      sockaddr_in addr; 
      addr.sin_family = AF_INET;
      addr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
      addr.sin_port = htons( 8081 );
      if ( 0!=connect( s, (SOCKADDR*) &addr, sizeof(addr) ) ) {
        printf("%X ", WSAGetLastError());
        return 0;
      }
      send(s, (const char*)&mci, sizeof(mci), 0);
      shutdown(s, SD_BOTH);
      closesocket(s);
      return 0;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 357k
  • Answers 357k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer The other answers are correct. Here is some code you… May 14, 2026 at 9:40 am
  • Editorial Team
    Editorial Team added an answer you ruin the noConflict concept by reassigning the jquery to… May 14, 2026 at 9:40 am
  • Editorial Team
    Editorial Team added an answer If you get that particular error, you don't actually have… May 14, 2026 at 9:40 am

Related Questions

No related questions found

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.