Browse Source

Follow my own formatting guidelines

master
parent
commit
187004db78
No known key found for this signature in database GPG Key ID: DA34C790D267C164
11 changed files with 98 additions and 54 deletions
  1. +1
    -1
      CONTRIBUTING.md
  2. +3
    -1
      src/Bampersand.cr
  3. +20
    -6
      src/Perms.cr
  4. +0
    -2
      src/State.cr
  5. +5
    -2
      src/Util.cr
  6. +18
    -21
      src/commands/core.cr
  7. +19
    -5
      src/commands/mod.cr
  8. +2
    -6
      src/commands/ops.cr
  9. +13
    -4
      src/commands/tag.cr
  10. +3
    -1
      src/modules/Board.cr
  11. +14
    -5
      src/modules/ModTools.cr

+ 1
- 1
CONTRIBUTING.md View File

@ -1,7 +1,7 @@
# Code style
Run `crystal tool format` over your code before committing to enforce standardized formatting.
Avoid line lengths over 100 characters, and if that's not possible, expand arguments into newlines as necessary, e.g. like:
Avoid line lengths over 80 characters, and if that's not possible, expand arguments into newlines as necessary, e.g. like:
```
SomeModule::very_long_function_invocation(


+ 3
- 1
src/Bampersand.cr View File

@ -83,7 +83,9 @@ module Bampersand
Board.handle_reaction(payload)
end
bot!.on_guild_create do |payload|
Log.info("Joined new guild #{payload.name} — Owner is #{payload.owner_id}")
Log.info(
"Joined new guild #{payload.name} — Owner is #{payload.owner_id}"
)
end
bot!.on_guild_member_add do |payload|
JoinLeaveLog.handle_join(payload)


+ 20
- 6
src/Perms.cr View File

@ -26,23 +26,29 @@ module Perms
get_highest(guild_id, user_id) >= level
end
# Get the highest privilege level an user has access to in this guild(nilable)
def get_highest(guild_id, user_id)
# Get the highest privilege level an user has access to in this guild(nilable)
return Level::Operator if user_id == ENV["admin"].to_u64
# Can't run privileged commands outside a guild
return Level::User if guild_id.nil?
guild_id = guild_id.not_nil!
return Level::Owner if user_id == cache!.resolve_guild(guild_id).owner_id.to_u64
if user_id == cache!.resolve_guild(guild_id).owner_id.to_u64
return Level::Owner
end
guild_perms = @@perms[guild_id]?
if guild_perms && guild_perms[Level::Admin]?
member = cache!.resolve_member(guild_id, user_id)
role_id = guild_perms[Level::Admin]
return Level::Admin if member.roles.any? { |role| role.to_u64 == role_id }
return Level::Admin if member.roles.any? do |role|
role.to_u64 == role_id
end
end
if guild_perms && guild_perms[Level::Moderator]?
member = cache!.resolve_member(guild_id, user_id)
role_id = guild_perms[Level::Moderator]
return Level::Moderator if member.roles.any? { |role| role.to_u64 == role_id }
return Level::Moderator if member.roles.any? do |role|
role.to_u64 == role_id
end
end
return Level::User
end
@ -50,12 +56,20 @@ module Perms
def update_perms(guild_id, level, role_id)
@@perms[guild_id] = {} of Level => UInt64? unless @@perms[guild_id]?
@@perms[guild_id][level] = role_id
Bampersand::DATABASE.exec "insert into perms values (?,?,?)", guild_id.to_i64, @@perms[guild_id][Level::Admin]?.try(&.to_i64), @@perms[guild_id][Level::Moderator]?.try(&.to_i64)
Bampersand::DATABASE.exec(
"insert into perms values (?,?,?)", guild_id.to_i64,
@@perms[guild_id][Level::Admin]?.try(&.to_i64),
@@perms[guild_id][Level::Moderator]?.try(&.to_i64)
)
end
# Not sure when this might turn out to be useful as the functionality is
# already integrated into Command
macro assert_level(level)
raise "Unauthorized. Required: {{level}}" unless Perms.check(ctx.guild_id, ctx.issuer.id.to_u64, Perms::Level::{{level}})
unless Perms.check(
ctx.guild_id, ctx.issuer.id.to_u64, Perms::Level::{{level}}
)
raise "Unauthorized. Required: {{level}}"
end
end
end

+ 0
- 2
src/State.cr View File

@ -37,8 +37,6 @@ module State
def load_state
state = {} of UInt64 => GuildState
Bampersand::DATABASE.query "select * from state" do |rs|
# Adjust expected column count when the data schema is changed
raise "Invalid column count #{rs.column_count}" unless rs.column_count == 1 + 10
rs.each do
state[rs.read(Int64).to_u64] = {
features: Features.new(rs.read(Int32)),


+ 5
- 2
src/Util.cr View File

@ -19,12 +19,15 @@ module Util
cache!.resolve_role(element)
end
roles.any? do |element|
element.permissions.includes?(permissions) || element.permissions.includes?(Discord::Permissions::Administrator)
element.permissions.includes?(permissions) ||
element.permissions.includes?(Discord::Permissions::Administrator)
end
end
macro assert_perms(context, permissions)
raise "Insufficient permissions" unless Util.perms?({{context}}, Discord::Permissions::{{permissions}})
unless Util.perms?({{context}}, Discord::Permissions::{{permissions}})
raise "Insufficient permissions. Required: {{permissions}}"
end
end
# Currently not needed as all guild-requiring commands are level-privileged


+ 18
- 21
src/commands/core.cr View File

@ -1,37 +1,34 @@
PINGS = ["Pyongyang!", "Ding!", "Pong!", "[reverberating PONG]", "Plonk."]
Commands.register_command("ping", "Pongs you.", Perms::Level::User) do |args, ctx|
ping = Time.utc_now - ctx.timestamp
":ping_pong: " + ["Pyongyang!", "Ding!", "Pong!", "[reverberating PONG]", "Plonk."].sample + " | `#{ping.total_milliseconds.to_i}ms`"
":ping_pong: " + PINGS.sample + " | `#{ping.total_milliseconds.to_i}ms`"
end
Commands.register_command("help", "Lists commands. Pass a single argument to search command descriptions.", Perms::Level::User) do |args, ctx|
output = if args.size != 1
Commands.command_info.keys.select { |e| !e.includes?(" ") }.reduce(" ") { |memo, e| memo + "*`#{e}`*, " }.rchop(", ")
Commands.command_info.keys.select do |e|
!e.includes?(" ")
end.reduce(" ") do |memo, e|
memo + "*`#{e}`*, "
end.rchop(", ")
else
Commands.command_info.keys.select { |e| e.includes?(args[0]) }.sort!.reduce(" ") { |memo, e| memo + "*`#{e}`* #{Commands.command_info[e].desc}\n" }
Commands.command_info.keys.select do |e|
e.includes?(args[0])
end.sort!.reduce(" ") do |memo, e|
memo + "*`#{e}`* #{Commands.command_info[e].desc}\n"
end
end
{text: output.lstrip.size > 0 ? output : "No results found.", title: "Commands"}
{
text: output.lstrip.size > 0 ? output : "No results found.",
title: "Commands",
}
end
Commands.register_command("about",
"Displays stats about Bampersand and links to further resources.",
Perms::Level::User) do |args, ctx|
Commands.register_command("about", "Displays stats about Bampersand and links to further resources.", Perms::Level::User) do |args, ctx|
uptime = Time.monotonic - Bampersand::STARTUP
{
title: "**BAMPERSAND VERSION #{Bampersand::VERSION}**",
text: "This is a simple utility bot for Discord powered by [Crystal](https://crystal-lang.org).\nYou can take a peek <:blobpeek:559732380697362482> at the [documentation](https://git.15318.de/Dingens/Bampersand/wiki/Home) and the [source code](https://git.15318.de/Dingens/Bampersand)!\nCurrently running on #{cache!.guilds.size} guilds, serving #{cache!.users.size} users.\nUptime is #{uptime.days}d #{uptime.hours}h #{uptime.minutes}m #{uptime.seconds}s. Bot operator is <@#{ENV["admin"]}>.",
}
end
Commands.register_command("ops restart",
"Restarts Bampersand.",
Perms::Level::Operator) do |args, ctx|
system("sudo systemctl restart bampersand")
raise "You should not be able to see this."
end
Commands.register_command("ops rebuild",
"Rebuilds Bampersand from the latest source.",
Perms::Level::Operator) do |args, ctx|
raise "Pull failed" unless system("git pull origin master")
raise "Build failed" unless system("shards build --release")
"Successfully rebuilt in #{Time.utc_now - ctx.timestamp}."
end

+ 19
- 5
src/commands/mod.cr View File

@ -76,7 +76,9 @@ Commands.register_command("unmute", "Attempts to unmute all mentioned users.", P
args.each do |argument|
begin
user = Arguments.to_user(argument)
bot!.remove_guild_member_role(guild_id, user.id.to_u64, mute_role.id.to_u64)
bot!.remove_guild_member_role(
guild_id, user.id.to_u64, mute_role.id.to_u64
)
output += ":heavy_check_mark: Unmuted <@#{user.id}>" + "\n"
rescue
output += ":x: Failed to unmute #{argument}\n"
@ -88,7 +90,10 @@ end
Commands.register_command("warn add", "Adds a warning for the mentioned user, reason optional.", Perms::Level::Moderator) do |args, ctx|
target_user = Arguments.at_position(args, 0, :user).as(Discord::User)
reason = args.size > 0 ? args.join(" ") : ""
Bampersand::DATABASE.exec "insert into warnings (guild_id, user_id, mod_id, text) values (?,?,?,?)", ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64, ctx.issuer.id.to_u64.to_i64, reason
Bampersand::DATABASE.exec(
"insert into warnings (guild_id, user_id, mod_id, text) values (?,?,?,?)",
ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64,
ctx.issuer.id.to_u64.to_i64, reason)
{
title: "Warning added for #{target_user.username}##{target_user.discriminator}",
text: "Responsible Moderator<@#{ctx.issuer.id}>\n#{reason}",
@ -98,7 +103,10 @@ Commands.register_command("warn list", "Lists all warnings for the mentioned use
target_user = Arguments.at_position(args, 0, :user).as(Discord::User)
output = ""
count = 0
Bampersand::DATABASE.query "select mod_id, text, timestamp from warnings where guild_id == ? and user_id == ?", ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64 do |rs|
Bampersand::DATABASE.query(
"select mod_id, text, timestamp from warnings where guild_id == ? and user_id == ?",
ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64
) do |rs|
rs.each do
mod_id = rs.read(Int64)
text = rs.read(String)
@ -111,12 +119,18 @@ Commands.register_command("warn list", "Lists all warnings for the mentioned use
end
Commands.register_command("warn remove", "Removes the oldest warning for the mentioned user.", Perms::Level::Moderator) do |args, ctx|
target_user = Arguments.at_position(args, 0, :user).as(Discord::User)
Bampersand::DATABASE.exec "delete from warnings where guild_id == ? and user_id == ? limit 1", ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64
Bampersand::DATABASE.exec(
"delete from warnings where guild_id == ? and user_id == ? limit 1",
ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64
)
true
end
Commands.register_command("warn expunge", "Removes all warnings for the mentioned user.", Perms::Level::Admin) do |args, ctx|
target_user = Arguments.at_position(args, 0, :user).as(Discord::User)
Bampersand::DATABASE.exec "delete from warnings where guild_id == ? and user_id == ?", ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64
Bampersand::DATABASE.exec(
"delete from warnings where guild_id == ? and user_id == ?",
ctx.guild_id.not_nil!.to_i64, target_user.id.to_u64.to_i64
)
true
end


+ 2
- 6
src/commands/ops.cr View File

@ -1,12 +1,8 @@
Commands.register_command("ops restart",
"Restarts Bampersand.",
Perms::Level::Operator) do |args, ctx|
Commands.register_command("ops restart", "Restarts Bampersand.", Perms::Level::Operator) do |args, ctx|
system("sudo systemctl restart bampersand")
raise "You should not be able to see this."
end
Commands.register_command("ops rebuild",
"Rebuilds Bampersand from the latest source.",
Perms::Level::Operator) do |args, ctx|
Commands.register_command("ops rebuild", "Rebuilds Bampersand from the latest source.", Perms::Level::Operator) do |args, ctx|
raise "Pull failed" unless system("git pull origin master")
raise "Build failed" unless system("shards build --release")
"Successfully rebuilt in #{Time.utc_now - ctx.timestamp}."


+ 13
- 4
src/commands/tag.cr View File

@ -5,8 +5,10 @@ Commands.register_command("tag update", "Updates/creates the tag with the passed
tag_name = args.shift
raise "Tag name may not contain newlines." if tag_name.includes?("\n")
tag_content = args.join(" ")
Bampersand::DATABASE.exec "insert into tags (guild_id, name, content) values (?,?,?)",
Bampersand::DATABASE.exec(
"insert into tags (guild_id, name, content) values (?,?,?)",
guild.to_i64, tag_name, tag_content
)
true
end
Commands.register_command("tag delete", "Deletes the tag with the passed name.", Perms::Level::Moderator) do |args, ctx|
@ -14,15 +16,19 @@ Commands.register_command("tag delete", "Deletes the tag with the passed name.",
Arguments.assert_count(args, 1)
guild = ctx.guild_id.not_nil!
tag_name = args.shift
Bampersand::DATABASE.exec "delete from tags where guild_id == ? and name == ?",
Bampersand::DATABASE.exec(
"delete from tags where guild_id == ? and name == ?",
guild.to_i64, tag_name
)
true
end
Commands.register_command("tag list", "Lists all defined tags.", Perms::Level::User) do |args, ctx|
Util.assert_guild(ctx)
output = ""
guild = ctx.guild_id.not_nil!
Bampersand::DATABASE.query "select name from tags where guild_id == ?", guild.to_i64 do |rs|
Bampersand::DATABASE.query(
"select name from tags where guild_id == ?", guild.to_i64
) do |rs|
rs.each do
output += " `#{rs.read(String)}`"
end
@ -43,7 +49,10 @@ Commands.register_command("tag", "[Edit and display custom messages]", Perms::Le
guild = ctx.guild_id.not_nil!
tag_name = args.shift
output = ""
Bampersand::DATABASE.query "select content from tags where guild_id == ? and name == ?", guild.to_i64, tag_name do |rs|
Bampersand::DATABASE.query(
"select content from tags where guild_id == ? and name == ?",
guild.to_i64, tag_name
) do |rs|
rs.each do
output = rs.read(String)
end


+ 3
- 1
src/modules/Board.cr View File

@ -7,7 +7,9 @@ module Board
def load_board
board_data = {} of UInt64 => UInt64
Bampersand::DATABASE.query "select source_message, board_message from board" do |rs|
Bampersand::DATABASE.query(
"select source_message, board_message from board"
) do |rs|
raise "Invalid column count" unless rs.column_count == 2
rs.each do
board_data[rs.read(Int64).to_u64] = rs.read(Int64).to_u64


+ 14
- 5
src/modules/ModTools.cr View File

@ -17,14 +17,20 @@ module ModTools
def create_mute_role(guild_id)
mute_role = bot!.create_guild_role(guild_id, "B& Muted")
cache!.guild_channels(guild_id).each do |channel_id|
bot!.edit_channel_permissions(channel_id, mute_role.id, "role", Discord::Permissions::None, Discord::Permissions::SendMessages)
bot!.edit_channel_permissions(
channel_id, mute_role.id, "role",
Discord::Permissions::None, Discord::Permissions::SendMessages
)
end
current_user = cache!.resolve_current_user
member = cache!.resolve_member(guild_id, current_user.id)
position = member.roles.map do |role_id|
cache!.resolve_role(role_id).position
end.max
bot!.modify_guild_role_positions(guild_id, [Discord::REST::ModifyRolePositionPayload.new(mute_role.id, position)])
bot!.modify_guild_role_positions(
guild_id,
[Discord::REST::ModifyRolePositionPayload.new(mute_role.id, position)]
)
cache!.cache(mute_role)
cache!.add_guild_role(guild_id, mute_role.id)
mute_role
@ -36,7 +42,6 @@ module ModTools
def load_slowmodes
slowmodes = {} of UInt64 => UInt32
Bampersand::DATABASE.query "select * from slowmodes" do |rs|
raise "Invalid column count #{rs.column_count}" unless rs.column_count == 2
rs.each do
slowmodes[rs.read(Int64).to_u64] = rs.read(Int64).to_u32
end
@ -50,13 +55,17 @@ module ModTools
def set_channel_slowmode(channel_id, secs)
@@slowmodes[channel_id] = secs
@@last_msgs[channel_id] = {} of UInt64 => Time
Bampersand::DATABASE.exec "insert into slowmodes values (?, ?)", channel_id.to_i64, secs.to_i64
Bampersand::DATABASE.exec(
"insert into slowmodes values (?, ?)", channel_id.to_i64, secs.to_i64
)
end
def remove_channel_slowmode(channel_id)
@@slowmodes.delete(channel_id)
@@last_msgs.delete(channel_id)
Bampersand::DATABASE.exec "delete from slowmodes where channel_id == ?", channel_id.to_i64
Bampersand::DATABASE.exec(
"delete from slowmodes where channel_id == ?", channel_id.to_i64
)
end
def get_channel_slowmode(channel_id)


Loading…
Cancel
Save