basic rank system support

This commit is contained in:
Jill 2023-01-09 14:18:43 +03:00
parent 4c9eb58632
commit 964e6c28ee
4 changed files with 121 additions and 0 deletions

View File

@ -37,6 +37,43 @@ spam_thres = -3
# allow new accounts to be created
allow_registration = true
# determine what permissions different ranks of users get
# ranks (based on `position`) will get all perms of
# ranks below (<) their own
# todo: document this fully
[ranks.everyone]
position = 0
[ranks.everyone.permissions]
upload_levels = true # todo: unimplemented
backup_save = true # todo: unimplemented
level_comment = true # todo: unimplemented
profile_comment = true # todo: unimplemented
leaderboard = true # todo: unimplemented
level_leaderboard = true # todo: unimplemented
send_friend_requests = true # todo: unimplemented
send_messages = true # todo: unimplemented
reupload_songs = true # todo: unimplemented
reupload_levels = true # todo: unimplemented
[ranks.mod]
position = 1
badge = 1 # todo: unimplemented
is_mod = true # can request mod access ingame # todo: unimplemented
text_color = [200, 255, 200]
[ranks.mod.permissions]
rate_levels = true # todo: unimplemented
rate_levels_demon = true # todo: unimplemented
[ranks.eldermod]
position = 2
badge = 2
is_mod = true
text_color = [75, 255, 75]
[ranks.eldermod.permissions]
delete_level_comments = true # todo: unimplemented
delete_others_levels = true # todo: unimplemented
[sessions]
# allow sessions to be created (for 1.9, as it
# doesn't send the password for authentication

View File

@ -0,0 +1,7 @@
-- +migrate up
ALTER TABLE accounts DROP COLUMN is_admin;
ALTER TABLE accounts ADD COLUMN rank TEXT;
-- +migrate down
ALTER TABLE accounts DROP COLUMN rank;
ALTER TABLE accounts ADD COLUMN is_admin INTEGER NOT NULL DEFAULT 0;

View File

@ -25,6 +25,7 @@ require "./lib/reupload"
require "./lib/creator_points"
require "./lib/versions"
require "./lib/ips"
require "./lib/ranks"
require "./patch-exe.cr"
@ -308,6 +309,7 @@ module CrystalGauntlet
check_server_length(false)
Reupload.init()
Ranks.init()
@@up_at = Time.utc
LOG.notice { "Listening on #{listen_on.to_s.colorize(:white)}" }

75
src/lib/ranks.cr Normal file
View File

@ -0,0 +1,75 @@
module CrystalGauntlet::Ranks
extend self
class Rank
getter name : String
getter position : Int64 = 0
getter badge : Int64 = 0
getter is_mod : Bool = false
getter text_color : Array(Int64)? = nil
getter permissions : Hash(String, Bool) = Hash(String, Bool).new
def initialize(@name, @position = 0, @badge = 0, @is_mod = false, @text_color = nil, @permissions = Hash(String, Bool).new)
end
def has_permission(key : String)
@permissions[key]? || false
end
end
NULL_RANK = Rank.new(name: "null", position: -1)
@@ranks = [] of Rank
def init()
config_get("ranks").as(Hash(String, TOML::Type)).each() do |key, value_|
value = value_.as(Hash(String, TOML::Type))
perms = value["permissions"]?.as?(Hash(String, TOML::Type)) || Hash(String, Bool).new
@@ranks << Rank.new(
name: key,
position: value["position"].as(Int64),
badge: value["badge"]?.as?(Int64) || 0_i64,
is_mod: value["is_mod"]?.as?(Bool) || false,
text_color: value["text_color"]?.as?(Array(Int64)),
permissions: perms.transform_values { |v| v.as?(Bool) || false }
)
end
if @@ranks.empty?
LOG.error { "Ranks are empty! Things might go very, very wrong" }
end
@@ranks.sort! { |a, b| a.position <=> b.position }
end
def get_rank(rank_name : String) : Rank?
@@ranks.find { |r| r.name == rank_name }
end
def get_rank(account_id : Int32) : Rank
begin
rank_name = DATABASE.query_one("select rank from accounts where id = ?", account_id, as: {String})
rescue
rank_name = "everyone"
end
get_rank(rank_name) || @@ranks[0]? || NULL_RANK
end
def get_permissions(rank : Rank) : Hash(String, Bool)
prev_ranks = @@ranks.select { |i| i.position < rank.position }
prev_ranks << rank
prev_ranks.reduce(Hash(String, Bool).new(false)) { |a, b| a.merge(b.permissions) }
end
def get_permissions(account_id : Int32)
get_permissions(get_rank(account_id))
end
def has_permission(rank : Rank, perm : String)
get_permissions(rank)[perm]? || false
end
def has_permission(account_id : Int32, perm : String)
get_permissions(account_id)[perm]? || false
end
end