Ejemplo n.º 1
0
Archivo: Peer.cs Proyecto: ProDog/Zoro
 private void OnStart(int port, int ws_port)
 {
     ListenerPort = port;
     timer        = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(0, 5000, Context.Self, new Timer(), ActorRefs.NoSender);
     if ((port > 0 || ws_port > 0) &&
         localAddresses.All(p => !p.IsIPv4MappedToIPv6 || IsIntranetAddress(p)) &&
         UPnP.Discover())
     {
         try
         {
             localAddresses.Add(UPnP.GetExternalIP());
             if (port > 0)
             {
                 UPnP.ForwardPort(port, ProtocolType.Tcp, "Zoro");
             }
             if (ws_port > 0)
             {
                 UPnP.ForwardPort(ws_port, ProtocolType.Tcp, "Zoro WebSocket");
             }
         }
         catch { }
     }
     if (port > 0)
     {
         tcp_manager.Tell(new Tcp.Bind(Self, new IPEndPoint(IPAddress.Any, port), options: new[] { new Inet.SO.ReuseAddress(true) }));
     }
     if (ws_port > 0)
     {
         ws_host = new WebHostBuilder().UseKestrel().UseUrls($"http://*:{ws_port}").Configure(app => app.UseWebSockets().Run(ProcessWebSocketAsync)).Build();
         ws_host.Start();
     }
 }
Ejemplo n.º 2
0
        void mWorkerForwarder_DoWork(object sender, DoWorkEventArgs e)
        {
            int  tries  = 0;
            bool adding = (bool)e.Argument;

retry:
            try {
                tries++;
                if (!UPnP.Discover())
                {
                    e.Result = 0;
                }
                else if (adding)
                {
                    UPnP.ForwardPort(port, ProtocolType.Tcp, Server.SoftwareName + "Server");
                    e.Result = 1;
                }
                else
                {
                    UPnP.DeleteForwardingRule(port, ProtocolType.Tcp);
                    e.Result = 3;
                }
            } catch {
                if (tries < 2)
                {
                    goto retry;
                }
                e.Result = 2;
            }
        }
Ejemplo n.º 3
0
        void mWorkerForwarder_DoWork(object sender, DoWorkEventArgs e)
        {
            int  port   = (int)((object[])e.Argument)[0];
            bool adding = (bool)((object[])e.Argument)[1];

            try {
                if (!UPnP.CanUseUpnp)
                {
                    e.Result = 0;
                    return;
                }
                else
                {
                    if (adding)
                    {
                        UPnP.ForwardPort(port, ProtocolType.Tcp, "MCForgeServer");
                        e.Result = 1;
                    }
                    else
                    {
                        UPnP.DeleteForwardingRule(port, ProtocolType.Tcp);
                        e.Result = 3;
                    }
                    return;
                }
            }
            catch {
                e.Result = 2;
                return;
            }
        }
Ejemplo n.º 4
0
        private void frmMain_Load(object sender, EventArgs e)
        {
            listenServer = new Server(8192);

            listenServer.AddTypesToSerializer(typeof(IPacket), new Type[]
            {
                typeof(Core.Packets.ServerPackets.InitializeCommand),
                typeof(Core.Packets.ServerPackets.Disconnect),
                typeof(Core.Packets.ServerPackets.Reconnect),
                typeof(Core.Packets.ServerPackets.Uninstall),
                typeof(Core.Packets.ServerPackets.DownloadAndExecute),
                typeof(Core.Packets.ServerPackets.UploadAndExecute),
                typeof(Core.Packets.ServerPackets.Desktop),
                typeof(Core.Packets.ServerPackets.GetProcesses),
                typeof(Core.Packets.ServerPackets.KillProcess),
                typeof(Core.Packets.ServerPackets.StartProcess),
                typeof(Core.Packets.ServerPackets.Drives),
                typeof(Core.Packets.ServerPackets.Directory),
                typeof(Core.Packets.ServerPackets.DownloadFile),
                typeof(Core.Packets.ServerPackets.MouseClick),
                typeof(Core.Packets.ServerPackets.GetSystemInfo),
                typeof(Core.Packets.ServerPackets.VisitWebsite),
                typeof(Core.Packets.ServerPackets.ShowMessageBox),
                typeof(Core.Packets.ServerPackets.Update),
                typeof(Core.Packets.ServerPackets.Monitors),
                typeof(Core.Packets.ServerPackets.ShellCommand),
                typeof(Core.Packets.ServerPackets.Rename),
                typeof(Core.Packets.ServerPackets.Delete),
                typeof(Core.Packets.ServerPackets.Action),
                typeof(Core.Packets.ClientPackets.Initialize),
                typeof(Core.Packets.ClientPackets.Status),
                typeof(Core.Packets.ClientPackets.UserStatus),
                typeof(Core.Packets.ClientPackets.DesktopResponse),
                typeof(Core.Packets.ClientPackets.GetProcessesResponse),
                typeof(Core.Packets.ClientPackets.DrivesResponse),
                typeof(Core.Packets.ClientPackets.DirectoryResponse),
                typeof(Core.Packets.ClientPackets.DownloadFileResponse),
                typeof(Core.Packets.ClientPackets.GetSystemInfoResponse),
                typeof(Core.Packets.ClientPackets.MonitorsResponse),
                typeof(Core.Packets.ClientPackets.ShellCommandResponse)
            });

            listenServer.ServerState += serverState;
            listenServer.ClientState += clientState;
            listenServer.ClientRead  += clientRead;

            if (XMLSettings.AutoListen)
            {
                if (XMLSettings.UseUPnP)
                {
                    UPnP.ForwardPort(ushort.Parse(XMLSettings.ListenPort.ToString()));
                }
                listenServer.Listen(XMLSettings.ListenPort);
            }
        }
Ejemplo n.º 5
0
        private static bool DiscoverNeo()
        {
            if (UPnP.Discover())
            {
                Console.WriteLine("You have an UPnP-enabled router and your IP is: " + UPnP.ExternalIp);
                UPnP.ForwardPort(_neoTcpPort, ProtocolType.Tcp, "NEO Tcp");

                return(true);
            }
            return(false);
        }
Ejemplo n.º 6
0
        private void FrmMain_Load(object sender, EventArgs e)
        {
            InitializeServer();

            if (XMLSettings.AutoListen)
            {
                if (XMLSettings.UseUPnP)
                {
                    UPnP.ForwardPort(ushort.Parse(XMLSettings.ListenPort.ToString()));
                }
                ListenServer.Listen(XMLSettings.ListenPort);
            }
        }
Ejemplo n.º 7
0
        private void OnStart(ChannelsConfig config)
        {
            ListenerTcpPort = config.Tcp?.Port ?? 0;
            ListenerWsPort  = config.WebSocket?.Port ?? 0;

            MinDesiredConnections    = config.MinDesiredConnections;
            MaxConnections           = config.MaxConnections;
            MaxConnectionsPerAddress = config.MaxConnectionsPerAddress;

            // schedule time to trigger `OnTimer` event every TimerMillisecondsInterval ms
            timer = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(0, 5000, Context.Self, new Timer(), ActorRefs.NoSender);
            if ((ListenerTcpPort > 0 || ListenerWsPort > 0) &&
                localAddresses.All(p => !p.IsIPv4MappedToIPv6 || IsIntranetAddress(p)) &&
                UPnP.Discover())
            {
                try
                {
                    localAddresses.Add(UPnP.GetExternalIP());

                    if (ListenerTcpPort > 0)
                    {
                        UPnP.ForwardPort(ListenerTcpPort, ProtocolType.Tcp, "NEO Tcp");
                    }
                    if (ListenerWsPort > 0)
                    {
                        UPnP.ForwardPort(ListenerWsPort, ProtocolType.Tcp, "NEO WebSocket");
                    }
                }
                catch { }
            }
            if (ListenerTcpPort > 0)
            {
                tcp_manager.Tell(new Tcp.Bind(Self, config.Tcp, options: new[] { new Inet.SO.ReuseAddress(true) }));
            }
            if (ListenerWsPort > 0)
            {
                var host = "*";

                if (!config.WebSocket.Address.GetAddressBytes().SequenceEqual(IPAddress.Any.GetAddressBytes()))
                {
                    // Is not for all interfaces
                    host = config.WebSocket.Address.ToString();
                }

                ws_host = new WebHostBuilder().UseKestrel().UseUrls($"http://{host}:{ListenerWsPort}").Configure(app => app.UseWebSockets().Run(ProcessWebSocketAsync)).Build();
                ws_host.Start();
            }
        }
Ejemplo n.º 8
0
 private void btnListen_Click(object sender, EventArgs e)
 {
     if (btnListen.Text == "Start listening" && !_listenServer.Listening)
     {
         try
         {
             if (chkUseUpnp.Checked && !UPnP.IsPortForwarded)
             {
                 UPnP.ForwardPort(ushort.Parse(ncPort.Value.ToString(CultureInfo.InvariantCulture)));
             }
             if (chkNoIPIntegration.Checked)
             {
                 NoIpUpdater.Start();
             }
             _listenServer.Listen(ushort.Parse(ncPort.Value.ToString(CultureInfo.InvariantCulture)));
         }
         finally
         {
             btnListen.Text      = "Stop listening";
             ncPort.Enabled      = false;
             txtPassword.Enabled = false;
         }
     }
     else if (btnListen.Text == "Stop listening" && _listenServer.Listening)
     {
         try
         {
             _listenServer.Disconnect();
             if (UPnP.IsPortForwarded)
             {
                 UPnP.RemovePort();
             }
         }
         finally
         {
             btnListen.Text      = "Start listening";
             ncPort.Enabled      = true;
             txtPassword.Enabled = true;
         }
     }
 }
Ejemplo n.º 9
0
        void mWorkerForwarder_DoWork(object sender, DoWorkEventArgs e)
        {
            int  tries  = 0;
            int  port   = (int)((object[])e.Argument)[0];
            bool adding = (bool)((object[])e.Argument)[1];

retry:
            try {
                if (!UPnP.CanUseUpnp)
                {
                    e.Result = 0;
                }
                else
                {
                    if (adding)
                    {
                        tries++;
                        UPnP.ForwardPort(port, ProtocolType.Tcp, "MCGalaxyServer");
                        e.Result = 1;
                    }
                    else
                    {
                        UPnP.DeleteForwardingRule(port, ProtocolType.Tcp);
                        e.Result = 3;
                    }
                }
            }
            catch {
                if (tries < 2)
                {
                    goto retry;
                }

                e.Result = 2;
            }
        }
Ejemplo n.º 10
0
        void mWorkerForwarder_DoWork(object sender, DoWorkEventArgs e)
        {
            bool adding = (bool)e.Argument;

            try {
                if (!UPnP.Discover())
                {
                    e.Result = 0;
                }
                else if (adding)
                {
                    UPnP.ForwardPort(port, ProtocolType.Tcp, Server.SoftwareName + "Server");
                    e.Result = 1;
                }
                else
                {
                    UPnP.DeleteForwardingRule(port, ProtocolType.Tcp);
                    e.Result = 3;
                }
            } catch (Exception ex) {
                Logger.LogError("Unexpected UPnP error", ex);
                e.Result = 2;
            }
        }
Ejemplo n.º 11
0
        public Server(IPEndPoint endpoint, ServerSettings settings, ModData modData, bool dedicated)
        {
            Log.AddChannel("server", "server.log");

            listener = new TcpListener(endpoint);
            listener.Start();
            var localEndpoint = (IPEndPoint)listener.LocalEndpoint;

            Ip        = localEndpoint.Address;
            Port      = localEndpoint.Port;
            Dedicated = dedicated;
            Settings  = settings;

            Settings.Name = OpenRA.Settings.SanitizedServerName(Settings.Name);

            ModData = modData;

            randomSeed = (int)DateTime.Now.ToBinary();

            if (Settings.AllowPortForward)
            {
                UPnP.ForwardPort(Settings.ListenPort, Settings.ExternalPort).Wait();
            }

            foreach (var trait in modData.Manifest.ServerTraits)
            {
                serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait));
            }

            LobbyInfo = new Session
            {
                GlobalSettings =
                {
                    RandomSeed         = randomSeed,
                    Map                = settings.Map,
                    ServerName         = settings.Name,
                    EnableSingleplayer = settings.EnableSingleplayer || !dedicated,
                    GameUid            = Guid.NewGuid().ToString()
                }
            };

            new Thread(_ =>
            {
                foreach (var t in serverTraits.WithInterface <INotifyServerStart>())
                {
                    t.ServerStarted(this);
                }

                Log.Write("server", "Initial mod: {0}", ModData.Manifest.Id);
                Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);

                var timeout = serverTraits.WithInterface <ITick>().Min(t => t.TickTimeout);
                for (;;)
                {
                    var checkRead = new List <Socket>();
                    if (State == ServerState.WaitingPlayers)
                    {
                        checkRead.Add(listener.Server);
                    }

                    checkRead.AddRange(Conns.Select(c => c.Socket));
                    checkRead.AddRange(PreConns.Select(c => c.Socket));

                    if (checkRead.Count > 0)
                    {
                        Socket.Select(checkRead, null, null, timeout);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        break;
                    }

                    foreach (var s in checkRead)
                    {
                        if (s == listener.Server)
                        {
                            AcceptConnection();
                            continue;
                        }

                        var preConn = PreConns.SingleOrDefault(c => c.Socket == s);
                        if (preConn != null)
                        {
                            preConn.ReadData(this);
                            continue;
                        }

                        var conn = Conns.SingleOrDefault(c => c.Socket == s);
                        if (conn != null)
                        {
                            conn.ReadData(this);
                        }
                    }

                    foreach (var t in serverTraits.WithInterface <ITick>())
                    {
                        t.Tick(this);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        if (Settings.AllowPortForward)
                        {
                            UPnP.RemovePortForward().Wait();
                        }
                        break;
                    }
                }

                foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>())
                {
                    t.ServerShutdown(this);
                }

                PreConns.Clear();
                Conns.Clear();
                try { listener.Stop(); }
                catch { }
            })
            {
                IsBackground = true
            }.Start();
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Performs a direct transfer, meaning we act as a SOCKS5 server.
        /// </summary>
        /// <param name="session">The SI session whose data to transfer.</param>
        /// <exception cref="Socks5Exception">The SOCKS5 server could not be
        /// instantiated.</exception>
        /// <exception cref="XmppErrorException">The server returned an XMPP error code.
        /// Use the Error property of the XmppErrorException to obtain the specific
        /// error condition.</exception>
        /// <exception cref="XmppException">The server returned invalid data or another
        /// unspecified XMPP error occurred.</exception>
        void DirectTransfer(SISession session)
        {
            // Create the listening SOCKS5 server.
            Socks5Server socks5Server = null;

            try {
                socks5Server = CreateSocks5Server(serverPortFrom, serverPortTo);
            } catch (Exception e) {
                throw new Socks5Exception("The SOCKS5 server could not be created.", e);
            }
            IEnumerable <IPAddress> externalAddresses = null;

            try {
                externalAddresses = GetExternalAddresses();
                // Check if we might need to forward the server port.
                if (externalAddresses.Any(addr => BehindNAT(addr)) && UseUPnP)
                {
                    try {
                        UPnP.ForwardPort(socks5Server.Port, ProtocolType.Tcp,
                                         "XMPP SOCKS5 File-transfer");
                    } catch (InvalidOperationException) {
                        // If automatic port forwarding failed for whatever reason, just
                        // go on normally. The user can still configure forwarding manually.
                    }
                }
            } catch (NotSupportedException) {
                // Not much we can do.
            }
            // Waiting for a client connection is a blocking call and we need to
            // negotiate the SOCKS5 connection after we send the IQ request but
            // _before_ we wait for the IQ response.
            Task.Factory.StartNew(() => {
                try {
                    AcceptClientConnection(session, socks5Server, acceptTimeout);
                    SendData(session, socks5Server.GetStream());
                } finally {
                    socks5Server.Close();
                }
            });

            // Send target a list of streamhosts, one for each active network interface.
            var xml = Xml.Element("query", "http://jabber.org/protocol/bytestreams")
                      .Attr("sid", session.Sid);
            // Compile a set of all our IP addresses that we can advertise.
            ISet <IPAddress> ips = new HashSet <IPAddress>();

            if (externalAddresses != null)
            {
                ips.UnionWith(externalAddresses);
            }
            ips.UnionWith(GetIpAddresses());
            foreach (var ip in ips)
            {
                xml.Child(Xml.Element("streamhost")
                          .Attr("jid", im.Jid.ToString())
                          .Attr("host", ip.ToString())
                          .Attr("port", socks5Server.Port.ToString()));
            }
            // Send IQ with streamhosts to the target.
            var iq = im.IqRequest(IqType.Set, session.To, im.Jid, xml);

            if (iq.Type == IqType.Error)
            {
                throw Util.ExceptionFromError(iq, "The SOCKS5 connection could not " +
                                              "be established.");
            }
        }
Ejemplo n.º 13
0
        public Server(IPEndPoint endpoint, ServerSettings settings, ModData modData, bool dedicated)
        {
            Log.AddChannel("server", "server.log");

            listener = new TcpListener(endpoint);
            listener.Start();
            var localEndpoint = (IPEndPoint)listener.LocalEndpoint;

            Ip        = localEndpoint.Address;
            Port      = localEndpoint.Port;
            Dedicated = dedicated;
            Settings  = settings;

            Settings.Name = OpenRA.Settings.SanitizedServerName(Settings.Name);

            ModData = modData;

            playerDatabase = modData.Manifest.Get <PlayerDatabase>();

            randomSeed = (int)DateTime.Now.ToBinary();

            if (UPnP.Status == UPnPStatus.Enabled)
            {
                UPnP.ForwardPort(Settings.ListenPort, Settings.ListenPort).Wait();
            }

            foreach (var trait in modData.Manifest.ServerTraits)
            {
                serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait));
            }

            serverTraits.TrimExcess();

            LobbyInfo = new Session
            {
                GlobalSettings =
                {
                    RandomSeed         = randomSeed,
                    Map                = settings.Map,
                    ServerName         = settings.Name,
                    EnableSingleplayer = settings.EnableSingleplayer || !dedicated,
                    EnableSyncReports  = settings.EnableSyncReports,
                    GameUid            = Guid.NewGuid().ToString(),
                    Dedicated          = dedicated
                }
            };

            new Thread(_ =>
            {
                foreach (var t in serverTraits.WithInterface <INotifyServerStart>())
                {
                    t.ServerStarted(this);
                }

                Log.Write("server", "Initial mod: {0}", ModData.Manifest.Id);
                Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);

                while (true)
                {
                    var checkRead = new List <Socket>();
                    if (State == ServerState.WaitingPlayers)
                    {
                        checkRead.Add(listener.Server);
                    }

                    checkRead.AddRange(Conns.Select(c => c.Socket));
                    checkRead.AddRange(PreConns.Select(c => c.Socket));

                    // Block for at most 1 second in order to guarantee a minimum tick rate for ServerTraits
                    // Decrease this to 100ms to improve responsiveness if we are waiting for an authentication query
                    var localTimeout = waitingForAuthenticationCallback > 0 ? 100000 : 1000000;
                    if (checkRead.Count > 0)
                    {
                        Socket.Select(checkRead, null, null, localTimeout);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        break;
                    }

                    foreach (var s in checkRead)
                    {
                        if (s == listener.Server)
                        {
                            AcceptConnection();
                            continue;
                        }

                        var preConn = PreConns.SingleOrDefault(c => c.Socket == s);
                        if (preConn != null)
                        {
                            preConn.ReadData(this);
                            continue;
                        }

                        var conn = Conns.SingleOrDefault(c => c.Socket == s);
                        if (conn != null)
                        {
                            conn.ReadData(this);
                        }
                    }

                    delayedActions.PerformActions(0);

                    foreach (var t in serverTraits.WithInterface <ITick>())
                    {
                        t.Tick(this);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        if (UPnP.Status == UPnPStatus.Enabled)
                        {
                            UPnP.RemovePortForward().Wait();
                        }
                        break;
                    }
                }

                foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>())
                {
                    t.ServerShutdown(this);
                }

                PreConns.Clear();
                Conns.Clear();
                try { listener.Stop(); }
                catch { }
            })
            {
                IsBackground = true
            }.Start();
        }
Ejemplo n.º 14
0
        private void DirectTransfer(SISession session)
        {
            Func <IPAddress, bool> predicate    = null;
            Socks5Server           socks5Server = null;

            try
            {
                socks5Server = this.CreateSocks5Server(this.serverPortFrom, this.serverPortTo);
            }
            catch (Exception exception)
            {
                throw new Socks5Exception("The SOCKS5 server could not be created.", exception);
            }
            IEnumerable <IPAddress> source = null;

            try
            {
                source = this.GetExternalAddresses();
                if (predicate == null)
                {
                    predicate = addr => this.BehindNAT(addr);
                }
                if (source.Any <IPAddress>(predicate) && this.UseUPnP)
                {
                    try
                    {
                        UPnP.ForwardPort(socks5Server.Port, ProtocolType.Tcp, "XMPP SOCKS5 File-transfer");
                    }
                    catch (InvalidOperationException)
                    {
                    }
                }
            }
            catch (NotSupportedException)
            {
            }
            Task.Factory.StartNew(delegate {
                try
                {
                    this.AcceptClientConnection(session, socks5Server, 0x2bf20);
                    this.SendData(session, socks5Server.GetStream());
                }
                finally
                {
                    socks5Server.Close();
                }
            });
            XmlElement       e   = Xml.Element("query", "http://jabber.org/protocol/bytestreams").Attr("sid", session.Sid);
            ISet <IPAddress> set = new HashSet <IPAddress>();

            if (source != null)
            {
                set.UnionWith(source);
            }
            set.UnionWith(GetIpAddresses(null));
            foreach (IPAddress address in set)
            {
                e.Child(Xml.Element("streamhost", null).Attr("jid", base.im.Jid.ToString()).Attr("host", address.ToString()).Attr("port", socks5Server.Port.ToString()));
            }
            Iq errorIq = base.im.IqRequest(IqType.Set, session.To, base.im.Jid, e, null, -1, "");

            if (errorIq.Type == IqType.Error)
            {
                throw Util.ExceptionFromError(errorIq, "The SOCKS5 connection could not be established.");
            }
        }
Ejemplo n.º 15
0
        public Server(List <IPEndPoint> endpoints, ServerSettings settings, ModData modData, ServerType type)
        {
            Log.AddChannel("server", "server.log", true);

            SocketException lastException   = null;
            var             checkReadServer = new List <Socket>();

            foreach (var endpoint in endpoints)
            {
                var listener = new TcpListener(endpoint);
                try
                {
                    try
                    {
                        listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 1);
                    }
                    catch (Exception ex)
                    {
                        if (ex is SocketException || ex is ArgumentException)
                        {
                            Log.Write("server", "Failed to set socket option on {0}: {1}", endpoint.ToString(), ex.Message);
                        }
                        else
                        {
                            throw;
                        }
                    }

                    listener.Start();
                    listeners.Add(listener);
                    checkReadServer.Add(listener.Server);
                }
                catch (SocketException ex)
                {
                    lastException = ex;
                    Log.Write("server", "Failed to listen on {0}: {1}", endpoint.ToString(), ex.Message);
                }
            }

            if (listeners.Count == 0)
            {
                throw lastException;
            }

            Type     = type;
            Settings = settings;

            Settings.Name = OpenRA.Settings.SanitizedServerName(Settings.Name);

            ModData = modData;

            playerDatabase = modData.Manifest.Get <PlayerDatabase>();

            randomSeed = (int)DateTime.Now.ToBinary();

            if (type != ServerType.Local && settings.EnableGeoIP)
            {
                GeoIP.Initialize();
            }

            if (UPnP.Status == UPnPStatus.Enabled)
            {
                UPnP.ForwardPort(Settings.ListenPort, Settings.ListenPort).Wait();
            }

            foreach (var trait in modData.Manifest.ServerTraits)
            {
                serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait));
            }

            serverTraits.TrimExcess();

            LobbyInfo = new Session
            {
                GlobalSettings =
                {
                    RandomSeed         = randomSeed,
                    Map                = settings.Map,
                    ServerName         = settings.Name,
                    EnableSingleplayer = settings.EnableSingleplayer || Type != ServerType.Dedicated,
                    EnableSyncReports  = settings.EnableSyncReports,
                    GameUid            = Guid.NewGuid().ToString(),
                    Dedicated          = Type == ServerType.Dedicated
                }
            };

            new Thread(_ =>
            {
                foreach (var t in serverTraits.WithInterface <INotifyServerStart>())
                {
                    t.ServerStarted(this);
                }

                Log.Write("server", "Initial mod: {0}", ModData.Manifest.Id);
                Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);

                while (true)
                {
                    var checkRead = new List <Socket>();
                    if (State == ServerState.WaitingPlayers)
                    {
                        checkRead.AddRange(checkReadServer);
                    }

                    checkRead.AddRange(Conns.Select(c => c.Socket));
                    checkRead.AddRange(PreConns.Select(c => c.Socket));

                    // Block for at most 1 second in order to guarantee a minimum tick rate for ServerTraits
                    // Decrease this to 100ms to improve responsiveness if we are waiting for an authentication query
                    var localTimeout = waitingForAuthenticationCallback > 0 ? 100000 : 1000000;
                    if (checkRead.Count > 0)
                    {
                        Socket.Select(checkRead, null, null, localTimeout);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        break;
                    }

                    foreach (var s in checkRead)
                    {
                        var serverIndex = checkReadServer.IndexOf(s);
                        if (serverIndex >= 0)
                        {
                            AcceptConnection(listeners[serverIndex]);
                            continue;
                        }

                        var preConn = PreConns.SingleOrDefault(c => c.Socket == s);
                        if (preConn != null)
                        {
                            preConn.ReadData(this);
                            continue;
                        }

                        var conn = Conns.SingleOrDefault(c => c.Socket == s);
                        conn?.ReadData(this);
                    }

                    delayedActions.PerformActions(0);

                    // PERF: Dedicated servers need to drain the action queue to remove references blocking the GC from cleaning up disposed objects.
                    if (Type == ServerType.Dedicated)
                    {
                        Game.PerformDelayedActions();
                    }

                    foreach (var t in serverTraits.WithInterface <ITick>())
                    {
                        t.Tick(this);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        if (UPnP.Status == UPnPStatus.Enabled)
                        {
                            UPnP.RemovePortForward().Wait();
                        }
                        break;
                    }
                }

                foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>())
                {
                    t.ServerShutdown(this);
                }

                PreConns.Clear();
                Conns.Clear();

                foreach (var listener in listeners)
                {
                    try { listener.Stop(); }
                    catch { }
                }
            })
            {
                IsBackground = true
            }.Start();
        }
Ejemplo n.º 16
0
        public Server(IPEndPoint endpoint, ServerSettings settings, ModData modData)
        {
            Log.AddChannel("server", "server.log");

            internalState = ServerState.WaitingPlayers;
            listener      = new TcpListener(endpoint);
            listener.Start();
            var localEndpoint = (IPEndPoint)listener.LocalEndpoint;

            Ip   = localEndpoint.Address;
            Port = localEndpoint.Port;

            Settings = settings;
            ModData  = modData;

            randomSeed = (int)DateTime.Now.ToBinary();

            if (Settings.AllowPortForward)
            {
                UPnP.ForwardPort(3600);
            }

            foreach (var trait in modData.Manifest.ServerTraits)
            {
                serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait));
            }

            LobbyInfo = new Session();
            LobbyInfo.GlobalSettings.RandomSeed = randomSeed;
            LobbyInfo.GlobalSettings.Map        = settings.Map;
            LobbyInfo.GlobalSettings.ServerName = settings.Name;
            LobbyInfo.GlobalSettings.Dedicated  = settings.Dedicated;
            FieldLoader.Load(LobbyInfo.GlobalSettings, modData.Manifest.LobbyDefaults);

            foreach (var t in serverTraits.WithInterface <INotifyServerStart>())
            {
                t.ServerStarted(this);
            }

            Log.Write("server", "Initial mod: {0}", ModData.Manifest.Mod.Id);
            Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map);

            new Thread(_ =>
            {
                var timeout = serverTraits.WithInterface <ITick>().Min(t => t.TickTimeout);
                for (;;)
                {
                    var checkRead = new List <Socket>();
                    if (State == ServerState.WaitingPlayers)
                    {
                        checkRead.Add(listener.Server);
                    }
                    foreach (var c in Conns)
                    {
                        checkRead.Add(c.Socket);
                    }
                    foreach (var c in PreConns)
                    {
                        checkRead.Add(c.Socket);
                    }

                    if (checkRead.Count > 0)
                    {
                        Socket.Select(checkRead, null, null, timeout);
                    }
                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        break;
                    }

                    foreach (var s in checkRead)
                    {
                        if (s == listener.Server)
                        {
                            AcceptConnection();
                        }
                        else if (PreConns.Count > 0)
                        {
                            var p = PreConns.SingleOrDefault(c => c.Socket == s);
                            if (p != null)
                            {
                                p.ReadData(this);
                            }
                        }
                        else if (Conns.Count > 0)
                        {
                            var conn = Conns.SingleOrDefault(c => c.Socket == s);
                            if (conn != null)
                            {
                                conn.ReadData(this);
                            }
                        }
                    }

                    foreach (var t in serverTraits.WithInterface <ITick>())
                    {
                        t.Tick(this);
                    }

                    if (State == ServerState.ShuttingDown)
                    {
                        EndGame();
                        if (Settings.AllowPortForward)
                        {
                            UPnP.RemovePortforward();
                        }
                        break;
                    }
                }

                foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>())
                {
                    t.ServerShutdown(this);
                }

                PreConns.Clear();
                Conns.Clear();
                try { listener.Stop(); }
                catch { }
            })
            {
                IsBackground = true
            }.Start();
        }
Ejemplo n.º 17
0
 public void NoService()
 {
     Assert.ThrowsException <Exception>(() => UPnP.ForwardPort(1, System.Net.Sockets.ProtocolType.Tcp, ""));
     Assert.ThrowsException <Exception>(() => UPnP.DeleteForwardingRule(1, System.Net.Sockets.ProtocolType.Tcp));
     Assert.ThrowsException <Exception>(() => UPnP.GetExternalIP());
 }