首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F1 2019 UDP解码

F1 2019 UDP解码
EN

Stack Overflow用户
提问于 2020-02-15 02:47:06
回答 1查看 951关注 0票数 0

我目前正在为我自己的F1方向盘显示器工作。F1 2019 (由codemasters提供)通过UDP发送数据。该数据存储在字节数组中。

我在解码返回的数组时遇到了一些问题。问题是我得到了很多信息,但我不知道如何处理这些信息。我会告诉你我试过的东西。

我通过端口20777 (游戏的标准端口)连接到游戏:

代码语言:javascript
复制
using System.Net;
using System.Net.Sockets;

var Client = new UdpClient(20777); //Connectionport

在下一段代码中,我从游戏中获取信息:

代码语言:javascript
复制
var RemoteIP = new IPEndPoint(IPAddress.Any, 60240);

byte[] received = Client.EndReceive(res, ref RemoteIP);

如您所见,游戏中的数据当前存储在一个字节数组中。

(对我来说)最难的部分来了。

F1 2019发送的数据被打包在结构中(从我从他们的网站上了解到的)。但我不知道如何从字节数组中获取信息并进入正确的变量(例如,当前速度是多少,或者汽车的档位是多少)。

有关数据包的信息位于codemasters的网站上:

https://forums.codemasters.com/topic/44592-f1-2019-udp-specification/

现在实际的问题是:

当我键入这行代码时:

代码语言:javascript
复制
short game_version = BitConverter.ToInt16(received, 0);

我将其显示在文本框中,变量game_version现在是2019。

我不明白为什么有了indexnumber 0,字节就会在2019年转换。

我不知道用哪个索引号来得到我想要的每个变量。

我希望有人能对这件事有所了解。在codemasters论坛上,似乎每个人都知道如何从字节数组中获取数据。

向您致以亲切的问候。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-16 18:06:25

好的,我发现(感谢Jeremy),我需要从字节数组中获取一个结构。我遵循了以下示例:Example1 Example2

因此,Codemaster( F1 2019的制造商)正在发送一个字节数组,其中包含所有需要的信息。它们已将结构转换为字节数组。这些结构包含游戏发出的所有信息。因此,需要做的事情是将字节数组转换回结构。请记住,来自Codemaster的结构布局需要保持不变,否则您将无法在正确的变量中获得正确的信息。

代码语言:javascript
复制
PacketHeader packetheader = ByteArrayToPacketHeader(received);

PacketHeader ByteArrayToPacketHeader(byte[] bytes)
{
   GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
   PacketHeader stuff;
   try
   {
     stuff = (PacketHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(PacketHeader));
   }
   finally
   {
   handle.Free();
   }
   return stuff;
   }

目前,上面的代码将传入的字节数组(已接收)转换为结构PacketHeader。该结构如下所示:

代码语言:javascript
复制
public struct PacketHeader
    {
        public ushort m_packetFormat;         // 2019
        public byte m_gameMajorVersion;     // Game major version - "X.00"
        public byte m_gameMinorVersion;     // Game minor version - "1.XX"
        public byte m_packetVersion;        // Version of this packet type, all start from 1
        public byte m_packetId;             // Identifier for the packet type, see below
        public ulong m_sessionUID;           // Unique identifier for the session
        public float m_sessionTime;          // Session timestamp
        public uint m_frameIdentifier;      // Identifier for the frame the data was retrieved on
        public byte m_playerCarIndex;       // Index of player's car in the array
    };

每个包含信息的包(结构)都有一个PacketHeader。通过转换每个包的报头,您可以在变量: stuff中获得相应的信息。

Here you can see the information of the PacketHeader while debugging

我将尝试解释代码的作用。我不确定我能不能100%地解释它,因为我自己并不完全理解它。

代码语言:javascript
复制
PacketHeader ByteArrayToPacketHeader(byte[] bytes)
{

}

首先,我做了一个新的方法。此方法将结构从字节数组中拉出。然后,我将所需的变量添加到方法中:

代码语言:javascript
复制
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
PacketHeader stuff;

我真的不理解句柄,但如果它是我想的那样,它就会锁定字节,这样它们就可以正确转换。

我还创建了一个变量: stuff。在这个变量中,结构将被“存储”。在下一部分中,我添加了转换代码:

代码语言:javascript
复制
try
{
  stuff = (PacketHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(PacketHeader));
}
finally
{
   handle.Free();
}
return stuff;

转换就是这段代码。在代码中填充PacketHeader时,将遵循结构布局并填充变量。

需要完成的最后一部分是调用此方法。我是这样做的:

代码语言:javascript
复制
PacketHeader packetheader = ByteArrayToPacketHeader(received);

在这里,您可以看到我调用了方法packetheader并创建了一个名为PacketHeader的变量。在这个变量中,所有信息都将被存储。

重要!填写要在接收到的插槽中使用的字节数组。这样,该方法将使用该字节数组。

如果我现在想从PacketHeader结构中调用一个变量,我只需编写以下代码:

代码语言:javascript
复制
packetheader.m_packetFormat (example)

目前,我能够从PacketHeader中获得正确的信息,但仍然不能从其他结构中获得。但我离完成我的项目又近了一步!

如果解释不完全正确,我很抱歉。(我自己还在学习)。如果您对此解释有任何建议或注意事项,请与我联系。我想了解更多关于这个主题的知识。

致以亲切的问候。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60231960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档