]> git.mxchange.org Git - flightgear.git/blobdiff - src/MultiPlayer/multiplaymgr.cxx
Fixed an property tieing issue on sim reset.
[flightgear.git] / src / MultiPlayer / multiplaymgr.cxx
index 1d36ec257333c9edf2b531cbf4efdfa197065b52..9a541382786f10de1cabd9433d103e07ba0e5de4 100644 (file)
@@ -1,6 +1,6 @@
 //////////////////////////////////////////////////////////////////////
 //
-// multiplaymgr.hpp
+// multiplaymgr.cxx
 //
 // Written by Duncan McCreanor, started February 2003.
 // duncan.mccreanor@airservicesaustralia.com
@@ -526,14 +526,44 @@ union FGMultiplayMgr::MsgBuf
     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;
@@ -780,7 +810,7 @@ FGMultiplayMgr::update(double)
     }
     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) {
@@ -858,6 +888,15 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
   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";
 
@@ -884,19 +923,20 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
       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) {
@@ -953,7 +993,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
           SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type);
           xdr++;
           break;
-      }            
+      }
 
       motionInfo.properties.push_back(pData);
     }
@@ -962,7 +1002,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
       // 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:
@@ -976,7 +1016,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg,
 //////////////////////////////////////////////////////////////////////
 //
 //  handle a chat message
-//  FIXME: display chat message withi flightgear
+//  FIXME: display chat message within flightgear
 //
 //////////////////////////////////////////////////////////////////////
 void