Adds ability to fix duplicates

Can check for things like Name.plugin(1).js and auto-rename the file is possible.
This commit is contained in:
Zack Rauen 2020-10-03 20:50:31 -04:00
parent 30c4653b20
commit 30ecf92a8d
5 changed files with 70 additions and 12 deletions

View File

@ -33,6 +33,7 @@ export default class AddonManager {
get name() {return "";}
get moduleExtension() {return "";}
get extension() {return "";}
get duplicatePattern() {return /./;}
get addonFolder() {return "";}
get language() {return "";}
get prefix() {return "addon";}
@ -80,10 +81,30 @@ export default class AddonManager {
if (this.watcher) return Logger.error(this.name, `Already watching ${this.prefix} addons.`);
Logger.log(this.name, `Starting to watch ${this.prefix} addons.`);
this.watcher = fs.watch(this.addonFolder, {persistent: false}, async (eventType, filename) => {
if (!eventType || !filename || !filename.endsWith(this.extension)) return;
if (!eventType || !filename) return;
const absolutePath = path.resolve(this.addonFolder, filename);
if (!filename.endsWith(this.extension)) {
// Lets check to see if this filename has the duplicated file pattern `something(1).ext`
const match = filename.match(this.duplicatePattern);
if (!match) continue;
const ext = match[0];
const truncated = filename.replace(ext, "");
const newFilename = truncated + this.extension;
// If this file already exists, give a warning and move on.
if (fs.existsSync(newFile)) {
Logger.warn("AddonManager", `Duplicate files found: ${filename} and ${newFilename}`);
continue;
}
// Rename the file and let it go on
fs.renameSync(absolutePath, path.resolve(this.addonFolder, newFilename));
}
await new Promise(r => setTimeout(r, 100));
try {
const stats = fs.statSync(path.resolve(this.addonFolder, filename));
const stats = fs.statSync(absolutePath);
if (!stats.isFile()) return;
if (!stats || !stats.mtime || !stats.mtime.getTime()) return;
if (typeof(stats.mtime.getTime()) !== "number") return;
@ -266,13 +287,31 @@ export default class AddonManager {
const files = fs.readdirSync(this.addonFolder);
for (const filename of files) {
if (!fs.statSync(path.resolve(this.addonFolder, filename)).isFile() || !filename.endsWith(this.extension)) continue;
const absolutePath = path.resolve(this.addonFolder, filename);
if (!fs.statSync(absolutePath).isFile()) continue;
if (!filename.endsWith(this.extension)) {
// Lets check to see if this filename has the duplicated file pattern `something(1).ext`
const match = filename.match(this.duplicatePattern);
if (!match) continue;
const ext = match[0];
const truncated = filename.replace(ext, "");
const newFilename = truncated + this.extension;
// If this file already exists, give a warning and move on.
if (fs.existsSync(newFile)) {
Logger.warn("AddonManager", `Duplicate files found: ${filename} and ${newFilename}`);
continue;
}
// Rename the file and let it go on
fs.renameSync(absolutePath, path.resolve(this.addonFolder, newFilename));
}
const addon = this.loadAddon(filename, false);
if (addon instanceof AddonError) errors.push(addon);
}
this.saveState();
if (Settings.get(this.collection, this.category, this.id)) this.watchAddons();
//if (Settings.get(this.collection, this.category, this.id)) this.watchAddons();
return errors;
}

View File

@ -46,9 +46,9 @@ export default class Patcher {
}
static resolveModule(module) {
if (module instanceof Function || (module instanceof Object && !(module instanceof Array))) return module;
if (!module || typeof(module) === "function" || (typeof(module) === "object" && !Array.isArray(module))) return module;
if (typeof module === "string") return DiscordModules[module];
if (module instanceof Array) return WebpackModules.findByUniqueProperties(module);
if (Array.isArray(module)) return WebpackModules.findByUniqueProperties(module);
return null;
}
@ -112,6 +112,7 @@ export default class Patcher {
children: []
};
patch.proxyFunction = module[functionName] = this.makeOverride(patch);
Object.assign(module[functionName], patch.originalFunction);
module[functionName].__originalFunction = patch.originalFunction;
module[functionName].toString = () => patch.originalFunction.toString();
this.patches.push(patch);
@ -217,6 +218,7 @@ export default class Patcher {
patch.children.splice(patch.children.findIndex(cpatch => cpatch.id === child.id && cpatch.type === type), 1);
if (patch.children.length <= 0) {
const patchNum = this.patches.findIndex(p => p.module == module && p.functionName == functionName);
if (patchNum < 0) return;
this.patches[patchNum].revert();
this.patches.splice(patchNum, 1);
}

View File

@ -16,6 +16,7 @@ export default new class PluginManager extends AddonManager {
get name() {return "PluginManager";}
get moduleExtension() {return ".js";}
get extension() {return ".plugin.js";}
get duplicatePattern() {return /\.plugin\([0-9]+\)\.js/}
get addonFolder() {return path.resolve(Config.dataPath, "plugins");}
get prefix() {return "plugin";}
get language() {return "javascript";}

View File

@ -14,6 +14,7 @@ export default new class ThemeManager extends AddonManager {
get name() {return "ThemeManager";}
get moduleExtension() {return ".css";}
get extension() {return ".theme.css";}
get duplicatePattern() {return /\.theme\([0-9]+\)\.css/}
get addonFolder() {return path.resolve(Config.dataPath, "themes");}
get prefix() {return "theme";}
get language() {return "css";}

View File

@ -25,7 +25,10 @@ export class Filters {
return module => {
const component = filter(module);
if (!component) return false;
return props.every(property => component[property] !== undefined);
for (let p = 0; p < props.length; p++) {
if (component[props[p]] === undefined) return false;
}
return true;
};
}
@ -40,7 +43,10 @@ export class Filters {
const component = filter(module);
if (!component) return false;
if (!component.prototype) return false;
return fields.every(field => component.prototype[field] !== undefined);
for (let f = 0; f < fields.length; f++) {
if (component.prototype[fields[f]] === undefined) return false;
}
return true;
};
}
@ -54,7 +60,10 @@ export class Filters {
return module => {
const method = filter(module);
if (!method) return false;
return method.toString([]).search(search) !== -1;
let methodString = "";
try {methodString = method.toString([]);}
catch (err) {methodString = method.toString();}
return methodString.search(search) !== -1;
};
}
@ -65,7 +74,9 @@ export class Filters {
*/
static byString(...strings) {
return module => {
const moduleString = module.toString([]);
let moduleString = "";
try {moduleString = module.toString([]);}
catch (err) {moduleString = module.toString();}
for (const s of strings) {
if (!moduleString.includes(s)) return false;
}
@ -130,6 +141,10 @@ export default class WebpackModules {
* @return {Any}
*/
static getModule(filter, first = true) {
const wrappedFilter = (m) => {
try {return filter(m);}
catch (err) {return false;}
};
const modules = this.getAllModules();
const rm = [];
for (const index in modules) {
@ -139,8 +154,8 @@ export default class WebpackModules {
let foundModule = null;
if (!exports) continue;
if (exports.__esModule && exports.default && filter(exports.default)) foundModule = exports.default;
if (filter(exports)) foundModule = exports;
if (exports.__esModule && exports.default && wrappedFilter(exports.default)) foundModule = exports.default;
if (wrappedFilter(exports)) foundModule = exports;
if (!foundModule) continue;
if (first) return protect(foundModule);
rm.push(protect(foundModule));