private void GridSearch_Friend() { int bestNameLength = int.MaxValue; RelayStorage store = m_netStore; if (store == null) { Log.DebugLog("no storage", Logger.severity.DEBUG); return; } store.SearchLastSeen(seen => { IMyCubeGrid grid = seen.Entity as IMyCubeGrid; if (grid != null && grid.DisplayName.Length < bestNameLength && grid.DisplayName.LowerRemoveWhitespace().Contains(m_targetGridName) && CanTarget(seen)) { Grid = seen; bestNameLength = grid.DisplayName.Length; if (bestNameLength == m_targetGridName.Length) { Log.DebugLog("perfect match LastSeen: " + seen.Entity.getBestName()); return(true); } } return(false); }); if (Grid != null) { Log.DebugLog("Best match LastSeen: " + Grid.Entity.getBestName()); } }
/// <summary> /// Search every possible ore detector for materials. /// </summary> /// <param name="requester">Must be able to control OreDetector and have same NetworkStorage</param> /// <param name="oreType">Voxel materials to search for</param> public static void SearchForMaterial(ShipControllerBlock requester, byte[] oreType, OreSearchComplete onComplete) { Vector3D position = requester.CubeBlock.GetPosition(); RelayStorage storage = requester.NetworkStorage; Static.m_thread.EnqueueAction(() => { List <OreDetector> oreDetectors = ResourcePool <List <OreDetector> > .Get(); Registrar.ForEach((OreDetector detector) => { if (detector.Block.IsWorking && requester.CubeBlock.canControlBlock(detector.Block) && detector.m_netClient.GetStorage() == storage) { oreDetectors.Add(detector); } }); IOrderedEnumerable <OreDetector> sorted = oreDetectors.OrderBy(detector => Vector3D.DistanceSquared(position, detector.Block.GetPosition())); foreach (OreDetector detector in sorted) { if (detector.GetOreLocations(position, oreType, onComplete)) { return; } } oreDetectors.Clear(); ResourcePool <List <OreDetector> > .Return(oreDetectors); onComplete(false, null, null, null); }); }
/// <summary> /// Read the data from the storage. /// </summary> public void ReadFromStorage() { try { this.Endpoint = RelayStorage.ReadEndpoint(); this.Groups = RelayStorage.ReadGroups(); this.Messages = RelayStorage.ReadMessages(); } catch (Exception) { // Let's not to crash the client. } }
/// <summary> /// Save the data into the storage. /// </summary> public void SaveToStorage() { try { RelayStorage.SaveEndpoint(this.Endpoint); RelayStorage.SaveGroups(this.Groups); RelayStorage.SaveMessages(this.Messages); } catch (Exception) { // Let's not to crash the client. } }
private void GridUpdate() { Log.DebugLog("Grid == null", Logger.severity.FATAL, condition: Grid == null); if (!Grid.IsValid) { Log.DebugLog("no longer valid: " + Grid.Entity.getBestName(), Logger.severity.DEBUG); Grid = null; return; } if (m_mustBeRecent && !Grid.isRecent()) { Log.DebugLog("no longer recent: " + Grid.Entity.getBestName() + ", age: " + (Globals.ElapsedTime - Grid.LastSeenAt)); Grid = null; return; } if (!CanTarget(Grid)) { Log.DebugLog("can no longer target: " + Grid.Entity.getBestName(), Logger.severity.DEBUG); Grid = null; return; } RelayStorage storage = m_netStore; if (storage == null) { Log.DebugLog("lost storage", Logger.severity.DEBUG); Grid = null; return; } LastSeen updated; if (!m_netStore.TryGetLastSeen(Grid.Entity.EntityId, out updated)) { Log.AlwaysLog("Where does the good go? Searching for " + Grid.Entity.EntityId, Logger.severity.WARNING); Grid = null; return; } //Log.DebugLog("updating grid last seen " + Grid.LastSeenAt + " => " + updated.LastSeenAt, "GridUpdate()"); Grid = updated; }
private void UpdateLastSeen() { RelayStorage store = m_controlBlock.NetworkStorage; if (store == null) { Log.DebugLog("failed to get storage", Logger.severity.INFO); m_character = null; return; } if (m_character != null) { if (store.TryGetLastSeen(m_character.Entity.EntityId, out m_character)) { Log.DebugLog("got updated last seen"); return; } else { Log.DebugLog("failed to update last seen", Logger.severity.WARNING); m_character = null; m_timeoutAt = Globals.ElapsedTime + timeout; } } store.SearchLastSeen((LastSeen seen) => { Log.DebugLog("seen: " + seen.Entity.getBestName()); if (seen.Entity is IMyCharacter && seen.Entity.DisplayName.LowerRemoveWhitespace().Contains(m_charName)) { Log.DebugLog("found a last seen for character"); m_character = seen; return(true); } return(false); }); Log.DebugLog("failed to find a character from last seen", condition: m_character == null); }
/// <summary> /// Updates myAntenna and sends LastSeen of this missile to launcher. /// </summary> private void UpdateNetwork() { if (myAntenna != null) { myAntenna.Update100(); } if (m_launcherRelay == null) { Log.DebugLog("No launcher client", Logger.severity.WARNING); return; } RelayStorage store = m_launcherRelay.GetStorage(); if (store == null) { Log.DebugLog("Launcher's net client does not have a storage", Logger.severity.WARNING); return; } //Log.DebugLog("Updating launcher with location of this missile", "UpdateNetwork()"); store.Receive(new LastSeen(MyEntity, LastSeen.DetectedBy.None)); }
private InitialTargetStatus GetInitialTarget() { if (loadedAmmo == null || loadedAmmo.MissileDefinition == null) { Log.DebugLog("no ammo"); return(InitialTargetStatus.NotReady); } if (m_weaponTarget.Options.TargetGolis.IsValid()) { Log.TraceLog("golis: " + m_weaponTarget.Options.TargetGolis); m_weaponTarget.SetTarget(new GolisTarget(CubeBlock, m_weaponTarget.Options.TargetGolis)); return(InitialTargetStatus.Golis); } if (m_weaponTarget.CurrentControl != WeaponTargeting.Control.Off && !(m_weaponTarget.CurrentTarget is NoTarget)) { Log.TraceLog("from active weapon, control: " + m_weaponTarget.CurrentControl + ", target: " + m_weaponTarget.CurrentTarget); return(InitialTargetStatus.FromWeapon); } else { Log.TraceLog("clearing weapon target"); m_weaponTarget.SetTarget(NoTarget.Instance); } RelayStorage storage = m_relayPart.GetStorage(); if (storage == null) { Log.TraceLog("Failed to get storage for launcher"); return(InitialTargetStatus.NoStorage); } else { ITerminalProperty <float> rangeProperty = CubeBlock.GetProperty("Range") as ITerminalProperty <float>; if (rangeProperty == null) { Logger.AlwaysLog("rangeProperty == null", Logger.severity.FATAL); return(InitialTargetStatus.NotReady); } float range = rangeProperty.GetValue(CubeBlock); if (range < 1f) { range = loadedAmmo.MissileDefinition.MaxTrajectory; } m_weaponTarget.GetLastSeenTarget(storage, range); if (!(m_weaponTarget.CurrentTarget is NoTarget)) { Log.TraceLog("LastSeen: " + m_weaponTarget.CurrentTarget.Entity.nameWithId()); return(InitialTargetStatus.FromWeapon); } else if (m_weaponTarget.Options.TargetEntityId != 0) { return(InitialTargetStatus.NotFoundId); } else { return(InitialTargetStatus.NotFoundAny); } } }
private void GridSearch_Enemy() { RelayStorage store = m_netStore; if (store == null) { Log.DebugLog("no storage", Logger.severity.DEBUG); return; } if (m_targetEntityId != 0L) { LastSeen target; if (store.TryGetLastSeen(m_targetEntityId, out target) && CanTarget(target)) { Grid = target; Log.DebugLog("found target: " + target.Entity.getBestName()); } else { Grid = null; } return; } List <LastSeen> enemies = ResourcePool <List <LastSeen> > .Get(); Vector3D position = m_controlBlock.CubeBlock.GetPosition(); store.SearchLastSeen(seen => { if (!seen.IsValid || !seen.isRecent()) { return(false); } IMyCubeGrid asGrid = seen.Entity as IMyCubeGrid; if (asGrid == null) { return(false); } if (!m_controlBlock.CubeBlock.canConsiderHostile(asGrid)) { return(false); } enemies.Add(seen); Log.DebugLog("enemy: " + asGrid.DisplayName); return(false); }); Log.DebugLog("number of enemies: " + enemies.Count); IOrderedEnumerable <LastSeen> enemiesByDistance = enemies.OrderBy(OrderValue != null ? OrderValue : seen => Vector3D.DistanceSquared(position, seen.GetPosition())); m_reason = ReasonCannotTarget.None; foreach (LastSeen enemy in enemiesByDistance) { if (CanTarget(enemy)) { Grid = enemy; Log.DebugLog("found target: " + enemy.Entity.getBestName()); enemies.Clear(); ResourcePool <List <LastSeen> > .Return(enemies); return; } } Grid = null; Log.DebugLog("nothing found"); enemies.Clear(); ResourcePool <List <LastSeen> > .Return(enemies); }
/// <summary> /// Targets a LastSeen chosen from the given storage, will overrride current target. /// </summary> /// <param name="storage">NetworkStorage to get LastSeen from.</param> public void GetLastSeenTarget(RelayStorage storage, double range) { if (Globals.UpdateCount < m_nextLastSeenSearch) { return; } m_nextLastSeenSearch = Globals.UpdateCount + 100ul; if (storage == null) { //Log.DebugLog("no storage", "GetLastSeenTarget()", Logger.severity.INFO); return; } if (storage.LastSeenCount == 0) { //Log.DebugLog("no last seen in storage", "GetLastSeenTarget()", Logger.severity.DEBUG); return; } LastSeen processing; IMyCubeBlock targetBlock; if (CurrentTarget.Entity != null && storage.TryGetLastSeen(CurrentTarget.Entity.EntityId, out processing) && processing.isRecent()) { LastSeenTarget lst = myTarget as LastSeenTarget; if (lst != null && lst.Block != null && !lst.Block.Closed) { Log.TraceLog("Updating current last seen target"); lst.Update(processing); CurrentTarget = myTarget; return; } if (ChooseBlock(processing, out targetBlock)) { Log.TraceLog("Updating current last seen, chose a new block"); myTarget = new LastSeenTarget(processing, targetBlock); CurrentTarget = myTarget; return; } } if (Options.TargetEntityId > 0L) { if (storage.TryGetLastSeen(Options.TargetEntityId, out processing)) { Log.TraceLog("Got last seen for entity id"); ChooseBlock(processing, out targetBlock); myTarget = new LastSeenTarget(processing, targetBlock); CurrentTarget = myTarget; } //else // Log.DebugLog("failed to get last seen from entity id", "GetLastSeenTarget()"); return; } processing = null; targetBlock = null; if (SEAD) { throw new NotImplementedException(); //float highestPowerLevel = 0f; //storage.ForEachLastSeen((LastSeen seen) => { // if (seen.isRecent() && Options.CanTargetType(seen.Entity) && CanConsiderHostile(seen.Entity)) // { // IMyCubeBlock block; // float powerLevel; // if (RadarEquipment_old.GetRadarEquipment(seen, out block, out powerLevel) && powerLevel > highestPowerLevel) // { // highestPowerLevel = powerLevel; // processing = seen; // targetBlock = block; // } // } //}); } else { Vector3D myPos = ProjectilePosition(); TargetType bestType = TargetType.LowestPriority; double maxRange = range * range; double closestDist = maxRange; storage.ForEachLastSeen(seen => { TargetType typeOfSeen = TargetingOptions.GetTargetType(seen.Entity); if (typeOfSeen <= bestType && Options.CanTargetType(typeOfSeen) && seen.isRecent() && CanConsiderHostile(seen.Entity)) { IMyCubeBlock block; if (!ChooseBlock(seen, out block) || !CheckWeaponsTargeting(typeOfSeen, seen.Entity)) { return; } if (typeOfSeen == bestType && targetBlock != null && block == null) { return; } double dist = Vector3D.DistanceSquared(myPos, seen.LastKnownPosition); if ((typeOfSeen < bestType && dist < maxRange) || dist < closestDist) { closestDist = dist; bestType = typeOfSeen; processing = seen; targetBlock = block; } } }); Log.DebugLog(() => "chose last seen with entity: " + processing.Entity.nameWithId() + ", block: " + targetBlock.getBestName() + ", type: " + bestType + ", distance squared: " + closestDist + ", position: " + processing.Entity.GetPosition(), condition: processing != null); Log.DebugLog("no last seen target found", condition: processing == null); } if (processing == null) { if (this is Guided.GuidedMissile) { Log.TraceLog("GuidedMissile failed to get LastSeen target, keeping previous"); return; } //Log.DebugLog("failed to get a target from last seen", "GetLastSeenTarget()"); myTarget = NoTarget.Instance; CurrentTarget = myTarget; } else { myTarget = new LastSeenTarget(processing, targetBlock); CurrentTarget = myTarget; } }
private void LoadSaveData(Builder_ArmsData data) { if (data == null) { Logger.DebugLog("No data to load"); return; } #pragma warning disable 612, 618 if (Comparer <Version> .Default.Compare(data.ArmsVersion, default(Version)) == 0) { Logger.DebugLog("Old version: " + data.ModVersion); data.ArmsVersion = new Version(data.ModVersion); } #pragma warning restore 612, 618 Logger.AlwaysLog("Save version: " + data.ArmsVersion, Rynchodon.Logger.severity.INFO); // relay Dictionary <Message.Builder_Message, Message> messages = MyAPIGateway.Multiplayer.IsServer ? new Dictionary <Message.Builder_Message, Message>() : null; SerializableGameTime.Adjust = new TimeSpan(data.SaveTime); foreach (RelayStorage.Builder_NetworkStorage bns in data.AntennaStorage) { RelayNode node; if (!Registrar.TryGetValue(bns.PrimaryNode, out node)) { Logger.AlwaysLog("Failed to get node for: " + bns.PrimaryNode, Rynchodon.Logger.severity.WARNING); continue; } RelayStorage store = node.Storage; if (store == null) // probably always true { node.ForceCreateStorage(); store = node.Storage; if (store == null) { Logger.AlwaysLog("failed to create storage for " + node.DebugName, Rynchodon.Logger.severity.ERROR); continue; } } foreach (LastSeen.Builder_LastSeen bls in bns.LastSeenList) { LastSeen ls = new LastSeen(bls); if (ls.IsValid) { store.Receive(ls); } else { Logger.AlwaysLog("failed to create a valid last seen from builder for " + bls.EntityId, Rynchodon.Logger.severity.WARNING); if (m_failedLastSeen == null) { m_failedLastSeen = new CachingDictionary <long, CachingList <LastSeen.Builder_LastSeen> >(); UpdateManager.Register(100, RetryLastSeen); } CachingList <LastSeen.Builder_LastSeen> list; if (!m_failedLastSeen.TryGetValue(bns.PrimaryNode, out list)) { list = new CachingList <LastSeen.Builder_LastSeen>(); m_failedLastSeen.Add(bns.PrimaryNode, list, true); } list.Add(bls); list.ApplyAdditions(); } } Logger.DebugLog("added " + bns.LastSeenList.Length + " last seen to " + store.PrimaryNode.DebugName, Rynchodon.Logger.severity.DEBUG); // messages in the save file belong on the server if (messages == null) { continue; } foreach (Message.Builder_Message bm in bns.MessageList) { Message msg; if (!messages.TryGetValue(bm, out msg)) { msg = new Message(bm); messages.Add(bm, msg); } else { Logger.DebugLog("found linked message", Rynchodon.Logger.severity.TRACE); } if (msg.IsValid) { store.Receive(msg); } else { Logger.AlwaysLog("failed to create a valid message from builder for " + bm.DestCubeBlock + "/" + bm.SourceCubeBlock, Rynchodon.Logger.severity.WARNING); } } Logger.DebugLog("added " + bns.MessageList.Length + " message to " + store.PrimaryNode.DebugName, Rynchodon.Logger.severity.DEBUG); } // past this point, only synchronized data if (!MyAPIGateway.Multiplayer.IsServer) { data = null; return; } // system disruption foreach (Disruption.Builder_Disruption bd in data.SystemDisruption) { Disruption disrupt; switch (bd.Type) { case "AirVentDepressurize": disrupt = new AirVentDepressurize(); break; case "CryoChamberMurder": disrupt = new CryoChamberMurder(); break; case "DisableTurret": disrupt = new DisableTurret(); break; case "DoorLock": disrupt = new DoorLock(); break; case "EMP": disrupt = new EMP(); break; case "GravityReverse": disrupt = new GravityReverse(); break; case "JumpDriveDrain": disrupt = new JumpDriveDrain(); break; case "MedicalRoom": disrupt = new MedicalRoom(); break; case "TraitorTurret": disrupt = new TraitorTurret(); break; default: Logger.AlwaysLog("Unknown disruption: " + bd.Type, Rynchodon.Logger.severity.WARNING); continue; } disrupt.Start(bd); } // autopilot if (data.Autopilot != null) { foreach (ShipAutopilot.Builder_Autopilot ba in data.Autopilot) { ShipAutopilot autopilot; if (Registrar.TryGetValue(ba.AutopilotBlock, out autopilot)) { autopilot.ResumeFromSave(ba); } else { Logger.AlwaysLog("failed to find autopilot block " + ba.AutopilotBlock, Rynchodon.Logger.severity.WARNING); } } } // programmable block if (data.ProgrammableBlock != null) { foreach (ProgrammableBlock.Builder_ProgrammableBlock bpa in data.ProgrammableBlock) { ProgrammableBlock pb; if (Registrar.TryGetValue(bpa.BlockId, out pb)) { pb.ResumeFromSave(bpa); } else { Logger.AlwaysLog("failed to find programmable block " + bpa.BlockId, Rynchodon.Logger.severity.WARNING); } } } // text panel if (data.TextPanel != null) { foreach (TextPanel.Builder_TextPanel btp in data.TextPanel) { TextPanel panel; if (Registrar.TryGetValue(btp.BlockId, out panel)) { panel.ResumeFromSave(btp); } else { Logger.AlwaysLog("failed to find text panel " + btp.BlockId, Rynchodon.Logger.severity.WARNING); } } } // weapon if (data.Weapon != null) { foreach (WeaponTargeting.Builder_WeaponTargeting bwt in data.Weapon) { WeaponTargeting targeting; if (WeaponTargeting.TryGetWeaponTargeting(bwt.WeaponId, out targeting)) { targeting.ResumeFromSave(bwt); } else { Logger.AlwaysLog("failed to find weapon " + bwt.WeaponId, Rynchodon.Logger.severity.WARNING); } } } // entity values if (data.EntityValues != null) { UpgradeEntityValue.Load(data.EntityValues); } // sync if (data.Sync != null) { ASync.SetBuilder(data.Sync); } data = null; }
private void RetryLastSeen() { foreach (KeyValuePair <long, CachingList <LastSeen.Builder_LastSeen> > storageLastSeen in m_failedLastSeen) { RelayNode node; if (Registrar.TryGetValue(storageLastSeen.Key, out node)) { RelayStorage store = node.Storage; foreach (LastSeen.Builder_LastSeen builder in storageLastSeen.Value) { if (MyAPIGateway.Entities.EntityExists(builder.EntityId)) { LastSeen ls = new LastSeen(builder); if (ls.IsValid) { Logger.DebugLog("Successfully created a LastSeen. Primary node: " + storageLastSeen.Key + ", entity: " + ls.Entity.nameWithId()); storageLastSeen.Value.Remove(builder); } else { Logger.AlwaysLog("Unknown failure with last seen", Rynchodon.Logger.severity.ERROR); } } else { Logger.DebugLog("Not yet available: " + builder.EntityId); } } storageLastSeen.Value.ApplyRemovals(); if (storageLastSeen.Value.Count == 0) { Logger.DebugLog("Finished with: " + storageLastSeen.Key, Rynchodon.Logger.severity.DEBUG); m_failedLastSeen.Remove(storageLastSeen.Key); } else { Logger.DebugLog("For " + storageLastSeen.Key + ", " + storageLastSeen.Value.Count + " builders remain"); } } else { Logger.DebugLog("Failed to get node for " + storageLastSeen.Key, Rynchodon.Logger.severity.WARNING); } } m_failedLastSeen.ApplyRemovals(); if (m_failedLastSeen.Count() == 0) { Logger.DebugLog("All LastSeen have been successfully added", Rynchodon.Logger.severity.INFO); m_failedLastSeen = null; UpdateManager.Unregister(100, RetryLastSeen); } else { Logger.DebugLog(m_failedLastSeen.Count() + " primary nodes still have last seen to be added"); if (Globals.UpdateCount >= 3600) { foreach (KeyValuePair <long, CachingList <LastSeen.Builder_LastSeen> > storageLastSeen in m_failedLastSeen) { foreach (LastSeen.Builder_LastSeen builder in storageLastSeen.Value) { Logger.AlwaysLog("Failed to add last seen to world. Primary node: " + storageLastSeen.Key + ", entity ID: " + builder.EntityId, Rynchodon.Logger.severity.WARNING); } } m_failedLastSeen = null; UpdateManager.Unregister(100, RetryLastSeen); } } }