3
0
Fork 0
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:
Dragory 2018-07-30 23:35:44 +03:00
parent e7734c558c
commit ad6afdfac1
10 changed files with 199 additions and 4 deletions

View 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
View file

@ -2490,6 +2490,11 @@
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
"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": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",

View file

@ -35,6 +35,7 @@
"knub": "^9.4.13",
"lodash.at": "^4.6.0",
"lodash.difference": "^4.5.0",
"lodash.intersection": "^4.4.0",
"lodash.isequal": "^4.5.0",
"mariasql": "^0.2.6",
"moment-timezone": "^0.5.21",

View file

@ -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_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_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_DELETE": "🗑 Channel **#{channel.name}** was deleted",

View 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();
}
}

View file

@ -13,7 +13,7 @@ export enum LogType {
MEMBER_ROLE_REMOVE,
MEMBER_NICK_CHANGE,
MEMBER_USERNAME_CHANGE,
MEMBER_ROLES_RESTORE,
MEMBER_RESTORE,
CHANNEL_CREATE,
CHANNEL_DELETE,

View file

@ -20,6 +20,7 @@ import { LogsPlugin } from "./plugins/Logs";
import { PostPlugin } from "./plugins/Post";
import { ReactionRolesPlugin } from "./plugins/ReactionRoles";
import { CensorPlugin } from "./plugins/Censor";
import { PersistPlugin } from "./plugins/Persist";
import knex from "./knex";
// Run latest database migrations
@ -34,7 +35,8 @@ knex.migrate.latest().then(() => {
logs: LogsPlugin,
post: PostPlugin,
reaction_roles: ReactionRolesPlugin,
censor: CensorPlugin
censor: CensorPlugin,
persist: PersistPlugin
},
globalPlugins: {
bot_control: BotControlPlugin

View 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;
}
}

View file

@ -141,7 +141,7 @@ export class LogsPlugin extends Plugin {
if (member.nick !== oldMember.nick) {
this.serverLogs.log(LogType.MEMBER_NICK_CHANGE, {
member,
oldNick: oldMember.nick,
oldNick: oldMember.nick || "<none>",
newNick: member.nick
});
}

91
src/plugins/Persist.ts Normal file
View 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"])
});
}
}
}