first commit

This commit is contained in:
takumi091111
2017-09-25 09:38:07 +09:00
commit 6781dff326
9 changed files with 408 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.json
*.txt
*.yml

5
lib/classes.rb Normal file
View File

@ -0,0 +1,5 @@
class String
def with_comma
self.gsub(/(\d)(?=\d{3}+$)/, '\\1,')
end
end

190
lib/commands/game.rb Normal file
View File

@ -0,0 +1,190 @@
module Bot
module DiscordCommands
module GameCommands
extend Discordrb::Commands::CommandContainer
require 'nokogiri'
require 'capybara/poltergeist'
STEAM_SEARCH_URL = 'https://steamcommunity.com/search/users/#text='
PROFILE_REGEXP = /https?:\/\/steamcommunity.com\/profiles\//
command(:osu, usage: 'osu <ユーザー名>', description: 'osu!のユーザー情報を表示') do |event, id|
# osu!のユーザー情報取得
apiurl = CONFIG[:osu][:apiurl]
apikey = CONFIG[:osu][:apikey]
json = get_json("#{apiurl}?k=#{apikey}&u=#{id}&type=string")[0]
rank = "**SS** : #{json["count_rank_ss"]} / **S** : #{json["count_rank_s"]} / **A** : #{json["count_rank_a"]}"
country_rank = "##{json["pp_country_rank"].with_comma}"
event.channel.send_embed do |embed|
embed.author = Discordrb::Webhooks::EmbedAuthor.new(
name: 'osu! Profile',
url: "https://osu.ppy.sh/u/#{json["user_id"]}",
icon_url: 'https://i.ppy.sh/3ae9b08499c5b07e2c189aadc419aba4281211ce/687474703a2f2f772e7070792e73682f632f63392f4c6f676f2e706e67'
)
embed.footer = Discordrb::Webhooks::EmbedFooter.new(
text: "#{json["country"]} (#{country_rank})",
icon_url: "#{CONFIG[:flag][:url]}#{json["country"].downcase}.png"
)
embed.thumbnail = Discordrb::Webhooks::EmbedThumbnail.new(
url: "https://a.ppy.sh/#{json["user_id"]}"
)
embed.color = CONFIG[:osu][:color]
# フィールド
embed.add_field(
name: 'Name',
value: json["username"],
inline: true
)
embed.add_field(
name: 'ID',
value: json["user_id"],
inline: true
)
embed.add_field(
name: 'Lv',
value: json["level"].to_i.to_s,
inline: true
)
embed.add_field(
name: 'PP',
value: json["pp_raw"].to_i.round.to_s.with_comma+"pp",
inline: true
)
embed.add_field(
name: 'Performance',
value: '#'+json["pp_rank"].with_comma,
inline: true
)
embed.add_field(
name: 'Ranked Score',
value: json["ranked_score"].with_comma,
inline: true
)
embed.add_field(
name: 'Hit Accuracy',
value: json["accuracy"].to_f.round(2).to_s+"%",
inline: true
)
embed.add_field(
name: 'Play Count',
value: json["playcount"].with_comma,
inline: true
)
embed.add_field(
name: 'Rank',
value: rank
)
end
end
command(:steam, usage: 'steam <ユーザー名>', description: 'Steamのユーザー情報を表示') do |event, query|
# Capybara/Poltergistの設定
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :timeout => 100 })
end
# ページ取得
session = Capybara::Session.new(:poltergeist)
session.visit(STEAM_SEARCH_URL + query)
# パース
doc = Nokogiri::HTML(session.html)
url = doc.css('.searchPersonaName')[0].attribute('href').to_s
apikey = CONFIG[:steam][:apikey]
id = nil
# Steam IDの取得
if url.match(PROFILE_REGEXP)
# プロフィールページの場合
id = url.match(/\d+/)[0]
else
# カスタムURLの場合
vanityid = url.match(/id\/(.*)$/)[1]
vanitapi = "#{CONFIG[:steam][:vanitapi]}#{apikey}&vanityurl=#{vanityid}"
json = get_json(vanitapi)
id = json["response"]["steamid"]
end
playerapi = "#{CONFIG[:steam][:playerapi]}#{apikey}&steamids=#{id}"
json = get_json(playerapi)["response"]["players"][0]
event.channel.send_embed do |embed|
embed.author = Discordrb::Webhooks::EmbedAuthor.new(
name: 'Steam Profile',
url: json["profileurl"],
icon_url: "http://cache.filehippo.com/img/ex/1901__Steam_icon.png"
)
embed.thumbnail = Discordrb::Webhooks::EmbedThumbnail.new(
url: json["avatarfull"]
)
embed.color = CONFIG[:steam][:color]
# ユーザー名
embed.add_field(
name: 'Name',
value: json["personaname"],
inline: true
)
# Steam ID
embed.add_field(
name: 'Steam ID',
value: json["steamid"],
inline: true
)
# オンライン/オフラインの表示
state = "Online"
if json["personastate"] == 0
state = "Offline"
end
embed.add_field(
name: 'Status',
value: state,
inline: true
)
# ここから表示/非表示が分かれる
# 国
if json.include?("loccountrycode")
embed.add_field(
name: 'Country',
value: json["loccountrycode"],
inline: true
)
end
if state == "Offline"
# フッター
embed.footer = Discordrb::Webhooks::EmbedFooter.new(
text: "Last Online",
icon_url: "http://www.iconsdb.com/icons/preview/gray/account-login-xxl.png"
)
# タイムスタンプ
last_online = Time.at(json["lastlogoff"])
embed.timestamp = last_online
end
end
end
command(:test) do |event|
server = event.server
server.default_channel.send_message("#{event.user.mention}, Welcome to #{server.name}")
end
end
end
end

94
lib/commands/member.rb Normal file
View File

@ -0,0 +1,94 @@
module Bot
module DiscordCommands
module MemberCommands
extend Discordrb::Commands::CommandContainer
# 指定したメンバーの詳細情報表示
command(:member, usage: 'member <メンション>', description: 'メンバーの詳細情報を表示') do |event, user|
# ユーザーIDの数字部分のみ抽出
id = user.slice(/\d+/)
# メンバーオブジェクトの取得
member = event.server.member(id)
# 役職一覧を取得
roles = member.roles.map{|role| role.name}
# 埋め込みでメンバー情報を表示
event.channel.send_embed do |embed|
embed.thumbnail = Discordrb::Webhooks::EmbedThumbnail.new(url: member.avatar_url)
embed.add_field(name: '__Name__', value: "#{member.name}")
embed.add_field(name: '__ID__', value: "#{member.id}")
embed.add_field(name: '__Roles__', value: "#{roles.join(" ")}")
end
end
# メンバー一覧表示
command(:members, usage: 'members', description: 'メンバーの一覧を表示') do |event|
members = event.server.members
m_ary = members.map {|member| "@#{member.name}"}
event.channel.send_embed do |embed|
embed.add_field(name: '__Members__', value: "#{m_ary.join("\n")}")
end
end
# 指定したメンバーのアバター画像表示
command(:avatar, usage: 'avatar <メンション>', description: 'メンバーのアバター画像を表示') do |event, user|
id = user.slice(/\d+/)
member = event.server.member(id)
# 出力
event.respond member.avatar_url
end
# キック
command(:kick, usage: 'kick <メンション>', description: 'メンバーをキック') do |event, user|
id = user.slice(/\d+/)
name = event.server.member(id).name
event.server.kick(id)
event.respond "**#{name}** Kicked."
end
# ========== 役職系コマンド ==========
# 役職一覧表示
command(:roles, usage: 'roles', description: '役職の一覧を表示') do |event|
# 役職一覧を取得
roles = event.server.roles.map {|role| role.name}
# 埋め込みで役職を表示
event.channel.send_embed do |embed|
embed.add_field(name: '__Roles__', value: "#{roles.join("\n")}")
end
end
# 役職ごとのメンバーを一覧表示
command(:roleMembers, usage: 'roleMembers', description: '役職ごとのメンバーを一覧表示') do |event|
# 役職一覧を取得
event.server.roles.each do |role|
# @everyoneはスキップする
next if role.name == "@everyone"
m_ary = role.members.map {|member| "@#{member.name}"}
# 埋め込みで役職ごとのメンバーを表示
event.channel.send_embed do |embed|
# 配列を改行文字で結合
embed.add_field(name: "__Members in #{role.name}__", value: "#{m_ary.join("\n")}")
end
end
end
# 役職付加
command(:setRole, usage: 'setRole <メンション> <役職>', description: 'メンバーに役職を付加') do |event, user, role|
id = user.slice(/\d+/)
member = event.server.member(id)
role = event.server.roles.select {|r|r.name == role}[0]
member.add_role(role)
event.respond "Added!"
end
# 役職削除
command(:delRole, usage: 'delRole <メンション> <役職>', description: 'メンバーから役職を削除') do |event, user, role|
id = user.slice(/\d+/)
member = event.server.member(id)
role = event.server.roles.select {|r|r.name == role}[0]
member.remove_role(role)
event.respond "Deleted!"
end
end
end
end

23
lib/commands/message.rb Normal file
View File

@ -0,0 +1,23 @@
module Bot
module DiscordCommands
module MessageCommands
extend Discordrb::Commands::CommandContainer
# 絵文字一覧表示
command(:emoji, usage: 'emoji', description: '絵文字の一覧を表示') do |event|
# 絵文字の取得(ハッシュ)
emojis = event.server.emoji
# ハッシュから値を取り出して配列にする
e_ary = emojis.values
# 配列を結合してスペースで区切って出力
event.respond "#{e_ary.join(" ")}"
end
# メッセージ削除
command(:del, usage: 'del <件数>', description: 'メッセージの削除', min_args: 1, max_args: 99) do |event, n|
event.channel.prune(n.to_i + 1, true)
nil
end
end
end
end

11
lib/commands/weather.rb Normal file
View File

@ -0,0 +1,11 @@
module Bot
module DiscordCommands
module WeatherCommands
extend Discordrb::Commands::CommandContainer
command(:weather) do |event|
nil
end
end
end
end

18
lib/events/member.rb Normal file
View File

@ -0,0 +1,18 @@
module Bot
module DiscordCommands
module MemberEvent
extend Discordrb::EventContainer
# メンバー参加時
member_join do |event|
server = event.server
server.default_channel.send_message("#{event.user.mention}, Welcome to #{server.name}")
end
# メンバー退出時
member_leave do |event|
server.default_channel.send_message("ByeBye...")
end
end
end
end

30
lib/methods.rb Normal file
View File

@ -0,0 +1,30 @@
require 'net/http'
require 'uri'
require 'json'
def get_json(location, limit = 10)
raise ArgumentError, 'too many HTTP redirects' if limit == 0
uri = URI.parse(location)
begin
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.open_timeout = 5
http.read_timeout = 10
http.get(uri.request_uri)
end
case response
when Net::HTTPSuccess
json = response.body
JSON.parse(json)
when Net::HTTPRedirection
location = response['location']
warn "redirected to #{location}"
get_json(location, limit - 1)
else
puts [uri.to_s, response.value].join(" : ")
# handle error
end
rescue => e
puts [uri.to_s, e.class, e].join(" : ")
# handle error
end
end

34
main.rb Normal file
View File

@ -0,0 +1,34 @@
ENV["SSL_CERT_FILE"] = 'E:/program/lib/cacert.pem'
require 'discordrb'
require 'yaml'
require_relative './lib/classes.rb'
require_relative './lib/methods.rb'
CONFIG = YAML.load_file('./config.yml')
module Bot
BOT = Discordrb::Commands::CommandBot.new(
token: CONFIG[:bot][:token],
client_id: CONFIG[:bot][:id],
prefix: CONFIG[:bot][:prefix]
)
# コマンドの読み込み
module DiscordCommands; end
Dir['lib/commands/*.rb'].each { |mod| load mod }
DiscordCommands.constants.each do |mod|
BOT.include! DiscordCommands.const_get mod
end
# イベント処理の読み込み
module DiscordEvents; end
Dir['lib/events/*.rb'].each { |mod| load mod }
DiscordEvents.constants.each do |mod|
BOT.include! DiscordEvents.const_get mod
end
BOT.run
end
bot.run