mirror of
https://github.com/mii443/rbot.git
synced 2025-08-22 15:45:30 +00:00
first commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.json
|
||||
*.txt
|
||||
*.yml
|
5
lib/classes.rb
Normal file
5
lib/classes.rb
Normal 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
190
lib/commands/game.rb
Normal 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
94
lib/commands/member.rb
Normal 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
23
lib/commands/message.rb
Normal 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
11
lib/commands/weather.rb
Normal 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
18
lib/events/member.rb
Normal 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
30
lib/methods.rb
Normal 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
34
main.rb
Normal 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
|
Reference in New Issue
Block a user