public ProtoVessel CreateProtoVessel()
        {
            var configNode = ConfigNodeSerializer.Deserialize(RawData, NumBytes);

            if (configNode == null || VesselCommon.VesselHasNaNPosition(configNode))
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            var newProto = VesselSerializer.CreateSafeProtoVesselFromConfigNode(configNode, VesselId);

            if (newProto == null)
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            if (VesselCommon.ProtoVesselHasInvalidParts(newProto))
            {
                return(null);
            }

            return(newProto);
        }
        /// <summary>
        /// This method uses a lot of memory so try to call it as less as possible and only when needed
        /// </summary>
        public void DeserializeVesselBytes()
        {
            lock (_vesselDataSyncLock)
            {
                _needToDeserializeData = false;
                var newVesselNode = ConfigNodeSerializer.Deserialize(_vesselData, _numBytes);
                if (!VesselCommon.VesselHasNaNPosition(newVesselNode))
                {                
                    //In case there's a deserialization error skip it and keep the older node
                    _vesselNode = newVesselNode;
                }
                if (_vesselNode == null)
                {
                    LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                    VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                    VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                    return;
                }

                var newProto = VesselSerializer.CreateSafeProtoVesselFromConfigNode(_vesselNode, VesselId);

                //In case there's a deserialization error skip it and keep the older proto
                if (newProto != null)
                {
                    HasInvalidParts = VesselCommon.ProtoVesselHasInvalidParts(newProto);

                    if (newProto.vesselID != VesselId)
                    {
                        LunaLog.LogError($"Tried to update the Vessel with a proto from a different vessel ID. Proto: {newProto.vesselID} CorrectId: {VesselId}");
                    }
                    else
                    {
                        _deserializedProtoVessel = newProto;
                    }
                }

                //If protovessel is still null then unfortunately we must remove that vessel as the server sent us a bad vessel
                if (_deserializedProtoVessel == null)
                {
                    LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                    VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                    VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                }
                else
                {
                    _vesselParts.Clear();
                    foreach (var protoPart in _deserializedProtoVessel.protoPartSnapshots)
                    {
                        _vesselParts.TryAdd(protoPart.flightID, protoPart);
                    }
                }
            }
        }
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselDockMsgData msgData))
            {
                return;
            }

            LunaLog.Log("Docking message received!");

            //Add the new vessel data to the store
            VesselsProtoStore.HandleVesselProtoData(msgData.FinalVesselData, msgData.NumBytes, msgData.DominantVesselId, false);

            if (FlightGlobals.ActiveVessel?.id == msgData.WeakVesselId)
            {
                LunaLog.Log($"Docking NOT detected. We DON'T OWN the dominant vessel. Switching to {msgData.DominantVesselId}");

                VesselRemoveSystem.Singleton.AddToKillList(FlightGlobals.ActiveVessel.id, "Killing weak (active) vessel during a docking that was not detected");
                VesselSwitcherSystem.Singleton.SwitchToVessel(msgData.DominantVesselId);

                WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId);
            }
            if (FlightGlobals.ActiveVessel?.id == msgData.DominantVesselId && !VesselCommon.IsSpectating)
            {
                var newProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData, msgData.NumBytes);

                /* This is a strange case were we didn't detect the docking on time and the weak vessel send the new definition...
                 * Usually it happens when a vessel in a future subspace docks with a vessel in the past and the vessel in the past is the dominant vessel
                 * The reason why is bad is because the ModuleDockingNode sent by the WEAK vessel will tell us that we are
                 * NOT the dominant (because we received the vesselproto from the WEAK vessel) so we won't be able to undock properly...
                 * This will be fixed if we go to the space center and reload again the vessel...
                 */
                LunaLog.Log("Docking NOT detected. We OWN the dominant vessel");

                //This is the case when the user that docked with us has invalid parts
                if (VesselCommon.ProtoVesselHasInvalidParts(newProto))
                {
                    return;
                }

                if (FlightGlobals.FindVessel(msgData.WeakVesselId) != null)
                {
                    LunaLog.Log($"Weak vessel {msgData.WeakVesselId} still exists in our game. Removing it now");
                    VesselRemoveSystem.Singleton.AddToKillList(msgData.WeakVesselId, "Killing weak vessel during a docking that was not detected");
                    VesselRemoveSystem.Singleton.KillVessel(msgData.WeakVesselId, "Weak vessel in a docking");
                }

                /* We own the dominant vessel and dind't detected the docking event so we need to reload our OWN vessel
                 * so if we send our own protovessel later, we send the updated definition
                 */
                LunaLog.Log($"Creating the missing parts in our own vessel. Current: {FlightGlobals.ActiveVessel.parts.Count} Expected: {newProto.protoPartSnapshots.Count}");
                //ProtoToVesselRefresh.CreateMissingPartsInCurrentProtoVessel(FlightGlobals.ActiveVessel, newProto);
                VesselLoader.ReloadVessel(newProto);

                LunaLog.Log("Force sending the new proto vessel");
                VesselProtoSystem.Singleton.MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel, true, false);

                WarpSystem.WarpIfSubspaceIsMoreAdvanced(msgData.SubspaceId);
                return;
            }

            //Some other 2 players docked so just remove the weak vessel.
            VesselRemoveSystem.Singleton.AddToKillList(msgData.WeakVesselId, "Killing weak vessel during a docking of 2 far players");
        }