//////////////////////////////////////////////////////////////////////
//
-// multiplaymgr.hpp
+// multiplaymgr.cxx
//
// Written by Duncan McCreanor, started February 2003.
// duncan.mccreanor@airservicesaustralia.com
T_MsgHdr Header;
};
+bool
+FGMultiplayMgr::isSane(const FGExternalMotionData& motionInfo)
+{
+ // check for corrupted data (NaNs)
+ bool isCorrupted = false;
+ isCorrupted |= ((osg::isNaN(motionInfo.time )) ||
+ (osg::isNaN(motionInfo.lag )) ||
+ (osg::isNaN(motionInfo.orientation(3) )));
+ for (unsigned i = 0; (i < 3)&&(!isCorrupted); ++i)
+ {
+ isCorrupted |= ((osg::isNaN(motionInfo.position(i) ))||
+ (osg::isNaN(motionInfo.orientation(i) ))||
+ (osg::isNaN(motionInfo.linearVel(i)) )||
+ (osg::isNaN(motionInfo.angularVel(i)) )||
+ (osg::isNaN(motionInfo.linearAccel(i)) )||
+ (osg::isNaN(motionInfo.angularAccel(i)) ));
+ }
+ return !isCorrupted;
+}
+
void
FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo)
{
if ((! mInitialised) || (! mHaveServer))
return;
+
if (! mHaveServer) {
- SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server");
- return;
+ SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server");
+ return;
+ }
+
+ if (!isSane(motionInfo))
+ {
+ // Current local data is invalid (NaN), so stop MP transmission.
+ // => Be nice to older FG versions (no NaN checks) and don't waste bandwidth.
+ SG_LOG(SG_NETWORK, SG_ALERT, "FGMultiplayMgr::SendMyPosition - "
+ << "Local data is invalid (NaN). Data not transmitted.");
+ return;
}
static MsgBuf msgBuf;
}
if (MsgHdr->Version != PROTO_VER) {
SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - "
- << "message has invalid protocoll number!" );
+ << "message has invalid protocol number!" );
break;
}
if (MsgHdr->MsgLen != bytes) {
for (unsigned i = 0; i < 3; ++i)
motionInfo.angularAccel(i) = XDR_decode_float(PosMsg->angularAccel[i]);
+ // sanity check: do not allow injection of corrupted data (NaNs)
+ if (!isSane(motionInfo))
+ {
+ // drop this message, keep old position until receiving valid data
+ SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::ProcessPosMsg - "
+ << "Position message with invalid data (NaN) received from "
+ << MsgHdr->Callsign);
+ return;
+ }
//cout << "INPUT MESSAGE\n";
goto noprops;
}
while (xdr < Msg.propsRecvdEnd()) {
- FGPropertyData* pData = new FGPropertyData;
// simgear::props::Type type = simgear::props::UNSPECIFIED;
// First element is always the ID
- pData->id = XDR_decode_uint32(*xdr);
+ unsigned id = XDR_decode_uint32(*xdr);
//cout << pData->id << " ";
xdr++;
// Check the ID actually exists and get the type
- const IdPropertyList* plist = findProperty(pData->id);
+ const IdPropertyList* plist = findProperty(id);
if (plist)
{
+ FGPropertyData* pData = new FGPropertyData;
+ pData->id = id;
pData->type = plist->type;
// How we decode the remainder of the property depends on the type
switch (pData->type) {
SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type);
xdr++;
break;
- }
+ }
motionInfo.properties.push_back(pData);
}
// We failed to find the property. We'll try the next packet immediately.
SG_LOG(SG_NETWORK, SG_INFO, "FGMultiplayMgr::ProcessPosMsg - "
"message from " << MsgHdr->Callsign << " has unknown property id "
- << pData->id);
+ << id);
}
}
noprops:
//////////////////////////////////////////////////////////////////////
//
// handle a chat message
-// FIXME: display chat message withi flightgear
+// FIXME: display chat message within flightgear
//
//////////////////////////////////////////////////////////////////////
void