Release: Release v1.0.0

pull/8/head
Ducko 4 years ago
parent f624d47982
commit 7ca2a6174a

@ -1,5 +1,16 @@
# GooseMod Changelog
## Release v1.0.0
- ### Features
- #### Injector
- Added separator between other GooseMod options and reinstall and uninstall
- Added Module store
- Added normal (brand) button and text setting option
- Now reopens settings when doing some things instead of just closing
## Beta v0.9.2
- ### Features

@ -1,9 +1,135 @@
(async function () {
this.version = '0.9.2';
this.version = '1.0.0';
this.embedded = false;
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const reopenSettings = async () => {
this.settings.close();
await sleep(50);
this.settings.open();
await sleep(50);
[...settingsSidebarGooseModContainer.children].find((x) => x.textContent === 'Module Store').click();
};
this.cspBypasser = {
frame: document.createElement('iframe'),
init: async () => {
this.cspBypasser.frame.src = 'https://canary.discordapp.com/api/404';
document.body.appendChild(this.cspBypasser.frame);
await sleep(1000);
let script = document.createElement('script');
script.type = 'text/javascript';
let code = `
window.addEventListener('message', async (e) => {
const {url, type} = e.data;
const req = await fetch(\`https://cors-anywhere.herokuapp.com/\${url}\`, {
cache: 'no-store'
});
e.source.postMessage(type === 'json' ? await req.json() : await req.text());
}, false);`;
script.appendChild(document.createTextNode(code));
this.cspBypasser.frame.contentDocument.head.appendChild(script);
},
json: (url) => {
return new Promise((res) => {
this.cspBypasser.frame.contentWindow.postMessage({url, type: 'json'});
window.addEventListener('message', async (e) => {
res(e.data);
}, false);
});
},
text: (url) => {
return new Promise((res) => {
this.cspBypasser.frame.contentWindow.postMessage({url, type: 'text'});
window.addEventListener('message', async (e) => {
res(e.data);
}, false);
});
},
};
await this.cspBypasser.init();
this.moduleStoreAPI = {
modules: [],
apiBaseURL: 'https://gitdab.com/duck/GooseMod-JSONAPI/raw/branch/master/api',
updateModules: async () => {
this.moduleStoreAPI.modules = await this.cspBypasser.json(`${this.moduleStoreAPI.apiBaseURL}/modules.json`);
},
importModule: async (moduleName) => {
const moduleInfo = this.moduleStoreAPI.modules.find((x) => x.filename === moduleName);
const jsCode = await this.cspBypasser.text(moduleInfo.codeURL);
await this.importModule({
filename: `${moduleInfo.filename}.js`,
data: jsCode
});
if (this.modules[moduleInfo.filename].onLoadingFinished !== undefined) {
await this.modules[moduleInfo.filename].onLoadingFinished();
}
let settingItem = this.settings.items.find((x) => x[1] === 'Module Store');
let item = settingItem[2].find((x) => x.subtext === moduleInfo.description);
item.type = 'text-and-danger-button';
item.buttonText = 'Reimport';
reopenSettings();
},
moduleRemoved: async (m) => {
let item = settingItem[2].find((x) => x.subtext === m.description);
item.type = 'text-and-button';
item.buttonText = 'Import';
},
updateStoreSetting: () => {
let item = this.settings.items.find((x) => x[1] === 'Module Store');
item[2] = item[2].slice(0, 3);
for (let m of this.moduleStoreAPI.modules) {
item[2].push({
type: 'text-and-button',
text: `${m.name} <span class="description-3_Ncsb">by</span> ${m.author} <span class="description-3_Ncsb">(v${m.version})</span>`,
buttonText: 'Import',
subtext: m.description,
onclick: () => {
this.moduleStoreAPI.importModule(m.filename);
this.settings.close();
}
});
}
}
};
await this.moduleStoreAPI.updateModules();
this.logger = {
regionColors: {
'import': 'rgb(100, 0, 0)'
@ -339,6 +465,61 @@
break;
case 'text-and-button':
el = document.createElement('div');
el.classList.add('marginBottom20-32qID7');
let txtEl3 = document.createElement('span');
txtEl3.classList.add('titleDefault-a8-ZSr', 'title-31JmR4');
txtEl3.style.float = 'left';
txtEl3.innerHTML = e.text;
let buttonEl2 = document.createElement('div');
buttonEl2.classList.add('button-38aScr', 'lookFilled-1Gx00P', 'colorBrand-3pXr91', 'sizeSmall-2cSMqn', 'grow-q77ONN');
buttonEl2.onclick = () => {
e.onclick(el);
};
buttonEl2.style.cursor = 'pointer';
buttonEl2.style.float = 'right';
let contentsEl3 = document.createElement('div');
contentsEl3.classList.add('contents-18-Yxp');
contentsEl3.textContent = e.buttonText;
buttonEl2.appendChild(contentsEl3);
el.appendChild(txtEl3);
el.appendChild(buttonEl2);
if (e.subtext) {
let subtextEl2 = document.createElement('div');
subtextEl2.classList.add('colorStandard-2KCXvj', 'size14-e6ZScH', 'description-3_Ncsb', 'formText-3fs7AJ', 'note-1V3kyJ', 'modeDefault-3a2Ph1');
subtextEl2.textContent = e.subtext;
subtextEl2.style.clear = 'both';
el.appendChild(subtextEl2);
}
let dividerEl3 = document.createElement('div');
dividerEl3.classList.add('divider-3573oO', 'dividerDefault-3rvLe-');
dividerEl3.style.marginTop = e.subtext ? '20px' : '45px';
el.appendChild(dividerEl3);
break;
case 'button':
el = document.createElement('button');
@ -491,62 +672,69 @@
return String.fromCharCode.apply(null, new Uint8Array(buf));
};
this.importModules = async (files) => {
this.logger.debug('import', 'Looping through files');
this.importModule = async (f) => {
let field = f.filename.split('.').slice(0, -1).join('.'); // Get name of module via filename (taking away the file extension)
for (let f of files) {
let field = f.filename.split('.').slice(0, -1).join('.'); // Get name of module via filename (taking away the file extension)
this.logger.debug('import', `Importing module: "${field}"`);
this.logger.debug('import', `Importing module: "${field}"`);
let settingItem = this.settings.items.find((x) => x[1] === 'Manage Modules');
let settingItem = this.settings.items.find((x) => x[1] === 'Manage Modules');
if (this.modules[field] !== undefined) {
this.logger.debug(`import.load.module.${field}`, 'Module already imported, removing then installing new version');
if (this.modules[field] !== undefined) {
this.logger.debug(`import.load.module.${field}`, 'Module already imported, removing then installing new version');
await this.modules[field].remove();
await this.modules[field].remove();
settingItem[2].splice(settingItem[2].indexOf(settingItem[2].find((x) => x.text === `${this.modules[field].name} (${this.modules[field].version})`)), 1);
}
settingItem[2].splice(settingItem[2].indexOf(settingItem[2].find((x) => x.text === `${this.modules[field].name} (${this.modules[field].version})`)), 1);
}
if (typeof f.data === 'object') { // ArrayBuffer (UTF-8) -> String
f.data = ab2str(f.data);
}
if (typeof f.data === 'object') { // ArrayBuffer (UTF-8) -> String
f.data = ab2str(f.data);
}
this.modules[field] = eval(f.data); // Set this.modules.<module_name> to the return value of the module (an object containing handlers)
this.modules[field] = eval(f.data); // Set this.modules.<module_name> to the return value of the module (an object containing handlers)
this.logger.debug(`import.load.module.${field}`, `Evaled module JS`);
this.logger.debug(`import.load.module.${field}`, `Evaled module JS`);
this.bindHandlers(this.modules[field]); // Bind all handlers to module parent / returned object from module code
this.bindHandlers(this.modules[field]); // Bind all handlers to module parent / returned object from module code
this.logger.debug(`import.load.module.${field}`, `Binded handlers`);
this.logger.debug(`import.load.module.${field}`, `Binded handlers`);
await this.modules[field].onImport(); // Run the module's onImport handler
await this.modules[field].onImport(); // Run the module's onImport handler
this.logger.debug(`import.load.module.${field}`, `Ran onImport()`);
this.logger.debug(`import.load.module.${field}`, `Ran onImport()`);
let toggleObj = {
type: 'text-and-danger-button',
text: `${this.modules[field].name} <span class="description-3_Ncsb">by</span> ${this.modules[field].author} <span class="description-3_Ncsb">(v${this.modules[field].version})</span>`,
buttonText: 'Remove',
subtext: this.modules[field].description,
onclick: (el) => {
this.modules[field].remove();
settingItem[2].splice(settingItem[2].indexOf(toggleObj), 1);
let toggleObj = {
type: 'text-and-danger-button',
text: `${this.modules[field].name} <span class="description-3_Ncsb">by</span> ${this.modules[field].author} <span class="description-3_Ncsb">(v${this.modules[field].version})</span>`,
buttonText: 'Remove',
subtext: this.modules[field].description,
onclick: (el) => {
this.modules[field].remove();
let settingEl = [...settingsSidebarGooseModContainer.children].find((x) => x.textContent === this.modules[field].name);
settingItem[2].splice(settingItem[2].indexOf(toggleObj), 1);
let settingEl = [...settingsSidebarGooseModContainer.children].find((x) => x.textContent === this.modules[field].name);
if (settingEl !== undefined) settingEl.remove();
if (settingEl !== undefined) settingEl.remove();
el.remove();
el.remove();
delete this.modules[field];
}
};
delete this.modules[field];
this.moduleStoreAPI.moduleRemoved(this.mdoules[field]);
}
};
settingItem[2].push(toggleObj);
settingItem[2].push(toggleObj);
this.logger.debug(`import.load.module.${field}`, `Added to Modules setting page`);
this.logger.debug(`import.load.module.${field}`, `Added to Modules setting page`);
};
this.importModules = async (files) => {
this.logger.debug('import', 'Looping through files');
for (let f of files) {
this.importModule(f);
}
this.logger.debug('import', 'Imported all files');
@ -600,7 +788,7 @@
this.settings.createItem('Manage Modules', ['',
{
type: 'button',
text: 'Import Modules',
text: 'Import Local Modules',
onclick: async () => {
let files = await this.importModulesFull();
@ -622,6 +810,27 @@
}
]);
this.settings.createItem('Module Store', ['',
{
type: 'button',
text: 'Update Index',
onclick: async () => {
await this.moduleStoreAPI.updateModules();
await this.moduleStoreAPI.updateStoreSetting();
reopenSettings();
},
},
{
type: 'header',
text: 'Available Modules'
}
]);
this.settings.createSeparator();
this.settings.createItem('Uninstall', [""], async () => {
if (await this.confirmDialog('Uninstall', 'Uninstall GooseMod', 'Are you sure you want to uninstall GooseMod? This is a quick uninstall, it may leave some code behind but there should be no remaining noticable changes.')) {
this.settings.close();
@ -644,20 +853,6 @@
this.settings.createHeading('GooseMod Modules');
if (this.embedded === true) {
await this.importModules([
//<TEMPLATE_REPLACE>
]);
for (let p in this.modules) {
if (this.modules.hasOwnProperty(p) && this.modules[p].onLoadingFinished !== undefined) {
await this.modules[p].onLoadingFinished();
this.logger.debug(`import.module.runOnLoadingFinishedHandler.${p}`, 'Ran onLoadingFinished()');
}
}
}
this.remove = () => {
this.removed = true;
@ -668,13 +863,7 @@
}
};
this.settings.close();
await sleep(20);
this.settings.open();
await sleep(20);
await this.moduleStoreAPI.updateStoreSetting();
[...settingsSidebarGooseModContainer.children].find((x) => x.textContent === 'Manage Modules').click();
reopenSettings();
}).bind({})();

@ -7,7 +7,11 @@ let blocking = {
'sentry': true
};
let _XMLHttpRequest = XMLHttpRequest;
if (typeof window === 'undefined') { // JSON API generator evals
global.window = {XMLHttpRequest: {}};
}
let _XMLHttpRequest = window.XMLHttpRequest;
let obj = {
onImport: async function() {

Loading…
Cancel
Save