protected override GameServerInfo<OutboundServerConnection> GetServerInfo(string serverName)
        {
            GameServerInfo<OutboundServerConnection> gsi = null;

            string serverType = "";
            string address = "";
            int port = -1;
            int curConnections = -1;
            int maxConnections = -1;

            // Grab all registered content servers.
            if (DB.Instance.Server_GetRegistrations(serverName, out serverType, out address, out port, out  curConnections, out maxConnections))
            {
                gsi = new GameServerInfo<OutboundServerConnection>();
                gsi.Name = serverName;
                gsi.IP = address;
                gsi.Port = port;
                gsi.CurUsers = curConnections;
                gsi.MaxUsers = maxConnections;

                if (gsi.CurUsers >= gsi.MaxUsers)
                {
                    return null;
                }
            }

            return gsi;
        }
        protected override GameServerInfo <OutboundServerConnection> GetTargetServerForClusterHandoff(string serverGroup)
        {
            GameServerInfo <OutboundServerConnection> gsi = null;

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

            // Grab all registered content servers.
            if (DB.Instance.Server_GetRegistrations("", "chat", out addresses, out ids, out ports, out curConnections, out maxConnections))
            {
                // find the lowest population server
                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);
                }

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

            return(gsi);
        }
Exemple #3
0
        /// <summary>
        /// Queries the hive to see which lobby (central) server we can bounce the player to.
        /// Returns false if all lobby servers claim to be at capacity.  At that point, just D/C the player.
        /// </summary>
        /// <param name="address"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public static bool GetCentralHandoffAddress(ref string address, ref int port, ref string targetId)
        {
            GameServerInfo <OutboundServerConnection> gsi = null;
            // Grab the game server with the least number of players

            List <string> addresses;
            List <string> ids;
            List <int>    ports;
            List <int>    curConnections;
            List <int>    maxConnections;
            int           low = -1;

            if (!DB.Instance.Server_GetRegistrations("lobby", out addresses, out ids, out ports, out curConnections, out maxConnections))
            {
                // no lobby servers available
                return(false);
            }
            else
            {
                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(false);
                }
            }

            address  = addresses[low];
            port     = ports[low];
            targetId = ids[low];
            return(true);
        }
        private void OnCreateNewGame(INetworkConnection con, Packet gmsg)
        {
            PacketGenericMessage    genMsg = gmsg as PacketGenericMessage;
            PacketMatchNotification note   = (PacketMatchNotification)CreatePacket((int)LobbyPacketType.MatchNotification, 0, false, false);

            note.Kind       = MatchNotificationType.MatchCreated;
            note.NeedsReply = false;

            if (!ValidateHasCurrentCharacter())
            {
                genMsg.ReplyPacket = note;
                note.ReplyMessage  = "You must select a character before you can create a new game.";
                note.ReplyCode     = ReplyType.Failure;
                return;
            }

            //
            // <h2 style="text-align: center"><span style="color: #993300;"><a href="http://www.survivalnotes.org/content/category/fire"><span style="color: #993300;">Latest Entries</span></a>           <a href="http://www.survivalnotes.org/content/category/fire?r_sortby=highest_rated&amp;r_orderby=desc"><span style="color: #993300;">Highest Rated Entries</span></a></span></h2>
            // <h2 style="text-align: center"><span style="color: #993300;"><a href="http://www.survivalnotes.org/content/category/fire"><span style="color: #993300;">Latest Entries</span></a>           &nbsp;&nbsp;&nbsp;&nbsp;             <a href="http://www.survivalnotes.org/content/category/fire?r_sortby=highest_rated&amp;r_orderby=desc"><span style="color: #993300;">Highest Rated Entries</span></a></span></h2>
            //

            Log1.Logger(MyServer.ServerUserID).Info(string.Format("Player {0} requesting create new game '{1}' ...", ServerUser.AccountName, genMsg.Parms.GetStringProperty((int)PropertyID.Name)));
            string msg = "";

            GameServerInfo <OutboundServerConnection> gsi = RequestCreateNewGameServer(out msg);

            genMsg.ReplyPacket = note;
            note.ReplyMessage  = msg;
            if (gsi == null)
            {
                // Failed. Either no servers online, or they are full.
                note.ReplyCode = ReplyType.Failure;
                return;
            }
            else
            {
                // Contact that server and request a game be created.

                note.ReplyCode = ReplyType.OK;
                ServerUser.TransferToServerUnassisted(gsi.IP, gsi.Port, Guid.Empty, gsi.Name, gsi.UserID);
            }
        }
Exemple #5
0
        /// <summary>
        /// Phase 2: Player requests to play on a specified game server.  This method forwards that request to the game server.
        /// </summary>
        private void OnClusterHandoffRequest(INetworkConnection con, Packet msg)
        {
            PacketRequestHandoffToServerCluster packetRequestHandoffToServer = msg as PacketRequestHandoffToServerCluster;

            if (!ServerUser.IsAuthenticated)
            {
                KillConnection(" [" + ServerUser.AccountName + "] requested server hand off to [" + packetRequestHandoffToServer.TargetServerName + "] without being authenticated.");
            }

            GameServerInfo <OutboundServerConnection> gsi = GetServerInfo(packetRequestHandoffToServer.TargetServerName);

            if (gsi == null) // cluster offline or at capacity?
            {
                PacketGameServerTransferResult p = (PacketGameServerTransferResult)CreatePacket((int)PacketType.PacketGameServerAccessGranted, 0, true, true);
                p.ReplyMessage = "Game service not currently available.";
                p.ReplyCode    = ReplyType.Failure;

                // send an updated listing of online servers
                string servers = "";
                foreach (GameServerInfoGroup gr in MyServer.OutboundServerGroups.Groups.Values)
                {
                    string serverInfo = gr.ID + "," + gr.HasLiveOutboundServerConnections;
                    servers += "|" + serverInfo;
                }

                servers = servers.Trim('|');
                p.Parms.SetProperty((int)PropertyID.ServerListing, servers);

                msg.ReplyPacket = p;
                return;
            }

            Log1.Logger("LoginServer.Inbound.Login").Info("Player " + ServerUser.AccountName + " is requesting handoff to game server " + gsi.Name);

            // request auth ticket from game server

            Log1.Logger("LoginServer.Inbound.Login").Debug("Requesting authenticated client *" + ServerUser.AccountName + "* (" + RemoteIP + ") to be handed off to server group " + packetRequestHandoffToServer.TargetServerName + ".");
            ServerUser.TransferToServerUnassisted(gsi.IP, gsi.Port, Guid.Empty, gsi.UserID, gsi.Name);
            //gsi.Connection.RequestPlayerHandoff(ServerUser.ID, ServerUser.AccountName, packetRequestHandoffToServer.TargetResource, ServerUser.Profile, null, "");
        }
        protected override PacketLoginResult CreateLoginResultPacket()
        {
            PacketLoginResult lr = (PacketLoginResult)CreatePacket((int)PacketType.LoginResult, 0, true, true);

            lr.ReplyCode = ReplyType.OK;

            GameServerInfo <OutboundServerConnection> cons = GetTargetServerForClusterHandoff("");
            bool haveAnyOnline = cons != null;

            if (cons != null)
            {
                lr.ReplyMessage = cons.Name + "," + "TRUE|";
            }

            if (!haveAnyOnline)
            {
                lr.ReplyMessage = "No servers available for service. Try again later.";
                lr.IsCritical   = true;
                lr.ReplyCode    = ReplyType.Failure;
            }

            Log1.Logger("LoginServer.Inbound.Login").Debug("Sending client " + ServerUser.AccountName + " game server info: " + lr.ReplyMessage);

            if (m_IsNewAcct)
            {
                ServerUser.Profile.Alias = m_Alias;
                ServerUser.Profile.Save(MyServer.RequireAuthentication);

                if (lr.ReplyCode != ReplyType.OK)
                {
                    lr.ReplyMessage += "\r\n(Account was created, however)";
                }
            }
            lr.Parms.SetProperty("Alias", ServerUser.Profile.Alias);
            lr.Parms.SetProperty("ProfilePic", ServerUser.Profile.AddedProperties.GetByteArrayProperty("ProfilePic"));
            return(lr);
        }
Exemple #7
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();
        }
        protected override GameServerInfo<OutboundServerConnection> GetTargetServerForClusterHandoff(string serverGroup)
        {
            GameServerInfo<OutboundServerConnection> gsi = null;

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

            // Grab all registered content servers.
            if (DB.Instance.Server_GetRegistrations("", "lobby", out addresses, out ids, out ports, out curConnections, out maxConnections))
            {
                // find the lowest population server
                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;
                }

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

            return gsi;
        }
Exemple #9
0
        /// <summary>
        /// Loads the outgoing server connections from the App.Config file.
        /// </summary>
        private void LoadOutgoingConnections()
        {
            ConnectionConfigSection section = null;
            try
            {
                section = (ConnectionConfigSection)ConfigurationManager.GetSection("OutgoingConnections");
            }
            catch (Exception e)
            {
                Log1.Logger("Server").Fatal("Error loading config file section 'OutgoingConnections'. " + e.Message);
                return;
            }
            if (ConfigHelper.GetStringConfig("DatabaseConnectivity", "TRUE").ToLower() != "false")
            {
                DB.Instance.AddServerGroupSessionConnection("Default", ConfigurationManager.ConnectionStrings["SessionDataConnectionString"].ConnectionString);
            }
            OutboundServerUpdateInterval = section == null? int.MaxValue : section.UpdateIntervalSecs;
            GameServerInfoGroup group = null;
            if(section != null)
            {
                foreach (GroupElement g in section.Groups)
                {
                    group = new GameServerInfoGroup();
                    group.SharedHiveKey = g.SharedHiveKey;
                    group.ID = g.ID;

                    // DB session, if exists
                    if (g.SessionDataConnectionString.Length > 0)
                    {
                        DB.Instance.AddServerGroupSessionConnection(group.ID, g.SessionDataConnectionString);
                    }
                    else
                    {
                        DB.Instance.AddServerGroupSessionConnection(group.ID, ConfigurationManager.ConnectionStrings["SessionDataConnectionString"].ConnectionString);
                    }

                    string cm = g.ConnectMode.ToLower();
                    switch (cm)
                    {
                        case "roundrobin":
                            group.ConnectMode = OutgoingServerConnectMethod.RoundRobin;
                            break;
                        case "random":
                            group.ConnectMode = OutgoingServerConnectMethod.Random;
                            break;
                        default:
                            group.ConnectMode = OutgoingServerConnectMethod.All;
                            break;
                    }

                    foreach (ConnectionElement con in g.ConnectionItems)
                    {
                        try
                        {
                            GameServerInfo<OutboundServerConnection> gsi = new GameServerInfo<OutboundServerConnection>();
                            gsi.HostName = con.Address;
                            gsi.Name = con.ConnectionName;
                            gsi.ServiceID = con.ServiceID;
                            if (con.SharedHiveKey.Length < 1)
                            {
                                gsi.SharedHiveKey = g.SharedHiveKey;
                            }
                            else
                            {
                                gsi.SharedHiveKey = con.SharedHiveKey;
                            }

                            string ip = con.Address;
                            try
                            {
                                IPHostEntry iphe = Dns.GetHostEntry(ip); // 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 = con.Port;
                            gsi.IsOnline = false;
                            gsi.LastUpdate = DateTime.UtcNow;

                            if (group.OutboundServers.Exists(xcon => xcon.UniqueID == gsi.UniqueID))
                            {
                                Log1.Logger("Server").Error("Not adding outbound server [" + gsi.Name + "] as it's destination endpoing [" + gsi.UniqueID + "] matches an existing connection.");
                                continue;
                            }

                            gsi.ServerGroup = group.ID;
                            group.OutboundServers.Add(gsi);
                        }
                        finally
                        {
                        }
                    }
                }

                if (group != null)
                {
                    if (group.ConnectMode == OutgoingServerConnectMethod.Random || group.ConnectMode == OutgoingServerConnectMethod.RoundRobin)
                    {
                        // these two connect methods always start with a random index in the list.  this helps a little in balancing the load across many instances of servers, in lieu of a proper load balancer.
                        group.CurConnectionIndex = m_Random.Next(0, group.OutboundServers.Count);
                    }

                    OutboundServerGroups.Groups.Remove(group.ID);
                    OutboundServerGroups.Groups.Add(group.ID, group);
                }
            }
        }
        protected override bool HaveServersForService()
        {
            GameServerInfo <OutboundServerConnection> cons = GetTargetServerForClusterHandoff("");

            return(cons != null);
        }
Exemple #11
0
    /// <summary>
    /// Once the login server has authenticated us, it will send us a list of server clusters that it knows about.
    /// After the player has chosen a server cluster to play on (or perhaps the client auto-chooses one), this method
    /// can be called to petition the login server for handoff to that cluster.  The login server, in turn, will 
    /// petition the target cluster for the handoff.  Once the login server receives the result of the request, it 
    /// forwards it on to the player. If the petition is successful, the client will then possess an auth ticket which 
    /// can be used to connect to the target sub-server in the requested cluster.
    /// </summary>
    /// <param name="whichCluster">the cluster to request</param>
    /// <param name="targetResource">a specific resource we're interested in on the target cluster, if any.  helps route us to the correct sub-server that handles that resource</param>
    /// <returns>true, if the petition was dispatched, false if the target cluster is offline</returns>
    public bool PetitionLoginServerForClusterHandoff(GameServerInfo gsi, Guid targetResource)
    {
        if (gsi.IsOnline)
        {
            m_LoginCon.RequestHandoffToServer(gsi, targetResource);
            return true;
        }

        return false;
    }
Exemple #12
0
        public override void StartServer()
        {
            base.StartServer();
            // FORMAT: serverNAME|state|desc
            string[] services = WispServices.GetInstalledServices();
            for (int i = 0; i < services.Length; i++)
            {
                string[] parts = services[i].Split(char.Parse("|"));
                if (parts.Length < 3)
                {
                    continue;
                }

                string name  = parts[0];
                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;                                // 7eus
                    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 (OutboundServers.ContainsKey(gsi.UniqueID))
                {
                    continue;
                }
                OutboundServers.Add(gsi.UniqueID, gsi);
            }
            StartOutboundServerUpdate();
        }