Example #1
0
        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());
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
 private string StorageName(RelayStorage store)
 {
     if (store == null)
     {
         return("null");
     }
     if (store.PrimaryNode == null)
     {
         return("NetworkStorage without PrimaryNode!");
     }
     return(store.PrimaryNode.DebugName);
 }
Example #5
0
 /// <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);
                 }
             }
     }
 }
Example #6
0
        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()");
                }
            }
        }
Example #7
0
        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()");
            });
        }
Example #8
0
        /// <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;
        }
Example #9
0
        /// <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;
                        }
                    }
                }
            });
        }
Example #10
0
        /// <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);
        }
Example #11
0
        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();
        }
Example #12
0
        /// <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;
            }
        }
Example #13
0
        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);
            }
        }
Example #14
0
        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());
        }
Example #15
0
        /// <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;
        }
Example #16
0
        /// <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();
            }
        }
Example #17
0
        /// <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)));
                }
            }
        }
Example #18
0
 /// <summary>
 /// Force this node to create a storage. Should only be called from game thread.
 /// </summary>
 public void ForceCreateStorage()
 {
     Storage = new RelayStorage(this);
 }
Example #19
0
        /// <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);
        }
Example #20
0
        /// <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);
            }
        }
Example #21
0
 private string StorageName(RelayStorage store)
 {
     if (store == null)
         return "null";
     if (store.PrimaryNode == null)
         return "NetworkStorage without PrimaryNode!";
     return store.PrimaryNode.LoggingName;
 }
Example #22
0
        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();
        }
Example #23
0
        /// <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)));
        }
Example #24
0
 /// <summary>
 /// Force this node to create a storage. Should only be called from game thread.
 /// </summary>
 public void ForceCreateStorage()
 {
     Storage = new RelayStorage(this);
 }
Example #25
0
 /// <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);
 }