private void DisplyAutopilotStatus() { //Log.DebugLog("Building autopilot list", "DisplyAutopilotStatus()", Logger.severity.TRACE); RelayStorage store = m_networkClient.GetStorage(); if (store == null) { m_textPanel.WritePublicText("No network connection"); return; } List <SortableAutopilot> autopilots = ResourcePool <List <SortableAutopilot> > .Get(); Vector3D mypos = m_block.GetPosition(); Registrar.ForEach <AutopilotTerminal>(ap => { IRelayPart relayPart; if (RelayClient.TryGetRelayPart((IMyCubeBlock)ap.m_block, out relayPart) && relayPart.GetStorage() == store && m_block.canControlBlock(ap.m_block)) { autopilots.Add(new SortableAutopilot(ap, mypos)); } }); autopilots.Sort(); StringBuilder displayText = new StringBuilder(); displayText.Append(timeString); displayText.Append(DateTime.Now.ToLongTimeString()); displayText.AppendLine(); int count = 0; foreach (SortableAutopilot ap in autopilots) { displayText.Append(tab); displayText.Append(ap.Autopilot.m_block.CubeGrid.DisplayName); displayText.Append(tab); displayText.Append(PrettySI.makePretty(ap.Distance)); displayText.AppendLine("m"); ap.Autopilot.AppendingCustomInfo(displayText); displayText.AppendLine(); count++; if (count >= 5) { break; } } autopilots.Clear(); ResourcePool <List <SortableAutopilot> > .Return(autopilots); string displayString = displayText.ToString(); //Log.DebugLog("Writing to panel: " + m_textPanel.DisplayNameText + ":\n\t" + displayString, "DisplyAutopilotStatus()", Logger.severity.TRACE); m_textPanel.WritePublicText(displayText.ToString()); }
/// <summary> /// Copies all the transmissions to the target storage. Used when merging storages or adding a push to. /// </summary> /// <param name="recipient">NetworkStorage to copy transmissions to.</param> public void CopyTo(RelayStorage recipient) { Log.DebugLog("recipient == this", Logger.severity.FATAL, condition: recipient == this); Log.DebugLog("copying to: " + recipient.PrimaryNode.DebugName, Logger.severity.DEBUG); using (recipient.lock_lastSeen.AcquireExclusiveUsing()) ForEachLastSeen(recipient.in_Receive); using (recipient.lock_messages.AcquireExclusiveUsing()) ForEachMessage(recipient.in_Receive); }
/// <summary> /// Creates a new NetworkStorage with all the same LastSeen and Message. Used when nodes lose connection. /// </summary> /// <param name="primary">The node that will be the primary for the new storage.</param> /// <returns>A new storage that is a copy of this one.</returns> public RelayStorage Clone(RelayNode primary) { Log.DebugLog("cloning, primary " + primary.DebugName, Logger.severity.DEBUG); RelayStorage clone = new RelayStorage(primary); // locks need not be held on clone ForEachLastSeen(clone.m_lastSeen.Add); ForEachMessage(msg => clone.m_messages.Add(msg)); return(clone); }
private string StorageName(RelayStorage store) { if (store == null) { return("null"); } if (store.PrimaryNode == null) { return("NetworkStorage without PrimaryNode!"); } return(store.PrimaryNode.DebugName); }
/// <summary> /// <para>Adds a NetworkStorage to s_sendToSet and, if it is not already present, all NetworkStorage it will push to.</para> ///// <para>lock_sendToSet should be exclusively locked before invoking this method.</para> /// </summary> /// <param name="storage">NetworkStorage to add to sendToSet</param> private static void AddStorage(HashSet <RelayStorage> sendToSet, RelayStorage storage) { if (sendToSet.Add(storage)) { using (storage.lock_pushTo_count.AcquireSharedUsing()) foreach (RelayNode connected in storage.m_pushTo_count.Keys) { if (connected.Storage != null) { AddStorage(sendToSet, connected.Storage); } } } }
private void SelectLastSeen(RelayStorage store, List <long> entityIds) { Vector3D myPos = m_block.GetPosition(); foreach (long id in entityIds) { LastSeen seen; if (store.TryGetLastSeen(id, out seen)) { ExtensionsRelations.Relations relations = m_block.getRelationsTo(seen.Entity, ExtensionsRelations.Relations.Enemy).highestPriority(); m_sortableList.Add(new sortableLastSeen(myPos, seen, relations, m_options)); //Log.DebugLog("item: " + seen.Entity.getBestName() + ", relations: " + relations, "Display_FromProgram()"); } } }
private void AllLastSeen(RelayStorage store) { Vector3D myPos = m_block.GetPosition(); store.ForEachLastSeen((LastSeen seen) => { IMyCubeGrid grid = seen.Entity as IMyCubeGrid; if (grid != null && AttachedGrid.IsGridAttached(m_block.CubeGrid, grid, AttachedGrid.AttachmentKind.Physics)) { return; } ExtensionsRelations.Relations relations = m_block.getRelationsTo(seen.Entity, ExtensionsRelations.Relations.Enemy).highestPriority(); m_sortableList.Add(new sortableLastSeen(myPos, seen, relations, m_options)); //Log.DebugLog("item: " + seen.Entity.getBestName() + ", relations: " + relations, "Display()"); }); }
/// <summary> /// Gets the NetworkStorage this client is connected to or null, if it is not connected to a storage. /// Always test against null, player may forget to put an antenna on the ship. /// </summary> /// <returns>The NetworkStorage this client is connected to or null.</returns> public RelayStorage GetStorage() { RelayNode node = GetNode(); RelayStorage store = node != null ? node.Storage : null; m_logger.debugLog(m_storage != store, "current storage: " + StorageName(m_storage) + ", new storage: " + StorageName(store)); if (store != m_storage && m_messageHandler != null) { if (m_storage != null) m_storage.RemoveMessageHandler(m_block.EntityId); if (store != null) store.AddMessageHandler(m_block.EntityId, m_messageHandler); } m_storage = store; return m_storage; }
/// <summary> /// Looks for a missile threating the ship the player is controlling. /// </summary> private void UpdateMissileThreat() { if (!(m_controlled is IMyCubeBlock)) { //Log.DebugLog("not controlling a ship"); return; } if (m_storage == null) { Log.TraceLog("no storage getter"); return; } RelayStorage store = m_storage.Invoke(); if (store == null) { Log.TraceLog("no storage"); return; } byte timeToImpact = byte.MaxValue; m_threat = null; store.ForEachLastSeen((LastSeen seen) => { if (seen.Type == LastSeen.EntityType.Missile) { GuidedMissile guided; if (Registrar.TryGetValue(seen.Entity, out guided) && IsThreat(guided)) { Log.DebugLog("threat: " + guided.MyEntity, Logger.severity.TRACE); byte tti; if (GetTimeToImpact(guided, out tti) && tti < timeToImpact) { timeToImpact = tti; m_threat = guided; } } } }); }
/// <summary> /// Gets the NetworkStorage this client is connected to or null, if it is not connected to a storage. /// Always test against null, player may forget to put an antenna on the ship. /// </summary> /// <returns>The NetworkStorage this client is connected to or null.</returns> public RelayStorage GetStorage() { RelayNode node = GetNode(); RelayStorage store = node != null ? node.Storage : null; Log.DebugLog("current storage: " + StorageName(m_storage) + ", new storage: " + StorageName(store), condition: m_storage != store); if (store != m_storage && m_messageHandler != null) { if (m_storage != null) { m_storage.RemoveMessageHandler(m_block.EntityId); } if (store != null) { store.AddMessageHandler(m_block.EntityId, m_messageHandler); } } m_storage = store; return(m_storage); }
private static void GetStorage(long entityId, out IMyCubeBlock block, out RelayStorage storage) { IMyEntity entity; if (!MyAPIGateway.Entities.TryGetEntityById(entityId, out entity)) { Logger.AlwaysLog("Failed to get entity id for " + entityId, Logger.severity.WARNING); block = null; storage = null; return; } block = entity as IMyCubeBlock; if (block == null) { Logger.AlwaysLog("Entity is not a block: " + entityId, Logger.severity.WARNING); storage = null; return; } storage = RelayClient.GetOrCreateRelayPart(block).GetStorage(); }
/// <summary> /// Targets a LastSeen chosen from the given storage, will overrride current target. /// </summary> /// <param name="storage">NetworkStorage to get LastSeen from.</param> protected void GetLastSeenTarget(RelayStorage storage, double range) { if (Globals.UpdateCount < m_nextLastSeenSearch) return; m_nextLastSeenSearch = Globals.UpdateCount + 100ul; if (storage == null) { //myLogger.debugLog("no storage", "GetLastSeenTarget()", Logger.severity.INFO); return; } if (storage.LastSeenCount == 0) { //myLogger.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) { lst.Update(processing); CurrentTarget = myTarget; return; } if (ChooseBlock(processing, out targetBlock)) { myTarget = new LastSeenTarget(processing, targetBlock); CurrentTarget = myTarget; return; } } if (Options.TargetEntityId.HasValue) { if (storage.TryGetLastSeen(Options.TargetEntityId.Value, out processing)) { ChooseBlock(processing, out targetBlock); myTarget = new LastSeenTarget(processing, targetBlock); CurrentTarget = myTarget; } //else // myLogger.debugLog("failed to get last seen from entity id", "GetLastSeenTarget()"); return; } processing = null; targetBlock = null; if (SEAD) { float highestPowerLevel = 0f; storage.ForEachLastSeen((LastSeen seen) => { if (seen.isRecent() && CubeBlock.canConsiderHostile(seen.Entity) && Options.CanTargetType(seen.Entity)) { IMyCubeBlock block; float powerLevel; if (RadarEquipment.GetRadarEquipment(seen, out block, out powerLevel) && powerLevel > highestPowerLevel) { highestPowerLevel = powerLevel; processing = seen; targetBlock = block; } } }); } else { // choose closest grid Vector3D myPos = ProjectilePosition(); double closestDist = range * range; storage.ForEachLastSeen(seen => { if (seen.isRecent() && CubeBlock.canConsiderHostile(seen.Entity) && Options.CanTargetType(seen.Entity)) { IMyCubeBlock block; if (!ChooseBlock(seen, out block)) return; // always prefer a grid with a block if (targetBlock != null && block == null) return; double dist = Vector3D.DistanceSquared(myPos, seen.LastKnownPosition); if (dist < closestDist) { closestDist = dist; processing = seen; targetBlock = block; } } }); } if (processing == null) { //myLogger.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 UpdateGPS() { byte newInterval = UserSettings.GetSetting(UserSettings.ByteSettingName.UpdateIntervalHUD); if (newInterval != m_updateIntervalGPS) { Log.DebugLog("Update interval changed from " + m_updateIntervalGPS + " to " + newInterval, Logger.severity.DEBUG); UpdateManager.Unregister(m_updateIntervalGPS, UpdateGPS); UpdateManager.Register(newInterval, UpdateGPS); m_updateIntervalGPS = newInterval; } if (m_storage == null) { Log.TraceLog("no storage getter"); return; } RelayStorage store = m_storage.Invoke(); if (store == null) { Log.TraceLog("no storage"); return; } if (store.LastSeenCount == 0) { Log.TraceLog("No LastSeen"); return; } Vector3D myPosition = m_controlled.GetPosition(); foreach (var pair in Data) { pair.Value.MaxOnHUD = UserSettings.GetSetting(pair.Key); pair.Value.Prepare(); } Log.TraceLog("primary node: " + store.PrimaryNode.DebugName); m_haveTerminalAccess.Clear(); foreach (RelayNode node in Registrar.Scripts <RelayNode>()) { MyCubeGrid grid = (node.Entity as MyCubeBlock)?.CubeGrid; Log.TraceLog("grid: " + grid.nameWithId() + ", node storage: " + node.GetStorage()?.PrimaryNode.DebugName); if (grid != null && node.GetStorage()?.PrimaryNode == store.PrimaryNode && m_haveTerminalAccess.Add(grid)) { foreach (var aGrid in Attached.AttachedGrid.AttachedGrids(grid, Attached.AttachedGrid.AttachmentKind.Terminal, true)) { m_haveTerminalAccess.Add(aGrid); } } } store.ForEachLastSeen((LastSeen seen) => { Log.TraceLog("seen: " + seen.Entity.nameWithId()); if (!seen.isRecent()) { Log.TraceLog("not recent: " + seen.Entity.nameWithId()); return; } if (seen.isRecent_Broadcast()) { Log.TraceLog("already visible: " + seen.Entity.getBestName()); return; } if (seen.Entity is IMyCubeGrid && m_haveTerminalAccess.Contains((IMyCubeGrid)seen.Entity)) { Log.TraceLog("terminal linked: " + seen.Entity.nameWithId()); return; } UserSettings.ByteSettingName setting; if (!CanDisplay(seen, out setting)) { Log.TraceLog("cannot display: " + seen.Entity.nameWithId()); return; } GpsData relateData; if (!Data.TryGetValue(setting, out relateData)) { Log.DebugLog("failed to get setting data, setting: " + setting, Logger.severity.WARNING); return; } if (relateData.MaxOnHUD == 0) { Log.TraceLog("type not permitted: " + seen.Entity.nameWithId()); return; } Log.TraceLog("approved: " + seen.Entity.nameWithId()); float distance = Vector3.DistanceSquared(myPosition, seen.GetPosition()); relateData.distanceSeen.Add(new DistanceSeen(distance, seen)); }); m_haveTerminalAccess.Clear(); foreach (var pair in Data) { UpdateGPS(pair.Key, pair.Value); } }
private void Display(List <long> entityIds = null) { if (entityIds != null) { UpdateInstructions(); } //Log.DebugLog("Building display list", "Display()", Logger.severity.TRACE); RelayStorage store = m_networkClient.GetStorage(); if (store == null) { //m_textPanel.WritePublicText("No network connection"); m_textSurface.WriteText("No network connection"); return; } m_sortableList = ResourcePool <List <sortableLastSeen> > .Get(); if (entityIds == null) { AllLastSeen(store); } else { SelectLastSeen(store, entityIds); } if (m_sortableList.Count == 0) { //m_textPanel.WritePublicText("No entities detected"); m_textSurface.WriteText("No entities detected"); m_sortableList.Clear(); ResourcePool <List <sortableLastSeen> > .Return(m_sortableList); return; } m_lastDisplay = Globals.ElapsedTime; m_sortableList.Sort(); StringBuilder displayText = new StringBuilder(); displayText.Append(timeString); displayText.Append(DateTime.Now.ToLongTimeString()); displayText.AppendLine(); int count = 0; foreach (sortableLastSeen sortable in m_sortableList) { sortable.TextForPlayer(displayText, count++); if (count >= 20) { break; } } m_sortableList.Clear(); ResourcePool <List <sortableLastSeen> > .Return(m_sortableList); string displayString = displayText.ToString(); //Log.DebugLog("Writing to panel: " + m_textPanel.DisplayNameText + ":\n\t" + displayString, "Display()", Logger.severity.TRACE); //m_textPanel.WritePublicText(displayText.ToString()); m_textPanel.WriteText(displayText.ToString()); }
/// <summary> /// Creates a new NetworkStorage with all the same LastSeen and Message. Used when nodes lose connection. /// </summary> /// <param name="primary">The node that will be the primary for the new storage.</param> /// <returns>A new storage that is a copy of this one.</returns> public RelayStorage Clone(RelayNode primary) { m_logger.debugLog("cloning, primary " + primary.LoggingName, Logger.severity.DEBUG); RelayStorage clone = new RelayStorage(primary); // locks need not be held on clone ForEachLastSeen(clone.m_lastSeen.Add); ForEachMessage(msg => clone.m_messages.Add(msg)); return clone; }
/// <summary> /// Check opts, load/unload /// </summary> public void Update100() { if (m_holoEntities.Count != 0 && DateTime.UtcNow >= m_clearAllAt) { Log.DebugLog("clearing all holo entities"); foreach (SeenHolo sh in m_holoEntities.Values) { Log.DebugLog("removing " + sh.Seen.Entity.EntityId + "from m_holoEntities (clear all)"); OnRemove(sh); } m_holoEntities.Clear(); } if (!Enabled) { return; } Vector3D playerPos = MyAPIGateway.Session.Player.GetPosition(), holoCentre = m_offset.ToWorld(m_block); double distSquared = Vector3D.DistanceSquared(playerPos, holoCentre); m_playerCanSee = distSquared <= 1e4d; if (m_playerCanSee && distSquared > 100d) { List <MyLineSegmentOverlapResult <MyEntity> > entitiesInRay = ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Get(); m_playerCanSee = false; MyEntity[] ignore = new MyEntity[] { (MyEntity)MyAPIGateway.Session.Player.Controller.ControlledEntity }; foreach (Vector3 vector in Static.Directions) { LineD ray = new LineD(playerPos, holoCentre + vector * m_radiusHolo); MyGamePruningStructure.GetTopmostEntitiesOverlappingRay(ref ray, entitiesInRay); if (!RayCast.Obstructed(ray, entitiesInRay.Select(overlap => overlap.Element), ignore)) { m_playerCanSee = true; entitiesInRay.Clear(); break; } entitiesInRay.Clear(); } ResourcePool <List <MyLineSegmentOverlapResult <MyEntity> > > .Return(entitiesInRay); } if (!m_playerCanSee) { return; } RelayStorage storage = m_netClient.GetStorage(); if (storage == null) { ((IMyTerminalBlock)m_block).AppendCustomInfo("No network connection"); return; } m_clearAllAt = DateTime.UtcNow + Static.keepInCache; storage.ForEachLastSeen(CreateHolo); foreach (SeenHolo sh in m_holoEntities.Values) { if (CanDisplay(sh.Seen)) { if (!sh.Holo.Render.Visible) { Log.DebugLog("showing holo: " + sh.Seen.Entity.getBestName()); SetupProjection(sh.Holo); SetVisible(sh.Holo, true); } if (sh.Seen.Entity is MyCubeGrid && sh.ColouredByIntegrity != ((m_options & Option.IntegrityColours) != 0)) { if (sh.ColouredByIntegrity) { RestoreColour(sh); } else { ColourByIntegrity(sh); } } } else if (sh.Holo.Render.Visible) { Log.DebugLog("hiding holo: " + sh.Seen.Entity.getBestName()); SetVisible(sh.Holo, false); } } if (m_holoEntitiesRemove.Count != 0) { foreach (long entityId in m_holoEntitiesRemove) { Log.DebugLog("removing " + entityId + "from m_holoEntities"); SeenHolo sh; if (!m_holoEntities.TryGetValue(entityId, out sh)) { // this may be normal Log.DebugLog("not in m_holoEntities: " + entityId, Logger.severity.WARNING); continue; } OnRemove(sh); m_holoEntities.Remove(entityId); } m_holoEntitiesRemove.Clear(); } }
/// <summary> /// Updates direct connections between this node and other nodes. /// When debug is set, checks connection to primary storage node. /// </summary> public void Update100() { s_sendPositionTo.Clear(); bool checkPrimary = false; Registrar.ForEach((RelayNode node) => { if (node == this) { return; } CommunicationType connToNode = TestConnection(node); if (connToNode == CommunicationType.TwoWay) { if (m_directConnect.Add(node)) { Log.TraceLog("Now connected to " + node.DebugName, Logger.severity.DEBUG); if (this.Storage == null) { if (node.Storage != null) { Log.TraceLog("Using storage from other node: " + node.DebugName + ", primary: " + node.Storage.PrimaryNode.DebugName, Logger.severity.DEBUG); this.Storage = node.Storage; } } else if (node.Storage != null && this.Storage != node.Storage) { // should prefer blocks since they are less likely to be removed from world while offline if (this.Block != null && node.Block == null) { Log.TraceLog("Nodes have different storages, copying to this node's storage because this node is a block", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } else if (this.Block == null && node.Block != null) { Log.TraceLog("Nodes have different storages, copying to other node's storage beacause other node is a block", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else if (this.Storage.Size < node.Storage.Size) { Log.TraceLog("Nodes have different storages, copying to other node's storage", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else { Log.TraceLog("Nodes have different storages, copying to this node's storage", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } } } } else { if (m_directConnect.Remove(node)) { Log.TraceLog("No longer connected to " + node.DebugName, Logger.severity.DEBUG); checkPrimary = true; } } if (Storage != null) { if (connToNode == CommunicationType.OneWay) { if (m_oneWayConnect.Add(node)) { Log.TraceLog("New one-way connection to " + node.DebugName, Logger.severity.DEBUG); Storage.AddPushTo(node); } } else { if (m_oneWayConnect.Remove(node)) { Log.TraceLog("Lost one-way connection to " + node.DebugName, Logger.severity.DEBUG); Storage.RemovePushTo(node); } } } }); if (Storage == null) { Log.DebugLog("No storage, creating a new one", Logger.severity.INFO); Storage = new RelayStorage(this); } else if (checkPrimary && !IsConnectedTo(Storage.PrimaryNode)) { Log.DebugLog("Lost connection to primary, cloning storage", Logger.severity.INFO); Storage = Storage.Clone(this); } // connections don't update immediately, so don't worry about a single message (per block) Log.TraceLog("Not connected to primary node", Logger.severity.INFO, condition: !IsConnectedTo(Storage.PrimaryNode)); IMyEntity topEntity = m_entity.GetTopMostParent(); Log.TraceLog("Sending self to " + s_sendPositionTo.Count + " neutral/hostile storages", Logger.severity.TRACE); RelayStorage.Receive(s_sendPositionTo, new LastSeen(topEntity, LastSeen.DetectedBy.Broadcasting)); if (Storage.VeryRecentRadarInfo(topEntity.EntityId)) { return; } if (Block == null) { Storage.Receive(new LastSeen(topEntity, LastSeen.DetectedBy.Broadcasting, new LastSeen.RadarInfo(topEntity))); } else { foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(Block.CubeGrid, AttachedGrid.AttachmentKind.Terminal, true)) { Storage.Receive(new LastSeen(grid, LastSeen.DetectedBy.Broadcasting, new LastSeen.RadarInfo(grid))); } } }
/// <summary> /// Force this node to create a storage. Should only be called from game thread. /// </summary> public void ForceCreateStorage() { Storage = new RelayStorage(this); }
/// <summary> /// Copies all the transmissions to the target storage. Used when merging storages or adding a push to. /// </summary> /// <param name="recipient">NetworkStorage to copy transmissions to.</param> public void CopyTo(RelayStorage recipient) { m_logger.debugLog(recipient == this, "recipient == this", Logger.severity.FATAL); m_logger.debugLog("copying to: " + recipient.PrimaryNode.LoggingName, Logger.severity.DEBUG); using (recipient.lock_lastSeen.AcquireExclusiveUsing()) ForEachLastSeen(recipient.in_Receive); using (recipient.lock_messages.AcquireExclusiveUsing()) ForEachMessage(recipient.in_Receive); }
/// <summary> /// Creates the parameter for the block and runs the program. /// </summary> private void HandleDetected() { if (m_progBlock.IsRunning) { return; } StringBuilder parameter = new StringBuilder(); bool first = true; RelayStorage store = m_networkClient.GetStorage(); if (store == null) { return; } store.ForEachLastSeen((LastSeen seen) => { ExtensionsRelations.Relations relations = (m_progBlock as IMyCubeBlock).getRelationsTo(seen.Entity, ExtensionsRelations.Relations.Enemy).highestPriority(); bool friendly = ExtensionsRelations.toIsFriendly(relations); string bestName = friendly ? seen.Entity.getBestName() : seen.HostileName(); TimeSpan sinceSeen; Vector3D predictedPosition = seen.predictPosition(out sinceSeen); if (first) { first = false; } else { parameter.Append(entitySeparator); } parameter.Append(seen.Entity.EntityId); parameter.Append(fieldSeparator); parameter.Append((byte)relations); parameter.Append(fieldSeparator); parameter.Append((byte)seen.Type); parameter.Append(fieldSeparator); parameter.Append(bestName); parameter.Append(fieldSeparator); parameter.Append(seen.isRecent_Radar()); parameter.Append(fieldSeparator); parameter.Append(seen.isRecent_Jam()); parameter.Append(fieldSeparator); parameter.Append((int)sinceSeen.TotalSeconds); parameter.Append(fieldSeparator); parameter.Append(Math.Round(predictedPosition.X, 1)); parameter.Append(fieldSeparator); parameter.Append(Math.Round(predictedPosition.Y, 1)); parameter.Append(fieldSeparator); parameter.Append(Math.Round(predictedPosition.Z, 1)); parameter.Append(fieldSeparator); parameter.Append(Math.Round(seen.LastKnownVelocity.X, 1)); parameter.Append(fieldSeparator); parameter.Append(Math.Round(seen.LastKnownVelocity.Y, 1)); parameter.Append(fieldSeparator); parameter.Append(Math.Round(seen.LastKnownVelocity.Z, 1)); parameter.Append(fieldSeparator); if (seen.RadarInfoIsRecent()) { parameter.Append(seen.Info.Volume); } else { parameter.Append(0f); } if (!friendly && seen.Type == LastSeen.EntityType.Grid && m_blockCountList_sb.Length > 2 && seen.isRecent() && m_blockCountList_btl != null) { int[] blockCounts = m_blockCountList_btl.Count(CubeGridCache.GetFor((IMyCubeGrid)seen.Entity)); if (blockCounts.Length != 0) { parameter.Append(fieldSeparator); parameter.Append(string.Join(fieldSeparator.ToString(), blockCounts)); } } }); if (parameter.Length == 0) { Log.DebugLog("no detected entities"); return; } //Log.DebugLog("parameters:\n" + parameter.ToString().Replace(string.Empty + entitySeparator, entitySeparator + "\n")); if (!m_progBlock.TryRun(parameter.ToString())) { Log.AlwaysLog("Failed to run program", Logger.severity.INFO); } }
private string StorageName(RelayStorage store) { if (store == null) return "null"; if (store.PrimaryNode == null) return "NetworkStorage without PrimaryNode!"; return store.PrimaryNode.LoggingName; }
private static void GetStorage(long entityId, out IMyCubeBlock block, out RelayStorage storage) { IMyEntity entity; if (!MyAPIGateway.Entities.TryGetEntityById(entityId, out entity)) { Static.logger.alwaysLog("Failed to get entity id for " + entityId, Logger.severity.WARNING); block = null; storage = null; return; } block = entity as IMyCubeBlock; if (block == null) { Static.logger.alwaysLog("Entity is not a block: " + entityId, Logger.severity.WARNING); storage = null; return; } storage = RelayClient.GetOrCreateRelayPart(block).GetStorage(); }
/// <summary> /// Updates direct connections between this node and other nodes. /// When debug is set, checks connection to primary storage node. /// </summary> public void Update100() { s_sendPositionTo.Clear(); if (m_comp_laser != null) m_comp_laser.Update(); bool checkPrimary = false; Registrar.ForEach((RelayNode node) => { if (node == this) return; CommunicationType connToNode = TestConnection(node); if (connToNode == CommunicationType.TwoWay) { if (m_directConnect.Add(node)) { m_logger.debugLog("Now connected to " + node.LoggingName, Logger.severity.DEBUG); if (this.Storage == null) { if (node.Storage != null) { m_logger.debugLog("Using storage from other node: " + node.LoggingName + ", primary: " + node.Storage.PrimaryNode.LoggingName, Logger.severity.DEBUG); this.Storage = node.Storage; } } else if (node.Storage != null && this.Storage != node.Storage) { // should prefer blocks since they are less likely to be removed from world while offline if (this.Block != null && node.Block == null) { m_logger.debugLog("Nodes have different storages, copying to this node's storage because this node is a block", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } else if (this.Block == null && node.Block != null) { m_logger.debugLog("Nodes have different storages, copying to other node's storage beacause other node is a block", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else if (this.Storage.Size < node.Storage.Size) { m_logger.debugLog("Nodes have different storages, copying to other node's storage", Logger.severity.DEBUG); this.Storage.CopyTo(node.Storage); this.Storage = node.Storage; } else { m_logger.debugLog("Nodes have different storages, copying to this node's storage", Logger.severity.DEBUG); node.Storage.CopyTo(this.Storage); node.Storage = this.Storage; } } } } else { if (m_directConnect.Remove(node)) { m_logger.debugLog("No longer connected to " + node.LoggingName, Logger.severity.DEBUG); checkPrimary = true; } } if (Storage != null) if (connToNode == CommunicationType.OneWay) { if (m_oneWayConnect.Add(node)) { m_logger.debugLog("New one-way connection to " + node.LoggingName, Logger.severity.DEBUG); Storage.AddPushTo(node); } } else { if (m_oneWayConnect.Remove(node)) { m_logger.debugLog("Lost one-way connection to " + node.LoggingName, Logger.severity.DEBUG); Storage.RemovePushTo(node); } } }); if (Storage == null) { m_logger.debugLog("No storage, creating a new one", Logger.severity.INFO); Storage = new RelayStorage(this); } else if (checkPrimary && !IsConnectedTo(Storage.PrimaryNode)) { m_logger.debugLog("Lost connection to primary, cloning storage", Logger.severity.INFO); Storage = Storage.Clone(this); } // connections don't update immediately, so don't worry about a single message (per block) m_logger.debugLog(!IsConnectedTo(Storage.PrimaryNode), "Not connected to primary node", Logger.severity.INFO); IMyEntity topEntity = m_entity.GetTopMostParent(); m_logger.debugLog("Sending self to " + s_sendPositionTo.Count + " neutral/hostile storages", Logger.severity.TRACE); RelayStorage.Receive(s_sendPositionTo, new LastSeen(topEntity, LastSeen.UpdateTime.Broadcasting)); Storage.Receive(new LastSeen(topEntity, LastSeen.UpdateTime.Broadcasting, new RadarInfo(topEntity))); }
/// <summary> /// <para>Adds a NetworkStorage to s_sendToSet and, if it is not already present, all NetworkStorage it will push to.</para> ///// <para>lock_sendToSet should be exclusively locked before invoking this method.</para> /// </summary> /// <param name="storage">NetworkStorage to add to sendToSet</param> private static void AddStorage(HashSet<RelayStorage> sendToSet, RelayStorage storage) { if (sendToSet.Add(storage)) using (storage.lock_pushTo_count.AcquireSharedUsing()) foreach (RelayNode connected in storage.m_pushTo_count.Keys) if (connected.Storage != null) AddStorage(sendToSet, connected.Storage); }