Ejemplo n.º 1
0
        /// <summary>
        /// Attempts to log in to the server.
        /// Must be authenticated.
        /// </summary>
        /// <param name="displayName">Display name to log in with</param>
        /// <param name="useServerDisplayName">Use the server's copy of the user's display name if it has one</param>
        /// <param name="acceptingTrades">Whether to accept trades from other users</param>
        public void SendLogin(string displayName, bool useServerDisplayName = false, bool acceptingTrades = true)
        {
            if (!authenticator.Authenticated)
            {
                return;
            }

            // Create and pack a new LoginPacket
            LoginPacket packet = new LoginPacket
            {
                SessionId            = authenticator.SessionId,
                DisplayName          = displayName,
                UseServerDisplayName = useServerDisplayName,
                AcceptingTrades      = acceptingTrades
            };
            Any packedPacket = ProtobufPacketHelper.Pack(packet);

            RaiseLogEntry(new LogEventArgs("Sending LoginPacket", LogLevel.DEBUG));

            // Send it on its way
            netClient.Send(MODULE_NAME, packedPacket.ToByteArray());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles incoming <see cref="LoginPacket"/>s, attempting to log in users.
        /// </summary>
        /// <param name="connectionId">Original connection ID</param>
        /// <param name="packet">Incoming packet</param>
        /// <exception cref="UserNoLongerExistsException">User no longer exists for some reason even though we just checked like a second ago</exception>
        private void handleLoginPacket(string connectionId, LoginPacket packet)
        {
            // Make sure the client is authenticated
            if (!authenticator.IsAuthenticated(connectionId, packet.SessionId))
            {
                RaiseLogEntry(new LogEventArgs(string.Format("Failed login attempt for session {0}: Invalid session", packet.SessionId)));

                // Fail the login attempt due to an invalid session
                sendFailedLoginResponsePacket(connectionId, LoginFailureReason.SessionId, "Session is not valid, it may have expired. Try reconnecting.");

                // Stop here
                return;
            }

            // Try get the username from their session
            if (!authenticator.TryGetUsername(connectionId, packet.SessionId, out string username))
            {
                RaiseLogEntry(new LogEventArgs(string.Format("Failed login attempt for session {0}: Couldn't get username", packet.SessionId)));

                // Fail the login attempt due to an invalid session/username
                sendFailedLoginResponsePacket(connectionId, LoginFailureReason.InternalServerError, "Server failed to get the username associated with the session. Try reconnecting.");

                // Stop here
                return;
            }

            // Passed authentication checks, time to accept the login attempt

            // Try to get the user by their username
            if (TryGetUserUuid(username, out string uuid))
            {
                // Try to log them in
                if (!TryLogIn(uuid))
                {
                    // This shouldn't happen because we just got their UUID but ok.
                    throw new UserNoLongerExistsException(uuid);
                }
            }
            else
            {
                // Otherwise create a new user
                uuid = CreateUser(username, packet.DisplayName, true);
            }

            // Check if they want to use the display name stored on the server
            string displayName = packet.DisplayName;

            if (packet.UseServerDisplayName)
            {
                // Try to get the display name stored server-side
                if (!TryGetDisplayName(uuid, out displayName))
                {
                    // This should never happen because we just made sure that the user existed no more than 30 lines ago, but just in case...
                    throw new UserNoLongerExistsException(uuid);
                }
            }
            else
            {
                // Check the length of their username without markup
                if (TextHelper.StripRichText(packet.DisplayName).Length > maxDisplayNameLength)
                {
                    // Fail the login attempt due to display name length
                    sendFailedLoginResponsePacket(connectionId, LoginFailureReason.DisplayName, "Display name is too long.");

                    // Stop here
                    return;
                }

                // Update the user's display name on the server with the one they've provided
                UpdateUser(uuid, TextHelper.SanitiseRichText(packet.DisplayName));
            }

            // Set whether they are accepting trades
            UpdateUser(uuid, acceptingTrades: packet.AcceptingTrades);

            // Add their UUID/Session ID pair to connectedUsers
            lock (connectedUsersLock)
            {
                // Remove an existing session, if it exists
                connectedUsers.Remove(connectionId);

                // Add this session with the freshly-logged in UUID
                connectedUsers.Add(connectionId, uuid);
            }

            // Log the event
            RaiseLogEntry(new LogEventArgs(string.Format("User {0} successfully logged in as \"{1}\" (SessionID: {2}, UUID: {3})", username, displayName, packet.SessionId, uuid)));

            // Send a successful login response
            sendSuccessfulLoginResponsePacket(connectionId, uuid, displayName);

            // Send a sync packet with the current user list
            sendSyncPacket(connectionId);

            // Raise the OnLogin event
            OnLogin?.Invoke(this, new ServerLoginEventArgs(connectionId, uuid));
        }