public bool TransferToServerUnassisted(string address, int port, Guid contentID, string targetServerID, string targetServerName) { Log1.Logger("Server").Debug("Unassisted server transfer for user[" + AccountName + "] to [" + address + ":" + port.ToString() + ", " + targetServerID + "]."); if (MyConnection != null && MyConnection.IsAlive) { RenewAuthorizationTicket(true, targetServerID); PacketGameServerTransferResult p = (PacketGameServerTransferResult)MyConnection.CreatePacket((int)PacketType.PacketGameServerAccessGranted, 0, true, true); p.AuthTicket = AuthTicket; p.ServerIP = address; p.ServerPort = port; p.IsAssistedTransfer = false; p.TargetResource = contentID; p.ServerName = targetServerName; p.ReplyCode = ReplyType.OK; p.ReplyMessage = ""; //this.TransferTarget = ""; this.TransferTarget = targetServerID; MyConnection.Send(p); // set expiration AuthorizationExpires = DateTime.UtcNow + TimeSpan.FromSeconds(15); m_HasBeenTransferred = true; return(true); } return(false); }
/// <summary> /// Fires when a child server replies with a heartbeat pong. Also updates the GSI object with things like current number of users /// </summary> protected virtual void OnServerPong(INetworkConnection con, Packet msg) { PacketServerUpdate pong = msg as PacketServerUpdate; IPEndPoint ipe = (IPEndPoint)((OutboundServerConnection)con).RemoteEndPoint; GameServerInfo <OutboundServerConnection> gi = Server.GetGSIByIPAndPort(ipe.Address.ToString(), ipe.Port); if (gi == null) { return; } //Log1.Logger("Server.Outbound.Network").Debug("Got server heartbeat from " + pong.UserID + "/" + pong.ServerName); gi.UserID = ServerUserID = pong.UserID; gi.Name = gi.Connection.Name = pong.ServerName; gi.CurUsers = pong.CurrentPlayers; gi.MaxUsers = pong.MaxPlayers; gi.LastUpdate = DateTime.UtcNow; gi.IsOnline = true; Server.UpdateOutboundServerAvailability(gi.ServerGroup); if (ServerUserID == null || ServerUserID.Length < 1) { Log1.Logger("Server.Outbound.Network").Error("Outbound server " + pong.ServerName + " did not indicate their username to us. Was one set in that server's App.Config?. Disconnecting from that server. We need that ID."); gi.Connection.KillConnection("ServerUserID not set on remote server."); } }
public void ReadPatchNotes() { StreamReader r = null; try { string directory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string file = Path.Combine(directory, "Patches", "PatchNotes.txt"); if (!File.Exists(file)) { Log1.Logger("Patcher").Error("Could not locate patch notes file [" + file + "]."); return; } r = new StreamReader(file); while (r.Peek() > -1) { string line = r.ReadToEnd(); PatchNotes = line; Log1.Logger("Patcher").Info("Read patch notes file:\r\n" + PatchNotes); } } catch { } finally { if (r != null) { r.Close(); r.Dispose(); } } }
private void OnUserAddServiceNoteRequest(INetworkConnection con, Packet r) { Log1.Logger("Zeus.Inbound.Client").Debug("Add service note request from " + ServerUser.AccountName + "."); PacketGenericMessage msg = r as PacketGenericMessage; Guid account = msg.Parms.GetGuidProperty(2); string note = msg.Parms.GetStringProperty(3); if (note.Trim().Length < 1) { r.ReplyPacket.ReplyMessage = "Can't add a blank message."; r.ReplyPacket.ReplyCode = ReplyType.Failure; return; } r.ReplyPacket = CreateStandardReply(r, ReplyType.OK, ""); r.ReplyPacket.Parms.SetProperty(1, MyServer.ServerUserID); r.ReplyPacket.Parms.SetProperty(2, account); if (!DB.Instance.User_CreateServiceLogEntry(account, "Service Note", ServerUser.AccountName, note, -1)) { r.ReplyPacket.ReplyCode = ReplyType.Failure; r.ReplyPacket.ReplyMessage = "Database error while trying to add note."; } }
public static bool RemoveConnection(Guid conId) { INetworkConnection con = null; if (!Clients.TryGetValue(conId, out con)) { return(false); } if (con == null) { return(false); } InboundConnection inb = con as InboundConnection; if (inb != null && inb.ServerUser != null) { inb.ServerUser.MyConnection = null; } Log1.Logger("Server.Login").Info("Untracking socket " + conId.ToString()); bool haveIt = false; if (Clients.ContainsKey(conId)) { haveIt = true; PerfMon.IncrementCustomCounter("Live Connections", -1); } Clients.Remove(conId); return(haveIt); }
private void OnLogRequest(INetworkConnection con, Packet r) { PacketGenericMessage msg = r as PacketGenericMessage; Log1.Logger("Zeus").Debug("Log request from " + ServerUser.AccountName); r.ReplyPacket = CreateStandardReply(r, ReplyType.OK, ""); r.ReplyPacket.IsCompressed = true; Hierarchy h = LogManager.GetRepository() as Hierarchy; LimitedMemoryLogAppender memoryAppender = h.Root.GetAppender("MemoryAppender") as LimitedMemoryLogAppender; string[] filters = msg.Parms.GetStringArrayProperty(2); LoggingEvent[] evts = memoryAppender.GetEvents(); List <string> logs = new List <string>(); for (int i = 0; i < evts.Length; i++) { for (int x = 0; x < filters.Length; x++) { if (evts[i].LoggerName == filters[x]) { logs.Add(string.Format("[{2}]\t =>{0}\t: {1}", evts[i].TimeStamp.ToUniversalTime().ToString("hh:mm:ss tt"), evts[i].RenderedMessage, evts[i].Level.Name)); } } } r.ReplyPacket.Parms.SetProperty(1, MyServer.ServerUserID); r.ReplyPacket.Parms.SetProperty(2, logs.ToArray()); }
private void OnUserSearch(INetworkConnection con, Packet r) { Log1.Logger("Zeus").Debug("User search request from " + ServerUser.AccountName + "."); PacketGenericMessage msg = r as PacketGenericMessage; string name = msg.Parms.GetStringProperty(2).Trim(); string email = msg.Parms.GetStringProperty(3).Trim(); Guid guid = msg.Parms.GetGuidProperty(4); int page = msg.Parms.GetIntProperty(5).GetValueOrDefault(0); int pageSize = msg.Parms.GetIntProperty(6).GetValueOrDefault(0); string ip = msg.Parms.GetStringProperty(7).Trim(); WispUsersInfo users = new WispUsersInfo(); users.AllowRemoteConnections = ZeusServer.AllowRemote; r.ReplyPacket = CreateStandardReply(r, ReplyType.OK, ""); r.ReplyPacket.Parms.SetProperty(1, MyServer.ServerUserID); r.ReplyPacket.Parms.SetProperty(2, users); r.ReplyPacket.Parms.SetProperty(3, name); r.ReplyPacket.Parms.SetProperty(4, email); r.ReplyPacket.Parms.SetProperty(5, guid); r.ReplyPacket.Parms.SetProperty(6, page); r.ReplyPacket.Parms.SetProperty(7, pageSize); r.ReplyPacket.Parms.SetProperty(8, ip); users.TotalUserCount = -1; if (MyServer.RequireAuthentication) { r.ReplyPacket.Parms.SetProperty(2, SearchDBUsers(name, email, guid, ip, page, pageSize)); } }
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.Save(MyServer.RequireAuthentication); if (lr.ReplyCode != ReplyType.OK) { lr.ReplyMessage += "\r\n(Account was created, however)"; } } return(lr); }
protected static void OnTimerElapsed(object state) { DateTime now = DateTime.UtcNow; lock (m_SyncRoot) { bool anyActiveCounters = false; Dictionary <string, PerfHistory> .Enumerator enu = History.GetEnumerator(); while (enu.MoveNext()) { PerfHistory h = enu.Current.Value; if (!h.IsEnabled) { continue; } anyActiveCounters = true; if (now - h.LastSample >= h.SampleInterval) { h.AddSample((float)Math.Round(h.Counter.NextValue() / h.Divisor, 2)); //Log1.Logger("Performance").Debug("Sampled performance counter [" + h.Category + "|" + h.CounterName + "|" + h.InstanceName + "] with a value of [" + h.History[h.History.Count - 1].Value + "]."); } } if (!anyActiveCounters) { Log1.Logger("Performance").Error("Unable to start sampling performance counters: No performance counters are currently active."); StopSamplingCounters(); } } StartSamplingCounters(); }
public string DeleteCharacterStat(string characterId, string propertyId, string executor) { string msg = ""; try { int propId = int.Parse(propertyId); int charId = int.Parse(characterId); if (!DB.Instance.Character_DeleteStat(charId, propId)) { msg = "DB Error deleting character [" + charId + "] stat ID [" + propId + "]."; Log1.Logger("Server.Commands").Info(msg); return(msg); } msg = "[" + executor + "] successfully deleted character [" + charId + "] stat ID [" + propId + "]."; } catch (Exception e) { msg = "Error occurred trying to delete Stat on character. " + e.Message; } return(msg); }
public string UpdateCharacterFloatProperty(string characterId, string propertyId, string newValue, string executor) { string msg = ""; try { int propId = int.Parse(propertyId); int charId = int.Parse(characterId); if (newValue == null || newValue.Length < 1) { msg = "Value must be formatted as a floating point number."; Log1.Logger("Server.Commands").Info(msg); return(msg); } float fval = float.Parse(newValue); if (!DB.Instance.Character_UpdateFloatProperty(charId, propId, "", fval)) { msg = "DB Error setting character [" + charId + "] property ID [" + propId + "] to [" + newValue + "]."; Log1.Logger("Server.Commands").Info(msg); return(msg); } msg = "[" + executor + "] successfully set character [" + charId + "] property ID [" + propId + "] to [" + newValue + "]."; } catch (Exception e) { msg = "Error occurred trying to update property on character. " + e.Message; } return(msg); }
public string InsertCharacterStringProperty(string characterId, string propertyId, string propertyName, string newValue, string executor) { string msg = ""; try { if (propertyName == null || propertyName.Length < 1) { msg = "Property name can't be blank."; return(msg); } int propId = int.Parse(propertyId); int charId = -1; if (characterId.Trim().Length > 0) { charId = int.Parse(characterId); } if (!DB.Instance.Character_UpdateStringProperty(charId, propId, propertyName, newValue)) { msg = "DB Error setting character [" + charId + "] property ID [" + propId + "] to [" + newValue + "]."; Log1.Logger("Server.Commands").Info(msg); return(msg); } msg = "[" + executor + "] successfully set character [" + charId + "] property ID [" + propId + "] to [" + newValue + "]."; } catch (Exception e) { msg = "Error occurred trying to set Property on character. " + e.Message; } return(msg); }
public void SetLoggedOut() { if (m_CurrentSessionID != CurrentSessionID || CurrentSessionID == Guid.Empty || m_CurrentLoginTime == DateTime.MinValue) { return; } lock (m_Lock) { if (LoginHistoryIP.Count != LoginHistoryTime.Count || LoginHistoryTime.Count != LogoffHistoryTime.Count) { Log1.Logger("Server").Error("Unable to set user's [" + Username + "] profile as logged out. Login History variables are not the same size."); return; } LoginHistoryIP.Enqueue(m_CurrentIP); LoginHistoryTime.Enqueue(m_CurrentLoginTime); LogoffHistoryTime.Enqueue(DateTime.UtcNow); TimeSpan thisSession = DateTime.UtcNow - m_CurrentLoginTime; m_TotalSessionTime += thisSession.Ticks; while (LoginHistoryIP.Count > MaxSessionsToStore) { LoginHistoryIP.Dequeue(); LoginHistoryTime.Dequeue(); LogoffHistoryTime.Dequeue(); } m_CurrentSessionID = Guid.Empty; m_CurrentLoginTime = DateTime.MinValue; } }
/// <summary> /// Enqueues a task to the I/O completion port task queue /// </summary> /// <param name="t"></param> public void AddTask(Task t) { // Hook up task complete callback via TaskContinuation mechanism. t.ContinueWith(parent => { OnTaskComplete(parent); }, TaskContinuationOptions.ExecuteSynchronously); // See if we have a task running already or if we can kick new task off immediately lock (m_TaskQueue) { if (m_TaskRunning) { #if DEBUG if (t.AsyncState != null) { Log1.Logger("|||PFX|||").Debug("Queueing PFX task: " + t.AsyncState.ToString()); } #endif // already have a task running. enqueue m_TaskQueue.Enqueue(t); } else { #if DEBUG if (t.AsyncState != null) { Log1.Logger("|||PFX|||").Debug("Immediately Starting PFX task: " + t.AsyncState.ToString()); } #endif m_TaskRunning = true; t.Start(); } } }
private INetworkConnection GetOwningServerConnection() { INetworkConnection con = null; if (ServerUser != null && ServerUser.OwningServer.Length > 0) { if (ServerUser.OwningServer == MyServer.ServerUserID) { // don't need to let ourselves know. return(con); } con = ConnectionManager.GetParentConnection(ServerUser.OwningServer); if (con == null) { GameServerInfo <OutboundServerConnection> ocon = MyServer.GetOutboundServerByServerUserID(ServerUser.OwningServer); if (ocon == null) { Log1.Logger("Server.Inbound.Network").Error("Player was transferred by " + ServerUser.OwningServer + ", but that server couldn't be found."); return(null); } con = ocon.Connection; } } return(con); }
/// <summary> /// Add a custom performance counter. Counter won't be installed until InstallCounters() is called. /// </summary> public static void TrackCustomCounter(string name, string helpText, PerformanceCounterType type, TimeSpan sampleInterval, int maxSamplesToCache, string divisor) { if (m_Sampling) { return; } CounterCreationData ccd = new CounterCreationData(); ccd.CounterName = name; ccd.CounterHelp = helpText; ccd.CounterType = type; PerfHistory h = GetHistory(name, "Wisp", ""); try { h.Divisor = float.Parse(divisor); } catch (FormatException exc) { Log1.Logger("Performance").Error("Custom Counter " + h.Key + " has an invalid [Divisor] - must be in float format!"); h.Divisor = 1; } h.SampleInterval = sampleInterval; h.HelpText = helpText; h.MaxHistorySamplesToKeep = maxSamplesToCache; h.IsCustom = true; _Counters.Add(ccd); Log1.Logger("Performance").Debug("Tracking custom performance counter [" + name + "|Wisp|" + "]"); }
/// <summary> /// Sends the target connection a listing and status of all game server clusters that this login server knows about. /// This is the listing that the client should allow the player too choose from in the UI. /// Returns false if currently no servers are available for service. /// </summary> /// <param name="con"></param> protected virtual PacketLoginResult CreateLoginResultPacket() { // send login result PacketLoginResult lr = (PacketLoginResult)CreatePacket((int)PacketType.LoginResult, 0, true, true); lr.ReplyCode = ReplyType.OK; bool haveAnyOnline = false; foreach (GameServerInfoGroup g in MyServer.OutboundServerGroups.Groups.Values) { if (!haveAnyOnline) { haveAnyOnline = g.HasLiveOutboundServerConnections; } string serverInfo = g.ID + "," + g.HasLiveOutboundServerConnections; lr.ReplyMessage += "|" + serverInfo; } lr.ReplyMessage = lr.ReplyMessage.Trim('|'); if (!haveAnyOnline) { lr.ReplyMessage = "No Wisp servers are currently online on this machine."; } Log1.Logger("Zeus.Inbound.Client.Login").Debug("Sending client " + ServerUser.AccountName + " Wisp server info: " + lr.ReplyMessage); return(lr); }
/// <summary> /// Removes a player from the active Players list /// </summary> /// <param name="character">the character to add</param> public virtual void RemovePlayer(ServerCharacterInfo character, string reason, bool playerInitiated) { //Task t = new Task((state) => { lock (m_Game.AllPlayersSyncRoot) { if (Players.Remove(character.ID)) { Log1.Logger("SERVER").Info("Removed player [#" + character.CharacterName + "] from game [" + Name + "] [" + GameID.ToString() + "]."); AllPlayers = (List <ICharacterInfo>)Players.Values.ToList <ICharacterInfo>(); if (CurrentGameState == GameState.Started && !Solved) { // player quit after we started the game, but before we finished the match AddToQuittersRoster(character); } OnPlayerRemoved(character, reason, playerInitiated); // What's the state of the game after player left? if (CurrentGameState == GameState.Lobby) { GameStartStrategy.NotifyPlayerLeftLobby(character.ID); } else if (CurrentGameState == GameState.Started) { GameAbortStrategy.NotifyPlayerLeftGame(character.ID); } } } } //, "Remove Player from game" + character.ToString(), TaskCreationOptions.LongRunning); //m_NetQ.AddTask(t); }
/// <summary> /// Removes all entries in the games to server mapping table. /// </summary> /// <param name="owningClusterServerId"></param> /// <returns></returns> public static bool Lobby_ClearGamesMap(this DB db) { bool result = true; SqlConnection con = DB.SessionDataConnection; SqlCommand cmd = DB.GetCommand(con, "Lobby_DeleteGamesServerMap", true); try { con.Open(); cmd.ExecuteNonQuery(); } catch (Exception e) { Log1.Logger("Server").Error("[DATABASE ERROR] : " + e.Message); result = false; } finally { if (con != null) { con.Close(); con.Dispose(); con = null; } } return(result); }
private static bool CanExecute(string[] RolesHave, string executor, CommandData c, string[] parms, ref string msg) { if (Array.IndexOf(RolesHave, "Administrator") < 0) { bool allowed = false; for (int i = 0; i < c.AllowedRoles.Length; i++) { if (Array.IndexOf(RolesHave, c.AllowedRoles[i]) > -1) { allowed = true; break; } } if (!allowed) { Log1.Logger("Server.Commands").Warn("[" + executor + "] attempted executing command [" + c.CommandName + "] without adequate permissions."); msg = "Not enough permissions for that command."; return(false); } } if (parms.Length == 0 || parms.Length - 1 != c.ParmNames.Length) { msg = "Not enough parameters. " + c.UsageHelp; return(false); } return(true); }
private void OnUserOverviewRequest(INetworkConnection con, Packet r) { Log1.Logger("Zeus").Debug("User overview request from " + ServerUser.AccountName + "."); PacketGenericMessage msg = r as PacketGenericMessage; int pageNum = msg.Parms.GetIntProperty(2).GetValueOrDefault(0); int pageSize = msg.Parms.GetIntProperty(3).GetValueOrDefault(50); if (!ServerUser.Profile.IsUserInRole("ActiveCustomerService")) { Log1.Logger("Server.Commands").Warn("[" + ServerUser.AccountName + "] has insufficient permissions to request user info."); r.ReplyPacket = CreateStandardReply(r, ReplyType.Failure, "Insufficient permissions. Only Administrators can request Zeus users."); return; } WispUsersInfo users = new WispUsersInfo(); users.AllowRemoteConnections = ZeusServer.AllowRemote; r.ReplyPacket = CreateStandardReply(r, ReplyType.OK, ""); r.ReplyPacket.Parms.SetProperty(1, MyServer.ServerUserID); r.ReplyPacket.Parms.SetProperty(2, users); users.TotalUserCount = -1; if (MyServer.RequireAuthentication) { int totalUsers = 0; Membership.GetAllUsers(0, 1, out totalUsers); users.TotalUserCount = totalUsers; users.UserDataStore = "Database"; } }
private static Assembly GetAssembly(string name) { if (name == null || name.Length < 1) { return(Assembly.GetCallingAssembly()); } // Get entry assembly - When running as windows service, weird directory voodoo happens with System32 directory string directory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); name = Path.Combine(directory, name); Assembly ass = null; if (LoadedAssemblies.TryGetValue(name, out ass)) { return(ass); } try { ass = Assembly.LoadFrom(name); if (ass != null) { LoadedAssemblies.Add(name, ass); } return(ass); } catch (Exception e) { Log1.Logger("Server.Commands").Error("Tried loading assembly [" + name + "] and failed. " + e.Message, e); return(null); } }
/// <summary> /// Adds the user's account to the authorized users list. This method should also disconnect any previous sockets that might be connected using the same account /// </summary> /// <param name="client"></param> /// <param name="persist">Determines if the ticket should be persisted in the datastore. Normally, you only need to do this when you are about to transfer control of the player to another server in the Hive.</param> /// <returns></returns> public static bool AuthorizeUser(ServerUser client, bool persist) { if (client == null) { return(false); } lock (m_AuthorizedAccountsSyncRoot) { if (client.MyConnection != null && client.MyConnection.IsAlive) { client.Profile.SetLoggedIn(client.MyConnection.RemoteEndPoint.AddressFamily.ToString(), client.MyConnection.RemoteEndPoint.ToString()); } ServerUser existing = null; if (AuthorizedAccounts.TryGetValue(client.AccountName.ToLower(), out existing)) { UnAuthorizeUser(existing); if (existing.MyConnection != null) { existing.MyConnection.KillConnection("Logging in from another client."); } } Log1.Logger("Server.Login").Debug("Authorizing *" + client.AccountName.ToLower() + "*"); AuthorizedAccounts.Add(client.AccountName.ToLower(), client); AuthorizedAccounts.Associate(client.ID, client.AccountName.ToLower()); client.RenewAuthorizationTicket(persist); } return(true); }
protected override void OnStart(string[] args) { Log1.Logger("Login").Info("Starting Login server"); Thread t = new Thread(new ThreadStart(StartAsync)); t.Start(); }
static void OnTimeoutTimerElapsed(object sender, ElapsedEventArgs e) { m_TimeoutTimer.Stop(); // characters about that have expired List <ServerCharacterInfo> expired = new List <ServerCharacterInfo>(); lock (m_CharacterMap) { Dictionary <int, CacheItem> .Enumerator enu = m_CharacterMap.GetEnumerator(); DateTime aboutTo = DateTime.UtcNow + TimeSpan.FromSeconds(30); DateTime now = DateTime.UtcNow; while (enu.MoveNext()) { if (enu.Current.Value.ExpirationTime < now) { expired.Add(enu.Current.Value.Character); } } // remove expired for (int i = 0; i < expired.Count; i++) { Log1.Logger("Server.Character").Debug("Character cache expired for character " + expired[i].CharacterInfo.CharacterName + " owned by " + expired[i].Owner.ToString()); m_CharacterMap.Remove(expired[i].CharacterInfo.ID); } } // notify host of pending expiration m_TimeoutTimer.Start(); }
/// <summary> /// Sends the target connection a listing and status of all game server clusters that this login server knows about. /// This is the listing that the client should allow the player too choose from in the UI. /// Returns false if currently no servers are available for service. /// </summary> /// <param name="con"></param> protected virtual PacketLoginResult CreateLoginResultPacket() { // send login result PacketLoginResult lr = (PacketLoginResult)CreatePacket((int)PacketType.LoginResult, 0, true, true); lr.ReplyCode = ReplyType.OK; bool haveAnyOnline = false; foreach (GameServerInfoGroup g in MyServer.OutboundServerGroups.Groups.Values) { if (!haveAnyOnline) { haveAnyOnline = g.HasLiveOutboundServerConnections; } GameServerInfo <OutboundServerConnection> svr = g.NextConnection(); string serverName = g.ID; string serverInfo = serverName + "," + g.HasLiveOutboundServerConnections; lr.ReplyMessage += "|" + serverInfo; } if (!haveAnyOnline) { lr.ReplyMessage = "No servers available for service."; lr.IsCritical = true; lr.ReplyCode = ReplyType.Failure; } Log1.Logger("LoginServer.Inbound.Login").Debug("Sending client " + ServerUser.AccountName + " game server info: " + lr.ReplyMessage); return(lr); }
/// <summary> /// The target child server requires that we log in with our shared secret (App.Config) before it will /// entertain any other requests from us. This method fires when the target server /// resolves the login request. /// </summary> protected override void OnServerLoginResponse(PacketLoginResult result) { base.OnServerLoginResponse(result); if (result.ReplyCode != ReplyType.OK) { Log1.Logger("Server").Error("Unable to login to target server [" + Name + "]. [" + result.ReplyMessage + "]."); return; } string ip = ""; ip = ((IPEndPoint)MyTCPSocket.RemoteEndPoint).Address.ToString(); int port = -1; port = ((IPEndPoint)MyTCPSocket.RemoteEndPoint).Port; string serverName = result.Parms.GetStringProperty("ServerName"); if (result.ReplyCode == ReplyType.OK) { ServerUserID = result.Parms.GetStringProperty((int)PropertyID.Name); } Server.UpdateGSIIP(ReportedIP, port, ip, serverName); PacketNull ping = CreatePacket((int)PacketType.Null, 0, false, false) as PacketNull; ping.NeedsReply = true; Send(ping); }
/// <summary> /// Removes a match from the list of games that a particular server is tracking - GamesPerServerMap /// </summary> /// <param name="serverName">the server to remove this game from</param> /// <param name="id">the id of the game to remove</param> /// <param name="lockData">if the match data should be thread-synchronized. set yes, if you know this method is called first in the stack (i.e. when you're calling it as a response to an inbound packet). Using the wrong will value will decrease performance as unnecessary thread Monitors will be set</param> public void RemoveGameFromServerTracking(Guid id, bool lockData) { if (lockData) { Monitor.Enter(MatchDataLock); } try { DB.Instance.Lobby_UntrackGameForServer(id); GameServerGame sg = null; if (Games.TryGetValue(id, out sg)) { if (Games.Remove(id)) { Log1.Logger("Server").Info("Removed game [" + id.ToString() + "] from server. Now tracking [" + Games.Count.ToString() + " games] on this server."); } m_TotalProjectedPlayerCount -= sg.MaxObservers + sg.MaxPlayers; Log1.Logger("Server").Debug("Padded connection count for server is now [" + m_TotalProjectedPlayerCount + "]."); } } catch { } finally { if (lockData) { Monitor.Exit(MatchDataLock); } } }
static void Main(string[] args) { if (args.Length != 0 && args[0].ToLower().Trim() == "/i") { Log1.Logger("Server").Info("Installing server. Please wait..."); WispServices.InstallService(Application.ExecutablePath, "WISPLogin", "Wisp Login Server"); } else if (args.Length != 0 && args[0].ToLower().Trim() == "/u") { Log1.Logger("Server").Info("Uninstalling server. Please wait..."); WispServices.UninstallService("WISPLogin"); } else if (args.Length == 0) { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new LoginServerProc() }; Log1.Logger("Server").Info("Starting server. Please wait..."); ServiceBase.Run(ServicesToRun); } else { // you will have to manually kill the process either through the // debugger or the task manager LoginServerProc service = new LoginServerProc(); service.Setup(); System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite); } }
/// <summary> /// Saves all currently loaded objects that are dirty to the database /// </summary> public void RunSaveCycle(string serverID) { if (m_StopSaving || 1 == Interlocked.Exchange(ref m_UpdatingSaveQueue, 1)) { // Failed to get the lock. Process is already/still running. return; } Interlocked.Exchange(ref m_SaveCycleScheduled, 0); DateTime start = DateTime.UtcNow; ICollection <IGameObject> items = AllObjects; string msg = ""; int processed = DB.Instance.Item_BatchUpdate((List <IGameObject>)items, out msg, this); DateTime fin = DateTime.UtcNow; TimeSpan len = fin - start; Log1.Logger("Server").Info("Game object save cycle wrote [" + processed.ToString() + " objects in " + len.ToString() + "]"); Log1.Logger("Server").Info("Server is now tracking [" + ObjectCount.ToString() + " game objects]."); StartSaveCycle(serverID, len.TotalMilliseconds > ConfigHelper.GetIntConfig("ItemSaveCycleTimerMs", 30000)); // Release the lock Interlocked.Exchange(ref m_UpdatingSaveQueue, 0); }