一日一点RakNet(18)--Network Messages

来源:互联网 发布:excel vba编程实例 编辑:程序博客网 时间:2024/05/18 02:08
 网络消息

 

从网络引擎发来的消息

       你接收到的一些数据包并不是使用你定义的类型,从你的代码中发送过来,而是从网络引擎中发来的消息。然而,你需要知道他们代表了什么含义,如何处理。每一个数据包的第一个字节,来自于API,会映射到如下列举的一些枚举类型。可能的接受方列举在了括号中,使用PakcetLogger::BaseIDTOString()将这些枚举类型转换为字符串。

//
// 保留类型—不要修改这些类型定义
//  所有的类型来自于RakPeer

// 这些类型不会返回给用户

// 来自于一个连接的系统的Ping。更新时间戳(仅仅内部使用)

ID_CONNECTED_PING,
// 来自于一个未连接系统的Ping。回复,但是不要更新时间戳(仅仅内部使用)

ID_UNCONNECTED_PING,
// 来自于未连接系统的Ping,如果已经打开了连接,则回复,不要更新时间戳(仅用于内部)

ID_UNCONNECTED_PING_OPEN_CONNECTIONS,
// 来自连接系统的Pong,更新时间戳(仅内部内部)

ID_CONNECTED_PONG,
// 一个可靠数据包,用于检测连接丢失(仅仅用于内部)

ID_DETECT_LOST_CONNECTIONS,
// C2S: 初始化查询: Header(1), OfflineMesageID(16), Protocol number(1), Pad(toMTU), 发送

// 不用分片,如果在服务器上协议失败,返回ID_INCOMPATIBLE_PROTOCOL_VERSION

// 到客户端

ID_OPEN_CONNECTION_REQUEST_1,
// S2C: Header(1), OfflineMesageID(16), server GUID(8), HasSecurity(1),

// Cookie(4, 如果设置了HasSecurity), public key (如果doSecurity设置为true),

// MTU(2). 如果公钥在客户端使用失败,返回ID_PUBLIC_KEY_MISMATCH
ID_OPEN_CONNECTION_REPLY_1,
// C2S: Header(1), OfflineMesageID(16), Cookie(4, 如果在服务器HasSecurity为true),

// clientSupportsSecurity(1 bit), handshakeChallenge (如果在服务器和客户端设置了security),

// remoteBindingAddress(6), MTU(2), client GUID(8)

// 如果cookie有效则分配连接间隙,服务器没有满,GUID和IP没有使用

ID_OPEN_CONNECTION_REQUEST_2,
// S2C: Header(1), OfflineMesageID(16), 服务器GUID(8), MTU(2),

// doSecurity(1位), handshakeAnswer (如果doSecurity值为true)
ID_OPEN_CONNECTION_REPLY_2,
/// C2S: Header(1), GUID(8), Timestamp, HasSecurity(1), Proof(32)
ID_CONNECTION_REQUEST,
// RakPeer –远端系统要求安全连接,给RakPeerInterface::Connect()公有密钥

ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY,
// RakPeer–给RakPeerInterface::Connect()传递了公共密钥,但是系统没有开启安全检测

ID_OUR_SYSTEM_REQUIRES_SECURITY,
// RakPeer- 传递给RakPeerInterface::Connect()的公钥密钥是错误的

ID_PUBLIC_KEY_MISMATCH,
// RakPeer-与ID_ADVERTISE_SYSTEM相同,但是仅仅是系统内部使用,不会返回给用户

// 第二个字节指明类型,当前用于NAT 穿透的端口广播。

// 参考ID_NAT_ADVERTISE_RECIPIENT_PORT

ID_OUT_OF_BAND_INTERNAL,
// 如果调用了RakPeerInterface::Send(),其中PacketReliability中有 _WITH_ACK_RECEIPT,

// 然后稍迟一点调用RakPeerInterface::Receive(),可以得到ID_SND_RECEIPT_ACKED或

// ID_SND_RECEIPT_LOSS。消息有5字节长,并且1-4字节包含了一个本地有序的号码,

//它标识了这条消息。这个数字会由RakPeerInterface::Send()或RakPeerInterface::SendList()

//返回. ID_SND_RECEIPT_ACKED意味着这条消息到达了接受方

ID_SND_RECEIPT_ACKED,
// 如果用PacketReliability包含_WITH_ACK_RECEIPT 调用的RakPeerInterface::Send()

// 然后调用RakPeerInterface::Receive(),会得到一个ID_SND_RECEIPT_ACKED或

// ID_SND_RECEIPT_LOSS。这条消息会有5字节长,并且1-4字节会包含一个标识这条消

// 息的数字。这个数字由RakPeerInterface::Send()或RakPeerInterface::SendList()返回

// ID_SND_RECEIPT_LOSS意味着消息没有达到的确认(这条消息发送了,或许没有发送,

// 可能没有).在连接断开或关闭时,对于没有发送的消息会得到ID_SND_RECEIPT_LOSS

// 标识,应该将这些消息当做是完全丢失了

ID_SND_RECEIPT_LOSS,

//
// 用户类型-不要修改这些定义
//

// RakPeer-在客户端/服务器环境下,我们的连接要求服务器已经接受

ID_CONNECTION_REQUEST_ACCEPTED,
// RakPeer-如果连接请求无法完成时,给玩家回复这样一个消息

ID_CONNECTION_ATTEMPT_FAILED,
// RakPeer-向你当前要连接到的系统发送连接请求。

ID_ALREADY_CONNECTED,
// RakPeer-远端系统已经成功连接。

ID_NEW_INCOMING_CONNECTION,
// RakPeer-试图连接的系统不接受新的连接。

ID_NO_FREE_INCOMING_CONNECTIONS,
// RakPeer-系统在Packet::systemAddress中指定的已经从服务器断开的。对于客户端,这个

// 标识意味着服务器已经关闭

ID_DISCONNECTION_NOTIFICATION,
// RakPeer-可靠数据包不能传递到Packet::systemAddress指定系统。到该系统连接已经断开

ID_CONNECTION_LOST,
// RakPeer-被要连接到的系统禁止掉了

ID_CONNECTION_BANNED,
// RakPeer-远端系统使用了密码,因为设置密码不正确拒绝了连接请求

ID_INVALID_PASSWORD,
// 在 RakNetVersion.h中的RAKNET_PROTOCOL_VERSION与远端系统上的本值不匹配

// 这意味这两个系统无法通信

// 消息的第二个字节包含了远端系统的RAKNET_PROTOCOL_VERSION值

ID_INCOMPATIBLE_PROTOCOL_VERSION,

// 意味着这个IP最近连接到了系统,作为安全连接,已经无法再建立连接

// 参考RakPeer::SetLimitIPConnectionFrequency()

ID_IP_RECENTLY_CONNECTED,
// RakPeer- sizeof(RakNetTime)个字节大小的值,紧跟着它的一个字节代表了自动修改的

// 发送方和接收方系统的差值,需要调用用SetOccasionalPing方法获取这个值。

ID_TIMESTAMP,
// RakPeer-来自未连接的系统的Pong。第一个字节是ID_UNCONNECTED_PONG,

// 第二个 sizeof(RakNet::TimeMS)大小字节的值是ping。紧跟着这个字节的是系统指定的

// 枚举数据,使用bitstreams读取。

ID_UNCONNECTED_PONG,
// RakPeer- 通知远端系统我们的IP/Port。

// 在接受方,所有的传递的ID_ADVERTISE_SYSTEM数据是传递的数据参数。

ID_ADVERTISE_SYSTEM,
// RakPeer-下载一个大的消息,格式是ID_DOWNLOAD_PROGRESS (MessageID),

// partCount (unsigned int),partTotal (unsigned int),partLength (unsigned int),

// 第一个部分数据 (length <= MAX_MTU_SIZE)。参见文件FileListTransferCBInterface.h中

// 的OnFileProgress的三个参数 partCount, partTotal和partLength

ID_DOWNLOAD_PROGRESS,

// ConnectionGraph2插件-在客户端/服务器环境中,一个客户端已经断开了连接,

// 修改Packet::systemAddress以反映这个断开的客户端的systemAddress

ID_REMOTE_DISCONNECTION_NOTIFICATION,
// ConnectionGraph2插件-在客户端/服务器环境,客户端被迫断开了连接

// 修改Packet::systemAddress来反映这个已经断开连接的客户端的systemAddress

ID_REMOTE_CONNECTION_LOST,
// ConnectionGraph2 产检: 1-4字节 = count。

// 对于 (count items)包含了{SystemAddress, RakNetGUID}

ID_REMOTE_NEW_INCOMING_CONNECTION,

/// FileListTransfer插件 – 设置数据

ID_FILE_LIST_TRANSFER_HEADER,
// FileListTransfer plugin – 一个文件
ID_FILE_LIST_TRANSFER_FILE,
// 请求加入文件,发送多个文件。

ID_FILE_LIST_REFERENCE_PUSH_ACK,

// DirectoryDeltaTransfer 插件-从远端系统请求要下载的目录
ID_DDT_DOWNLOAD_REQUEST,

// RakNetTransport plugin – 用于远端控制台的提供者消息

ID_TRANSPORT_STRING,

// ReplicaManager plugin – 创建一个对象
ID_REPLICA_MANAGER_CONSTRUCTION,
// ReplicaManager plugin – 改变对象的范围
ID_REPLICA_MANAGER_SCOPE_CHANGE,
// ReplicaManager plugin – 序列化对象的数据
ID_REPLICA_MANAGER_SERIALIZE,
// ReplicaManager plugin – 新的连接,要发送所有的对象

ID_REPLICA_MANAGER_DOWNLOAD_STARTED,
// ReplicaManager plugin –完成了所有序列化对象的下载

ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE,
// 已经存在于远端系统对象的序列化构造

ID_REPLICA_MANAGER_3_SERIALIZE_CONSTRUCTION_EXISTING,
ID_REPLICA_MANAGER_3_LOCAL_CONSTRUCTION_REJECTED,
ID_REPLICA_MANAGER_3_LOCAL_CONSTRUCTION_ACCEPTED,

// RakVoice plugin – 打开通信信道
ID_RAKVOICE_OPEN_CHANNEL_REQUEST,
// RakVoice plugin – 接收通信信道
ID_RAKVOICE_OPEN_CHANNEL_REPLY,
// RakVoice plugin – 关闭通信信道
ID_RAKVOICE_CLOSE_CHANNEL,
// RakVoice plugin – 语音数据
ID_RAKVOICE_DATA,

// Autopatcher plugin – 获取一个从某个时间开始的修改过的文件

ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE,
// Autopatcher plugin – 要创建的文件的列表

ID_AUTOPATCHER_CREATION_LIST,
// Autopatcher plugin – 要删除的文件的列表

ID_AUTOPATCHER_DELETION_LIST,
// Autopatcher plugin – 要升级的文件的列表

ID_AUTOPATCHER_GET_PATCH,
// Autopatcher plugin – 用于一个文件列表的补丁列表

ID_AUTOPATCHER_PATCH_LIST,
// Autopatcher plugin –返回到用户:一个补丁系统数据库的错误

ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR,
// Autopatcher plugin –从补丁系统下载的所有文件已经完成下载

ID_AUTOPATCHER_FINISHED_INTERNAL,
ID_AUTOPATCHER_FINISHED,
// Autopatcher plugin – 返回到用户: 需要重启完成补丁过程。

ID_AUTOPATCHER_RESTART_APPLICATION,

// NATPunchthrough plugin: 内部使用
ID_NAT_PUNCHTHROUGH_REQUEST,
// NATPunchthrough plugin: internal
ID_NAT_CONNECT_AT_TIME,
// NATPunchthrough plugin: internal
ID_NAT_GET_MOST_RECENT_PORT,
// NATPunchthrough plugin: internal
ID_NAT_CLIENT_READY,

// NATPunchthrough plugin:目的系统没有连接到服务器,偏移量为1的字节包含了

// RakNetGUID, NatPunchthroughClient::OpenNAT()的目的域。
ID_NAT_TARGET_NOT_CONNECTED,
// NATPunchthrough plugin:目的系统没有对ID_NAT_GET_MOST_RECENT_PORT做出

//反应,或许插件没有安装,从偏移量为1的字节开始

// 包含了NatPunchthroughClient::OpenNAT()目的域的RakNetGUID。
ID_NAT_TARGET_UNRESPONSIVE,
// NATPunchthrough plugin: 在建立设置穿透时,服务器丢失了到目的系统的连接

// 可能消息没有安装。从偏移量为1的字节开始

// 包含了NatPunchthroughClient::OpenNAT()目的域的RakNetGUID。
ID_NAT_CONNECTION_TO_TARGET_LOST,
// NATPunchthrough plugin: 穿透工作正在进行,可能该插件没有安装。从偏移量为1的字节

//开始包含了NatPunchthroughClient::OpenNAT()目的域的RakNetGUID。

ID_NAT_ALREADY_IN_PROGRESS,
// NATPunchthrough plugin: 这条消息是本地系统生成的,并不是来自网络,

// packet::guid 包含了NatPunchthroughClient::OpenNAT()的目的域。如果自己是发送方,

// 第一个字节为1,否则是0

ID_NAT_PUNCHTHROUGH_FAILED,
// NATPunchthrough plugin: 穿透成功。参考packet::systemAddress和packet::guid。

// 如果你是发送者第一个字节为1,否则为0

// 你现在可以使用RakPeer::Connect() or其他调用与系统通信

ID_NAT_PUNCHTHROUGH_SUCCEEDED,

// ReadyEvent plugin – 为一个特殊的系统设置准备好状态。

// 消息之后的最前面的四个字节包含了id值

ID_READY_EVENT_SET,
// ReadyEvent plugin – 将一个系统的准备好状态重置掉,消息后的4个字节包含了id值

ID_READY_EVENT_UNSET,
// 所有的系统都处于ID_READY_EVENT_SET状态

// 消息后的4个字节包含了id值
ID_READY_EVENT_ALL_SET,
// \internal, 在游戏中不要使用

// ReadyEvent plugin – 准备好事件状态请求,新连接时用于拉取数据

ID_READY_EVENT_QUERY,

/// Lobby 数据包,第二个字节表明了数据类型
ID_LOBBY_GENERAL,

// RPC3, RPC4插件错误
ID_RPC_REMOTE_ERROR,
// 基于RPC系统的穿件的替换

ID_RPC_PLUGIN,

// FileListTransfer传递大文件,仅仅在需要的时候再读取,以节省内存

ID_FILE_LIST_REFERENCE_PUSH,
// 强制重置所有的准备好事件

ID_READY_EVENT_FORCE_ALL_SET,

// 房间函数
ID_ROOMS_EXECUTE_FUNC,
ID_ROOMS_LOGON_STATUS,
ID_ROOMS_HANDLE_CHANGE,

/// Lobby2消息
ID_LOBBY2_SEND_MESSAGE,
ID_LOBBY2_SERVER_ERROR,

// 通知用户新的主机的GUID. Packet::Guid包含了这个新的主机的RakNetGuid。

// 老主机可以使用BitStream->Read(RakNetGuid)读取这个值

ID_FCM2_NEW_HOST,
/// \internal For FullyConnectedMesh2 plugin
ID_FCM2_REQUEST_FCMGUID,
/// \internal For FullyConnectedMesh2 plugin
ID_FCM2_RESPOND_CONNECTION_COUNT,
// \internal For FullyConnectedMesh2 plugin
ID_FCM2_INFORM_FCMGUID,

// UDP 代理消息。第二个类型表明数据类型

ID_UDP_PROXY_GENERAL,

// SQLite3Plugin – 执行
ID_SQLite3_EXEC,
// SQLite3Plugin – 远端数据库位置

ID_SQLite3_UNKNOWN_DB,
// SQLiteClientLoggerPlugin事件发生
ID_SQLLITE_LOGGER,

// 向NatTypeDetectionServer发送数据
ID_NAT_TYPE_DETECTION_REQUEST,
// 向NatTypeDetectionClient发送。字节1包含了NAT检测类型

ID_NAT_TYPE_DETECTION_RESULT,

// 用于router2 插件

ID_ROUTER_2_INTERNAL,
// 没有可用路径,或没有到远端系统的连接

// Packet::guid 包含了我们要达到的端点的guid
ID_ROUTER_2_FORWARDING_NO_PATH,
// \brief 现在可以调用connect, ping, 其他操作

// 按照如下代码进行连接:
//
// RakNet::BitStream bs(packet->data, packet->length, false);
// bs.IgnoreBytes(sizeof(MessageID));
// RakNetGUID endpointGuid;
// bs.Read(endpointGuid);
// unsigned short sourceToDestPort;
// bs.Read(sourceToDestPort);
// char ipAddressString[32];
// packet->systemAddress.ToString(false, ipAddressString);
// rakPeerInterface->Connect(ipAddressString, sourceToDestPort, 0,0);
ID_ROUTER_2_FORWARDING_ESTABLISHED,
// 一个转发连接的IP已经改变

// 对于每一个 ID_ROUTER_2_FORWARDING_ESTABLISHED读取endpointGuid 和 port
ID_ROUTER_2_REROUTED,

// \internal 用于team balancer 插件

ID_TEAM_BALANCER_INTERNAL,
// 由于人数已满而无法转到满意的团队。然而,如果这个团队有人离开,你会获得

// 获取 ID_TEAM_BALANCER_SET_TEAM值,字节1包含了你想要加入团队的号码
ID_TEAM_BALANCER_REQUESTED_TEAM_CHANGE_PENDING,
// 由于团队已经上锁,无法转到想去的团队,你会获得

// 获取 ID_TEAM_BALANCER_SET_TEAM值,字节1包含了你想要加入团队的号码

ID_TEAM_BALANCER_TEAMS_LOCKED,
// Team balancer插件通知你你的团队。Byte 1 包含了你要加入的团队

ID_TEAM_BALANCER_TEAM_ASSIGNED,

// Gamebryo Lightspeed集成
ID_LIGHTSPEED_INTEGRATION,

// XBOX 集成
ID_XBOX_LOBBY,

// 密码用于挑战传递这个密码的系统,意味着其他的系统需要使用我们传递给

// TwoWayAuthentication::Challenge()的密码调用TwoWayAuthentication::AddPassword()
/// You can read the identifier used to challenge as follows:
/// RakNet::BitStream bs(packet->data, packet->length, false);

// bs.IgnoreBytes(sizeof(RakNet::MessageID)); RakNet::RakString password; bs.Read(password);
ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS,
ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS,
// 远端系统使用TwoWayAuthentication::Challenge()向我们发送一个挑战,挑战失败

// 如果其他的系统需要将挑战保持,你应该调用RakPeer::CloseConnection()

// 终止到其他系统的连接(此处不理解是什么意思,包括前面两条)
ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE,
// 其他的系统没有加入我们在TwoWayAuthentication::AddPassword()使用的密码

// 可以使用如下读取挑战标识符:

// RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID));

// RakNet::RakString password; bs.Read(password);
ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE,
// 其他的系统没有在事件门限内给出反应。这个系统或者是没有运行相应插件,

// 或者它在某个事件上长时间阻塞了。

// 可以按照如下方式读取用于challenge的标识符:

/// RakNet::BitStream bs(packet->data, packet->length, false);

// bs.IgnoreBytes(sizeof(MessageID));

// RakNet::RakString password; bs.Read(password);
ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT,
// \内部
ID_TWO_WAY_AUTHENTICATION_NEGOTIATION,

// CloudClient / CloudServer
ID_CLOUD_POST_REQUEST,
ID_CLOUD_RELEASE_REQUEST,
ID_CLOUD_GET_REQUEST,
ID_CLOUD_GET_RESPONSE,
ID_CLOUD_UNSUBSCRIBE_REQUEST,
ID_CLOUD_SERVER_TO_SERVER_COMMAND,
ID_CLOUD_SUBSCRIPTION_NOTIFICATION,

// 可以在不修改用户的枚举类型前提下,增加一些协议

ID_RESERVED_1,
ID_RESERVED_2,
ID_RESERVED_3,
ID_RESERVED_4,
ID_RESERVED_5,
ID_RESERVED_6,
ID_RESERVED_7,
ID_RESERVED_8,
ID_RESERVED_9,

// 留给用户,从这个值开始你的消息类型定义

ID_USER_PACKET_ENUM,

 

        这些在具体使用的时候,还要再进行理解,很多理解的都不到位,不进行实际的开发,不能够完全理解其中的一些消息的作用。

 

By 北洋小郭

转载请注明出处,切勿用于商业。谢谢!