예제 #1
0
        /// <summary>
        /// Looks at all the attached content servers and determines which one has the lowest population, i.e. the one the player should play on.
        /// Returns null if no suitable servers are found (i.e. all available servers are at capacity).
        /// </summary>
        /// <returns></returns>
        public GameServerInfo <OutboundServerConnection> GetLowPopGameServer()
        {
            GameServerInfo <OutboundServerConnection> gsi = null;
            // Grab the game server with the least number of players

            GameServerInfoGroup g = OutboundServerGroups.Groups["Default"];

            if (g == null)
            {
                return(null);
            }

            List <string> addresses;
            List <string> ids;
            List <int>    ports;
            List <int>    curConnections;
            List <int>    maxConnections;

            if (!DB.Instance.Server_GetRegistrations("content", out addresses, out ids, out ports, out curConnections, out maxConnections))
            {
                gsi = g.NextConnection();
            }
            else
            {
                int   low      = 0;
                float lowRatio = 1f;
                for (int i = 0; i < ids.Count; i++)
                {
                    float ratio = (float)curConnections[i] / (float)maxConnections[i];
                    if (ratio < lowRatio)
                    {
                        lowRatio = ratio;
                        low      = i;
                    }
                }

                if (lowRatio >= 1)
                {
                    // All servers are at capacity
                    return(null);
                }

                // See if we're connected to that server
                //gsi = GetOutboundServerByServerUserID(ids[low]);

                //if (gsi == null || !gsi.IsOnline)
                {
                    // Create a temp object with latest info from DB
                    gsi          = new GameServerInfo <OutboundServerConnection>();
                    gsi.Name     = ids[low];
                    gsi.UserID   = ids[low];
                    gsi.IP       = addresses[low];
                    gsi.Port     = ports[low];
                    gsi.CurUsers = curConnections[low];
                    gsi.MaxUsers = maxConnections[low];
                }
            }

            return(gsi);
        }
예제 #2
0
        /// <summary>
        /// Gets called when a player requests to be handed off to a particular Hive.  This Base implementation simply returns the "Next" server
        /// in the indicated server group's connection list, using the group's ConnectMethod to determine the algorithm by which the "Next"
        /// connection is chosen (I.e. random or roundrobin).  This implementation only considers currently connected servers as candidates.
        /// </summary>
        /// <param name="serverGroup"></param>
        /// <returns></returns>
        protected virtual GameServerInfo <OutboundServerConnection> GetTargetServerForClusterHandoff(string serverGroup)
        {
            GameServerInfoGroup g = MyServer.OutboundServerGroups[serverGroup];

            if (g == null)
            {
                return(null);
            }
            return(g.NextConnection());;
        }
예제 #3
0
        public override void StartServer()
        {
            base.StartServer();
            // FORMAT: serverNAME|state|desc
            string[]            services = WispServices.GetInstalledServices();
            GameServerInfoGroup gr       = new GameServerInfoGroup();

            OutboundServerUpdateInterval = 10;
            gr.ID = "Default";
            OutboundServerGroups.Groups.Clear();
            OutboundServerGroups.Groups.Add(gr.ID, gr);

            for (int i = 0; i < services.Length; i++)
            {
                string[] parts = services[i].Split(char.Parse("|"));
                if (parts.Length < 3)
                {
                    continue;
                }

                string name = parts[0];
                if (name.ToLower() == "zeus")
                {
                    continue; // don't connect to self
                }

                string state = parts[1];
                string desc  = parts[2];

                object val = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\" + name, "ImagePath", "");
                if (val == null)
                {
                    Log1.Logger("Server").Error("Wisp registry claims that service [" + name + "] is installed, but the Windows registry does not agree.");
                    continue;
                }

                string exePath   = val.ToString();
                string directory = Path.GetDirectoryName(exePath);
                if (!Directory.Exists(directory))
                {
                    Log1.Logger("Server").Error("Windows registry claims that Wisp service [" + name + "] is installed at [" + directory + "] but that directory was not found.");
                    continue;
                }

                string targetConfig = exePath + ".config";
                if (!File.Exists(targetConfig))
                {
                    Log1.Logger("Server").Error("Unable to locate config file [" + targetConfig + "] for service [" + name + "] and so the connection port can't be determnined.");
                    continue;
                }

                int port = 0;
                try
                {
                    string configContents = File.ReadAllText(targetConfig);
                    int    loc            = configContents.IndexOf("ListenOnPort");
                    if (loc < 0)
                    {
                        Log1.Logger("Server").Error("Failed to find 'ListenOnPort' directive in config file [" + targetConfig + "] for service [" + name + "]. Unable to determine port for that service.");
                        continue;
                    }

                    int    valLoc    = configContents.IndexOf("\"", loc + 13);
                    int    valEndLoc = configContents.IndexOf("\"", valLoc + 1);
                    string sport     = configContents.Substring(valLoc + 1, valEndLoc - valLoc - 1);
                    if (!int.TryParse(sport, out port) || port <= 0)
                    {
                        Log1.Logger("Server").Error("'ListenOnPort' directive in config file [" + targetConfig + "] for service [" + name + "] was in the wrong format - [" + sport + "]. Unable to determine port for that service.");
                        continue;
                    }
                }
                catch (Exception e)
                {
                    Log1.Logger("Server").Error("Failed to read config file [" + targetConfig + "] for service [" + name + "]. Unable to determine port for that service.", e);
                    continue;
                }

                GameServerInfo <OutboundServerConnection> gsi = new GameServerInfo <OutboundServerConnection>();
                gsi.HostName = "localhost";
                gsi.Name     = name;
                string ip = "localhost";
                try
                {
                    gsi.ServiceID = 7;
                    IPHostEntry iphe = Dns.GetHostEntry("localhost"); // this call will delay the server from starting if it doesn't resolve fast enough.

                    bool gotOne = false;
                    foreach (IPAddress addy in iphe.AddressList)
                    {
                        if (addy.AddressFamily == AddressFamily.InterNetwork)
                        {
                            gotOne = true;
                            ip     = addy.ToString();
                            break;
                        }
                    }

                    if (!gotOne)
                    {
                        Log1.Logger("Server.Network").Error("Could not resolve IP address for server " + gsi.Name + " (" + ip + ")");
                        continue;
                    }
                }
                catch (Exception e)
                {
                    Log1.Logger("Server.Network").Error("Error setting up outbound server connection. " + gsi.Name + " / " + gsi.HostName + " : " + e.Message, e);
                    // try the next address in the config
                    continue;
                }

                if (ip.Trim().Length < 1)
                {
                    // try the next address in the config
                    continue;
                }

                gsi.IP         = ip;
                gsi.Port       = port;
                gsi.IsOnline   = false;
                gsi.LastUpdate = DateTime.UtcNow;


                if (gr.OutboundServers.Exists(con => con.UniqueID == gsi.UniqueID))
                {
                    continue;
                }

                gr.OutboundServers.Add(gsi);
            }
            StartOutboundServerUpdate();
        }