Skip to content

Commit 8c32cdb

Browse files
Refactor skill role stuff
1 parent 1659090 commit 8c32cdb

10 files changed

Lines changed: 185 additions & 166 deletions

File tree

src/components/anti-invite-links.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,28 +203,12 @@ export default class AntiInviteLinks extends BotComponent {
203203
}
204204
}
205205

206-
async member_is_proficient_or_higher(member: Discord.GuildMember | null) {
207-
if (!member) {
208-
return false;
209-
}
210-
const skill_roles = member.roles.cache.filter(role =>
211-
Object.values(this.wheatley.skill_roles).some(skill_role => role.id == skill_role.id),
212-
);
213-
if (skill_roles.size > 1) {
214-
const skill_role_ranks = Object.values(this.wheatley.skill_roles).map(role => role.id);
215-
const proficient_index = skill_role_ranks.indexOf(this.wheatley.skill_roles.proficient.id);
216-
assert(proficient_index !== -1);
217-
return skill_roles.some(role => skill_role_ranks.indexOf(role.id) >= proficient_index);
218-
}
219-
return false;
220-
}
221-
222206
async handle_message(message: Discord.Message) {
223207
if (await this.wheatley.check_permissions(message.author, Discord.PermissionFlagsBits.ModerateMembers)) {
224208
return;
225209
}
226210
const match = match_invite(message.content);
227-
if (match && !(await this.is_allowed(match)) && !(await this.member_is_proficient_or_higher(message.member))) {
211+
if (match && !(await this.is_allowed(match)) && !(await this.wheatley.is_established_member(message.author))) {
228212
const quote = await this.utilities.make_quote_embeds(message);
229213
await message.delete();
230214
assert(!(message.channel instanceof Discord.PartialGroupDMChannel));

src/components/moderation/modmail.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,8 @@ export default class Modmail extends BotComponent {
280280
});
281281
await this.log_action(interaction.member, "Modmail button spammed");
282282
} else {
283-
const member = await this.wheatley.guild.members.fetch(interaction.user.id);
284-
const non_beginner_skill_roles = member.roles.cache.filter(role =>
285-
Object.values(this.wheatley.skill_roles).some(
286-
skill_role => role.id == skill_role.id && skill_role.name != "Beginner",
287-
),
288-
);
289-
if (non_beginner_skill_roles.size > 0) {
290-
// fast-path people who can read
283+
if (await this.wheatley.is_established_member(interaction.user)) {
284+
// fast-path established members
291285
await interaction.deferReply({
292286
ephemeral: true,
293287
});

src/components/role-manager.ts

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ import { unwrap } from "../utils/misc.js";
55
import { M } from "../utils/debugging-and-logging.js";
66
import { BotComponent } from "../bot-component.js";
77
import { CommandSetBuilder } from "../command-abstractions/command-set-builder.js";
8-
import { skill_roles_order, skill_roles_order_id, Wheatley } from "../wheatley.js";
98
import { set_interval } from "../utils/node.js";
109
import { build_description } from "../utils/strings.js";
1110

12-
type user_role_entry = {
11+
export type user_role_entry = {
1312
user_id: string;
1413
roles: string[];
15-
last_known_skill_role: string | null;
1614
};
1715

1816
type role_check = (member: Discord.GuildMember) => Promise<void>;
@@ -23,7 +21,6 @@ type role_update_listener = {
2321
};
2422

2523
export default class RoleManager extends BotComponent {
26-
private skill_role_log!: Discord.TextChannel;
2724
private staff_member_log!: Discord.TextChannel;
2825
interval: NodeJS.Timeout | null = null;
2926

@@ -49,7 +46,6 @@ export default class RoleManager extends BotComponent {
4946
}
5047

5148
override async setup(commands: CommandSetBuilder) {
52-
this.skill_role_log = await this.utilities.get_channel(this.wheatley.channels.skill_role_log);
5349
this.staff_member_log = await this.utilities.get_channel(this.wheatley.channels.staff_member_log);
5450
}
5551

@@ -85,20 +81,13 @@ export default class RoleManager extends BotComponent {
8581
this.wheatley.roles.linked_github.id,
8682
]);
8783

88-
this.register_role_check(this.check_skill_roles.bind(this));
89-
this.register_role_update_listener(new Set(skill_roles_order_id), this.check_for_skill_role_bump.bind(this));
90-
9184
const check = () => {
9285
this.check_members().catch(this.wheatley.critical_error.bind(this.wheatley));
9386
};
9487
check();
9588
this.interval = set_interval(check, HOUR);
9689
}
9790

98-
get_highest_skill_role(roles: string[]) {
99-
return skill_roles_order_id.filter(id => roles.includes(id)).at(-1) ?? null;
100-
}
101-
10291
async check_member_roles(member: Discord.GuildMember) {
10392
for (const check of this.role_checks) {
10493
await check(member);
@@ -108,10 +97,9 @@ export default class RoleManager extends BotComponent {
10897
const diff = old_roles?.symmetricDifference(current_roles);
10998
if (diff === undefined || diff.size > 0) {
11099
const role_ids = current_roles.map(role => role.id);
111-
const skill_role = this.get_highest_skill_role(member.roles.cache.map(role => role.id));
112100
await this.database.user_roles.findOneAndUpdate(
113101
{ user_id: member.id },
114-
{ $set: skill_role ? { roles: role_ids, last_known_skill_role: skill_role } : { roles: role_ids } },
102+
{ $set: { roles: role_ids } },
115103
{ upsert: true },
116104
);
117105
const new_roles = new Set(role_ids);
@@ -124,53 +112,6 @@ export default class RoleManager extends BotComponent {
124112
}
125113
}
126114

127-
async check_skill_roles(member: Discord.GuildMember) {
128-
const skill_roles = member.roles.cache.filter(role =>
129-
Object.values(this.wheatley.skill_roles).some(skill_role => role.id == skill_role.id),
130-
);
131-
if (skill_roles.size > 1) {
132-
M.log("removing duplicate skill roles for", member.user.tag);
133-
skill_roles.sort((a, b) => b.rawPosition - a.rawPosition);
134-
M.debug(skill_roles.map(x => x.name));
135-
M.debug(skill_roles.map(x => x.name).slice(1));
136-
for (const role of skill_roles.map(x => x).slice(1)) {
137-
await member.roles.remove(role);
138-
}
139-
}
140-
}
141-
142-
async check_for_skill_role_bump(member: Discord.GuildMember) {
143-
const roles_entry = await this.database.user_roles.findOne({ user_id: member.id });
144-
const last_known_skill_level =
145-
roles_entry && roles_entry.last_known_skill_role
146-
? this.wheatley.get_skill_role_index(roles_entry.last_known_skill_role)
147-
: -1;
148-
const current_skill_role = this.get_highest_skill_role(member.roles.cache.map(role => role.id));
149-
const current_skill_level = current_skill_role ? this.wheatley.get_skill_role_index(current_skill_role) : -1;
150-
if (
151-
current_skill_level > skill_roles_order.indexOf("beginner") &&
152-
current_skill_level > last_known_skill_level
153-
) {
154-
assert(current_skill_role);
155-
M.log("Detected skill level increase for", member.user.tag);
156-
await this.skill_role_log.send({
157-
embeds: [
158-
new Discord.EmbedBuilder()
159-
.setAuthor({
160-
name: member.displayName,
161-
iconURL: member.displayAvatarURL(),
162-
})
163-
.setColor(unwrap(await this.wheatley.guild.roles.fetch(current_skill_role)).color)
164-
.setDescription(
165-
roles_entry?.last_known_skill_role
166-
? `<@&${roles_entry.last_known_skill_role}> -> <@&${current_skill_role}>`
167-
: `<@&${current_skill_role}>`,
168-
),
169-
],
170-
});
171-
}
172-
}
173-
174115
async check_members() {
175116
M.log("Starting role checks");
176117
try {

src/modules/tccpp/components/anti-screenshot.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,8 @@ export default class AntiScreenshot extends BotComponent {
103103
async anti_screenshot(starter_message: Discord.Message, thread: Discord.ThreadChannel) {
104104
await delay(1000);
105105
assert(starter_message);
106-
assert(starter_message.member);
107-
// trust people with skill roles
108-
if (this.wheatley.has_skill_roles_other_than_beginner(starter_message.member)) {
106+
// trust established members
107+
if (await this.wheatley.is_established_member(starter_message.author)) {
109108
return;
110109
}
111110
// check if it has images and no code
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Discord from "discord.js";
2+
import { unwrap } from "../../../utils/misc.js";
3+
import { M } from "../../../utils/debugging-and-logging.js";
4+
import { BotComponent } from "../../../bot-component.js";
5+
import RoleManager from "../../../components/role-manager.js";
6+
import { CommandSetBuilder } from "../../../command-abstractions/command-set-builder.js";
7+
import SkillRoles from "./skill-roles.js";
8+
9+
export default class TheEstablishment extends BotComponent {
10+
// private established_role!: Discord.Role;
11+
12+
override async setup(commands: CommandSetBuilder) {
13+
// const role_manager = unwrap(this.wheatley.components.get("RoleManager")) as RoleManager;
14+
// role_manager.register_role_check(this.check_established.bind(this));
15+
this.wheatley.is_established_member = this.is_established_member.bind(this);
16+
}
17+
18+
private async is_established_member(
19+
options: Discord.GuildMember | Discord.User | Discord.UserResolvable | Discord.FetchMemberOptions,
20+
) {
21+
const member = await this.wheatley.try_fetch_guild_member(options);
22+
if (!member) {
23+
return false;
24+
}
25+
return (
26+
SkillRoles.find_highest_skill_role_index(member.roles.cache) > 0 ||
27+
member.premiumSince != null ||
28+
member.permissions.has(Discord.PermissionFlagsBits.MuteMembers) ||
29+
member.permissions.has(Discord.PermissionFlagsBits.ModerateMembers)
30+
);
31+
}
32+
33+
// private async check_established(member: Discord.GuildMember) {}
34+
}

src/modules/tccpp/components/formatting-error-detection.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { strict as assert } from "assert";
55
import { M } from "../../../utils/debugging-and-logging.js";
66
import { colors, MINUTE } from "../../../common.js";
77
import { BotComponent } from "../../../bot-component.js";
8+
import SkillRoles from "./skill-roles.js";
89
import { build_description, parse_out } from "../../../utils/strings.js";
910
import Code from "../../../components/code.js";
1011
import { SelfClearingMap, SelfClearingSet } from "../../../utils/containers.js";
@@ -121,10 +122,8 @@ export default class FormattingErrorDetection extends BotComponent {
121122
}
122123

123124
has_likely_format_errors(message: Discord.Message) {
124-
const has_skill_roles_other_than_beginner = message.member
125-
? this.wheatley.has_skill_roles_other_than_beginner(message.member)
126-
: false;
127-
if (has_skill_roles_other_than_beginner) {
125+
// trust Proficient+ members
126+
if (message.member && SkillRoles.find_highest_skill_role_index(message.member.roles.cache) >= 2) {
128127
return false;
129128
}
130129
return FormattingErrorDetection.has_likely_format_errors(message.content);

src/modules/tccpp/components/permissions-manager.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { HOUR } from "../../../common.js";
77
import { BotComponent } from "../../../bot-component.js";
88
import { Wheatley } from "../../../wheatley.js";
99
import { unwrap } from "../../../utils/misc.js";
10+
import { skill_role_ids } from "./skill-roles.js";
1011

1112
const categories_map = {
1213
staff_logs: "1135927261472755712",
@@ -138,10 +139,10 @@ export default class PermissionManager extends BotComponent {
138139
deny: [...acive_voice_permissions, SET_VOICE_STATUS_PERMISSION_BIT],
139140
},
140141
[this.wheatley.roles.voice.id]: { allow: acive_voice_permissions },
141-
[this.wheatley.skill_roles.intermediate.id]: { allow: acive_voice_permissions },
142-
[this.wheatley.skill_roles.proficient.id]: { allow: acive_voice_permissions },
143-
[this.wheatley.skill_roles.advanced.id]: { allow: acive_voice_permissions },
144-
[this.wheatley.skill_roles.expert.id]: { allow: acive_voice_permissions },
142+
[skill_role_ids[1]]: { allow: acive_voice_permissions },
143+
[skill_role_ids[2]]: { allow: acive_voice_permissions },
144+
[skill_role_ids[3]]: { allow: acive_voice_permissions },
145+
[skill_role_ids[4]]: { allow: acive_voice_permissions },
145146
[this.wheatley.roles.server_booster.id]: { allow: acive_voice_permissions },
146147
[this.wheatley.roles.no_voice.id]: no_interaction_at_all,
147148
[this.wheatley.roles.no_off_topic.id]: no_interaction_at_all,

0 commit comments

Comments
 (0)