mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
feat(persist): reapply persisted data after delay
This enables better interoperability with other bots that apply roles on join. This is because bots that apply roles on join often run into a race condition where they're both setting the member's roles at the same time without knowing about the other, which results in one bot's roles overriding the other one's. Reapplying Zeppelin's roles after a delay should ensure that persisted roles get applied properly even in these cases.
This commit is contained in:
parent
1e5378a274
commit
514e93aa23
1 changed files with 44 additions and 22 deletions
|
@ -1,14 +1,51 @@
|
|||
import { PermissionFlagsBits } from "discord.js";
|
||||
import { GuildMember, PermissionFlagsBits } from "discord.js";
|
||||
import { GuildPluginData } from "knub";
|
||||
import intersection from "lodash.intersection";
|
||||
import { PersistedData } from "../../../data/entities/PersistedData";
|
||||
import { SECONDS } from "../../../utils";
|
||||
import { canAssignRole } from "../../../utils/canAssignRole";
|
||||
import { getMissingPermissions } from "../../../utils/getMissingPermissions";
|
||||
import { missingPermissionError } from "../../../utils/missingPermissionError";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin";
|
||||
import { persistEvt } from "../types";
|
||||
import { PersistPluginType, persistEvt } from "../types";
|
||||
|
||||
const p = PermissionFlagsBits;
|
||||
|
||||
async function applyPersistedData(
|
||||
pluginData: GuildPluginData<PersistPluginType>,
|
||||
persistedData: PersistedData,
|
||||
member: GuildMember,
|
||||
): Promise<string[]> {
|
||||
const config = await pluginData.config.getForMember(member);
|
||||
const guildRoles = Array.from(pluginData.guild.roles.cache.keys());
|
||||
const restoredData: string[] = [];
|
||||
|
||||
const persistedRoles = config.persisted_roles;
|
||||
if (persistedRoles.length) {
|
||||
const roleManager = pluginData.getPlugin(RoleManagerPlugin);
|
||||
const rolesToRestore = intersection(persistedRoles, persistedData.roles, guildRoles).filter(
|
||||
(roleId) => !member.roles.cache.has(roleId),
|
||||
);
|
||||
|
||||
if (rolesToRestore.length) {
|
||||
restoredData.push("roles");
|
||||
for (const roleId of rolesToRestore) {
|
||||
roleManager.addRole(member.id, roleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.persist_nicknames && persistedData.nickname && member.nickname !== persistedData.nickname) {
|
||||
restoredData.push("nickname");
|
||||
await member.edit({
|
||||
nick: persistedData.nickname,
|
||||
});
|
||||
}
|
||||
|
||||
return restoredData;
|
||||
}
|
||||
|
||||
export const LoadDataEvt = persistEvt({
|
||||
event: "guildMemberAdd",
|
||||
|
||||
|
@ -23,7 +60,6 @@ export const LoadDataEvt = persistEvt({
|
|||
await pluginData.state.persistedData.clear(member.id);
|
||||
|
||||
const config = await pluginData.config.getForMember(member);
|
||||
const restoredData: string[] = [];
|
||||
|
||||
// Check permissions
|
||||
const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!;
|
||||
|
@ -52,25 +88,11 @@ export const LoadDataEvt = persistEvt({
|
|||
}
|
||||
}
|
||||
|
||||
const persistedRoles = config.persisted_roles;
|
||||
if (persistedRoles.length) {
|
||||
const roleManager = pluginData.getPlugin(RoleManagerPlugin);
|
||||
const rolesToRestore = intersection(persistedRoles, persistedData.roles, guildRoles);
|
||||
|
||||
if (rolesToRestore.length) {
|
||||
restoredData.push("roles");
|
||||
for (const roleId of rolesToRestore) {
|
||||
roleManager.addRole(member.id, roleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.persist_nicknames && persistedData.nickname) {
|
||||
restoredData.push("nickname");
|
||||
await member.edit({
|
||||
nick: persistedData.nickname,
|
||||
});
|
||||
}
|
||||
const restoredData = await applyPersistedData(pluginData, persistedData, member);
|
||||
setTimeout(() => {
|
||||
// Reapply persisted data after a while for better interop with other bots that restore roles
|
||||
void applyPersistedData(pluginData, persistedData, member);
|
||||
}, 5 * SECONDS);
|
||||
|
||||
if (restoredData.length) {
|
||||
pluginData.getPlugin(LogsPlugin).logMemberRestore({
|
||||
|
|
Loading…
Add table
Reference in a new issue