Пример #1
0
        public void SendVesselMessage(Vessel vessel)
        {
            if (vessel == null)
            {
                return;
            }

            //Update the protovessel definition!
            vessel.BackupVessel();

            //Defend against NaN orbits
            if (VesselHasNaNPosition(vessel.protoVessel))
            {
                LunaLog.Log($"[LMP]: Vessel {vessel.id} has NaN position");
                return;
            }

            foreach (var pps in vessel.protoVessel.protoPartSnapshots)
            {
                //Remove tourists from the vessel
                //TODO: Probably this can be done in the CleanUpVesselNode method
                foreach (var pcm in
                         pps.protoModuleCrew.Where(pcm => pcm.type == ProtoCrewMember.KerbalType.Tourist).ToArray())
                {
                    pps.protoModuleCrew.Remove(pcm);
                }
            }

            var vesselNode = new ConfigNode();

            try
            {
                vessel.protoVessel.Save(vesselNode);
            }
            catch (Exception)
            {
                LunaLog.LogError("[LMP]: Error while saving vessel");
                return;
            }

            //Clean up the vessel so we send only the important data
            CleanUpVesselNode(vesselNode, vessel.id);

            var vesselBytes = ConfigNodeSerializer.Serialize(vesselNode);

            if (vesselBytes.Length > 0)
            {
                UniverseSyncCache.QueueToCache(vesselBytes);

                SendMessage(new VesselProtoMsgData
                {
                    VesselId   = vessel.id,
                    VesselData = vesselBytes
                });
            }
            else
            {
                LunaLog.LogError($"[LMP]: Failed to create byte[] data for {vessel.id}");
            }
        }
Пример #2
0
        private void OnVesselWillDestroy(Vessel vessel)
        {
            if (vesselWorker.VesselRecentlyKilled(vessel.id))
            {
                return;
            }
            bool pilotedByAnotherPlayer = lockSystem.LockExists("control-" + vessel.id) && !lockSystem.LockIsOurs("control-" + vessel.id);
            bool updatedByAnotherPlayer = lockSystem.LockExists("update-" + vessel.id) && !lockSystem.LockIsOurs("update-" + vessel.id);
            bool updatedInTheFuture     = vesselWorker.VesselUpdatedInFuture(vessel.id);

            //Vessel was packed within the last 5 seconds
            if (lastPackTime.ContainsKey(vessel.id) && (Client.realtimeSinceStartup - lastPackTime[vessel.id]) < 5f)
            {
                lastPackTime.Remove(vessel.id);
                if (vessel.situation == Vessel.Situations.FLYING && (pilotedByAnotherPlayer || updatedByAnotherPlayer || updatedInTheFuture))
                {
                    DarkLog.Debug("Hacky load: Saving player vessel getting packed in atmosphere");
                    ProtoVessel pv        = vessel.BackupVessel();
                    ConfigNode  savedNode = new ConfigNode();
                    pv.Save(savedNode);
                    vesselWorker.LoadVessel(savedNode, vessel.id, true);
                }
            }
            if (lastPackTime.ContainsKey(vessel.id))
            {
                lastPackTime.Remove(vessel.id);
            }
        }
        public void SendVesselMessage(Vessel vessel, bool forceReload = false)
        {
            if (vessel == null || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id))
            {
                return;
            }

            if (!vessel.orbitDriver)
            {
                LunaLog.LogWarning($"Cannot send vessel {vessel.vesselName} - {vessel.id}. It's orbit driver is null!");
                return;
            }

            if (vessel.orbitDriver.Ready())
            {
                vessel.protoVessel = vessel.BackupVessel();
                SendVesselMessage(vessel.protoVessel, forceReload);
            }
            else
            {
                //Orbit driver is not ready so wait max 10 frames until it's ready
                CoroutineUtil.StartConditionRoutine("SendVesselMessage",
                                                    () => SendVesselMessage(vessel),
                                                    () => vessel.orbitDriver.Ready(), 10);
            }
        }
Пример #4
0
        public void SendVesselMessage(Vessel vessel, bool forceSend, bool forceReloadOnReceive)
        {
            if (vessel == null || (!forceSend && VesselCommon.IsSpectating) || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id))
            {
                return;
            }

            if (!forceSend && !LockSystem.LockQuery.UnloadedUpdateLockBelongsToPlayer(vessel.id, SettingsSystem.CurrentSettings.PlayerName))
            {
                return;
            }
            if (!forceSend && !LockSystem.LockQuery.UpdateLockBelongsToPlayer(vessel.id, SettingsSystem.CurrentSettings.PlayerName))
            {
                return;
            }

            var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel);

            if (forceSend || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                SendVesselMessage(vessel.BackupVessel(), forceReloadOnReceive);
            }

            if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                VesselsProtoStore.AddOrUpdateVesselToDictionary(vessel);
            }
        }
Пример #5
0
        public void ExportSelectedCraft(Vessel vessel)
        {
            CreateFolder();

            string filename = KSPUtil.ApplicationRootPath + "/Ships/export/" + HighLogic.SaveFolder + "_" + vessel.vesselName;

            Log($"Exporting vessel: {vessel.vesselName}\nExporting to file: {filename}");

            ConfigNode nodeToSave = new ConfigNode();

            //save vessel
            ConfigNode  vesselNode = new ConfigNode("VESSEL");
            ProtoVessel pVessel    = vessel.BackupVessel();

            pVessel.Save(vesselNode);
            nodeToSave.AddNode("VESSEL", vesselNode);

            //save active crew member info
            foreach (ProtoCrewMember pcm in pVessel.GetVesselCrew())
            {
                ConfigNode pcmNode = new ConfigNode("CREW");
                pcm.Save(pcmNode);
                nodeToSave.AddNode("CREW", pcmNode);
            }

            nodeToSave.Save(filename);

            ScreenMessage message = new ScreenMessage(vessel.vesselName + " exported to " + filename, 6, ScreenMessageStyle.UPPER_CENTER);

            ScreenMessages.PostScreenMessage(message);
        }
Пример #6
0
        public static void UnhangarCraft(Vessel vVesselStored, StaticObject soHangar)
        {
            RemoveCorrectCraft(vVesselStored, soHangar);

            // Convert the stored protovessel to a new protovessel.
            // Use BackupVessel because that seems to work and protovessel does not. `\o/`
            ProtoVessel pVessel = vVesselStored.BackupVessel();

            // Get rid of the original hidden vessel - even though it was unloaded KSP still 'sees' the original craft.
            // I do not care why. :|
            vVesselStored.state = Vessel.State.DEAD;

            foreach (Part p in vVesselStored.Parts)
            {
                if (p != null && p.gameObject != null)
                {
                    p.gameObject.DestroyGameObject();
                }
            }

            // Load the new protovessel we made. KSP won't reload (or rather render) a vessel that was unloaded - it will only load a protovessel. :$
            pVessel.Load(FlightDriver.FlightStateCache.flightState);
            // I suspect this is actually a KSP bug since the same crap happens with newly spawned static objects. If you query the active state
            // of the invisible craft, it claims it is active. And no, forcing the renderers doesn't work either.

            // Convert protovessel to vessel
            Vessel vNewVessel = pVessel.vesselRef;

            // Unload then reload the vessel - this seems to be the way to properly re-initialise flightstate etc.
            // Don't do this and you get a craft with a stuck surface velocity reading. It looks like KSP transposes orbital
            // and surface velocity or some other stupid s**t. I don't care.
            // And yes, this time KSP does load an unloaded vessel with no need for protovessel b******t. I don't care why.
            vNewVessel.Unload();
            vNewVessel.Load();
        }
Пример #7
0
        private static string GetInvalidVesselParts(Vessel checkVessel)
        {
            var bannedParts = checkVessel.BackupVessel().protoPartSnapshots
                              .Where(p => !SystemsContainer.Get <ModSystem>().AllowedParts.Contains(p.partName.ToLower())).Distinct();

            var bannedPartsStr = bannedParts.Aggregate("", (current, bannedPart) => current + $"{bannedPart}\n");

            return(bannedPartsStr);
        }
Пример #8
0
        public void SendDockInformation(Guid weakVesselId, Vessel dominantVessel, int subspaceId)
        {
            var vesselBytes = VesselSerializer.SerializeVessel(dominantVessel.BackupVessel());

            if (vesselBytes.Length > 0)
            {
                CreateAndSendDockMessage(weakVesselId, dominantVessel.id, subspaceId, vesselBytes);
            }
        }
Пример #9
0
        // static functions, that make live a lot easier

        /// <summary>
        /// Stores a Vessel into the specified Hangar
        /// </summary>
        internal static void StoreVessel(Vessel vessel, Hangar hangar)
        {
            StoredVessel storedVessel = new StoredVessel
            {
                uuid       = vessel.protoVessel.vesselID,
                vesselName = vessel.GetDisplayName()
            };

            //get the experience and assign the crew to the rooster
            foreach (Part part in vessel.parts)
            {
                int count = part.protoModuleCrew.Count;

                if (count != 0)
                {
                    ProtoCrewMember[] crewList = part.protoModuleCrew.ToArray();

                    for (int i = 0; i < count; i++)
                    {
                        crewList[i].flightLog.AddEntryUnique(FlightLog.EntryType.Recover);
                        crewList[i].flightLog.AddEntryUnique(FlightLog.EntryType.Land, FlightGlobals.currentMainBody.name);
                        crewList[i].ArchiveFlightLog();

                        // remove the crew from the ship
                        part.RemoveCrewmember(crewList[i]);
                    }
                }
            }


            // save the ship
            storedVessel.vesselNode = new ConfigNode("VESSEL");

            //create a backup of the current state, then save that state
            ProtoVessel backup = vessel.BackupVessel();

            backup.Save(storedVessel.vesselNode);

            // save the stored information in the hangar
            hangar.storedVessels.Add(storedVessel);

            // remove the stored vessel from the game
            vessel.MakeInactive();
            vessel.Unload();
            //vessel.Die();

            FlightGlobals.RemoveVessel(vessel);
            if (vessel != null)
            {
                vessel.protoVessel.Clean();
            }

            //UnityEngine.Object.Destroy(vessel.gameObject);

            GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);
            HighLogic.LoadScene(GameScenes.SPACECENTER);
        }
Пример #10
0
        public void SendVesselMessage(Vessel vessel)
        {
            if (vessel == null || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id))
            {
                return;
            }

            vessel.protoVessel = vessel.BackupVessel();
            SendVesselMessage(vessel.protoVessel);
        }
Пример #11
0
        private static string GetInvalidVesselParts(Vessel checkVessel)
        {
            var bannedParts = checkVessel.BackupVessel().protoPartSnapshots
                              .Where(p => !ModSystem.Singleton.AllowedParts.Contains(p.partName.ToLower())).Distinct().ToArray();

            var bannedPartsStr = bannedParts.Aggregate("", (current, bannedPart) => current + (bannedPart + "\n"));

            Debug.Log($"[LMP]: Checked vessel {checkVessel.id } for banned parts, is ok: {bannedParts.Length == 0}");

            return(bannedPartsStr);
        }
Пример #12
0
        private void OnVesselCreate(Vessel vessel)
        {
            ProtoVessel pv = vessel.BackupVessel();
            List<uint> vesselParts = new List<uint>();
            bool killShip = false;
            bool vesselOk = false;
            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
            {
                if (pps.flightID == 0)
                {
                    loadGuid = vessel.id;
                    //When you spawn a new vessel in all the part ID's are 0 until OnFlightReady.
                    return;
                }
                vesselParts.Add(pps.flightID);
                if (partToVessel.ContainsKey(pps.flightID))
                {
                    killShip = true;
                    foreach (Vessel otherVessel in partToVessel[pps.flightID])
                    {
                        if (otherVessel.id == vessel.id)
                        {
                            vesselOk = true;
                        }
                        //Either of the locks are ours or neither of the locks exist
                        if (LockSystem.fetch.LockIsOurs("control-" + otherVessel.id) || LockSystem.fetch.LockIsOurs("update-" + otherVessel.id) || (!LockSystem.fetch.LockExists("control-" + otherVessel.id) && !LockSystem.fetch.LockExists("update-" + otherVessel.id)))
                        {
                            vesselOk = true;
                        }
                    }
                }
            }
            if (killShip && !vesselOk)
            {
                DarkLog.Debug("PartKiller: Destroying vessel fragment");
                vessel.Die();
            }
            else
            {
                vesselToPart.Add(vessel, vesselParts);
                foreach (uint partID in vesselParts)
                {
                    if (!partToVessel.ContainsKey(partID))
                    {
                        partToVessel.Add(partID, new List<Vessel>());
                    }
                    partToVessel[partID].Add(vessel);
                }
            }

        }
Пример #13
0
        private void OnVesselCreate(Vessel vessel)
        {
            ProtoVessel pv          = vessel.BackupVessel();
            List <uint> vesselParts = new List <uint>();
            bool        killShip    = false;
            bool        vesselOk    = false;

            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
            {
                if (pps.flightID == 0)
                {
                    loadGuid = vessel.id;
                    //When you spawn a new vessel in all the part ID's are 0 until OnFlightReady.
                    return;
                }
                vesselParts.Add(pps.flightID);
                if (partToVessel.ContainsKey(pps.flightID))
                {
                    killShip = true;
                    foreach (Vessel otherVessel in partToVessel[pps.flightID])
                    {
                        if (otherVessel.id == vessel.id)
                        {
                            vesselOk = true;
                        }
                        //Either of the locks are ours or neither of the locks exist
                        if (lockSystem.LockIsOurs("control-" + otherVessel.id) || lockSystem.LockIsOurs("update-" + otherVessel.id) || (!lockSystem.LockExists("control-" + otherVessel.id) && !lockSystem.LockExists("update-" + otherVessel.id)))
                        {
                            vesselOk = true;
                        }
                    }
                }
            }
            if (killShip && !vesselOk)
            {
                DarkLog.Debug("PartKiller: Destroying vessel fragment");
                vessel.Die();
            }
            else
            {
                vesselToPart.Add(vessel, vesselParts);
                foreach (uint partID in vesselParts)
                {
                    if (!partToVessel.ContainsKey(partID))
                    {
                        partToVessel.Add(partID, new List <Vessel>());
                    }
                    partToVessel[partID].Add(vessel);
                }
            }
        }
Пример #14
0
        public void ExportSelectedCraft(Vessel vessel)
        {
            CreateFolder();

            string vname1 = vessel.vesselName;

            string vname = "";

            Localizer.TryGetStringByTag(vname1, out vname);
            if (vname == "" || vname == null)
            {
                vname = vname1;
            }


            string filename = KSPUtil.ApplicationRootPath + "Ships/export/" + HighLogic.SaveFolder + "_" + vname;

            Log($"Exporting vessel: {vessel.vesselName}\nExporting to file: {filename}");

            ConfigNode nodeToSave = new ConfigNode();

            //save vessel
            ConfigNode  vesselNode = new ConfigNode("VESSEL");
            ProtoVessel pVessel    = vessel.BackupVessel();

            pVessel.Save(vesselNode);
            nodeToSave.AddNode("VESSEL", vesselNode);

            //save active crew member info
            foreach (ProtoCrewMember pcm in pVessel.GetVesselCrew())
            {
                ConfigNode pcmNode = new ConfigNode("CREW");
                pcm.Save(pcmNode);
                nodeToSave.AddNode("CREW", pcmNode);
            }

            nodeToSave.Save(filename);

            //ScreenMessage message = new ScreenMessage(vname+" exported to "+filename, 6, ScreenMessageStyle.UPPER_CENTER);
            //ScreenMessages.PostScreenMessage(message);

            PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Export", "Export Complete",
                                         "Vessel has been exported to:\n" + filename,
                                         "Ok", false, HighLogic.UISkin);
        }
        public void SendVesselMessage(Vessel vessel, bool force)
        {
            if (vessel == null || VesselCommon.IsSpectating || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id))
            {
                return;
            }

            var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel);

            if (force || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                SendVesselMessage(vessel.BackupVessel());
            }

            if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                VesselsProtoStore.AddOrUpdateVesselToDictionary(vessel);
            }
        }
Пример #16
0
        private void OnVesselWasModified(Vessel vessel)
        {
            if (!vesselToPart.ContainsKey(vessel))
            {
                //Killed as a fragment.
                return;
            }
            List <uint> addList    = new List <uint>();
            List <uint> removeList = new List <uint>(vesselToPart[vessel]);
            ProtoVessel pv         = vessel.BackupVessel();

            foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
            {
                if (removeList.Contains(pps.flightID))
                {
                    removeList.Remove(pps.flightID);
                }
                else
                {
                    addList.Add(pps.flightID);
                }
            }
            foreach (uint partID in addList)
            {
                if (!partToVessel.ContainsKey(partID))
                {
                    partToVessel.Add(partID, new List <Vessel>());
                }
                partToVessel[partID].Add(vessel);
                vesselToPart[vessel].Add(partID);
            }
            foreach (uint partID in removeList)
            {
                vesselToPart[vessel].Remove(partID);
                partToVessel[partID].Remove(vessel);
                if (partToVessel[partID].Count == 0)
                {
                    partToVessel.Remove(partID);
                }
            }
        }
Пример #17
0
        public void SendVesselMessage(Vessel vessel, bool force)
        {
            if (vessel == null || VesselCommon.IsSpectating || vessel.state == Vessel.State.DEAD)
            {
                return;
            }

            VesselProtoSystem.CurrentlyUpdatingVesselId = vessel.id;
            var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel);

            VesselProtoSystem.CurrentlyUpdatingVesselId = Guid.Empty;

            if (force || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                SendVesselMessage(vessel.BackupVessel());
            }

            if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id))
            {
                VesselsProtoStore.AddVesselToDictionary(vessel);
            }
        }
Пример #18
0
        public static void FlushVesselCache(string unloadedSeed, Guid unloadIgnoreID)
        {
            // Save a snapshot
            PersistenceGenerator.SaveSnapshot(unloadedSeed);
            // Cache the current system
            Vessel[]      allVessels         = GameObject.FindObjectsOfType <Vessel> ();
            List <Vessel> unclearableVessels = new List <Vessel> ();

            // Despawn all vessels
            Debugger.Log(allVessels.Length + " vessels need to be despawed.");
            if (unloadIgnoreID != Guid.Empty)
            {
                Debugger.Log("Vessel with ID " + unloadIgnoreID.ToString() + " will be ignored.");
            }
            for (int i = 0; i < allVessels.Length; i++)
            {
                Vessel vessel = allVessels [i];
                // Clear the vessel unless we are asked to ignore it
                if (vessel.id != unloadIgnoreID || unloadIgnoreID == Guid.Empty)
                {
                    vesselSeeds [vessel.id] = unloadedSeed;
                    if (!RemoveVesselFromSystem(vessel))
                    {
                        Debugger.LogWarning("Could not unload " + vessel.name);
                        unclearableVessels.Add(vessel);
                    }
                }
            }
            // Clear the vessel cache
            FlightGlobals.Vessels.Clear();
            HighLogic.CurrentGame.flightState.protoVessels.Clear();
            // If we couldn't unload something, ensure it's not duplicated
            foreach (Vessel vessel in unclearableVessels)
            {
                FlightGlobals.Vessels.Add(vessel);
                HighLogic.CurrentGame.flightState.protoVessels.Add(vessel.BackupVessel());
            }
        }
Пример #19
0
 private void OnVesselWillDestroy(Vessel vessel)
 {
     bool pilotedByAnotherPlayer = LockSystem.fetch.LockExists("control-" + vessel.id) && !LockSystem.fetch.LockIsOurs("control-" + vessel.id);
     bool updatedByAnotherPlayer = LockSystem.fetch.LockExists("update-" + vessel.id) && !LockSystem.fetch.LockIsOurs("update-" + vessel.id);
     bool updatedInTheFuture = VesselWorker.fetch.VesselUpdatedInFuture(vessel.id);
     //Vessel was packed within the last 5 seconds
     if (lastPackTime.ContainsKey(vessel.id) && (UnityEngine.Time.realtimeSinceStartup - lastPackTime[vessel.id]) < 5f)
     {
         lastPackTime.Remove(vessel.id);
         if (vessel.situation == Vessel.Situations.FLYING && (pilotedByAnotherPlayer || updatedByAnotherPlayer || updatedInTheFuture))
         {
             DarkLog.Debug("Hacky load: Saving player vessel getting packed in atmosphere");
             ProtoVessel pv = vessel.BackupVessel();
             ConfigNode savedNode = new ConfigNode();
             pv.Save(savedNode);
             VesselWorker.fetch.LoadVessel(savedNode, vessel.id, true);
         }
     }
     if (lastPackTime.ContainsKey(vessel.id))
     {
         lastPackTime.Remove(vessel.id);
     }
 }
Пример #20
0
 public static PersistentVessel CreateVessel(string seed, Vessel vessel)
 {
     return(CreateVessel(seed, vessel.BackupVessel()));
 }
Пример #21
0
 public StoredVessel(Vessel vsl)
 {
     vessel = vsl.BackupVessel();
     metric = new Metric(vsl);
     id     = vessel.vesselID;
     CoM    = vsl.findLocalCenterOfMass();
     crew   = vsl.GetVesselCrew();
     resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(vessel);
     //			fixTripLogger(); //FIXME
 }
Пример #22
0
 public void OnVesselCreate(Vessel createdVessel)
 {
     try
     {
         //DarkLog.Debug("Vessel creation detected: " + createdVessel.id + ", name: " + createdVessel.vesselName);
         ProtoVessel pv = createdVessel.BackupVessel();
         bool killShip = false;
         bool spawnDebris = false;
         string partOwner = null;
         string createdVesselID = pv.vesselID.ToString();
         foreach (ProtoPartSnapshot vesselPart in pv.protoPartSnapshots)
         {
             if (vesselPart != null)
             {
                 if (vesselParts.ContainsKey(vesselPart.flightID.ToString()))
                 {
                     partOwner = vesselParts[vesselPart.flightID.ToString()];
                     if (!killShip && (createdVesselID != partOwner))
                     {
                         if (LockSystem.fetch.LockIsOurs("control-" + partOwner) || LockSystem.fetch.LockIsOurs("update-" + partOwner) || !LockSystem.fetch.LockExists("update-" + partOwner))
                         {
                             //Vessel is ours, update the part owner.
                             spawnDebris = true;
                             vesselParts[vesselPart.flightID.ToString()] = createdVesselID;
                         }
                         else
                         {
                             DarkLog.Debug("Detected debris for a vessel we do not control, removing " + createdVesselID);
                             killShip = true;
                             break;
                         }
                     }
                 }
             }
         }
         if (killShip)
         {
             createdVessel.Die();
         }
         if (spawnDebris)
         {
             //DarkLog.Debug("Spawned debris " + createdVesselID + " from " + partOwner);
         }
     }
     catch (Exception e)
     {
         DarkLog.Debug("Threw in OnVesselCreate: " + e);
     }
 }
Пример #23
0
 private void CheckVesselParts(Vessel checkVessel)
 {
     List<string> allowedParts = ModWorker.fetch.GetAllowedPartsList();
     List<string> bannedParts = new List<string>();
     ProtoVessel checkProto = checkVessel.BackupVessel();
     foreach (ProtoPartSnapshot part in checkProto.protoPartSnapshots)
     {
         if (!allowedParts.Contains(part.partName))
         {
             if (!bannedParts.Contains(part.partName))
             {
                 bannedParts.Add(part.partName);
             }
         }
     }
     if (checkVessel.isActiveVessel)
     {
         bannedPartsString = "";
         foreach (string bannedPart in bannedParts)
         {
             bannedPartsString += bannedPart + "\n";
         }
     }
     DarkLog.Debug("Checked vessel " + checkVessel.id.ToString() + " for banned parts, is ok: " + (bannedParts.Count == 0));
     vesselPartsOk[checkVessel.id] = (bannedParts.Count == 0);
 }
Пример #24
0
        private bool loadVesselForRendezvous(ProtoVessel placeVessel, Vessel targetVessel)
        {
            targetVessel.BackupVessel();

            placeVessel.orbitSnapShot = targetVessel.protoVessel.orbitSnapShot;

            placeVessel.orbitSnapShot.epoch = 0.0;

            tempID = RmmUtil.Rand.Next(1000000000).ToString();
            //rename any vessels present with "AdministativeDockingName"
            foreach (Vessel ve in FlightGlobals.Vessels)
            {
                if (ve.vesselName == tempID)
                {
                    Vessel NameVessel = null;
                    NameVessel            = ve;
                    NameVessel.vesselName = "1";
                }
            }

            placeVessel.vesselID = Guid.NewGuid();

            placeVessel.vesselName = tempID;

            foreach (ProtoPartSnapshot p in placeVessel.protoPartSnapshots)
            {
                uint newFlightID = (UInt32)RmmUtil.Rand.Next(1000000000, 2147483647);

                // save flight ID of part which should dock
                if (p.flightID == _mission.flightIDDockPart)
                {
                    missionFlightIDDockPart = newFlightID;
                }

                // update flight ID of each part and vessel reference transform id.
                if (placeVessel.refTransform == p.flightID)
                {
                    p.flightID = newFlightID;
                    placeVessel.refTransform = p.flightID;
                }
                else
                {
                    p.flightID = newFlightID;
                }

                // clear out all crew
                if (p.protoModuleCrew != null && p.protoModuleCrew.Count() != 0)
                {
                    List <ProtoCrewMember> cl  = p.protoModuleCrew;
                    List <ProtoCrewMember> clc = new List <ProtoCrewMember>(cl);

                    foreach (ProtoCrewMember c in clc)
                    {
                        p.RemoveCrew(c);
                    }
                }

                foreach (ProtoPartModuleSnapshot pm in p.modules)
                {
                    if (pm.moduleName == "RMMModule")
                    {
                        pm.moduleValues.SetValue("trackingPrimary", false);
                        pm.moduleValues.SetValue("trackingActive", false);
                    }
                }
            }

            try
            {
                placeVessel.Load(HighLogic.CurrentGame.flightState);
                return(true);
            }
            catch
            {
                return(true);
            }
        }
Пример #25
0
        private bool loadVesselForRendezvous(ProtoVessel placeVessel, Vessel targetVessel)
        {
            targetVessel.BackupVessel();

            placeVessel.orbitSnapShot = targetVessel.protoVessel.orbitSnapShot;

            placeVessel.orbitSnapShot.epoch = 0.0;

            tempID = rand.Next(1000000000).ToString();
            //rename any vessels present with "AdministativeDockingName"
            foreach (Vessel ve in FlightGlobals.Vessels)
            {
                if (ve.vesselName == tempID)
                {
                    Vessel NameVessel = null;
                    NameVessel = ve;
                    NameVessel.vesselName = "1";
                }
            }

            placeVessel.vesselID = Guid.NewGuid();

            placeVessel.vesselName = tempID;

            foreach (ProtoPartSnapshot p in placeVessel.protoPartSnapshots)
            {
                if (placeVessel.refTransform == p.flightID)
                {
                    p.flightID = (UInt32)rand.Next(1000000000, 2147483647);
                    placeVessel.refTransform = p.flightID;
                }
                else
                {
                    p.flightID = (UInt32)rand.Next(1000000000, 2147483647);
                }

                if (p.protoModuleCrew != null && p.protoModuleCrew.Count() != 0)
                {
                    List<ProtoCrewMember> cl = p.protoModuleCrew;
                    List<ProtoCrewMember> clc = new List<ProtoCrewMember>(cl);

                    foreach (ProtoCrewMember c in clc)
                    {
                        p.RemoveCrew(c);
                        //print("remove");
                    }
                }
            }

            try
            {
                placeVessel.Load(HighLogic.CurrentGame.flightState);
                return true;
            }
            catch
            {
                //abortArrival();
                //return false;
                return true;
            }
        }
Пример #26
0
 private void OnVesselWasModified(Vessel vessel)
 {
     if (!vesselToPart.ContainsKey(vessel))
     {
         //Killed as a fragment.
         return;
     }
     List<uint> addList = new List<uint>();
     List<uint> removeList = new List<uint>(vesselToPart[vessel]);
     ProtoVessel pv = vessel.BackupVessel();
     foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots)
     {
         if (removeList.Contains(pps.flightID))
         {
             removeList.Remove(pps.flightID);
         }
         else
         {
             addList.Add(pps.flightID);
         }
     }
     foreach (uint partID in addList)
     {
         if (!partToVessel.ContainsKey(partID))
         {
             partToVessel.Add(partID, new List<Vessel>());
         }
         partToVessel[partID].Add(vessel);
         vesselToPart[vessel].Add(partID);
     }
     foreach (uint partID in removeList)
     {
         vesselToPart[vessel].Remove(partID);
         partToVessel[partID].Remove(vessel);
         if (partToVessel[partID].Count == 0)
         {
             partToVessel.Remove(partID);
         }
     }
 }
Пример #27
0
 public StoredVessel(Vessel vsl, bool compute_hull=false)
 {
     proto_vessel = vsl.BackupVessel();
     metric = new Metric(vsl, compute_hull);
     id     = proto_vessel.vesselID;
     name   = proto_vessel.vesselName;
     crew   = vsl.GetVesselCrew();
     resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(proto_vessel);
 }
Пример #28
0
        public static void UnhangarCraft(Vessel vVesselStored, StaticObject soHangar)
        {
            RemoveCorrectCraft(vVesselStored, soHangar);

            // Convert the stored protovessel to a new protovessel.
            // Use BackupVessel because that seems to work and protovessel does not. `\o/`
            ProtoVessel pVessel = vVesselStored.BackupVessel();

            // Get rid of the original hidden vessel - even though it was unloaded KSP still 'sees' the original craft.
            // I do not care why. :|
            vVesselStored.state = Vessel.State.DEAD;

            foreach (Part p in vVesselStored.Parts)
            {
                if (p != null && p.gameObject != null)
                    p.gameObject.DestroyGameObject();
            }

            // Load the new protovessel we made. KSP won't reload (or rather render) a vessel that was unloaded - it will only load a protovessel. :$
            pVessel.Load(FlightDriver.FlightStateCache.flightState);
            // I suspect this is actually a KSP bug since the same crap happens with newly spawned static objects. If you query the active state
            // of the invisible craft, it claims it is active. And no, forcing the renderers doesn't work either.

            // Convert protovessel to vessel
            Vessel vNewVessel = pVessel.vesselRef;

            // Unload then reload the vessel - this seems to be the way to properly re-initialise flightstate etc.
            // Don't do this and you get a craft with a stuck surface velocity reading. It looks like KSP transposes orbital
            // and surface velocity or some other stupid s**t. I don't care.
            // And yes, this time KSP does load an unloaded vessel with no need for protovessel b******t. I don't care why.
            vNewVessel.Unload();
            vNewVessel.Load();
        }
Пример #29
0
        public void SendVesselUpdateIfNeeded(Vessel checkVessel)
        {
            //Check vessel parts
            if (ModWorker.fetch.modControl != ModControlMode.DISABLED)
            {
                if (!vesselPartsOk.ContainsKey(checkVessel.id))
                {
                    CheckVesselParts(checkVessel);
                }
                if (!vesselPartsOk[checkVessel.id])
                {
                    //Vessel with bad parts
                    return;
                }
            }

            if (checkVessel.state == Vessel.State.DEAD)
            {
                //Don't send dead vessels
                return;
            }

            if (checkVessel.vesselType == VesselType.Flag && checkVessel.id == Guid.Empty && checkVessel.vesselName != "Flag")
            {
                DarkLog.Debug("Fixing flag GUID for " + checkVessel.vesselName);
                checkVessel.id = Guid.NewGuid();
            }

            //Only send updates for craft we have update locks for. Request the lock if it's not taken.
            if (!LockSystem.fetch.LockExists("update-" + checkVessel.id.ToString()))
            {
                LockSystem.fetch.ThrottledAcquireLock("update-" + checkVessel.id.ToString());
            }

            // Check if it isn't null before fetching it
            if (FlightGlobals.fetch.activeVessel != null)
            {
                //Take the update lock off another player if we have the control lock and it's our vessel
                if (checkVessel.id == FlightGlobals.fetch.activeVessel.id)
                {
                    if (LockSystem.fetch.LockExists("update-" + checkVessel.id.ToString()) && !LockSystem.fetch.LockIsOurs("update-" + checkVessel.id.ToString()) && LockSystem.fetch.LockIsOurs("control-" + checkVessel.id.ToString()))
                    {
                        LockSystem.fetch.ThrottledAcquireLock("update-" + checkVessel.id.ToString());
                        //Wait until we have the update lock
                        return;
                    }
                }
            }

            //Send updates for unpacked vessels that aren't being flown by other players
            bool notRecentlySentProtoUpdate = serverVesselsProtoUpdate.ContainsKey(checkVessel.id) ? ((UnityEngine.Time.realtimeSinceStartup - serverVesselsProtoUpdate[checkVessel.id]) > VESSEL_PROTOVESSEL_UPDATE_INTERVAL) : true;
            bool notRecentlySentPositionUpdate = serverVesselsPositionUpdate.ContainsKey(checkVessel.id) ? ((UnityEngine.Time.realtimeSinceStartup - serverVesselsPositionUpdate[checkVessel.id]) > (1f / (float)DynamicTickWorker.fetch.sendTickRate)) : true;

            //Check that is hasn't been recently sent
            if (notRecentlySentProtoUpdate)
            {
                ProtoVessel checkProto = checkVessel.BackupVessel();
                //TODO: Fix sending of flying vessels.
                if (checkProto != null)
                {
                    if (checkProto.vesselID != Guid.Empty)
                    {
                        //Also check for kerbal state changes
                        foreach (ProtoPartSnapshot part in checkProto.protoPartSnapshots)
                        {
                            foreach (ProtoCrewMember pcm in part.protoModuleCrew.ToArray())
                            {
                                SendKerbalIfDifferent(pcm);
                            }
                        }
                        RegisterServerVessel(checkProto.vesselID);
                        //Mark the update as sent
                        serverVesselsProtoUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup;
                        //Also delay the position send
                        serverVesselsPositionUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup;
                        latestUpdateSent[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup;
                        bool isFlyingUpdate = (checkProto.situation == Vessel.Situations.FLYING);
                        NetworkWorker.fetch.SendVesselProtoMessage(checkProto, false, isFlyingUpdate);
                    }
                    else
                    {
                        DarkLog.Debug(checkVessel.vesselName + " does not have a guid!");
                    }
                }
            }
            else if (notRecentlySentPositionUpdate && checkVessel.vesselType != VesselType.Flag)
            {
                //Send a position update - Except for flags. They aren't exactly known for their mobility.
                serverVesselsPositionUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup;
                latestUpdateSent[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup;
                VesselUpdate update = VesselUpdate.CopyFromVessel(checkVessel);
                if (update != null)
                {
                    NetworkWorker.fetch.SendVesselUpdate(update);
                }
            }
        }