/// <summary> /// Initializes a new instance of the IntroductionPacket class. /// </summary> /// <param name="inventoryPacket">The inventory packet which is part of the initialization.</param> /// <param name="orientationPacket">The orientation packet which is part of the initialization.</param> /// <param name="otherPlayersOrientation">The orientation packets representing the orientation of other players.</param> public IntroductionPacket(InventoryPacket inventoryPacket, OrientationPacket orientationPacket, params OrientationPacket[] otherPlayersOrientation) : base() { this.InventoryPacket = inventoryPacket; this.OrientationPacket = orientationPacket; this.OtherPlayersOrientation = new ReadOnlyCollection<OrientationPacket>(otherPlayersOrientation); }
/// <summary> /// Initializes a new instance of the IntroductionPacket class. /// </summary> /// <param name="inventoryPacket">The inventory packet which is part of the initialization.</param> /// <param name="orientationPacket">The orientation packet which is part of the initialization.</param> /// <param name="otherPlayers">The players to generate orientation packets from. Will automatically exclude an element if it's Username property is equal to that of orientationPacket.</param> public IntroductionPacket(InventoryPacket inventoryPacket, OrientationPacket orientationPacket, params Player[] otherPlayers) : base() { this.InventoryPacket = inventoryPacket; this.OrientationPacket = orientationPacket; Collection<OrientationPacket> otherOrientations = new Collection<OrientationPacket>(); for (int i = 0; i < otherPlayers.Length; i++) { if (otherPlayers[i].UserName != orientationPacket.UserName) { otherOrientations.Add(new OrientationPacket(otherPlayers[i])); } } this.OtherPlayersOrientation = new ReadOnlyCollection<OrientationPacket>(otherOrientations); }
/// <summary> /// Logs into a player account. If the player is already signed in, this simply returns true. /// </summary> /// <param name="userName">The user name of the client player.</param> /// <param name="password">The password of the client player.</param> /// <returns>Whether the login was successful.</returns> public bool ClientLogOn(string userName, string password) { lock (this) { bool loadedData = this.Load(userName); // Only try to login if the player hasn't already if (!this.LoggedIn) { // If a player data file was not successfully loaded, destroy the connection if (!loadedData) { PacketSender.Send(AuthenticationResultPacket.FailedInvalidUserName, this); this.Dispose(); return false; } // Get the MD5 of the player's password string passwordHash = SimpleCryptography.MD5(password); // If X minutes have passed, reset the attempted login count if ((DateTime.UtcNow.Ticks - this.LastLogOnAttempt) > PlayerHandler.LoginWaitTime) { this.AttemptedLogOnCount = 0; } // Set last login attempt time to now this.LastLogOnAttempt = DateTime.UtcNow.Ticks; this.LastLogOnAttemptIP = NetworkUtilities.GetRemoteIP(this.Connection.Connection.Client); // If there's not been too many wrong logins in a row and player is not banned if (this.AttemptedLogOnCount < PlayerHandler.MaxAttemptsIp && this.UserLevel != UserPermissionLevel.Disabled) { // If the password supplied by the login is equal to the password stored in the database, continue if (passwordHash.ToUpperInvariant() == this.PasswordHash.ToUpperInvariant()) { // Set the player logged in to true, player is now logged in! this.LoggedIn = true; // Reset the attempted logins since player is now authenticated if ((DateTime.UtcNow.Ticks - this.LastLogOnAttempt) > PlayerHandler.LoginWaitTime) { this.AttemptedLogOnCount = 0; } // Set the login success time and IP this.LastLogOnSuccess = DateTime.UtcNow.Ticks; this.LastLogOnSuccessIP = NetworkUtilities.GetRemoteIP(this.Connection.Connection.Client); // Tell the client his or her login was successful and tell other users he or she logged in PacketSender.Send(AuthenticationResultPacket.Success, this); InventoryPacket inv = new InventoryPacket(this.Inventory); OrientationPacket ori = new OrientationPacket(this); PacketSender.Send(new IntroductionPacket(inv, ori, this.server.Clients.ToArray()), this); PacketSender.SendToAll(new PlayerLoggedPacket(this, true)); } else { // Wrong password, increment login attempts and send message informing the // player that an incorrect password has been supplied, then terminate the connection this.AttemptedLogOnCount++; PacketSender.Send(AuthenticationResultPacket.FailedInvalidPassword, this); this.Dispose(); return false; } } else { // Too many wrong logins or player banned... increment attempted logins this.AttemptedLogOnCount++; if (this.AttemptedLogOnCount >= PlayerHandler.MaxAttemptsAll) { // If the player attempted to login far too many times set their user level // to banned (if it wasn't already), send message telling player that their // account has been disabled, and destroy the connection this.UserLevel = UserPermissionLevel.Disabled; this.DisableReason = DisableReason.ExcessLogins; PacketSender.Send(AuthenticationResultPacket.FailedAccountDisabled, this); this.Dispose(); return false; } else if (this.UserLevel == UserPermissionLevel.Disabled) { // The player is banned - deny 'em PacketSender.Send(AuthenticationResultPacket.FailedAccountDisabled, this); this.Dispose(); return false; } else if (this.AttemptedLogOnCount >= PlayerHandler.MaxAttemptsIp) { // Otherwise, if they only attempted to login a few too many times, // tell them that they have tried to login too many times and will // have to wait a while before trying again PacketSender.Send(AuthenticationResultPacket.FailedTooManyIncorrectLogins, this); this.Dispose(); return false; } } } else { // Tell the client he's already logged in PacketSender.Send(AuthenticationResultPacket.AlreadyLoggedIn, this); } return this.LoggedIn; } }