예제 #1
0
            public void RecognizeNode(SecurityPanelNode node)
            {
                if (node.OverlayResourceId > 0)
                {
                    BackgroundOverlay.SetImageResource(node.OverlayResourceId);
                    BackgroundOverlay.Visibility = ViewStates.Visible;
                }
                else
                {
                    BackgroundOverlay.Visibility = ViewStates.Invisible;
                }
                Action resolveNode;
                EventHandler <EventArgs <SecurityPanelNode> > onResolve;

                if (FirstNode != SecurityPanelNode.Unknown && SecondNode == SecurityPanelNode.Unknown && AllowSecondNode)
                {
                    SecondNode  = node;
                    NodeLink    = SecurityPanel.Linkages[FirstNode, SecondNode];
                    resolveNode = _resolveSecondNode;
                    onResolve   = OnSecondNode;
                }
                else if (node != SecurityPanelNode.Unknown)
                {
                    FirstNode   = node;
                    SecondNode  = SecurityPanelNode.Unknown;
                    resolveNode = _resolveFirstNode;
                    onResolve   = OnFirstNode;
                }
                else
                {
                    resolveNode = null;
                    onResolve   = null;
                }

                _cts?.Cancel();
                HeaderText = GetHeaderString();
                DetailText = GetDetailString();
                resolveNode?.Invoke();
                onResolve?.Invoke(this, new EventArgs <SecurityPanelNode>(node));
            }
예제 #2
0
        // This is currently a bit of a hack, because we only support a single security panel.  It's virtual, though, so... you do the math.
        public virtual void SetUpSecurity()
        {
            // Create all of the instances.  Their ctors will take care of inserting them in the dictionaries.
            var A = new SecurityPanelNode("Upper Solenoid", "A", Resource.Drawable.securitypanel_overlay_topleft);    // The one kept hot-meaning-unlocked so that the doors will auto-seal if power dies.
            var B = new SecurityPanelNode("Lower Solenoid", "B", Resource.Drawable.securitypanel_overlay_bottomleft); // The one kept cool-meaning-locked which is used to open them normally.
            var C = new SecurityPanelNode("Communications", "C", Resource.Drawable.securitypanel_overlay_bottom);
            var D = new SecurityPanelNode("Processor", "D", Resource.Drawable.securitypanel_overlay_center);

            Nodes.Add(A);
            Nodes.Add(B);
            Nodes.Add(C);
            Nodes.Add(D);

            var AtoB = new SecurityPanelNodeLink(A, B);
            var AtoC = new SecurityPanelNodeLink(A, C, true);
            var AtoD = new SecurityPanelNodeLink(A, D, true);
            var BtoA = new SecurityPanelNodeLink(B, A);
            var BtoC = new SecurityPanelNodeLink(B, C, true);
            var BtoD = new SecurityPanelNodeLink(B, D, true);
            var CtoA = new SecurityPanelNodeLink(C, A);
            var CtoB = new SecurityPanelNodeLink(C, B);
            var CtoD = new SecurityPanelNodeLink(C, D, true);
            var DtoA = new SecurityPanelNodeLink(D, A, true);
            var DtoB = new SecurityPanelNodeLink(D, B, true);
            var DtoC = new SecurityPanelNodeLink(D, C, true);

            // Define Examine strings
            A.Results[0] = "Clearly a solenoid used to shift the door's locking bolts.  No way to tell if 'powered on' means the door is locked or unlocked, though.";
            A.Results[2] = "This one is hot to the touch - must be live and at fairly high voltage.";
            B.Results[0] = A.Results[0];
            B.Results[2] = "This one is cool to the touch.  Probably off at present.";
            C.Results[0] = "Fiber-optic communications line to elsewhere in the building.";
            C.Results[2] = "Not a lot of data flowing out right now, mostly just telemetry from the processor over on the right.";
            D.Results[0] = "The central processor for this panel.  Not very smart, but smart enough.";
            D.Results[2] = "";

            // Define Measure linkages
            AtoB.MeasureResults[0] = "There's no direct connection between the two solenoids.";
            AtoC.MeasureResults[0] = "Looks like there's a single status line running from the solenoid to the comm relay.";
            AtoC.MeasureResults[1] = "This one is showing 3.3V, steady.  A pretty standard signal for 'on' or some other binary 'one'.";
            AtoD.MeasureResults[0] = "Looks like there's just a simple status line running back to the processor.";
            AtoD.MeasureResults[1] = AtoC.MeasureResults[2];

            BtoA.MeasureResults[0] = AtoB.MeasureResults[0];
            BtoC.MeasureResults[0] = AtoC.MeasureResults[0];
            BtoC.MeasureResults[1] = "This line is rated for the usual few volts, but currently it just reads zero.";
            BtoD.MeasureResults[0] = AtoD.MeasureResults[0];
            BtoD.MeasureResults[1] = BtoC.MeasureResults[1];

            CtoA.MeasureResults[0] = "There's no sign of any data in this direction.";
            CtoB.MeasureResults[0] = CtoA.MeasureResults[0];
            CtoD.MeasureResults[0] = "There's certainly some data flowing along this route, on an intermittent basis.";
            CtoD.MeasureResults[2] = "You do identify one channel here: an encrypyted data stream, probably from a card reader or some other access device.  If we had implemented it, your decker might be able to hack this and fake a valid code, but that's not coded yet.";

            DtoA.MeasureResults[0] = "A 3.3 volt control signal is stepped up to plus sixty volts and a pretty high current in the solenoid.";
            DtoA.MeasureResults[2] = "The way they've engineered this link, it's pretty clear that it's intended to stay hot much if not most of the time.";
            DtoB.MeasureResults[0] = "The step-up transformers along this path seem to be sitting idle; the high voltage lines currently inactive.";
            DtoC.MeasureResults[0] = "A data bus carries several signals out to the comms relay from the processor.";
            DtoC.MeasureResults[2] = "You'd have to have access to the source code, or several hours to play with this, before you could make any sense of what's in this data stream.";

            // Wire Cutter results (where nontrivial).
            // Note that .IsLinked = False is automatically a result; this is apart from that,
            // and a check for .IsLinked that will send up a "nothing to cut" if relevant is likewise built in.
            AtoC.WirecutterResult = () => { SuspiciousInfoHasBeenSent = true; };                       // Looks to the control panel like the backup locks just locked themselves.
            AtoD.WirecutterResult = () => { AlarmHasBeenRaised = true; Blare(AlarmFX); };              // The door knows IT didn't tell the backups to go dead, so someone's tampering.
            DtoC.WirecutterResult = () => { AlarmHasBeenRaised = true; Blare(AlarmFX); };              // Control just lost all communications with this door.
            DtoA.WirecutterResult = () => { SecondaryBoltsAreEngaged = true; Blare(BoltsClosingFX); }; // Congrats, you just screwed up and locked yourself out.
            DtoB.WirecutterResult = () => { DtoB.SolderingResult = AtoB.SolderingResult; };

            // Soldering results - similar IsLinked comments as above.
            AtoB.SolderingResult = async() =>
            {
                if (BtoC.IsLinked)
                {
                    SuspiciousInfoHasBeenSent = true;
                }
                if (BtoD.IsLinked)
                {
                    AlarmHasBeenRaised = true; Blare(AlarmFX);
                }
                ;
                Blare(BoltsOpeningFX);
                MainBoltsAreEngaged = false;
                await Speech.SayAllOf("Doors are now open; proceed.");
            };
            BtoA.SolderingResult = async() =>
            {
                await BoltsClosingFX.PlayToCompletion(10.0, true);

                SecondaryBoltsAreEngaged = true;
                await Speech.SayAllOf("Uh-oh.  That was the secondary bolts engaging - and you're pretty sure the solenoid won't be capable of opening them again.  Looks like Paper Crane is going to be making a service call... or two.");
            };
            AtoC.SolderingResult = AtoD.SolderingResult = async() =>
            {
                AlarmHasBeenRaised = true;
                await SparksFX.PlayToCompletion(1.0, true);

                await Speech.SayAllOf("You have managed to put about six amps through a delicate piece of circuitry.  Congratulations - you just 'bricked' this door.");

                AlarmFX.Play(1.0, false, true);
            };
        }