Friday, September 20, 2024 4:36:59 AM
> settings

Customize


Authenticate

> checks.rb
# frozen_string_literal: true

module ESM
  module Command
    class Base
      module Checks
        def check_failed!(error_name = nil, **args, &)
          raise_error!(error_name, **args.merge(path_prefix: "command_errors"), &)
        end

        def check_for_text_only!
          check_failed!(:text_only, user: current_user.mention) if text_only? && !text_channel?
        end

        def check_for_dm_only!
          # DM commands are allowed in player mode
          return if current_community&.player_mode_enabled?

          check_failed!(:dm_only, user: current_user.mention) if dm_only? && !dm_channel?
        end

        def check_for_owner!
          server = target_community.discord_server
          guild_member = current_user.on(server)

          check_failed!(:no_permissions, user: current_user.mention) if guild_member.nil?
          return if guild_member.owner?

          check_failed!(:no_permissions, user: current_user.mention)
        end

        def check_for_permissions!
          if !command_enabled?
            # If the community doesn't want to send a message, don't send a message.
            # This only applies to text channels. The user needs to know why the bot is not replying to their message
            if current_channel.text? && !notify_when_command_disabled?
              check_failed!(exception_class: ESM::Exception::CheckFailureNoMessage)
            else
              check_failed!(
                :command_not_enabled,
                user: current_user.mention,
                command_name: usage
              )
            end
          end

          if !command_allowed?
            check_failed!(:not_allowlisted, user: current_user.mention, command_name: usage)
          end

          if !command_allowed_in_channel?
            check_failed!(
              :not_allowed_in_text_channels,
              user: current_user.mention,
              command_name: usage
            )
          end
        end

        def check_for_registered!
          return if !registration_required? || current_user.registered?

          check_failed!(:not_registered, user: current_user.mention, full_username: current_user.distinct)
        end

        def check_for_cooldown!
          return unless on_cooldown?

          if current_cooldown.cooldown_type == "times"
            check_failed!(
              :on_cooldown_useage,
              user: current_user.mention,
              command_name: usage
            )

            return
          end

          check_failed!(
            :on_cooldown_time_left,
            user: current_user.mention,
            time_left: current_cooldown.to_s,
            command_name: usage
          )
        end

        def check_for_dev_only!
          # Empty on purpose
          raise ESM::Exception::CheckFailure, "" if dev_only? && !current_user.developer?
        end

        def check_for_connected_server!
          return unless argument?(:server_id)

          # Return if the server is not connected
          return if target_server.connected?

          check_failed!(:server_not_connected, user: current_user.mention, server_id: arguments.server_id)
        end

        def check_for_nil_target_server!
          return unless argument?(:server_id)
          return if !target_server.nil?

          check_failed! do
            provided_server_id = arguments.server_id

            ESM::Embed.build do |e|
              e.description =
                if provided_server_id.blank?
                  I18n.t("command_errors.invalid_server_id_blank", user: current_user.mention)
                else
                  # Attempt to correct them
                  corrections = ESM::Server.correct_id(provided_server_id)

                  if corrections.blank?
                    I18n.t(
                      "command_errors.invalid_server_id",
                      user: current_user.mention,
                      provided_server_id: provided_server_id
                    )
                  else
                    corrections = corrections.map_join(", ") { |correction| "`#{correction}`" }

                    I18n.t(
                      "command_errors.invalid_server_id_with_correction",
                      user: current_user.mention,
                      provided_server_id: provided_server_id,
                      correction: corrections
                    )
                  end
                end

              e.color = :red
            end
          end
        end

        def check_for_nil_target_community!
          return unless argument?(:community_id)
          return if !target_community.nil?

          check_failed! do
            provided_community_id = arguments.community_id

            # Attempt to correct them
            corrections = ESM::Community.correct(provided_community_id)

            ESM::Embed.build do |e|
              e.description =
                if corrections.blank?
                  I18n.t(
                    "command_errors.invalid_community_id",
                    user: current_user.mention,
                    provided_community_id: provided_community_id
                  )
                else
                  corrections = corrections.map_join(", ") { |correction| "`#{correction}`" }

                  I18n.t(
                    "command_errors.invalid_community_id_with_correction",
                    user: current_user.mention,
                    provided_community_id: provided_community_id,
                    correction: corrections
                  )
                end

              e.color = :red
            end
          end
        end

        def check_for_nil_target_user!
          return unless argument?(:target)
          return if !target_user.nil?

          check_failed!(:target_user_nil, user: current_user.mention)
        end

        # Order matters!
        def check_for_player_mode!
          # This only affects text channels
          return unless current_channel.text?

          # This only affects player_mode
          return unless current_community.player_mode_enabled?

          # Allow commands with DM only
          return if dm_only?

          # Admin/Different - Disallow
          # Admin/Same - Allow
          # Player/Different - Allow
          # Player/Same - Allow
          # I don't use `unless` often, but in this case, it simplifies the logic.
          return unless type == :admin && target_community && (current_community.id != target_community.id)

          check_failed!(
            :player_mode_command_not_available,
            user: current_user.mention,
            command_name: usage
          )
        end

        def check_for_different_community!
          # Only affects text channels
          return if !current_channel.text?

          # Only affects if player mode is disabled
          return if current_community.player_mode_enabled?

          # This doesn't affect commands with no target_community
          return if target_community.nil?

          # Allow if the command is being ran for the same community
          return if current_community.id == target_community.id

          # Allow if current_community is ESM, for debugging and support
          return if ESM.env.production? && current_community.guild_id == ESM::Community::ESM::ID

          check_failed!(:different_community_in_text, user: current_user.mention)
        end

        # Used by calling in a command that uses the request system.
        # This will raise ESM::Exception::CheckFailure if there is a pending request for the target_user
        def check_for_pending_request!
          return if request.nil?

          if target_user.nil? || current_user == target_user
            check_failed!(:pending_request_same_user, user: current_user.mention)
          else
            check_failed!(:pending_request_different_user, user: current_user.mention, target_user: target_user.mention)
          end
        end

        # Raises CheckFailure if the target_server does not belong to the current_community
        def check_for_owned_server!
          return if target_server.nil?
          return if target_server.community_id == current_community.id

          check_failed!(:owned_server, user: current_user.mention, community_id: current_community.community_id)
        end

        # Checks if the target_user is registered
        # This will always raise if the target_user is an instance of User::Ephemeral. (They aren't registered)
        #
        # @raise ESM::Exception::CheckFailure
        def check_for_registered_target_user!
          return if target_user.nil? || target_user.registered?

          check_failed!(:target_not_registered, user: current_user.mention, target_user: target_user.mention)
        end
      end
    end
  end
end
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8