mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Add persist plugin
This commit is contained in:
parent
e7734c558c
commit
ad6afdfac1
10 changed files with 199 additions and 4 deletions
17
migrations/20180730230000_create_persisted_data_table.js
Normal file
17
migrations/20180730230000_create_persisted_data_table.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
exports.up = async function(knex, Promise) {
|
||||||
|
if (! await knex.schema.hasTable('persisted_data')) {
|
||||||
|
await knex.schema.createTable('persisted_data', table => {
|
||||||
|
table.string('guild_id', 20).notNullable();
|
||||||
|
table.string('user_id', 20).notNullable();
|
||||||
|
table.string('roles', 1024).nullable().defaultTo(null);
|
||||||
|
table.string('nickname', 255).nullable().defaultTo(null);
|
||||||
|
table.integer('is_voice_muted').notNullable().defaultTo(0);
|
||||||
|
|
||||||
|
table.primary(['guild_id', 'user_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = async function(knex, Promise) {
|
||||||
|
await knex.schema.dropTableIfExists('persisted_data');
|
||||||
|
};
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -2490,6 +2490,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
|
||||||
"integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
|
"integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
|
||||||
},
|
},
|
||||||
|
"lodash.intersection": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz",
|
||||||
|
"integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU="
|
||||||
|
},
|
||||||
"lodash.isequal": {
|
"lodash.isequal": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
"knub": "^9.4.13",
|
"knub": "^9.4.13",
|
||||||
"lodash.at": "^4.6.0",
|
"lodash.at": "^4.6.0",
|
||||||
"lodash.difference": "^4.5.0",
|
"lodash.difference": "^4.5.0",
|
||||||
|
"lodash.intersection": "^4.4.0",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"mariasql": "^0.2.6",
|
"mariasql": "^0.2.6",
|
||||||
"moment-timezone": "^0.5.21",
|
"moment-timezone": "^0.5.21",
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"MEMBER_ROLE_REMOVE": "🔑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) role removed **{role.name}** by {mod.username}#{mod.discriminator}",
|
"MEMBER_ROLE_REMOVE": "🔑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) role removed **{role.name}** by {mod.username}#{mod.discriminator}",
|
||||||
"MEMBER_NICK_CHANGE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) changed their nickname from **{oldNick}** to **{newNick}**",
|
"MEMBER_NICK_CHANGE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) changed their nickname from **{oldNick}** to **{newNick}**",
|
||||||
"MEMBER_USERNAME_CHANGE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) changed their username from **{oldName}** to **{newName}**",
|
"MEMBER_USERNAME_CHANGE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) changed their username from **{oldName}** to **{newName}**",
|
||||||
"MEMBER_ROLES_RESTORE": "💿 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) roles were restored",
|
"MEMBER_RESTORE": "💿 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) was restored",
|
||||||
|
|
||||||
"CHANNEL_CREATE": "🖊 Channel **#{channel.name}** was created",
|
"CHANNEL_CREATE": "🖊 Channel **#{channel.name}** was created",
|
||||||
"CHANNEL_DELETE": "🗑 Channel **#{channel.name}** was deleted",
|
"CHANNEL_DELETE": "🗑 Channel **#{channel.name}** was deleted",
|
||||||
|
|
53
src/data/GuildPersistedData.ts
Normal file
53
src/data/GuildPersistedData.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import knex from "../knex";
|
||||||
|
import PersistedData from "../models/PersistedData";
|
||||||
|
|
||||||
|
export interface IPartialPersistData {
|
||||||
|
roles?: string[];
|
||||||
|
nickname?: string;
|
||||||
|
is_voice_muted?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GuildPersistedData {
|
||||||
|
protected guildId: string;
|
||||||
|
|
||||||
|
constructor(guildId) {
|
||||||
|
this.guildId = guildId;
|
||||||
|
}
|
||||||
|
|
||||||
|
async find(userId: string) {
|
||||||
|
const result = await knex("persisted_data")
|
||||||
|
.where("guild_id", this.guildId)
|
||||||
|
.where("user_id", userId)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
return result ? new PersistedData(result) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async set(userId: string, data: IPartialPersistData = {}) {
|
||||||
|
const finalData: any = {};
|
||||||
|
if (data.roles) finalData.roles = data.roles.join(",");
|
||||||
|
if (data.nickname) finalData.nickname = data.nickname;
|
||||||
|
if (data.is_voice_muted) finalData.is_voice_muted = data.is_voice_muted ? 1 : 0;
|
||||||
|
|
||||||
|
const existing = await this.find(userId);
|
||||||
|
if (existing) {
|
||||||
|
await knex("persisted_data")
|
||||||
|
.where("guild_id", this.guildId)
|
||||||
|
.where("user_id", userId)
|
||||||
|
.update(finalData);
|
||||||
|
} else {
|
||||||
|
await knex("persisted_data").insert({
|
||||||
|
...finalData,
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async clear(userId: string) {
|
||||||
|
await knex("persisted_data")
|
||||||
|
.where("guild_id", this.guildId)
|
||||||
|
.where("user_id", userId)
|
||||||
|
.delete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ export enum LogType {
|
||||||
MEMBER_ROLE_REMOVE,
|
MEMBER_ROLE_REMOVE,
|
||||||
MEMBER_NICK_CHANGE,
|
MEMBER_NICK_CHANGE,
|
||||||
MEMBER_USERNAME_CHANGE,
|
MEMBER_USERNAME_CHANGE,
|
||||||
MEMBER_ROLES_RESTORE,
|
MEMBER_RESTORE,
|
||||||
|
|
||||||
CHANNEL_CREATE,
|
CHANNEL_CREATE,
|
||||||
CHANNEL_DELETE,
|
CHANNEL_DELETE,
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { LogsPlugin } from "./plugins/Logs";
|
||||||
import { PostPlugin } from "./plugins/Post";
|
import { PostPlugin } from "./plugins/Post";
|
||||||
import { ReactionRolesPlugin } from "./plugins/ReactionRoles";
|
import { ReactionRolesPlugin } from "./plugins/ReactionRoles";
|
||||||
import { CensorPlugin } from "./plugins/Censor";
|
import { CensorPlugin } from "./plugins/Censor";
|
||||||
|
import { PersistPlugin } from "./plugins/Persist";
|
||||||
import knex from "./knex";
|
import knex from "./knex";
|
||||||
|
|
||||||
// Run latest database migrations
|
// Run latest database migrations
|
||||||
|
@ -34,7 +35,8 @@ knex.migrate.latest().then(() => {
|
||||||
logs: LogsPlugin,
|
logs: LogsPlugin,
|
||||||
post: PostPlugin,
|
post: PostPlugin,
|
||||||
reaction_roles: ReactionRolesPlugin,
|
reaction_roles: ReactionRolesPlugin,
|
||||||
censor: CensorPlugin
|
censor: CensorPlugin,
|
||||||
|
persist: PersistPlugin
|
||||||
},
|
},
|
||||||
globalPlugins: {
|
globalPlugins: {
|
||||||
bot_control: BotControlPlugin
|
bot_control: BotControlPlugin
|
||||||
|
|
26
src/models/PersistedData.ts
Normal file
26
src/models/PersistedData.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import Model from "./Model";
|
||||||
|
|
||||||
|
export default class PersistedData extends Model {
|
||||||
|
private _roles;
|
||||||
|
private _isVoiceMuted;
|
||||||
|
|
||||||
|
public guild_id: string;
|
||||||
|
public user_id: string;
|
||||||
|
public nickname: string;
|
||||||
|
|
||||||
|
set roles(v) {
|
||||||
|
this._roles = v ? v.split(",") : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get roles() {
|
||||||
|
return this._roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
set is_voice_muted(v) {
|
||||||
|
this._isVoiceMuted = v === 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
get is_voice_muted() {
|
||||||
|
return this._isVoiceMuted;
|
||||||
|
}
|
||||||
|
}
|
|
@ -141,7 +141,7 @@ export class LogsPlugin extends Plugin {
|
||||||
if (member.nick !== oldMember.nick) {
|
if (member.nick !== oldMember.nick) {
|
||||||
this.serverLogs.log(LogType.MEMBER_NICK_CHANGE, {
|
this.serverLogs.log(LogType.MEMBER_NICK_CHANGE, {
|
||||||
member,
|
member,
|
||||||
oldNick: oldMember.nick,
|
oldNick: oldMember.nick || "<none>",
|
||||||
newNick: member.nick
|
newNick: member.nick
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
91
src/plugins/Persist.ts
Normal file
91
src/plugins/Persist.ts
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import { Plugin, decorators as d } from "knub";
|
||||||
|
import { GuildPersistedData, IPartialPersistData } from "../data/GuildPersistedData";
|
||||||
|
import intersection from "lodash.intersection";
|
||||||
|
import { Member, MemberOptions } from "eris";
|
||||||
|
import { GuildLogs } from "../data/GuildLogs";
|
||||||
|
import { LogType } from "../data/LogType";
|
||||||
|
import { stripObjectToScalars } from "../utils";
|
||||||
|
|
||||||
|
export class PersistPlugin extends Plugin {
|
||||||
|
protected persistedData: GuildPersistedData;
|
||||||
|
protected logs: GuildLogs;
|
||||||
|
|
||||||
|
getDefaultOptions() {
|
||||||
|
return {
|
||||||
|
config: {
|
||||||
|
persisted_roles: [],
|
||||||
|
persist_nicknames: false,
|
||||||
|
persist_voice_mutes: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.persistedData = new GuildPersistedData(this.guildId);
|
||||||
|
this.logs = new GuildLogs(this.guildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("guildMemberRemove")
|
||||||
|
onGuildMemberRemove(_, member: Member) {
|
||||||
|
let persist = false;
|
||||||
|
const persistData: IPartialPersistData = {};
|
||||||
|
|
||||||
|
const persistedRoles = this.configValue("persisted_roles");
|
||||||
|
if (persistedRoles.length) {
|
||||||
|
const rolesToPersist = intersection(persistedRoles, member.roles);
|
||||||
|
if (rolesToPersist.length) {
|
||||||
|
persist = true;
|
||||||
|
persistData.roles = rolesToPersist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.configValue("persist_nicknames") && member.nick) {
|
||||||
|
persist = true;
|
||||||
|
persistData.nickname = member.nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.configValue("persist_voice_mutes")) {
|
||||||
|
persist = true;
|
||||||
|
persistData.is_voice_muted = member.voiceState.mute;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (persist) {
|
||||||
|
this.persistedData.set(member.id, persistData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("guildMemberAdd")
|
||||||
|
async onGuildMemberAdd(_, member: Member) {
|
||||||
|
const persistedData = await this.persistedData.find(member.id);
|
||||||
|
if (!persistedData) return;
|
||||||
|
|
||||||
|
let restore = false;
|
||||||
|
const toRestore: MemberOptions = {};
|
||||||
|
|
||||||
|
const persistedRoles = this.configValue("persisted_roles");
|
||||||
|
if (persistedRoles.length) {
|
||||||
|
const rolesToRestore = intersection(persistedRoles, persistedData.roles);
|
||||||
|
if (rolesToRestore.length) {
|
||||||
|
restore = true;
|
||||||
|
toRestore.roles = rolesToRestore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.configValue("persist_nicknames") && persistedData.nickname) {
|
||||||
|
restore = true;
|
||||||
|
toRestore.nick = persistedData.nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.configValue("persist_voice_mutes") && persistedData.is_voice_muted) {
|
||||||
|
restore = true;
|
||||||
|
toRestore.mute = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restore) {
|
||||||
|
await member.edit(toRestore, "Restored upon rejoin");
|
||||||
|
this.logs.log(LogType.MEMBER_RESTORE, {
|
||||||
|
member: stripObjectToScalars(member, ["user"])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue