3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-14 22:05:01 +00:00

feat: add member cache; handle all role changes with RoleManagerPlugin; exit gracefully

This commit is contained in:
Dragory 2023-05-07 17:56:55 +03:00
parent fd60a09947
commit fa50110766
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
48 changed files with 755 additions and 264 deletions

View file

@ -3,7 +3,9 @@ import { GuildLogs } from "../../data/GuildLogs";
import { GuildPersistedData } from "../../data/GuildPersistedData";
import { makeIoTsConfigParser } from "../../pluginUtils";
import { trimPluginDescription } from "../../utils";
import { GuildMemberCachePlugin } from "../GuildMemberCache/GuildMemberCachePlugin";
import { LogsPlugin } from "../Logs/LogsPlugin";
import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin";
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
import { LoadDataEvt } from "./events/LoadDataEvt";
import { StoreDataEvt } from "./events/StoreDataEvt";
@ -29,7 +31,7 @@ export const PersistPlugin = zeppelinGuildPlugin<PersistPluginType>()({
configSchema: ConfigSchema,
},
dependencies: () => [LogsPlugin],
dependencies: () => [LogsPlugin, RoleManagerPlugin, GuildMemberCachePlugin],
configParser: makeIoTsConfigParser(ConfigSchema),
defaultOptions,

View file

@ -2,9 +2,9 @@ import { GuildMemberEditOptions, PermissionFlagsBits } from "discord.js";
import intersection from "lodash.intersection";
import { canAssignRole } from "../../../utils/canAssignRole";
import { getMissingPermissions } from "../../../utils/getMissingPermissions";
import { memberRolesLock } from "../../../utils/lockNameHelpers";
import { missingPermissionError } from "../../../utils/missingPermissionError";
import { LogsPlugin } from "../../Logs/LogsPlugin";
import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin";
import { persistEvt } from "../types";
const p = PermissionFlagsBits;
@ -16,13 +16,11 @@ export const LoadDataEvt = persistEvt({
const member = meta.args.member;
const pluginData = meta.pluginData;
const memberRoleLock = await pluginData.locks.acquire(memberRolesLock(member));
const persistedData = await pluginData.state.persistedData.find(member.id);
if (!persistedData) {
memberRoleLock.unlock();
return;
}
await pluginData.state.persistedData.clear(member.id);
const toRestore: GuildMemberEditOptions = {
reason: "Restored upon rejoin",
@ -59,29 +57,29 @@ 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");
toRestore.roles = Array.from(new Set([...rolesToRestore, ...member.roles.cache.keys()]));
for (const roleId of rolesToRestore) {
roleManager.addRole(member.id, roleId);
}
}
}
if (config.persist_nicknames && persistedData.nickname) {
restoredData.push("nickname");
toRestore.nick = persistedData.nickname;
await member.edit({
nick: persistedData.nickname,
});
}
if (restoredData.length) {
await member.edit(toRestore);
await pluginData.state.persistedData.clear(member.id);
pluginData.getPlugin(LogsPlugin).logMemberRestore({
member,
restoredData: restoredData.join(", "),
});
}
memberRoleLock.unlock();
},
});

View file

@ -1,34 +1,41 @@
import { GuildMember } from "discord.js";
import intersection from "lodash.intersection";
import { IPartialPersistData } from "../../../data/GuildPersistedData";
import { PersistedData } from "../../../data/entities/PersistedData";
import { GuildMemberCachePlugin } from "../../GuildMemberCache/GuildMemberCachePlugin";
import { persistEvt } from "../types";
export const StoreDataEvt = persistEvt({
event: "guildMemberRemove",
async listener(meta) {
const member = meta.args.member as GuildMember;
const pluginData = meta.pluginData;
let persist = false;
const persistData: IPartialPersistData = {};
async listener({ pluginData, args: { member } }) {
const config = await pluginData.config.getForUser(member.user);
const persistData: Partial<PersistedData> = {};
const persistedRoles = config.persisted_roles;
if (persistedRoles.length && member.roles) {
const rolesToPersist = intersection(persistedRoles, [...member.roles.cache.keys()]);
if (member.partial) {
// Djs hasn't cached member data => use db cache
const data = await pluginData.getPlugin(GuildMemberCachePlugin).getCachedMemberData(member.id);
if (!data) {
return;
}
const rolesToPersist = config.persisted_roles.filter((roleId) => data.roles.includes(roleId));
if (rolesToPersist.length) {
persist = true;
persistData.roles = rolesToPersist;
}
if (config.persist_nicknames && data.nickname) {
persistData.nickname = data.nickname;
}
} else {
// Djs has cached member data => use that
const memberRoles = Array.from(member.roles.cache.keys());
const rolesToPersist = config.persisted_roles.filter((roleId) => memberRoles.includes(roleId));
if (rolesToPersist.length) {
persistData.roles = rolesToPersist;
}
if (config.persist_nicknames && member.nickname) {
persistData.nickname = member.nickname as any;
}
}
if (config.persist_nicknames && member.nickname) {
persist = true;
persistData.nickname = member.nickname;
}
if (persist) {
if (Object.keys(persistData).length) {
pluginData.state.persistedData.set(member.id, persistData);
}
},