瀏覽代碼

add pkmn-member command

Kylie Jo Swistak 6 年之前
父節點
當前提交
d946adfca0
共有 8 個文件被更改,包括 537 次插入57 次删除
  1. 17 1
      app/controllers/image_controller.rb
  2. 4 0
      app/models/carousels.rb
  3. 28 0
      app/models/char_carousel.rb
  4. 1 1
      app/models/regex.rb
  5. 14 0
      app/responses/carousel.rb
  6. 161 49
      app/responses/character.rb
  7. 297 4
      bot.rb
  8. 15 2
      lib/emoji.rb

+ 17 - 1
app/controllers/image_controller.rb

@@ -2,7 +2,7 @@ class ImageController
   def self.default_image(content, char_id)
     img_url =
       /\*\*URL to the Character\'s Appearance\*\*\:\s(.*)/.match(content)
-    img = CharImage.where(char_id: char_id),find_by(keyword: 'Default')
+    img = CharImage.where(char_id: char_id).find_by(keyword: 'Default')
 
     case
     when img_url && img
@@ -36,4 +36,20 @@ class ImageController
 
     img
   end
+
+  def self.img_scroll(char_id: , nsfw: false, img: nil, dir: nil)
+    imgs = nsfw ? CharImage.where(char_id: char_id) :
+      CharImage.where(char_id: char_id, category: 'SFW' )
+
+    cur_i = img ? imgs.index { |i| i[:id] == img } : imgs.length - 1
+
+    case dir
+    when :left
+      nex_i = cur_i == 0 ? imgs.length - 1 : cur_i - 1
+    else
+      nex_i = cur_i == imgs.length - 1 ? 0 : cur_i + 1
+    end
+
+    imgs[nex_i]
+  end
 end

+ 4 - 0
app/models/carousels.rb

@@ -0,0 +1,4 @@
+class Carousel < ActiveRecord::Base
+  validates :message_id, presence: true
+  validates :char_id, presence: true
+end

+ 28 - 0
app/models/char_carousel.rb

@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+require_relative '../../lib/emoji.rb'
+
+module CharCarousel
+  BIO = "Bio"
+  STATUS = "Status"
+  TYPE = "Type"
+  RUMORS = "Rumors"
+  IMAGE = "Images"
+  BAGS = "Inventory"
+  FAMILY = "Family Tree"
+  ALL = "All"
+  DEFAULT = "This Key"
+  CROSS = "Delete Message"
+
+  REACTIONS = {
+    Emoji::NOTEBOOK => BIO,
+    Emoji::QUESTION => STATUS,
+    Emoji::PALLET => TYPE,
+    Emoji::EAR => RUMORS,
+    Emoji::PICTURE => IMAGE,
+    Emoji::BAGS => BAGS,
+    Emoji::FAMILY => FAMILY,
+    Emoji::EYES => ALL,
+    Emoji::KEY => DEFAULT,
+    Emoji::CROSS => CROSS
+  }
+end

+ 1 - 1
app/models/regex.rb

@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module Regex
-  UID = /<@([0-9]+)>/
+  UID = /<@\!?([0-9]+)>/
   EDIT_URL = /Edit\sKey\s\(ignore\):\s([\s\S]*)/
   CHAR_APP = /\_New\sCharacter\sApplication\_:\s(.*)/
 end

+ 14 - 0
app/responses/carousel.rb

@@ -0,0 +1,14 @@
+require_relative '../../lib/emoji.rb'
+
+def section_react(message)
+  Emoji::CAROUSEL.each do |emote|
+    message.react(emote)
+  end
+end
+
+def arrow_react(message)
+  message.react(Emoji::UNDO)
+  message.react(Emoji::LEFT)
+  message.react(Emoji::RIGHT)
+  message.react(Emoji::CROSS)
+end

+ 161 - 49
app/responses/character.rb

@@ -1,75 +1,187 @@
-def character_embed(character, image, user, color)
+def character_embed(char:, img: nil, user:, color:, section: :all)
   fields = []
-  footer_text = "#{user.name}##{user.tag} | #{character.active}"
-  footer_text += " | #{character.rating}" if character.rating
+  footer_text = "#{user.name}##{user.tag} | #{char.active}"
+  footer_text += " | #{char.rating}" if char.rating
+  footer_text += " | #{img.category} " if section == :image
 
+  navigate = "React to Navigate"
+  footer_text += " | #{navigate}"
+
+  embed = Embed.new(
+    footer: {
+      icon_url: user.avatar_url,
+      text: footer_text
+    },
+    title: char.name,
+    color: color,
+  )
+
+  case section
+  when :all
+    embed.description = char.personality if char.personality
+    fields = char_type(char, fields)
+    fields = char_status(char, fields)
+    fields = char_bio(char, fields)
+    fields = char_rumors(char, fields)
+  when :default
+    embed.description = navigate
+    fields = char_sections(fields)
+  when :bio
+    embed.description = char.personality if char.personality
+    fields = char_bio(char, fields)
+  when :type
+    fields = char_type(char, fields)
+  when :status
+    fields = char_status(char, fields)
+  when :rumors
+    fields = char_rumors(char, fields)
+  when :image
+    if img
+      embed.title =
+        "#{char.name} | #{img.keyword}" unless img.keyword == 'Default'
+      embed.image = { url: img.url }
+    else
+      embed.description = "No character images found!"
+    end
+  end
+
+
+  embed.thumbnail = { url: img.url } if img && section != :image
+  embed.fields = fields
+
+  embed
+end
+
+def char_bio(char, fields)
   fields.push(
-    { name: 'Species', value: character.species, inline: true }
-  )if character.species
-  fields.push(
-    { name: 'Type', value: character.types, inline: true }
-  )if character.types
-  fields.push(
-    { name: 'Age', value: character.age, inline: true }
-  )if character.age
+    { name: 'Hometown', value: char.hometown, inline: true }
+  )if char.hometown
   fields.push(
-    { name: 'Weight', value: character.weight, inline: true }
-  )if character.weight
+    { name: 'Location', value: char.location, inline: true }
+  )if char.location
   fields.push(
-    { name: 'Height', value: character.height, inline: true }
-  )if character.height
+    { name: 'Likes', value: char.likes }
+  )if char.likes
   fields.push(
-    { name: 'Gender', value: character.gender, inline: true }
-  )if character.gender
+    { name: 'Dislikes', value: char.dislikes }
+  )if char.dislikes
   fields.push(
-    { name: 'Sexual Orientation', value: character.orientation, inline: true }
-  )if character.orientation
+    { name: 'Backstory', value: char.backstory }
+  )if char.backstory
   fields.push(
-    { name: 'Relationship Status', value: character.relationship, inline: true }
-  )if character.relationship
+    { name: 'Other', value: char.other }
+  )if char.other
   fields.push(
-    { name: 'Hometown', value: character.hometown, inline: true }
-  )if character.hometown
+    { name: 'DM Notes', value: char.dm_notes }
+  )if char.dm_notes
+
+  fields
+end
+
+def char_type(char, fields)
   fields.push(
-    { name: 'Location', value: character.location, inline: true }
-  )if character.location
+    { name: 'Species', value: char.species, inline: true }
+  )if char.species
   fields.push(
-    { name: 'Attacks', value: character.attacks }
-  )if character.attacks
+    { name: 'Type', value: char.types, inline: true }
+  )if char.types
+
+  if char.attacks
+    attacks = char.attacks
+    attacks = attacks.gsub(/\s?\|\s?/, "\n")
+
+    fields.push({ name: 'Attacks', value: attacks })
+  end
+
+  fields
+end
+
+def char_rumors(char, fields)
   fields.push(
-    { name: 'Likes', value: character.likes }
-  )if character.likes
+    { name: 'Warnings', value: char.warnings }
+  )if char.warnings
+
+  if char.rumors
+    rumors = char.rumors.split(/\s?\|\s?/)
+    rumors = rumors.shuffle
+    rumors = rumors.join("\n")
+
+    fields.push({ name: 'Rumors', value: rumors })
+  end
+
+  fields
+end
+
+def char_status(char, fields)
   fields.push(
-    { name: 'Dislikes', value: character.dislikes }
-  )if character.dislikes
+    { name: 'Age', value: char.age, inline: true }
+  )if char.age
   fields.push(
-    { name: 'Warnings', value: character.warnings }
-  )if character.warnings
+    { name: 'Gender', value: char.gender, inline: true }
+  )if char.gender
   fields.push(
-    { name: 'Rumors', value: character.rumors }
-  )if character.rumors
+    { name: 'Weight', value: char.weight, inline: true }
+  )if char.weight
   fields.push(
-    { name: 'Backstory', value: character.backstory }
-  )if character.backstory
+    { name: 'Height', value: char.height, inline: true }
+  )if char.height
   fields.push(
-    { name: 'Other', value: character.other }
-  )if character.other
+    { name: 'Sexual Orientation', value: char.orientation, inline: true }
+  )if char.orientation
   fields.push(
-    { name: 'DM Notes', value: character.dm_notes }
-  )if character.dm_notes
+    { name: 'Relationship Status', value: char.relationship, inline: true }
+  )if char.relationship
+
+  fields
+end
+
+def char_sections(fields)
+  CharCarousel::REACTIONS.map do |emoji, message|
+    fields.push({
+      name: emoji,
+      value: message,
+      inline: true
+    })
+  end
+
+  fields
+end
+
+def char_list_embed(chars, user = nil)
+  fields = []
+  active = []
+  npcs = []
+
+  chars.each do |char|
+    case char.active
+    when 'Active'
+      active.push char.name
+    when 'NPC'
+      npcs.push char.name
+    end
+  end
+
+  fields.push({
+    name: 'Active Characters',
+    value: active.join(", ")
+  })if active.length > 0
+
+  fields.push({
+    name: 'NPCs',
+    value: npcs.join(", ")
+  })if npcs.length > 0
 
   embed = Embed.new(
-    footer: {
-      icon_url: user.avatar_url,
-      text: footer_text
-    },
-    title: character.name,
-    color: color,
+    title: 'Registered Characters',
     fields: fields
   )
 
-  embed.description = character.personality if character.personality
-  embed.thumbnail = { url: image } if image
+  if user
+    user_name = user.nickname || user.name
+
+    embed.color = user.color.combined
+    embed.title = "#{user_name}'s Characters"
+  end
 
   embed
 end

+ 297 - 4
bot.rb

@@ -250,6 +250,117 @@ rescue ActiveRecord::RecordNotFound
   )
 end
 
+opts = {
+  "" => "List all guild members",
+  "@user" => "List all characters belonging to the user",
+  "name " => "Display the given character",
+  "name | section" => "Display the given section for the character",
+  "name | image | keword" => "Display the given image"
+}
+desc = "Display info about the guild members"
+member = Command.new(:member, desc, opts) do |event, name, section, keyword|
+  sections = [:all, :default, :bio, :type, :status, :rumors, :image]
+
+  case name
+  when Regex::UID
+    user_id = Regex::UID.match(name)
+  when String
+    char = Character.find_by!(name: name)
+
+    img = CharImage.where(char_id: char.id).find_by(keyword: 'Default')
+    user = event.server.member(char.user_id)
+    color = CharacterController.type_color(char)
+  end
+
+  case
+  when !name
+    chars = Character.all
+    char_list_embed(chars)
+  when name && user_id
+    chars = Character.where(user_id: user_id[1])
+    user = event.server.member(user_id[1])
+
+    char_list_embed(chars, user)
+  when name && char && !section
+    embed = character_embed(
+      char: char,
+      img: img,
+      section: :default,
+      user: user,
+      color: color
+    )
+
+    msg = event.send_embed("", embed)
+    Carousel.create(message_id: msg.id, char_id: char.id)
+
+    section_react(msg)
+  when char && section && keyword
+    embed = command_error_embed(
+      "Invalid Arguments",
+      member
+    )unless /image/i.match(section)
+
+    unless embed
+      img = CharImage.where(char_id: char.id).find_by!(keyword: keyword)
+
+      embed = error_embed(
+        "Wrong Channel!",
+        "The requested image is NSFW"
+      )if img.category == 'NSFW' && !event.channel.nsfw?
+    end
+
+    unless embed
+      embed = character_embed(
+        char: char,
+        img: img,
+        section: :image,
+        user: user,
+        color: color
+      )
+
+      msg = event.send_embed("", embed)
+      Carousel.create(message_id: msg.id, char_id: char.id, image_id: img.id)
+
+      arrow_react(msg)
+    end
+
+    embed
+  when name && char && section
+    sect = section.downcase.to_sym
+    nsfw = event.channel.nsfw?
+
+    img = ImageController.img_scroll(
+      char_id: char.id,
+      nsfw: nsfw
+    )if section == :image
+
+    if sections.detect{ |s| s == sect }
+      embed = character_embed(
+        char: char,
+        img: img,
+        section: sect,
+        user: user,
+        color: color,
+      )
+
+      msg = event.send_embed("", embed)
+      Carousel.create(message_id: msg.id, char_id: char.id, image_id: img.id)
+
+      if sect == :image
+        arrow_react(msg)
+      else
+        section_react(msg)
+      end
+    else
+      error_embed("Invalid Section!")
+    end
+  end
+
+
+rescue ActiveRecord::RecordNotFound => e
+  error_embed("Record Not Found!", e.message)
+end
+
 # ---
 
 commands = [
@@ -258,7 +369,8 @@ commands = [
   app,
   help,
   poll,
-  raffle
+  raffle,
+  member
 ]
 
 # This will trigger on every message sent in discord
@@ -325,6 +437,8 @@ bot.reaction_add do |event|
       :pm
     when event.message.from_bot? && content.match(/\_New\sCharacter\sImage\_:/)
       :image_application
+    when carousel = Carousel.find_by(message_id: event.message.id)
+      :carousel
     end
 
   vote =
@@ -334,9 +448,19 @@ bot.reaction_add do |event|
     when reactions[Emoji::CHECK]&.count.to_i > 1 then :check
     when reactions[Emoji::CROSS]&.count.to_i > 1 then :cross
     when reactions[Emoji::CRAYON]&.count.to_i > 1 then :crayon
+    when reactions[Emoji::NOTEBOOK]&.count.to_i > 1 then :notebook
+    when reactions[Emoji::QUESTION]&.count.to_i > 1 then :question
+    when reactions[Emoji::PALLET]&.count.to_i > 1 then :pallet
+    when reactions[Emoji::EAR]&.count.to_i > 1 then :ear
+    when reactions[Emoji::PICTURE]&.count.to_i > 1 then :picture
+    when reactions[Emoji::BAGS]&.count.to_i > 1 then :bags
+    when reactions[Emoji::FAMILY]&.count.to_i > 1 then :family
+    when reactions[Emoji::EYES]&.count.to_i > 1 then :eyes
+    when reactions[Emoji::KEY]&.count.to_i > 1 then :key
     when reactions[Emoji::PHONE]&.count.to_i > 1 then :phone
     when reactions[Emoji::LEFT]&.count.to_i > 1 then :left
     when reactions[Emoji::RIGHT]&.count.to_i > 1 then :right
+    when reactions[Emoji::UNDO]&.count.to_i > 1 then :back
     end
 
   case [form, vote]
@@ -346,11 +470,15 @@ bot.reaction_add do |event|
     user = event.server.member(uid[1])
 
     char = CharacterController.edit_character(params)
-    image_url = ImageController.default_image(content, char.id)
+    img = ImageController.default_image(content, char.id)
     color = CharacterController.type_color(char)
 
-
-    embed = character_embed(char, image_url, user, color) if char
+    embed = character_embed(
+      char: char,
+      img: img,
+      user: user,
+      color: color
+    )if char
 
     if embed
       bot.send_message(
@@ -447,6 +575,171 @@ bot.reaction_add do |event|
   when [:image_application, :cross]
     event.message.delete
 
+  when [:carousel, :notebook]
+    emoji = Emoji::NOTEBOOK
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :bio
+    )
+    event.message.edit("", embed)
+  when [:carousel, :question]
+    emoji = Emoji::QUESTION
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :status
+    )
+    event.message.edit("", embed)
+  when [:carousel, :pallet]
+    emoji = Emoji::PALLET
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :type
+    )
+    event.message.edit("", embed)
+  when [:carousel, :ear]
+    emoji = Emoji::EAR
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :rumors
+    )
+    event.message.edit("", embed)
+  when [:carousel, :picture]
+    event.message.delete_all_reactions
+
+    char = Character.find(carousel.char_id)
+    img = ImageController.img_scroll(
+      char_id: char.id,
+      nsfw: event.channel.nsfw?,
+    )
+    carousel.update(id: carousel.id, image_id: img.id)
+
+    embed = character_embed(
+      char: char,
+      img: img,
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :image
+    )
+    event.message.edit("", embed)
+    arrow_react(event.message)
+  when [:carousel, :bags]
+  when [:carousel, :family]
+  when [:carousel, :eyes]
+    emoji = Emoji::EYES
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :all
+    )
+    event.message.edit("", embed)
+  when [:carousel, :key]
+    emoji = Emoji::KEY
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :default
+    )
+    event.message.edit("", embed)
+  when [:carousel, :back]
+    event.message.delete_all_reactions
+
+    char = Character.find(carousel.char_id)
+    embed = character_embed(
+      char: char,
+      img: CharImage.where(char_id: char.id).find_by(keyword: 'Default'),
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :default
+    )
+    event.message.edit("", embed)
+    section_react(event.message)
+  when [:carousel, :left], [:carousel, :right]
+    emoji = vote == :left ? Emoji::LEFT : Emoji::RIGHT
+    users = event.message.reacted_with(emoji)
+
+    users.each do |user|
+      event.message.delete_reaction(user.id, emoji) unless user.current_bot?
+    end
+
+    char = Character.find(carousel.char_id)
+    img = ImageController.img_scroll(
+      char_id: char.id,
+      nsfw: event.channel.nsfw?,
+      img: carousel.image_id,
+      dir: vote
+    )
+
+    carousel.update(id: carousel.id, image_id: img.id)
+
+    embed = character_embed(
+      char: char,
+      img: img,
+      user: event.server.member(char.user_id),
+      color: CharacterController.type_color(char),
+      section: :image
+    )
+    event.message.edit("", embed)
+  when [:carousel, :cross]
+    event.message.delete
+    Carousel.find_by(message_id: event.message.id).delete
   end
 end
 

+ 15 - 2
lib/emoji.rb

@@ -27,10 +27,14 @@ module Emoji
   X = "🇽"
   Y = "🇾"
   Z = "🇿"
-  LEFT = "⬅"
-  RIGHT = "➡"
+
+  LEFT = "◀"
+  RIGHT = "▶"
+  UNDO = "⏫"
+
   CHECK = "✅"
   CROSS = "❌"
+
   SPEECH_BUBBLE = "💬"
   SCALE = "⚖"
   PICTURE = "🖼"
@@ -45,8 +49,17 @@ module Emoji
   KEY = "🔑"
   PAGE = "📄"
   FLAG = "🚩"
+  NOTEBOOK = "📔"
+  PALLET = "🎨"
+  EAR = "👂"
+  QUESTION = "❔"
+  BAGS = "🛍"
+  FAMILY = "👪"
+  EYES = "👀"
+
 
   LETTERS = [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
   CHAR_APP = [SPEECH_BUBBLE, SCALE, PICTURE, BOOKS, BABY, SKULL, VULGAR, NOTE]
   IMG_APP = [DOG, KEY, FLAG, PAGE, BOOKS, VULGAR]
+  CAROUSEL = [NOTEBOOK, QUESTION, PALLET, EAR, PICTURE, BAGS, FAMILY, EYES, KEY, CROSS]
 end