예제 #1
0
파일: Api.cs 프로젝트: UofG-CS21/SGame
        /// <summary>
        /// "SuperUser DO"; debug-only message used to forcefully set attributes of a connected ship.
        /// </summary>
        public void OnSudo(NetPeer peer, Messages.Sudo data)
        {
            Console.WriteLine("Sudo: {0}", data.Json.ToString());

            LocalSpaceship ship = null;

            if (data.Json.ContainsKey("token"))
            {
                var token = (string)data.Json["token"];
                ship = QuadTreeNode.ShipsByToken.GetValueOrDefault(token, null);
                if (ship == null)
                {
                    return;
                }
            }

            foreach (var kv in data.Json)
            {
                if (kv.Key == "token")
                {
                    continue;
                }

                AttributeSetter setter = SUDO_SETTER_MAP.GetValueOrDefault(kv.Key, null);
                if (setter == null)
                {
                    Console.Error.WriteLine("Sudo: Unrecognized attribute `" + kv.Key + "`");
                    return;
                }

                try
                {
                    setter.Invoke(this, ship, kv.Value);
                }
                catch (Exception exc)
                {
                    Console.Error.WriteLine("Sudo: Failed to set attribute `" + kv.Key + "`: " + exc.ToString());
                    return;
                }
            }

            // Send the same sudo back to the arbiter as ACK
            Bus.SendMessage(data, ArbiterPeer, LiteNetLib.DeliveryMethod.ReliableOrdered);
        }
예제 #2
0
        public async Task Sudo(ApiResponse response, ApiData data)
        {
            var message = new Messages.Sudo()
            {
                Json = data.Json
            };

            if (data.Json.ContainsKey("token"))
            {
                var shipToken = (string)data.Json["token"];
                var shipNode  = RoutingTable.NodeWithShip(shipToken);
                if (shipNode == null)
                {
                    response.Data["error"] = $"No ship with token: {shipToken}";
                    await response.Send(500);

                    return;
                }
                RoutingTable.BusMaster.SendMessage(message, shipNode.Peer, LiteNetLib.DeliveryMethod.ReliableOrdered);

                // Wait for the sudo to bounce back from the node
                await new MessageWaiter <Messages.Sudo>(RoutingTable.BusMaster, shipNode.Peer,
                                                        (sudo) => sudo.Json.Equals(message.Json)).Wait;
            }
            else
            {
                RoutingTable.BusMaster.BroadcastMessage(message);

                // Wait for ALL nodes to ACK sudo...
                var waiters = RoutingTable.BusMaster.Host.ConnectedPeerList
                              .Select((peer) => new MessageWaiter <Messages.Sudo>(RoutingTable.BusMaster, peer, (sudo) => sudo.Json.Equals(message.Json)).Wait)
                              .ToArray();
                Task.WaitAll(waiters);
            }

            await response.Send(200);
        }