discord-rebackup
Version:
An rewamped fork of the discord-backup module ! by the iHorizon Team
360 lines (359 loc) • 14.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setStorageFolder = exports.list = exports.remove = exports.load = exports.create = exports.fetch = void 0;
const discord_js_1 = require("discord.js");
const path_1 = require("path");
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const createMaster = require("./create");
const loadMaster = require("./load");
const utilMaster = require("./util");
const logger_1 = require("./logger");
let backups = process.cwd() + "/backups";
if (!(0, fs_1.existsSync)(backups)) {
(0, fs_1.mkdirSync)(backups);
}
/**
* Checks if a backup exists and returns its data
*/
const getBackupData = async (backupID) => {
return new Promise(async (resolve, reject) => {
const files = await (0, promises_1.readdir)(backups); // Read "backups" directory
// Try to get the json file
const file = files.filter((f) => f.split('.').pop() === 'json').find((f) => f === `${backupID}.json`);
if (file) {
// If the file exists
const backupData = require(`${backups}${path_1.sep}${file}`);
// Returns backup informations
resolve(backupData);
}
else {
// If no backup was found, return an error message
reject('function:getBackupData : No backup found');
}
});
};
/**
* Fetches a backup and returns the information about it
*/
const fetch = (backupID) => {
return new Promise(async (resolve, reject) => {
getBackupData(backupID)
.then((backupData) => {
const size = (0, fs_1.statSync)(`${backups}${path_1.sep}${backupID}.json`).size; // Gets the size of the file using fs
const backupInfos = {
data: backupData,
id: backupID,
size: Number((size / 1024).toFixed(2))
};
// Returns backup informations
resolve(backupInfos);
})
.catch(() => {
reject('function: fetch: No backup found');
});
});
};
exports.fetch = fetch;
/**
* Creates a new backup and saves it to the storage
*/
const create = async (guild, options = {
backupID: null,
maxMessagesPerChannel: 10,
jsonSave: true,
jsonBeautify: true,
doNotBackup: [],
backupMembers: false,
saveImages: '',
selfBot: false
}) => {
return new Promise(async (resolve, reject) => {
if (!options.selfBot && !guild.client.options.intents.has(discord_js_1.IntentsBitField.Flags.Guilds))
return reject('Guilds intent is required');
// Activer le mode selfbot si l'option est définie
if (options.selfBot) {
try {
const { enableSelfbotMode } = require('./util');
enableSelfbotMode();
}
catch (selfbotError) {
console.error(`Erreur lors de l'activation du mode selfbot: ${selfbotError}`);
// On continue même si le mode selfbot n'a pas pu être activé
}
}
// Initialisation des données de backup avec des valeurs par défaut
const backupData = {
name: 'Unknown Server',
verificationLevel: 0,
explicitContentFilter: 0,
defaultMessageNotifications: 0,
afk: null,
widget: {
enabled: false,
channel: null
},
channels: { categories: [], others: [] },
roles: [],
bans: [],
emojis: [],
members: [],
createdTimestamp: Date.now(),
guildID: '',
id: options.backupID ?? discord_js_1.SnowflakeUtil.generate().toString()
};
// Récupération des informations de base du serveur
try {
backupData.name = guild.name || 'Unknown Server';
backupData.verificationLevel = guild.verificationLevel;
backupData.explicitContentFilter = guild.explicitContentFilter;
backupData.defaultMessageNotifications = guild.defaultMessageNotifications;
backupData.guildID = guild.id;
// Récupération des informations AFK
if (guild.afkChannel) {
backupData.afk = {
name: guild.afkChannel.name,
timeout: guild.afkTimeout
};
}
// Récupération des informations du widget
try {
backupData.widget = {
enabled: guild.widgetEnabled || false,
channel: guild.widgetChannel ? guild.widgetChannel.name : null
};
}
catch (widgetError) {
console.error(`Erreur lors de la récupération des informations du widget: ${widgetError}`);
// On continue avec les valeurs par défaut
}
}
catch (basicInfoError) {
console.error(`Erreur lors de la récupération des informations de base du serveur: ${basicInfoError}`);
// On continue avec les valeurs par défaut
}
// Récupération des images du serveur
try {
if (guild.icon) {
backupData.iconURL = guild.icon;
if (options && options.saveImages && options.saveImages === 'base64') {
try {
const iconResponse = await (0, exports.fetch)(guild.icon);
const iconBuffer = await iconResponse.buffer();
backupData.iconBase64 = iconBuffer.toString('base64');
}
catch (iconError) {
console.error(`Erreur lors de la récupération de l'icône du serveur: ${iconError}`);
// On continue sans l'icône en base64
}
}
}
if (guild.splash) {
backupData.splashURL = guild.splash;
if (options && options.saveImages && options.saveImages === 'base64') {
try {
const splashResponse = await (0, exports.fetch)(guild.splash);
const splashBuffer = await splashResponse.buffer();
backupData.splashBase64 = splashBuffer.toString('base64');
}
catch (splashError) {
console.error(`Erreur lors de la récupération du splash du serveur: ${splashError}`);
// On continue sans le splash en base64
}
}
}
if (guild.banner) {
backupData.bannerURL = guild.banner;
if (options && options.saveImages && options.saveImages === 'base64') {
try {
const bannerResponse = await (0, exports.fetch)(guild.banner);
const bannerBuffer = await bannerResponse.buffer();
backupData.bannerBase64 = bannerBuffer.toString('base64');
}
catch (bannerError) {
console.error(`Erreur lors de la récupération de la bannière du serveur: ${bannerError}`);
// On continue sans la bannière en base64
}
}
}
}
catch (imageError) {
console.error(`Erreur lors de la récupération des images du serveur: ${imageError}`);
// On continue sans les images
}
// Backup des membres si demandé
if (options && options.backupMembers) {
try {
backupData.members = await createMaster.getMembers(guild);
}
catch (membersError) {
console.error(`Erreur lors de la récupération des membres: ${membersError}`);
// On continue avec un tableau vide
}
}
// Backup des bans si non exclu
if (!options || !(options.doNotBackup || []).includes('bans')) {
try {
backupData.bans = await createMaster.getBans(guild);
}
catch (bansError) {
console.error(`Erreur lors de la récupération des bans: ${bansError}`);
// On continue avec un tableau vide
}
}
// Backup des rôles si non exclu
if (!options || !(options.doNotBackup || []).includes('roles')) {
try {
backupData.roles = await createMaster.getRoles(guild);
}
catch (rolesError) {
console.error(`Erreur lors de la récupération des rôles: ${rolesError}`);
// On continue avec un tableau vide
}
}
// Backup des emojis si non exclu
if (!options || !(options.doNotBackup || []).includes('emojis')) {
try {
backupData.emojis = await createMaster.getEmojis(guild, options);
}
catch (emojisError) {
console.error(`Erreur lors de la récupération des emojis: ${emojisError}`);
// On continue avec un tableau vide
}
}
// Backup des canaux si non exclu
if (!options || !(options.doNotBackup || []).includes('channels')) {
try {
backupData.channels = await createMaster.getChannels(guild, options);
}
catch (channelsError) {
console.error(`Erreur lors de la récupération des canaux: ${channelsError}`);
// On continue avec des tableaux vides
}
}
// Sauvegarde du backup en JSON si demandé
if (!options || options.jsonSave === undefined || options.jsonSave) {
try {
// Convert Object to JSON
const backupJSON = options.jsonBeautify
? JSON.stringify(backupData, null, 4)
: JSON.stringify(backupData);
// Save the backup
await (0, promises_1.writeFile)(`${backups}${path_1.sep}${backupData.id}.json`, backupJSON, 'utf-8');
}
catch (saveError) {
console.error(`Erreur lors de la sauvegarde du backup: ${saveError}`);
// On continue et on retourne quand même les données
}
}
// Retourne les données même si certaines parties ont échoué
resolve(backupData);
});
};
exports.create = create;
/**
* Loads a backup for a guild
*/
const load = async (backup, guild, options = {
clearGuildBeforeRestore: true,
maxMessagesPerChannel: 100, // Augmentation de la valeur par défaut à 100 messages
devMode: false // Mode développeur désactivé par défaut
}) => {
return new Promise(async (resolve, reject) => {
// Activer le mode développeur si l'option est définie
if (options.devMode) {
(0, logger_1.enableDevMode)();
}
else {
(0, logger_1.disableDevMode)();
}
// Activer le mode selfbot si l'option est définie
if (options.selfBot) {
const { enableSelfbotMode } = require('./util');
enableSelfbotMode();
(0, logger_1.info)('Mode selfbot activé');
}
if (!guild) {
return reject('Invalid guild');
}
try {
const backupData = typeof backup === 'string' ? await getBackupData(backup) : backup;
try {
if (options.clearGuildBeforeRestore === undefined || options.clearGuildBeforeRestore) {
// Clear the guild
await utilMaster.clearGuild(guild);
}
await Promise.all([
// Restore guild configuration
loadMaster.loadConfig(guild, backupData),
// Restore guild roles
loadMaster.loadRoles(guild, backupData),
// Restore guild channels
loadMaster.loadChannels(guild, backupData, options),
// Restore afk channel and timeout
loadMaster.loadAFK(guild, backupData),
// Restore guild emojis
loadMaster.loadEmojis(guild, backupData),
// Restore guild bans
loadMaster.loadBans(guild, backupData),
// Restore embed channel
loadMaster.loadEmbedChannel(guild, backupData)
]);
}
catch (e) {
return reject(e);
}
// Then return the backup data
return resolve(backupData);
}
catch (e) {
return reject('function:load:No backup found');
}
});
};
exports.load = load;
/**
* Removes a backup
*/
const remove = async (backupID) => {
return new Promise((resolve, reject) => {
try {
require(`${backups}${path_1.sep}${backupID}.json`);
(0, fs_1.unlinkSync)(`${backups}${path_1.sep}${backupID}.json`);
resolve();
}
catch (error) {
reject('Backup not found');
}
});
};
exports.remove = remove;
/**
* Returns the list of all backup
*/
const list = async () => {
const files = await (0, promises_1.readdir)(backups); // Read "backups" directory
return files.map((f) => f.split('.')[0]);
};
exports.list = list;
/**
* Change the storage path
*/
const setStorageFolder = (path) => {
if (path.endsWith(path_1.sep)) {
path = path.substr(0, path.length - 1);
}
backups = path;
if (!(0, fs_1.existsSync)(backups)) {
(0, fs_1.mkdirSync)(backups);
}
};
exports.setStorageFolder = setStorageFolder;
exports.default = {
create: exports.create,
fetch: exports.fetch,
list: exports.list,
load: exports.load,
remove: exports.remove,
setStorageFolder: exports.setStorageFolder
};