public byte[] ToByteArray()
        {
            // Ensure it ok
            UpdateMinAndMaxSlotIds();
            Fragments = Fragments.OrderBy(x => x.Slot.Id).ToList();
            foreach (var fragment in Fragments)
            {
                fragment.AnimationFile     = fragment.AnimationFile.Replace("\\", "/");
                fragment.MetaDataFile      = fragment.MetaDataFile.Replace("\\", "/");
                fragment.SoundMetaDataFile = fragment.SoundMetaDataFile.Replace("\\", "/");
            }

            // Save
            using MemoryStream memStream = new MemoryStream();
            memStream.Write(Skeletons.ToByteArray());

            memStream.Write(ByteParsers.Int32.EncodeValue(MinSlotId, out _));
            memStream.Write(ByteParsers.Int32.EncodeValue(MaxSlotId, out _));

            memStream.Write(ByteParsers.Int32.EncodeValue(Fragments.Count, out _));
            foreach (var item in Fragments)
            {
                memStream.Write(item.ToByteArray());
            }

            return(memStream.ToArray());
        }
Beispiel #2
0
        public void SummonSkeleton(Vector3 pos)
        {
            Skeleton skeleton = EntityFactory.CreateEntity <Physics>("Skeleton", pos).GetRoot().GetComponent <Skeleton>();

            if (skeleton.Faction != null)
            {
                skeleton.Faction.Minions.Remove(skeleton.AI);
            }
            skeleton.Faction = this.Faction;
            this.Faction.AddMinion(skeleton.AI);
            Skeletons.Add(skeleton);
            Matrix animatePosition = skeleton.Sprite.LocalTransform;

            animatePosition.Translation = animatePosition.Translation - new Vector3(0, 1, 0);
            skeleton.Sprite.AnimationQueue.Add(new EaseMotion(1.0f, animatePosition, skeleton.Sprite.LocalTransform.Translation));
            Manager.World.ParticleManager.Trigger("green_flame", pos, Color.White, 10);
            Manager.World.ParticleManager.Trigger("dirt_particle", pos, Color.White, 10);

            var myEnvoy = Faction.TradeEnvoys.Where(envoy => envoy.Creatures.Contains(this)).FirstOrDefault();

            if (myEnvoy != null)
            {
                myEnvoy.Creatures.Add(skeleton.AI);
            }

            var myWarParty = Faction.WarParties.Where(party => party.Creatures.Contains(this)).FirstOrDefault();

            if (myWarParty != null)
            {
                myWarParty.Creatures.Add(skeleton.AI);
            }
        }
Beispiel #3
0
        public IEnumerable <Act.Status> SummonSkeletons()
        {
            while (true)
            {
                Skeletons.RemoveAll(skeleton => skeleton.IsDead);
                if (SummonTimer.HasTriggered && Skeletons.Count < MaxSkeletons)
                {
                    SummonTimer.Reset(SummonTimer.TargetTimeSeconds);
                    for (int i = Skeletons.Count; i < MaxSkeletons; i += 2)
                    {
                        SummonSkeleton();
                    }
                    yield return(Act.Status.Success);
                }
                else if (SummonTimer.HasTriggered)
                {
                    yield return(Act.Status.Success);
                }
                SummonTimer.Update(DwarfTime.LastTime);

                if (WanderTimer.HasTriggered)
                {
                    Physics.ApplyForce(MathFunctions.RandVector3Box(-5f, 5f, 0.01f, 0.01f, -5f, 5f), 1f);
                    GatherSkeletons();
                }
                WanderTimer.Update(DwarfTime.LastTime);

                if (AttackTimer.HasTriggered)
                {
                    OrderSkeletonsToAttack();
                }
                AttackTimer.Update(DwarfTime.LastTime);
                yield return(Act.Status.Running);
            }
        }
        /// <summary>
        /// Sorgt dafür, dass immer zuverlaessig immer nur der Skeleton der selben Person zurückgegeben wird.
        /// </summary>
        public Skeleton GetFixedSkeleton()
        {
            Skeleton skeleton = null;

            if (Skeletons != null)
            {
                if (_id == -1)
                {
                    skeleton = Skeletons.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked);
                    if (skeleton != null)
                    {
                        _id = skeleton.TrackingId;
                    }
                }
                else
                {
                    skeleton = Skeletons.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked && s.TrackingId == _id);
                    if (skeleton == null)
                    {
                        skeleton = Skeletons.FirstOrDefault(s => s.TrackingState == SkeletonTrackingState.Tracked);
                        if (skeleton != null)
                        {
                            _id = skeleton.TrackingId;
                        }
                        else
                        {
                            _id = -1;
                        }
                    }
                }
            }
            return(skeleton);
        }
Beispiel #5
0
 public Node Visit(Skeletons that, Dictionary <string, Node> data)
 {
     foreach (var skeleton in that.SkeletonList)
     {
         skeleton.Accept(this, data);
     }
     return(null);
 }
Beispiel #6
0
 private void OnTriggerEnter2D(Collider2D collision)
 {
     if (collision != null)
     {
         if (collision.CompareTag("Enemy"))
         {
             Skeletons skeletons = collision.gameObject.GetComponent <Skeletons>();
             skeletons.ChangeHealth(damage - PlayerController.playerController.player.Strenght);
         }
     }
 }
Beispiel #7
0
        public void SummonSkeleton(Vector3 pos)
        {
            Skeleton skeleton = EntityFactory.CreateEntity <Physics>("Skeleton", pos).GetRoot().GetComponent <Skeleton>();

            Skeletons.Add(skeleton);
            Matrix animatePosition = skeleton.Sprite.LocalTransform;

            animatePosition.Translation = animatePosition.Translation - new Vector3(0, 1, 0);
            skeleton.Sprite.AnimationQueue.Add(new EaseMotion(1.0f, animatePosition, skeleton.Sprite.LocalTransform.Translation));
            Manager.World.ParticleManager.Trigger("green_flame", pos, Color.White, 10);
            Manager.World.ParticleManager.Trigger("dirt_particle", pos, Color.White, 10);
        }
Beispiel #8
0
        /// <summary>
        /// Listens to the socket and registers all new requests
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="selfinfo">Selfinfo.</param>
        /// <param name="sock">Sock.</param>
        private static Task ListenAsync(PeerInfo selfinfo, TcpListener sock)
        {
            // Set up a channel for sending sockets
            var sockchan = Channel.Create <TcpClient>();
            var listener = Task.Run(async() =>
            {
                while (true)
                {
                    await sockchan.WriteAsync(await sock.AcceptTcpClientAsync());
                }
            });

            // Handle each request
            var handlers = Skeletons.CollectAsync(sockchan, async client => {
                var peer = PeerConnection.CreatePeer(selfinfo, selfinfo, client.GetStream());

                // Ping the peer
                var res = await peer.Item2.SendConnectionRequestAsync(null, null,
                                                                      new Protocol.Request()
                {
                    Operation = Protocol.Operation.Ping,
                    Self      = selfinfo,
                });

                // Register this peer with the broker
                await Channels.ConnectionBrokerRegistrations.Get().WriteAsync(
                    new ConnectionRegistrationRequest()
                {
                    IsTerminate   = false,
                    UpdateRouting = true,
                    Peer          = res.Response.Self,
                    Channel       = peer.Item2
                }
                    );

                // If we get anything back, register with the routing table
                if (res.Response.Peers != null)
                {
                    var router = Channels.RoutingTableRequests.Get();

                    log.Debug($"Ping response had {res.Response.Peers.Count} peers, registering with routing table");
                    foreach (var np in res.Response.Peers)
                    {
                        await router.AddPeerAsync(np.Key, np);
                    }
                }

                log.Debug("Completed initial ping sequence");
            }, 10);

            return(Task.WhenAll(listener, handlers));
        }
Beispiel #9
0
        /// <summary>
        /// Parse a Skeletons tag
        /// </summary>
        protected void ParseSkeletons()
        {
            SaxToken?token = Match(XmlNodeType.Element, TagNames.Skeletons);

            Skeletons = new Skeletons();
            CopyTokenAttributes(token, Skeletons);
            while (TestLookahead(XmlNodeType.Element, TagNames.Skeleton))
            {   //Parse each single Skeleton
                Skeleton skeleton = ParseSkeleton();
                //Add it to the model
                Skeletons.Add(skeleton);
            }
            token = Match(XmlNodeType.EndElement, TagNames.Skeletons);
        }
Beispiel #10
0
        public void SummonSkeleton()
        {
            Vector3  pos      = Position + MathFunctions.RandVector3Box(-1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f);
            Skeleton skeleton = EntityFactory.GenerateSkeleton(pos, Manager, GameState.Game.Content,
                                                               GameState.Game.GraphicsDevice, Chunks, PlayState.Camera, Faction, PlayState.PlanService,
                                                               this.Creature.Allies).GetChildrenOfType <Skeleton>().FirstOrDefault();

            Skeletons.Add(skeleton);
            Matrix animatePosition = skeleton.Sprite.LocalTransform;

            animatePosition.Translation = animatePosition.Translation - new Vector3(0, 1, 0);
            skeleton.Sprite.AnimationQueue.Add(new EaseMotion(1.0f, animatePosition, skeleton.Sprite.LocalTransform.Translation));
            PlayState.ParticleManager.Trigger("green_flame", pos, Color.White, 10);
            SoundManager.PlaySound(ContentPaths.Audio.tinkle, pos, true);
        }
Beispiel #11
0
        public IEnumerable <Act.Status> SummonSkeletons()
        {
            while (true)
            {
                Skeletons.RemoveAll(skeleton => skeleton.IsDead);
                Creature.CurrentCharacterMode  = CharacterMode.Idle;
                Creature.OverrideCharacterMode = false;

                SummonTimer.Update(DwarfTime.LastTime);
                if (SummonTimer.HasTriggered && Skeletons.Count < MaxSkeletons)
                {
                    Creature.CurrentCharacterMode  = Creature.Stats.CurrentClass.AttackMode;
                    Creature.OverrideCharacterMode = true;
                    Creature.Sprite.ReloopAnimations(Creature.Stats.CurrentClass.AttackMode);
                    SoundManager.PlaySound(ContentPaths.Audio.Oscar.sfx_ic_necromancer_summon, Position, true);
                    SummonTimer.Reset(SummonTimer.TargetTimeSeconds);
                    for (int i = Skeletons.Count; i < MaxSkeletons; i += 2)
                    {
                        SummonSkeleton();
                    }
                    yield return(Act.Status.Success);
                }
                else if (SummonTimer.HasTriggered)
                {
                    yield return(Act.Status.Success);
                }

                GatherSkeletonsTimer.Update(DwarfTime.LastTime);
                if (GatherSkeletonsTimer.HasTriggered)
                {
                    var wander = new WanderAct(this, GatherSkeletonsTimer.TargetTimeSeconds, 1.0f, 1.0f);

                    foreach (var status in wander.Run())
                    {
                        GatherSkeletons();
                        yield return(Act.Status.Running);
                    }
                }

                AttackTimer.Update(DwarfTime.LastTime);
                if (AttackTimer.HasTriggered)
                {
                    OrderSkeletonsToAttack();
                }

                yield return(Act.Status.Running);
            }
        }
Beispiel #12
0
        public void OrderSkeletonsToAttack()
        {
            List <CreatureAI> enemies = (from faction in Creature.Manager.Factions.Factions
                                         where Alliance.GetRelationship(Creature.Allies, faction.Value.Name) == Relationship.Hates
                                         from minion in faction.Value.Minions
                                         let dist = (minion.Position - Creature.AI.Position).Length()
                                                    where dist < AttackRange
                                                    select minion).ToList();

            List <Task>       attackTasks = enemies.Select(enemy => new KillEntityTask(enemy.Physics, KillEntityTask.KillType.Auto)).Cast <Task>().ToList();
            List <CreatureAI> skeletonAis = Skeletons.Select(skeleton => skeleton.AI).ToList();

            if (attackTasks.Count > 0)
            {
                TaskManager.AssignTasks(attackTasks, skeletonAis);
            }
        }
 private void ParseSkeleton(string message)
 {
     try
     {
         dynamic payload = JObject.Parse(message);
         JObject body    = payload.body;
         if (body.HasValues)
         {
             skeletons = body.ToObject <Dictionary <ulong, Skeleton> >();
             Skeletons?.Invoke(skeletons);
         }
     }
     catch (Exception e)
     {
         Debug.Log(e);
     }
 }
Beispiel #14
0
        public void OrderSkeletonsToAttack()
        {
            List <CreatureAI> enemies = (from faction in Creature.Manager.Factions.Factions
                                         where PlayState.ComponentManager.Diplomacy.GetPolitics(Creature.Faction, faction.Value).GetCurrentRelationship() == Relationship.Hateful
                                         from minion in faction.Value.Minions
                                         let dist = (minion.Position - Creature.AI.Position).Length()
                                                    where dist < AttackRange
                                                    select minion).ToList();

            List <Task>       attackTasks = enemies.Select(enemy => new KillEntityTask(enemy.Physics, KillEntityTask.KillType.Auto)).Cast <Task>().ToList();
            List <CreatureAI> skeletonAis = Skeletons.Select(skeleton => skeleton.AI).ToList();

            if (attackTasks.Count > 0)
            {
                TaskManager.AssignTasks(attackTasks, skeletonAis);
            }
        }
 void Update()
 {
     if (!StatusKinectSensor && playerSimulator != null)
     {
         if (timer == 0)
         {
             for (int i = 0; i < playerSimulator.Length; i++)
             {
                 skeletons[(ulong)i] = playerSimulator[i].skeleton;
             }
             Skeletons?.Invoke(skeletons);
             timer = interval;
         }
         else
         {
             timer -= Time.deltaTime;
         }
     }
 }
        private void KinectSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            Microsoft.Kinect.Skeleton[] skeletons = new Microsoft.Kinect.Skeleton[0];

            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null)
                {
                    skeletons = new Microsoft.Kinect.Skeleton[skeletonFrame.SkeletonArrayLength];
                    skeletonFrame.CopySkeletonDataTo(skeletons);

                    Skeletons.Clear();
                    foreach (Microsoft.Kinect.Skeleton skeleton in skeletons)
                    {
                        Skeletons.Add(new Skeleton(skeleton));
                    }
                }
            }

            OnSkeletonFrameReady();
        }
Beispiel #17
0
        static public ByteBuffer Save(GameObject go)
        {
            // 第一层,寻找自己不带Renderer的节点
            List <UnityEngine.Transform> lstTfs = new List <UnityEngine.Transform>();

            CollectTransforms.Do(lstTfs, go.transform);

            FlatBufferBuilder builder = new FlatBufferBuilder(InitBufferSize);

            Offset <Schema.Joint>[] joints = new Offset <Schema.Joint> [lstTfs.Count];
            for (int i = 0; i < lstTfs.Count; i++)
            {
                int parent = lstTfs.FindIndex(new Predicate <UnityEngine.Transform>(
                                                  (target) =>
                {
                    return(target.Equals(lstTfs[i].parent));
                }
                                                  ));
                var name = builder.CreateString(lstTfs[i].name);

                Schema.Joint.StartJoint(builder);
                Schema.Joint.AddNames(builder, name);
                Schema.Joint.AddTransform(builder, Schema.Transform.CreateTransform(builder,
                                                                                    lstTfs[i].localPosition.x, lstTfs[i].localPosition.y, lstTfs[i].localPosition.z,
                                                                                    lstTfs[i].localRotation.x, lstTfs[i].localRotation.y, lstTfs[i].localRotation.z, lstTfs[i].localRotation.w,
                                                                                    lstTfs[i].localScale.x, lstTfs[i].localScale.y, lstTfs[i].localScale.z
                                                                                    ));
                Schema.Joint.AddParent(builder, parent);
                joints[i] = Schema.Joint.EndJoint(builder);
            }
            VectorOffset jointVector = Skeletons.CreateJointsVector(builder, joints);

            Skeletons.StartSkeletons(builder);
            Skeletons.AddJoints(builder, jointVector);
            Offset <Schema.Skeletons> skeleton = Skeletons.EndSkeletons(builder);

            builder.Finish(skeleton.Value);
            return(builder.DataBuffer);
        }
Beispiel #18
0
        void _kinectService_SkeletonFrameReady(object sender, SkeletonArrayReadyEventArgs e)
        {
            Skeletons = e.SkeletonArray;

            Skeleton skeleton = Skeletons.GetFirstTrackedSkeleton();

            if (skeleton == null)
            {
                return;
            }

            Vector3D leftHand = GetJointVector(JointType.HandLeft, skeleton);

            Vector3D rightHand = GetJointVector(JointType.HandRight, skeleton);

            Vector3D handsMidpoint = new Vector3D((rightHand.X + leftHand.X) / 2.0, (rightHand.Y + leftHand.Y) / 2.0, (rightHand.Z + leftHand.Z) / 2.0);

            PositionX = skeleton.Position.X;
            PositionY = skeleton.Position.Y;
            PositionZ = skeleton.Position.Z;

            Velocity = (skeleton.Position.Z - handsMidpoint.Z) / 0.1;
        }
Beispiel #19
0
        /// <summary>
        /// Runs the console interface
        /// </summary>
        /// <returns>An awaitable task.</returns>
        public static Task RunAsync()
        {
            // Set up a console forwarder process
            var consoleOut = Skeletons.CollectAsync(
                Channels.ConsoleOutput.ForRead,
                x => Console.Out.WriteLineAsync(x ?? string.Empty)
                );

            // Set up a channel for sending control messages
            var inputChannel = Channel.Create <string>(buffersize: 10);

            // Set up the console reader process
            var consoleInput = AutomationExtensions.RunTask(
                new { Control = inputChannel.AsWrite() },
                async self =>
            {
                string line;

                // TODO: The blocking read prevents clean shutdown,
                // but direct access to the input stream has issues with the buffer
                while ((line = await Task.Run(() => Console.ReadLine())) != null)
                {
                    await self.Control.WriteAsync(line);
                }
            }
                );

            // Set up the control logic handler
            var proc = AutomationExtensions.RunTask(new
            {
                Control = inputChannel.AsRead(),
                Output  = Channels.ConsoleOutput.ForWrite
            },
                                                    async self =>
            {
                var peers = new List <Tuple <PeerInfo, Task, IWriteChannel <PeerRequest> > >();
                var rnd   = new Random();

                var portnr = 15000;

                await self.Output.WriteAsync(HELPTEXT);
                while (true)
                {
                    try
                    {
                        var commandline = await self.Control.ReadAsync() ?? string.Empty;
                        var command     = commandline.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ?? string.Empty;

                        if (string.Equals(command, "help", StringComparison.OrdinalIgnoreCase))
                        {
                            await self.Output.WriteAsync(HELPTEXT);
                        }
                        else if (string.Equals(command, "exit", StringComparison.OrdinalIgnoreCase) || string.Equals(command, "quit", StringComparison.OrdinalIgnoreCase))
                        {
                            return;
                        }
                        else if (string.Equals(command, "check", StringComparison.OrdinalIgnoreCase))
                        {
                            for (var i = peers.Count - 1; i >= 0; i--)
                            {
                                if (await peers[i].Item3.IsRetiredAsync)
                                {
                                    await self.Output.WriteAsync($"Peer {peers[i].Item1.Key} at {peers[i].Item1.Address} terminated");
                                    peers.RemoveAt(i);
                                }
                            }

                            await self.Output.WriteAsync($"Completed check, found {peers.Count} live peers");
                        }
                        else if (string.Equals(command, "node", StringComparison.OrdinalIgnoreCase))
                        {
                            var actions = commandline.Split(new char[] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);

                            if (string.Equals(actions[1], "start", StringComparison.OrdinalIgnoreCase))
                            {
                                var pi = new PeerInfo(Key.CreateRandomKey(), new IPEndPoint(IPAddress.Loopback, portnr));

                                await self.Output.WriteAsync($"Starting node {pi.Key} on {pi.Address}");
                                var chan = Channel.Create <PeerRequest>();
                                var s    = Task.Run(() =>
                                                    Peer.RunPeer(
                                                        pi, 5, 100, TimeSpan.FromDays(1),
                                                        peers.Count == 0 ? new EndPoint[0] : new[] { peers[rnd.Next(0, peers.Count - 1)].Item1.Address },
                                                        chan.AsRead()
                                                        )
                                                    .ContinueWith(_ => inputChannel.WriteAsync("check"))
                                                    );

                                peers.Add(new Tuple <PeerInfo, Task, IWriteChannel <PeerRequest> >(pi, s, chan));
                                portnr++;
                            }
                            else if (string.Equals(actions[1], "list", StringComparison.OrdinalIgnoreCase))
                            {
                                if (actions.Length != 2)
                                {
                                    await self.Output.WriteAsync("The list command takes no arguments");
                                    continue;
                                }

                                for (var i = 0; i < peers.Count; i++)
                                {
                                    await self.Output.WriteAsync(string.Format("{0}: {1} - {2}", i, peers[i].Item1.Key, peers[i].Item1.Address));
                                }
                                await self.Output.WriteAsync(string.Empty);
                            }
                            else if (string.Equals(actions[1], "connect", StringComparison.OrdinalIgnoreCase))
                            {
                                actions = commandline.Split(new char[] { ' ' }, 5, StringSplitOptions.RemoveEmptyEntries);
                                if (actions.Length != 4)
                                {
                                    await self.Output.WriteAsync("The connect command needs exactly two arguments, the ip and the port");
                                    continue;
                                }

                                if (!IPAddress.TryParse(actions[2], out var ip))
                                {
                                    await self.Output.WriteAsync($"Failed to parse ip: {actions[2]}");
                                    continue;
                                }

                                if (!int.TryParse(actions[3], out var port))
                                {
                                    await self.Output.WriteAsync($"Failed to parse {actions[3]} as an integer");
                                    continue;
                                }

                                var pi = new PeerInfo(Key.CreateRandomKey(), new IPEndPoint(IPAddress.Loopback, portnr));
                                await self.Output.WriteAsync($"Starting node {pi.Key} on {pi.Address}");
                                var chan = Channel.Create <PeerRequest>();

                                var s = Task.Run(() =>
                                                 Peer.RunPeer(
                                                     pi, 5, 100, TimeSpan.FromDays(1),
                                                     new[] { new IPEndPoint(ip, port) },
                                                     chan.AsRead()
                                                     )
                                                 .ContinueWith(_ => inputChannel.WriteAsync("check"))
                                                 );

                                peers.Add(new Tuple <PeerInfo, Task, IWriteChannel <PeerRequest> >(pi, s, chan));
                                portnr++;
                            }
                            else if (string.Equals(actions[1], "stop", StringComparison.OrdinalIgnoreCase) || string.Equals(actions[1], "stat", StringComparison.OrdinalIgnoreCase) || string.Equals(actions[1], "refresh", StringComparison.OrdinalIgnoreCase))
                            {
                                if (actions.Length != 3)
                                {
                                    await self.Output.WriteAsync($"The {actions[1]} command takes exactly one argument, the node number");
                                    continue;
                                }

                                if (!int.TryParse(actions[2], out var ix))
                                {
                                    await self.Output.WriteAsync($"Failed to parse {actions[2]} as an integer");
                                    continue;
                                }

                                if (ix < 0 || ix >= peers.Count)
                                {
                                    await self.Output.WriteAsync($"The node number must be positive and less than {peers.Count}");
                                    continue;
                                }

                                if (string.Equals(actions[1], "stop", StringComparison.OrdinalIgnoreCase))
                                {
                                    await self.Output.WriteAsync($"Stopping node {ix} ({peers[ix].Item1.Key} at {peers[ix].Item1.Address}) ...");
                                    await peers[ix].Item3.RetireAsync();
                                    await self.Output.WriteAsync($"Stopped node ({peers[ix].Item1.Key} at {peers[ix].Item1.Address}) ...");
                                    //peers.RemoveAt(ix);
                                }
                                else if (string.Equals(actions[1], "stat", StringComparison.OrdinalIgnoreCase))
                                {
                                    await self.Output.WriteAsync($"Requesting stats from node {ix} ({peers[ix].Item1.Key} at {peers[ix].Item1.Address}) ...");
                                    var channel = Channel.Create <PeerResponse>();
                                    await peers[ix].Item3.WriteAsync(new PeerRequest()
                                    {
                                        Operation = PeerOperation.Stats,
                                        Response  = channel
                                    });

                                    await self.Output.WriteAsync($"Stats requested, waiting for response...");
                                    await self.Output.WriteAsync(System.Text.Encoding.UTF8.GetString((await channel.ReadAsync()).Data));
                                }
                                else if (string.Equals(actions[1], "refresh", StringComparison.OrdinalIgnoreCase))
                                {
                                    await self.Output.WriteAsync($"Performing refresh on {ix} ({peers[ix].Item1.Key} at {peers[ix].Item1.Address}) ...");

                                    var channel = Channel.Create <PeerResponse>();
                                    await peers[ix].Item3.WriteAsync(new PeerRequest()
                                    {
                                        Operation = PeerOperation.Refresh,
                                        Response  = channel
                                    });

                                    var res = await channel.ReadAsync();
                                    await self.Output.WriteAsync($"Refreshed with {res.SuccessCount} node(s)");
                                }
                                else
                                {
                                    await self.Output.WriteAsync($"Node action not recognized: {actions[1]}");
                                }
                            }
                            else
                            {
                                await self.Output.WriteAsync($"Node command not recognized: {actions[1]}");
                            }
                        }
                        else if (string.Equals(command, "add", StringComparison.OrdinalIgnoreCase))
                        {
                            var actions = commandline.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                            if (actions.Length == 1)
                            {
                                await self.Output.WriteAsync("The add command needs the value to add");
                                continue;
                            }
                            if (peers.Count == 0)
                            {
                                await self.Output.WriteAsync("The add command does not work if no nodes are started");
                                continue;
                            }

                            var channel = Channel.Create <PeerResponse>();
                            var data    = System.Text.Encoding.UTF8.GetBytes(actions[1]);
                            var key     = Key.ComputeKey(data);

                            await self.Output.WriteAsync($"Adding {data.Length} byte(s) with key {key}");
                            await peers[rnd.Next(0, peers.Count)].Item3.WriteAsync(new PeerRequest()
                            {
                                Operation = PeerOperation.Add,
                                Key       = key,
                                Data      = data,
                                Response  = channel,
                            });

                            await self.Output.WriteAsync("Send add request, waiting for completion");
                            var res = await channel.ReadAsync();
                            await self.Output.WriteAsync($"Add inserted into {res.SuccessCount} node(s)");
                        }
                        else if (string.Equals(command, "get", StringComparison.OrdinalIgnoreCase))
                        {
                            var actions = commandline.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
                            if (actions.Length == 1)
                            {
                                await self.Output.WriteAsync("The get command needs the hash to find");
                                continue;
                            }
                            if (actions.Length == 3)
                            {
                                await self.Output.WriteAsync("The get command needs only one argument");
                                continue;
                            }
                            if (peers.Count == 0)
                            {
                                await self.Output.WriteAsync("The get command does not work if no nodes are started");
                                continue;
                            }

                            Key key;
                            try { key = new Key(actions[1]); }
                            catch (Exception ex)
                            {
                                await self.Output.WriteAsync($"Failed to parse key: {ex.Message}");
                                continue;
                            }


                            var channel = Channel.Create <PeerResponse>();

                            await self.Output.WriteAsync($"Locating key");
                            await peers[rnd.Next(0, peers.Count)].Item3.WriteAsync(new PeerRequest()
                            {
                                Operation = PeerOperation.Find,
                                Key       = key,
                                Response  = channel,
                            });

                            var res = await channel.ReadAsync();
                            if (res.Data == null)
                            {
                                await self.Output.WriteAsync($"Did not find the key ...");
                            }
                            else
                            {
                                await self.Output.WriteAsync($"Found: {System.Text.Encoding.UTF8.GetString(res.Data)}");
                            }
                        }
                        else if (string.Equals(command, "hash", StringComparison.OrdinalIgnoreCase))
                        {
                            var actions = commandline.Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                            if (actions.Length == 1)
                            {
                                await self.Output.WriteAsync("The add command needs the value to add");
                                continue;
                            }

                            await self.Output.WriteAsync($"Key: {Key.ComputeKey(actions[1])}");
                        }
                        else
                        {
                            await self.Output.WriteAsync($"Command not recognized: {command}");
                        }
                    }
                    catch (Exception ex)
                    {
                        await self.Output.WriteAsync($"Command failed: {ex.Message}");
                    }
                }
            }
                                                    );

            return(Task.WhenAll(consoleOut /*, consoleInput*/, proc));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="skeletons">The list of Skeletons</param>
 public SkeletonsController(Skeletons skeletons)
 {
     this.SkeletonsList = skeletons;
 }