/// <summary>
    /// Start a new server.
    /// </summary>

    bool StartLocal(int tcpPort, int udpPort, string fileName, int lobbyPort, Type type)
    {
        // Ensure that everything has been stopped first
        if (mGame.isActive)
        {
            Disconnect();
        }

        // If there is a lobby port, we should set up the lobby server and/or link first.
        // Doing so will let us inform the lobby that we are starting a new server.

        if (lobbyPort > 0)
        {
            if (type == Type.Tcp)
            {
                mLobby = new TcpLobbyServer();
            }
            else
            {
                mLobby = new UdpLobbyServer();
            }

            // Start a local lobby server
            if (mLobby.Start(lobbyPort))
            {
                if (type == Type.Tcp)
                {
                    mUp.OpenTCP(lobbyPort);
                }
                else
                {
                    mUp.OpenUDP(lobbyPort);
                }
            }
            else
            {
                mLobby = null;
                return(false);
            }

            // Create the local lobby link
            mGame.lobbyLink = new LobbyServerLink(mLobby);
        }

        // Start the game server
        if (mGame.Start(tcpPort, udpPort))
        {
            mUp.OpenTCP(tcpPort);
            mUp.OpenUDP(udpPort);
            if (!string.IsNullOrEmpty(fileName))
            {
                mGame.LoadFrom(fileName);
            }
            return(true);
        }

        // Something went wrong -- stop everything
        Disconnect();
        return(false);
    }
Exemple #2
0
    /// <summary>
    /// Start the server.
    /// </summary>

    public void Start(string serverName, int tcpPort, int udpPort, string lobbyAddress, int lobbyPort, bool useTcp, bool service, string fn = "server.dat")
    {
        mFilename = fn;
        List <IPAddress> ips  = Tools.localAddresses;
        string           text = "\nLocal IPs: " + ips.size;

        for (int i = 0; i < ips.size; ++i)
        {
            text += "\n  " + (i + 1) + ": " + ips[i];
            if (ips[i] == TNet.Tools.localAddress)
            {
                text += " (Primary)";
            }
        }

        Console.WriteLine(text + "\n");
        {
            // You don't have to Start() and WaitForThreads(). TNet will do it for you when you try to open a port via UPnP.
            // It is good practice to have UPnP resolved before trying to use it though. This way there is no delay when
            // you try to open a port.
            mUPnP = new UPnP();
            mUPnP.Start();
            mUPnP.WaitForThreads();

            Tools.Print("External IP: " + Tools.externalAddress);

            if (tcpPort > 0)
            {
                mGameServer      = new GameServer();
                mGameServer.name = serverName;

                if (!string.IsNullOrEmpty(lobbyAddress))
                {
                    // Remote lobby address specified, so the lobby link should point to a remote location
                    IPEndPoint ip = Tools.ResolveEndPoint(lobbyAddress, lobbyPort);
                    if (useTcp)
                    {
                        mGameServer.lobbyLink = new TcpLobbyServerLink(ip);
                    }
                    else
                    {
                        mGameServer.lobbyLink = new UdpLobbyServerLink(ip);
                    }
                }
                else if (lobbyPort > 0)
                {
                    // Server lobby port should match the lobby port on the client
                    if (useTcp)
                    {
                        mLobbyServer = new TcpLobbyServer();
                        mLobbyServer.Start(lobbyPort);
                        if (mUPnP.status != UPnP.Status.Failure)
                        {
                            mUPnP.OpenTCP(lobbyPort, OnPortOpened);
                        }
                    }
                    else
                    {
                        mLobbyServer = new UdpLobbyServer();
                        mLobbyServer.Start(lobbyPort);
                        if (mUPnP.status != UPnP.Status.Failure)
                        {
                            mUPnP.OpenUDP(lobbyPort, OnPortOpened);
                        }
                    }

                    // Local lobby server
                    mGameServer.lobbyLink = new LobbyServerLink(mLobbyServer);
                }

                // Start the actual game server and load the save file
                mGameServer.Start(tcpPort, udpPort);
                mGameServer.Load(mFilename);
                Tools.Print("Loaded " + mFilename);
            }
            else if (lobbyPort > 0)
            {
                if (useTcp)
                {
                    if (mUPnP.status != UPnP.Status.Failure)
                    {
                        mUPnP.OpenTCP(lobbyPort, OnPortOpened);
                    }
                    mLobbyServer = new TcpLobbyServer();
                    mLobbyServer.Start(lobbyPort);
                }
                else
                {
                    if (mUPnP.status != UPnP.Status.Failure)
                    {
                        mUPnP.OpenUDP(lobbyPort, OnPortOpened);
                    }
                    mLobbyServer = new UdpLobbyServer();
                    mLobbyServer.Start(lobbyPort);
                }
            }

            // Open up ports on the router / gateway
            if (mUPnP.status != UPnP.Status.Failure)
            {
                if (tcpPort > 0)
                {
                    mUPnP.OpenTCP(tcpPort, OnPortOpened);
                }
                if (udpPort > 0)
                {
                    mUPnP.OpenUDP(udpPort, OnPortOpened);
                }
                mUPnP.WaitForThreads();
            }

            // This approach doesn't work on Windows 7 and higher.
            AppDomain.CurrentDomain.ProcessExit += new EventHandler(delegate(object sender, EventArgs e) { Dispose(); });

            // This approach works only on Windows
            try { SetConsoleCtrlHandler(new HandlerRoutine(OnExit), true); }
            catch (Exception) { }

            for (; ;)
            {
                if (!service)
                {
                    Tools.Print("Press 'q' followed by ENTER when you want to quit.\n");
                    string command = Console.ReadLine();
                    if (command == "q")
                    {
                        break;
                    }
                    else if (command == "c")
                    {
                        TNet.Buffer.ReleaseUnusedMemory();
                    }
                }
                else
                {
                    Thread.Sleep(10000);
                }
            }
            Tools.Print("Shutting down...");
            Dispose();
        }

        if (!service)
        {
            Tools.Print("The server has shut down. Press ENTER to terminate the application.");
            Console.ReadLine();
        }
    }