diff --git a/HorseIsleServer/HorseIsleServer/Player/User.cs b/HorseIsleServer/HorseIsleServer/Player/User.cs index b31ef61..da18491 100644 --- a/HorseIsleServer/HorseIsleServer/Player/User.cs +++ b/HorseIsleServer/HorseIsleServer/Player/User.cs @@ -86,6 +86,7 @@ namespace HISP.Player public bool MuteAll = false; public bool MuteLogins = false; public string Gender; + public bool UserInfoSend = false; public bool MajorPriority = false; public bool MinorPriority = false; public bool HorseWindowOpen = false; diff --git a/HorseIsleServer/HorseIsleServer/Server/GameClient.cs b/HorseIsleServer/HorseIsleServer/Server/GameClient.cs index 2d076fe..76e7fd0 100644 --- a/HorseIsleServer/HorseIsleServer/Server/GameClient.cs +++ b/HorseIsleServer/HorseIsleServer/Server/GameClient.cs @@ -110,16 +110,37 @@ namespace HISP.Server if (this.isDisconnecting) return; this.isDisconnecting = true; + + // Close Socket + if (ClientSocket != null) + { + ClientSocket.Close(); + ClientSocket.Dispose(); + ClientSocket = null; + } + // Stop Timers if (timeoutTimer != null) + { timeoutTimer.Dispose(); + timeoutTimer = null; + } if (keepAliveTimer != null) + { keepAliveTimer.Dispose(); + keepAliveTimer = null; + } if (warnTimer != null) + { warnTimer.Dispose(); + warnTimer = null; + } if (kickTimer != null) + { kickTimer.Dispose(); + kickTimer = null; + } // Call OnDisconnect @@ -127,13 +148,6 @@ namespace HISP.Server GameServer.OnDisconnect(this); LoggedIn = false; - // Close Socket - if(ClientSocket != null) - { - ClientSocket.Close(); - ClientSocket.Dispose(); - } - } @@ -373,15 +387,6 @@ namespace HISP.Server public void Login(int id) { - // Check for duplicate - foreach (GameClient Client in GameClient.ConnectedClients) - { - if (Client.LoggedIn) - { - if (Client.LoggedinUser.Id == id) - Client.Kick(Messages.KickReasonDuplicateLogin); - } - } LoggedinUser = new User(this, id); LoggedIn = true; @@ -400,22 +405,51 @@ namespace HISP.Server } byte identifier = Packet[0]; - if (timeoutTimer != null) - timeoutTimer.Change(timeoutInterval, timeoutInterval); // Reset time before timing out - - if (keepAliveTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) + /* + * Every time ive tried to fix this properly by just checking if its null or something + * it keeps happening, so now im just going to catch the exception + * and hope it works. + */ + try { - if (LoggedIn) - LoggedinUser.Idle = false; - keepAliveTimer.Change(oneMinute, oneMinute); + if (timeoutTimer != null) + timeoutTimer.Change(timeoutInterval, timeoutInterval); // Reset time before timing out + else + return; + + if (keepAliveTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) + { + if (LoggedIn) + LoggedinUser.Idle = false; + keepAliveTimer.Change(oneMinute, oneMinute); + } + else + { + return; + } + + if (kickTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) + kickTimer.Change(kickInterval, kickInterval); + else + return; + + if (warnTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) + warnTimer.Change(warnInterval, warnInterval); + else + return; + + } + catch (ObjectDisposedException) + { + return; } - if (kickTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) - kickTimer.Change(kickInterval, kickInterval); - - if (warnTimer != null && identifier != PacketBuilder.PACKET_KEEP_ALIVE) - warnTimer.Change(warnInterval, warnInterval); + /* + * Put packet handling in a try/catch + * this prevents the entire server from crashing + * if theres an error in handling a particular packet. + */ try { if (!LoggedIn) // Must be either login or policy-file-request diff --git a/HorseIsleServer/HorseIsleServer/Server/GameServer.cs b/HorseIsleServer/HorseIsleServer/Server/GameServer.cs index 091714b..be93ba2 100644 --- a/HorseIsleServer/HorseIsleServer/Server/GameServer.cs +++ b/HorseIsleServer/HorseIsleServer/Server/GameServer.cs @@ -3671,38 +3671,53 @@ namespace HISP.Server Logger.ErrorPrint(sender.RemoteIp + " Requested user information when not logged in."); return; } + + // Prevent duplicate requests. + if (sender.LoggedinUser.UserInfoSend) + return; + + sender.LoggedinUser.UserInfoSend = true; + + // This allows the website to view that the player is online. Database.AddOnlineUser(sender.LoggedinUser.Id, sender.LoggedinUser.Administrator, sender.LoggedinUser.Moderator, sender.LoggedinUser.Subscribed, sender.LoggedinUser.NewPlayer); Logger.DebugPrint(sender.LoggedinUser.Username + " Requested user information."); - User user = sender.LoggedinUser; + // Send player current location & map data byte[] MovementPacket = PacketBuilder.CreateMovementPacket(user.X, user.Y, user.CharacterId, user.Facing, PacketBuilder.DIRECTION_TELEPORT, true); sender.SendPacket(MovementPacket); + // Send "Welcome to the Secret Land of Horses" message. byte[] WelcomeMessage = PacketBuilder.CreateWelcomeMessage(user.Username); sender.SendPacket(WelcomeMessage); - + // Send weather effects, and current server time. byte[] WorldData = PacketBuilder.CreateWorldData(World.ServerTime.Minutes, World.ServerTime.Days, World.ServerTime.Years, sender.LoggedinUser.GetWeatherSeen()); sender.SendPacket(WorldData); - // Send first time message; + // if the player is logging in for the first time, send Welcome newest rider of Horse Isle message. if (sender.LoggedinUser.NewPlayer) { byte[] NewUserMessage = PacketBuilder.CreateChat(Messages.NewUserMessage, PacketBuilder.CHAT_BOTTOM_RIGHT); sender.SendPacket(NewUserMessage); } - + // Send Security Codes, used (badly) to verify Minigame Rewards byte[] SecCodePacket = PacketBuilder.CreateSecCode(user.SecCodeSeeds, user.SecCodeInc, user.Administrator, user.Moderator); sender.SendPacket(SecCodePacket); + // Send player money count, total players and total unread mail. byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(user.Money, GameServer.GetNumberOfPlayers(), user.MailBox.UnreadMailCount); sender.SendPacket(BaseStatsPacketData); + // Sends Meta Window information (Nearby, current tile, etc) UpdateArea(sender); + /* + * Send all nearby players locations to the client + * if there not nearby, say there at 1000,1000. + */ foreach (GameClient client in GameClient.ConnectedClients) { if (client.LoggedIn) @@ -3723,18 +3738,29 @@ namespace HISP.Server } } + /* + * Update all nearby users + * that the new player logged in. + */ foreach (User nearbyUser in GameServer.GetNearbyUsers(sender.LoggedinUser.X, sender.LoggedinUser.Y, false, false)) if (nearbyUser.Id != sender.LoggedinUser.Id) if(!nearbyUser.MajorPriority) if(!nearbyUser.MinorPriority) UpdateArea(nearbyUser.LoggedinClient); + /* + * Send a list of isles, towns and areas to the player + * This is used for the world map. + */ + byte[] IsleData = PacketBuilder.CreatePlaceData(World.Isles.ToArray(), World.Towns.ToArray(), World.Areas.ToArray()); sender.SendPacket(IsleData); + // Tells the client which tiles are passable, which the player should appear ontop of and which it should be below. byte[] TileFlags = PacketBuilder.CreateTileOverlayFlags(Map.OverlayTileDepth); sender.SendPacket(TileFlags); + // Send Todays Note: byte[] MotdData = PacketBuilder.CreateMotd(); sender.SendPacket(MotdData); @@ -3743,7 +3769,11 @@ namespace HISP.Server if (RiddleEvent.Active) RiddleEvent.ShowStartMessage(sender); - // Give Queued Itmes + /* + * Gives Queued Items + * When you buy a PO from the store on the website + * its added to this queued items list. + */ DoItemPurchases(sender); // Send Queued Messages @@ -3755,7 +3785,7 @@ namespace HISP.Server } Database.ClearMessageQueue(sender.LoggedinUser.Id); - // Send login message + // Send "Playername Logged in" message byte[] loginMessageBytes = PacketBuilder.CreateChat(Messages.FormatLoginMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT); foreach (GameClient client in GameClient.ConnectedClients) if (client.LoggedIn) @@ -3764,8 +3794,10 @@ namespace HISP.Server client.SendPacket(loginMessageBytes); - // Tell other clients you exist - + /* + * Send players nearby to you + * your position, otherwise just send 1000,1000 + */ byte[] yourPlayerInfo = PacketBuilder.CreatePlayerInfoUpdateOrCreate(sender.LoggedinUser.X, sender.LoggedinUser.Y, sender.LoggedinUser.Facing, sender.LoggedinUser.CharacterId, sender.LoggedinUser.Username); byte[] yourPlayerInfoOffscreen = PacketBuilder.CreatePlayerInfoUpdateOrCreate(1000 + 4, 1000 + 1, sender.LoggedinUser.Facing, sender.LoggedinUser.CharacterId, sender.LoggedinUser.Username); @@ -5886,6 +5918,7 @@ namespace HISP.Server byte chatSide = Chat.GetSide(channel); message = Chat.DoCorrections(message); message = Chat.EscapeMessage(message); + // Encode bbcode message. if(ConfigReader.AllowBbcode || (sender.LoggedinUser.Moderator || sender.LoggedinUser.Administrator)) message = BBCode.EncodeBBCodeToMeta(message); @@ -7352,13 +7385,12 @@ namespace HISP.Server } + sender.Login(userId); + sender.LoggedinUser.Password = password; byte[] ResponsePacket = PacketBuilder.CreateLoginPacket(true); sender.SendPacket(ResponsePacket); - sender.Login(userId); - sender.LoggedinUser.Password = password; - Logger.DebugPrint(sender.RemoteIp + " Logged into : " + sender.LoggedinUser.Username + " (ADMIN: " + sender.LoggedinUser.Administrator + " MOD: " + sender.LoggedinUser.Moderator + ")"); }