Multiplayer protocol enhancements (MP2017.2 V2)
/sim/multiplay/protocol-version is either 1 or 2 and controls how packets are sent. V2 packets will only have the (motioninfo) basic properties visible to older clients. New string encoding that is efficient. Support short int encoding (pack a property and value into 4 bytes). Allow properties to be transmitted using a different encoding to the property type in the tree. Support scaled floats; most of the floats we transmit are small and thus can fit into a scaled short. V2 protocol uses transmit so most properties are either scaled floats or short ints. Allow the client to request a larger visibility range by setting /sim/multiplay/visibility-range-nm. This will transmit in the repurposed header field ReplyAddress - which has been renamed to RequestedRangeNm. This will require support from fgms to actually do anything. Extra debugging options. The most useful (for aircraft developers) is the loopback bit, as this allows model multiplay testing without running two instances. Update property /sim/multiplay/last-xmit-packet-len with the size of the packet transmitted Debug level bits in property /sim/multiplay/debug-level bit 1 - loopback (show your own model as an MP model) bit 2 - dump outgoing packets bit 3 - dump incoming packets bit 4 - hexdump outgoing packets
This commit is contained in:
commit
5d2e596043
5 changed files with 938 additions and 460 deletions
|
@ -55,6 +55,7 @@ const uint32_t PROTO_VER = 0x00010001; // 1.1
|
|||
#define OLD_PROP_MSG_ID 5
|
||||
#define RESET_DATA_ID 6
|
||||
#define POS_DATA_ID 7
|
||||
#define MP_2017_DATA_ID 8
|
||||
|
||||
// XDR demands 4 byte alignment, but some compilers use8 byte alignment
|
||||
// so it's safe to let the overall size of a network message be a
|
||||
|
@ -70,7 +71,7 @@ struct T_MsgHdr {
|
|||
xdr_data_t Version; // Protocoll version
|
||||
xdr_data_t MsgId; // Message identifier
|
||||
xdr_data_t MsgLen; // absolute length of message
|
||||
xdr_data_t ReplyAddress; // (player's receiver address
|
||||
xdr_data_t RequestedRangeNm; // obsolete field (ReplyAddress) reused to request a range to fgms
|
||||
xdr_data_t ReplyPort; // player's receiver port
|
||||
char Callsign[MAX_CALLSIGN_LEN]; // Callsign used by the player
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,6 +31,8 @@
|
|||
|
||||
#define MULTIPLAYTXMGR_HID "$Id$"
|
||||
|
||||
const int MIN_MP_PROTOCOL_VERSION = 1;
|
||||
const int MAX_MP_PROTOCOL_VERSION = 2;
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -70,11 +72,20 @@ private:
|
|||
{
|
||||
mPropertiesChanged = true;
|
||||
}
|
||||
|
||||
int getProtocolToUse()
|
||||
{
|
||||
int protocolVersion = pProtocolVersion->getIntValue();
|
||||
if (protocolVersion >= MIN_MP_PROTOCOL_VERSION && protocolVersion <= MAX_MP_PROTOCOL_VERSION)
|
||||
return protocolVersion;
|
||||
else
|
||||
return MIN_MP_PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
void findProperties();
|
||||
|
||||
void Send();
|
||||
void SendMyPosition(const FGExternalMotionData& motionInfo);
|
||||
short get_scaled_short(double v, double scale);
|
||||
|
||||
union MsgBuf;
|
||||
FGAIMultiplayer* addMultiplayer(const std::string& callsign,
|
||||
|
@ -100,8 +111,16 @@ private:
|
|||
// and the property nodes
|
||||
typedef std::map<unsigned int, SGSharedPtr<SGPropertyNode> > PropertyMap;
|
||||
PropertyMap mPropertyMap;
|
||||
|
||||
SGPropertyNode *pProtocolVersion;
|
||||
SGPropertyNode *pXmitLen;
|
||||
SGPropertyNode *pMultiPlayDebugLevel;
|
||||
SGPropertyNode *pMultiPlayRange;
|
||||
|
||||
typedef std::map<unsigned int, const struct IdPropertyList*> PropertyDefinitionMap;
|
||||
PropertyDefinitionMap mPropertyDefinition;
|
||||
|
||||
bool mPropertiesChanged;
|
||||
|
||||
MPPropertyListener* mListener;
|
||||
|
||||
double mDt; // reciprocal of /sim/multiplay/tx-rate-hz
|
||||
|
|
|
@ -73,6 +73,38 @@ XDR_encode_int32 ( const int32_t & n_Val )
|
|||
return (SWAP32(static_cast<xdr_data_t> (n_Val)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Safely convert from an int into a short. Anything outside the bounds of a short will
|
||||
* simply be the max/min value of short (+/- 32767)
|
||||
*/
|
||||
static short XDR_convert_int_to_short(int v1)
|
||||
{
|
||||
if (v1 < -32767)
|
||||
v1 = -32767;
|
||||
|
||||
if (v1 > 32767)
|
||||
v1 = 32767;
|
||||
|
||||
return (short)v1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack two 16bit shorts into a 32 bit int. By convention v1 is packed in the highword
|
||||
*/
|
||||
xdr_data_t XDR_encode_shortints32(const int v1, const int v2)
|
||||
{
|
||||
return XDR_encode_uint32(((XDR_convert_int_to_short(v1) << 16) & 0xffff0000) | ((XDR_convert_int_to_short(v2)) & 0xffff));
|
||||
}
|
||||
/* Decode packed shorts into two ints. V1 in the highword ($V1..V2..)*/
|
||||
void XDR_decode_shortints32(const xdr_data_t & n_Val, int &v1, int &v2)
|
||||
{
|
||||
int _v1 = XDR_decode_int32(n_Val);
|
||||
short s2 = (short)(_v1 & 0xffff);
|
||||
short s1 = (short)(_v1 >> 16);
|
||||
v1 = s1;
|
||||
v2 = s2;
|
||||
}
|
||||
|
||||
xdr_data_t
|
||||
XDR_encode_uint32 ( const uint32_t & n_Val )
|
||||
{
|
||||
|
|
|
@ -54,6 +54,9 @@ xdr_data2_t XDR_encode_uint64 ( const uint64_t & n_Val );
|
|||
int64_t XDR_decode_int64 ( const xdr_data2_t & n_Val );
|
||||
uint64_t XDR_decode_uint64 ( const xdr_data2_t & n_Val );
|
||||
|
||||
xdr_data_t XDR_encode_shortints32(const int v1, const int v2);
|
||||
void XDR_decode_shortints32(const xdr_data_t & n_Val, int &v1, int &v2);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//
|
||||
// FIXME: #1 these funtions must be fixed for
|
||||
|
|
Loading…
Reference in a new issue