diff --git a/lib/BetterDiscord.js b/lib/BetterDiscord.js
index 2d84b46f..10a3cc86 100644
--- a/lib/BetterDiscord.js
+++ b/lib/BetterDiscord.js
@@ -1,315 +1,153 @@
/* BetterDiscordApp Entry
- * Version: 2.2
+ * Version: 3.0
* Author: Jiiks | http://jiiks.net
* Date: 27/08/2015 - 15:51
- * Last Update: 30/03/2016
+ * Last Update: 06/05/2016
* https://github.com/Jiiks/BetterDiscordApp
*/
-//Imports
+'use strict';
+
var _fs = require("fs");
var _config = require("./config.json");
var _utils = require("./utils");
-var _ipc = require('ipc');
+var _utils2;
+var _bdIpc = require('electron').ipcMain;
+var _error = false;
-var _repo = "Jiiks";
+var _eol = require('os').EOL;
-//Beta flag
-var _beta = false;
-//Local flag
-var _local = false;
-var _localServer = "http://localhost";
-
-//Variables
-var _version;
var _mainWindow;
-var _updater;
-var _hash;
-var _userDefault = { "cache": null };
-var _userConfig = _userDefault;
-var _cacheExpired = true;
-var _cacheDays = 0;
+var _cfg = {};
+var _extData = {};
-var _dataPath;
-
-//IDE
-/*_config = {
- "Core": {
- "Version": "0.2.7"
- }
-};*/
-
-//noinspection JSUnresolvedVariable;
-var _os = process.platform;
-var _userFile;
-
-var _this;
function BetterDiscord(mainWindow) {
- _this = this;
_mainWindow = mainWindow;
- _version = _config.Core.Version;
- _utils = new _utils.Utils(mainWindow);
-
- this.createAndCheckData(this.init);
+ _cfg = _config.cfg;
+ _cfg.version = _config.Core.Version;
+ _cfg.os = process.platform;
+ _utils2 = new _utils.Utils(mainWindow);
+ hook();
+ createAndCheckData();
}
-BetterDiscord.prototype.initLoaders = function(){
- var os = process.platform;
- var _dataPath = os == "win32" ? process.env.APPDATA : os == 'darwin' ? process.env.HOME + '/Library/Preferences' : '/var/local';
- _dataPath += "/BetterDiscord/";
+function createAndCheckData() {
+ getUtils().log("Checking data/cache");
- if (!_fs.existsSync(_dataPath)) {
- _this.getUtils().log('BetterDiscord: Creating BD Dir');
- _fs.mkdirSync(_dataPath);
- }
-
- if (!_fs.existsSync(_dataPath + "plugins/")) {
- _this.getUtils().log('BetterDiscord: Creating Plugins Dir');
- _fs.mkdirSync(_dataPath + "plugins/");
- }
-
- if (!_fs.existsSync(_dataPath + "themes/")) {
- _this.getUtils().log('BetterDiscord: Creating Themes Dir');
- _fs.mkdirSync(_dataPath + "themes/");
- }
- _mainWindow.webContents.executeJavaScript('var themesupport2 = true');
-
- _fs.readdir(_dataPath + "plugins/", function(err, files) {
- if (err) {
- _this.getUtils().log(err);
- return;
- }
- _mainWindow.webContents.executeJavaScript('var bdplugins = {};');
- files.forEach(function(fileName) {
- var plugin = _fs.readFileSync(_dataPath + "plugins/" + fileName, 'utf8');
- var meta = plugin.split('\n')[0];
- if (meta.indexOf('META') < 0) {
- _this.getUtils().log('BetterDiscord: ERROR[Plugin META not found in file: ' + fileName + ']');
- return;
- }
- var pluginVar = meta.substring(meta.lastIndexOf('//META') + 6, meta.lastIndexOf('*//'));
- var parse = JSON.parse(pluginVar);
- var pluginName = parse['name'];
- _this.getUtils().log('BetterDiscord: Loading Plugin: ' + pluginName);
- _mainWindow.webContents.executeJavaScript(plugin);
- _mainWindow.webContents.executeJavaScript('(function() { var plugin = new ' + pluginName + '(); bdplugins[plugin.getName()] = { "plugin": plugin, "enabled": false } })();')
- });
- });
-
- _fs.readdir(_dataPath + 'themes/', function(err, files) {
- if (err) {
- _this.getUtils().log(err);
- return;
- }
- _mainWindow.webContents.executeJavaScript('var bdthemes = {};');
- files.forEach(function(fileName) {
- var theme = _fs.readFileSync(_dataPath + 'themes/' + fileName, 'utf8');
- var split = theme.split('\n');
- var meta = split[0];
- if (meta.indexOf('META') < 0) {
- _this.getUtils().log('BetterDiscord: ERROR[Theme META not found in file: ' + fileName + ']');
- return;
- }
- var themeVar = meta.substring(meta.lastIndexOf('//META') + 6, meta.lastIndexOf('*//'));
- var parse = JSON.parse(themeVar);
- var themeName = parse['name'];
- var themeAuthor = parse['author'];
- var themeDescription = parse['description'];
- var themeVersion = parse['version'];
- _this.getUtils().log('BetterDiscord: Loading Theme: ' + themeName);
- split.splice(0, 1);
- theme = split.join('\n');
- theme = theme.replace(/(\r\n|\n|\r)/gm, '');
- _mainWindow.webContents.executeJavaScript('(function() { bdthemes["' + themeName + '"] = { "enabled": false, "name": "' + themeName + '", "css": "' + escape(theme) + '", "description": "' + themeDescription + '", "author":"' + themeAuthor + '", "version":"' + themeVersion + '" } })();');
- });
- });
-};
-
-BetterDiscord.prototype.getUtils = function() {
- return _utils;
-};
-
-BetterDiscord.prototype.createAndCheckData = function(callback) {
-
- this.getUtils().log("Checking Cache");
-
- //New data path
- //noinspection JSUnresolvedVariable
- _dataPath = _os == "win32" ? process.env.APPDATA : _os == 'darwin' ? process.env.HOME + '/Library/Preferences' : '/var/local';
- _dataPath += "/BetterDiscord";
- _userFile = _dataPath + "/user.json";
+ _cfg.dataPath = (_cfg.os == 'win32' ? process.env.APPDATA : _cfg.os == 'darwin' ? process.env.HOME + '/Library/Preferences' : '/var/local') + '/BetterDiscord/';
+ _cfg.userFile = _cfg.dataPath + 'user.json';
try {
- //Create data path folder if it doesn't exist
- if (!_fs.existsSync(_dataPath)) {
- this.getUtils().log("Creating Data Folder @" + _dataPath);
- _fs.mkdirSync(_dataPath);
+ getUtils().mkdirSync(_cfg.dataPath);
+
+ if(_fs.existsSync(_cfg.userFile)) {
+ _cfg.userCfg = JSON.parse(_fs.readFileSync(_cfg.userFile));
}
- //Read user config if it exists
- if(_fs.existsSync(_userFile)) {
- _userConfig = JSON.parse(_fs.readFileSync(_userFile));
- }
-
- //Userfile doesn't exist
- if(_userConfig.cache == null) {
- _userConfig.cache = new Date();
+ if(_cfg.userCfg.cache == null) {
+ _cfg.userCfg.cache = new Date();
} else {
var currentDate = new Date();
- var cacheDate = new Date(_userConfig.cache);
+ var cacheDate = new Date(_cfg.userCfg.cache);
//Check if cache is expired
- if(Math.abs(currentDate.getDate() - cacheDate.getDate()) > _cacheDays) {
- _userConfig.cache = currentDate;
+ if(Math.abs(currentDate.getDate() - cacheDate.getDate()) > _cfg.cache.days) {
+ _cfg.userCfg.cache = currentDate;
} else {
- _cacheExpired = false;
+ _cfg.cache.expired = false;
}
}
//Write new cache date if expired
- if(_cacheExpired) {
- this.getUtils().log("Cache Expired or NULL");
- _fs.writeFileSync(_userFile, JSON.stringify(_userConfig));
+ if(_cfg.cache.expired) {
+ getUtils().log("Cache expired or null");
+ _fs.writeFileSync(_cfg.userFile, JSON.stringify(_cfg.userCfg));
}
- callback();
- }catch(err) {
- //Exit BD
+ init();
+ } catch(err) {
+ getUtils().err(err);
+ exit(err.message);
}
-};
+}
-BetterDiscord.prototype.init = function() {
- var self = this;
+function init() {
+ if(_cfg.branch == null) {
+ _cfg.branch = _cfg.beta ? "beta" : "master";
+ }
- this.getUtils().log("Initializing");
+ if(_cfg.repo == null) {
+ _cfg.repo = "Jiiks";
+ }
- this.getUtils().log("Getting latest hash");
-
- var branch = _beta ? "beta" : "master";
-
- this.getUtils().log("Using repo: " + _repo + " and branch: " + branch);
-
- //Get the latest commit hash
- this.getUtils().download("api.github.com", "/repos/" + _repo + "/BetterDiscordApp/commits/" + branch, function(data) {
-
- try {
- _hash = JSON.parse(data).sha;
- self.getUtils().execJs("var _hash = " + _hash + ";");
- }catch(err) {
- self.quit("Failed to load hash");
- return;
- }
-
- if(typeof(_hash) == "undefined") {
- self.quit("Failed to load hash");
- return;
- }
-
- self.getUtils().log("Hash: "+ _hash);
-
- //Download latest updater
- self.getUtils().download("raw.githubusercontent.com", "/" + _repo + "/BetterDiscordApp/" + _hash + "/data/updater.json", function(data) {
-
- try {
- _updater = JSON.parse(data);
- }catch(err) {
- self.quit("Failed to load updater data");
- return;
- }
-
- if(typeof(_updater) == "undefined") {
- self.quit("Failed to load updater data");
- return;
- }
-
- self.getUtils().log("Latest Versions: " + _updater.LatestVersion);
- self.getUtils().log("Using CDN: " + _updater.CDN);
- self.getUtils().log("Starting up");
- self.updateData();
- self.start();
- });
+ getUtils().log("Using repository: " + _cfg.repo + " and branch: " + _cfg.branch);
+ getUtils().log("Getting latest hash");
+ getUtils().attempt(getHash, 3, 0, "Failed to load hash", initUpdater, function() {
+ exit("Failed to load hash after 3 attempts");
});
-};
+}
-BetterDiscord.prototype.start = function() {
- _this.getUtils().log("Hooking dom-ready");
- var webContents = _this.getUtils().getWebContents();
- webContents.on('dom-ready', function() { _this.domReady(); });
- webContents.on("did-finish-loading", function() { if(!_domHooked) { _this.getUtils().log("Failsafe"); _this.domReady(); } });
-};
-
-BetterDiscord.prototype.quit = function(reason) {
- _this.getUtils().log("BetterDiscord ERR: " + reason);
-};
-
-var ipcHooked = false;
-
-var _domHooked = false;
-
-BetterDiscord.prototype.domReady = function() {
-
- _domHooked = true;
-
- if(ipcHooked) {
- _this.load(true);
- return;
- }
-
- ipcHooked = true;
- _this.load(false);
-};
-
-BetterDiscord.prototype.load = function(reload) {
- _this.getUtils().log("Hooked dom-ready");
-
- _this.initLoaders();
-
- if(reload) {
- _this.getUtils().log("Reloading");
- }
-
- if(!reload) {
- if(_updater.LatestVersion > _version) {
- _this.getUtils().execJs('alert("An update for BetterDiscord is available(v'+ _updater.LatestVersion +')! Download the latest version from GitHub!")');
+function getHash(callback) {
+ getUtils().download("api.github.com", "/repos/" + _cfg.repo + "/BetterDiscordApp/commits/" + _cfg.branch, function(data) {
+ try {
+ _cfg.hash = JSON.parse(data).sha;
+ getUtils().injectVar("_bdhash", _cfg.hash);
+ }catch(err) {
+ callback(false);
+ return;
+ }
+ if(_cfg.hash == undefined) {
+ callback(false);
+ return;
}
- }
-
- //Create loading element
- _this.getUtils().execJs('var loadingNode = document.createElement("DIV");');
- _this.getUtils().execJs('loadingNode.innerHTML = \'
BetterDiscord - Loading Libraries : \'');
- _this.getUtils().execJs('var flex = document.getElementsByClassName("flex-vertical flex-spacer")[0]; flex.appendChild(loadingNode);');
-
- //Create ipc
- _this.getUtils().execJs("var betterDiscordIPC = require('ipc');");
-
-
- if(!reload) {
- _this.getUtils().log("Hooking ipc async");
- _ipc.on('asynchronous-message', function(event, arg) { _this.ipcAsyncMessage(event, arg); });
- _this.getUtils().log("Hooked ipc async");
- }
-
- //Inject version
- _this.getUtils().execJs('var version = "'+_version+'"');
- //Inject cdn
- _this.getUtils().execJs('var bdcdn = "' + _updater.CDN + '";');
- //Load jQuery
- _this.getUtils().updateLoading("Loading Resources(jQuery)", 0, 100);
- _this.getUtils().injectJavaScriptSync("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", "load-jQueryUI");
-
-};
-var loadCount = 0;
-var libCount;
-var loadUs;
+ getUtils().log("Hash: " + _cfg.hash);
-BetterDiscord.prototype.updateData = function() {
- libCount = 9;
- loadUs = {
- 'load-jQueryUI': {
+ callback(true);
+ });
+}
+
+function initUpdater() {
+ getUtils().log("Getting updater");
+ getUtils().attempt(getUpdater, 3, 0, "Failed to load updater", waitForDom, function() {
+ exit("Failed to load updater after 3 attempts");
+ });
+}
+
+function getUpdater(callback) {
+ getUtils().download("raw.githubusercontent.com", "/" + _cfg.repo + "/BetterDiscordApp/" + _cfg.hash + "/data/updater.json", function(data) {
+ try {
+ _cfg.updater = JSON.parse(data);
+ } catch(err) {
+ callback(false);
+ return;
+ }
+
+ if(_cfg.updater == undefined) {
+ callback(false);
+ return;
+ }
+
+ if(_cfg.updater.LatestVersion == undefined || _cfg.updater.CDN == undefined) {
+ callback(false);
+ return;
+ }
+
+ getUtils().log("Latest Version: " + _cfg.updater.LatestVersion);
+ getUtils().log("Using CDN: " + _cfg.updater.CDN);
+ updateExtData();
+ callback(true);
+ });
+}
+
+function updateExtData() {
+ getUtils().log("Updating ext data");
+
+ _extData = {
+ 'load-jQueryCookie': {
'type': 'javascript',
- 'resource': 'jQueryUI',
+ 'resource': 'jQueryCookie',
'domain': 'cdnjs.cloudflare.com',
'url': '//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js',
'localurl': null,
@@ -320,9 +158,9 @@ BetterDiscord.prototype.updateData = function() {
'load-mainCSS': {
'type': 'css',
'resource': 'Main CSS',
- 'domain': _updater.CDN,
- 'url': '//' + _updater.CDN + '/' + _repo + '/BetterDiscordApp/' + _hash + '/css/main.min.css',
- 'localurl': _localServer + '/BetterDiscordApp/css/main.css',
+ 'domain': _cfg.updater.CDN,
+ 'url': '//' + _cfg.updater.CDN + '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/css/main.min.css',
+ 'localurl': _cfg.localServer + '/BetterDiscordApp/css/main.css',
'message': 'load-mainJS',
'cacheable': false,
'variable': null
@@ -330,18 +168,18 @@ BetterDiscord.prototype.updateData = function() {
'load-mainJS': {
'type': 'javascript',
'resource': 'Main JS',
- 'domain': _updater.CDN,
- 'url': '//' + _updater.CDN + '/' + _repo + '/BetterDiscordApp/' + _hash + '/js/main.min.js',
- 'localurl': _localServer + '/BetterDiscordApp/js/main.js',
- 'message': 'load-publicServers',
+ 'domain': _cfg.updater.CDN,
+ 'url': '//' + _cfg.updater.CDN + '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/js/main.min.js',
+ 'localurl': _cfg.localServer + '/BetterDiscordApp/js/main.js',
+ 'message': 'load-emoteData-twitchGlobal',
'cacheable': false,
'variable': null
},
'load-publicServers': {
'type': 'json',
'resource': 'Public Servers',
- 'domain': _updater.CDN,
- 'url': '/' + _repo + '/BetterDiscordApp/' + _hash + '/data/serverlist.json',
+ 'domain': _cfg.updater.CDN,
+ 'url': '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/data/serverlist.json',
'localurl': null,
'message': 'load-emoteData-twitchGlobal',
'cacheable': false,
@@ -356,7 +194,7 @@ BetterDiscord.prototype.updateData = function() {
'message': 'load-emoteData-twitchSub',
'cacheable': true,
'variable': 'emotesTwitch',
- 'localpath': _dataPath + "/emotes_twitch_global.json",
+ 'localpath': _cfg.dataPath + "/emotes_twitch_global.json",
'encoding': "utf8",
'https': true,
'parse': false,
@@ -367,13 +205,13 @@ BetterDiscord.prototype.updateData = function() {
'load-emoteData-twitchGlobal-fallback': {
'type': 'emotedata',
'resource': 'Twitch Global Emotedata',
- 'domain': _updater.CDN,
- 'url': '/' + _repo + '/BetterDiscordApp/' + _hash + '/data/emotedata_twitch_global.json',
+ 'domain': _cfg.updater.CDN,
+ 'url': '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/data/emotedata_twitch_global.json',
'localurl': null,
'message': 'load-emoteData-twitchSub',
'cacheable': true,
'variable': 'emotesTwitch',
- 'localpath': _dataPath + "/emotes_twitch_global.json",
+ 'localpath': _cfg.dataPath + "/emotes_twitch_global.json",
'encoding': "utf8",
'https': true,
'parse': false,
@@ -390,7 +228,7 @@ BetterDiscord.prototype.updateData = function() {
'message': 'load-emoteData-ffz',
'cacheable': true,
'variable': 'subEmotesTwitch',
- 'localpath': _dataPath + "/emotes_twitch_subscriber.json",
+ 'localpath': _cfg.dataPath + "/emotes_twitch_subscriber.json",
'encoding': "utf8",
'https': true,
'parse': true,
@@ -401,13 +239,13 @@ BetterDiscord.prototype.updateData = function() {
'load-emoteData-twitchSub-fallback': {
'type': 'emotedata',
'resource': 'Twitch Subscriber Emotedata',
- 'domain': _updater.CDN,
- 'url': '/' + _repo + '/BetterDiscordApp/' + _hash + '/data/emotedata_twitch_subscriber.json',
+ 'domain': _cfg.updater.CDN,
+ 'url': '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/data/emotedata_twitch_subscriber.json',
'localurl': null,
'message': 'load-emoteData-ffz',
'cacheable': true,
'variable': 'subEmotesTwitch',
- 'localpath': _dataPath + "/emotes_twitch_subscriber.json",
+ 'localpath': _cfg.dataPath + "/emotes_twitch_subscriber.json",
'encoding': "utf8",
'https': true,
'parse': true,
@@ -418,13 +256,13 @@ BetterDiscord.prototype.updateData = function() {
'load-emoteData-ffz': {
'type': 'emotedata',
'resource': 'FrankerFaceZ Emotedata',
- 'domain': _updater.CDN,
- 'url': '/' + _repo + '/BetterDiscordApp/' + _hash + '/data/emotedata_ffz.json',
+ 'domain': _cfg.updater.CDN,
+ 'url': '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/data/emotedata_ffz.json',
'localurl': null,
'message': 'load-emoteData-bttv',
'cacheable': true,
'variable': 'emotesFfz',
- 'localpath': _dataPath + "/emotes_ffz.json",
+ 'localpath': _cfg.dataPath + "/emotes_ffz.json",
'encoding': "utf8",
'https': true,
'parse': true,
@@ -441,7 +279,7 @@ BetterDiscord.prototype.updateData = function() {
'message': 'load-emoteData-bttv-2',
'cacheable': true,
'variable': 'emotesBTTV',
- 'localpath': _dataPath + "/emotes_bttv.json",
+ 'localpath': _cfg.dataPath + "/emotes_bttv.json",
'encoding': "utf8",
'https': true,
'parse': false,
@@ -452,13 +290,13 @@ BetterDiscord.prototype.updateData = function() {
'load-emoteData-bttv-2': {
'type': 'emotedata',
'resource': 'BTTV Emotedata',
- 'domain': _updater.CDN,
- 'url': '/' + _repo + '/BetterDiscordApp/' + _hash + '/data/emotedata_bttv.json',
+ 'domain': _cfg.updater.CDN,
+ 'url': '/' + _cfg.repo + '/BetterDiscordApp/' + _cfg.hash + '/data/emotedata_bttv.json',
'localurl': null,
'message': 'start-bd',
'cacheable': true,
'variable': 'emotesBTTV2',
- 'localpath': _dataPath + "/emotes_bttv_2.json",
+ 'localpath': _cfg.dataPath + "/emotes_bttv_2.json",
'encoding': "utf8",
'https': true,
'parse': false,
@@ -469,122 +307,385 @@ BetterDiscord.prototype.updateData = function() {
};
}
-BetterDiscord.prototype.ipcAsyncMessage = function(event, arg) {
+function hook() {
+ try {
+ var webContents = getUtils().getWebContents();
- if(loadUs.hasOwnProperty(arg)) {
- loadCount++;
- var loadMe = loadUs[arg];
- _this.getUtils().updateLoading("Loading Resources (" + loadMe.resource + ")", loadCount / libCount * 100, 100);
+ getUtils().log("Hooking dom-ready");
+ webContents.on('dom-ready', domReady);
- var url = loadMe.url;
- if(_local && loadMe.localurl != null) {
- url = loadMe.localurl;
+ webContents.on('did-finish-loading', function() {
+ if(domReadyHooked) {
+ return;
+ }
+ getUtils().log("Hooking did-finish-loading failsafe");
+ domReady();
+ getUtils().log("Hooked did-finish-loading failsafe");
+ });
+
+ }catch(err) {
+ exit(err);
+ }
+}
+
+function waitForDom() {
+ if(!domReadyHooked) {
+ setTimeout(waitForDom, 1000);
+ return;
+ }
+ ipcHooked = true;
+ load(false);
+}
+
+var domReadyHooked = false;
+var ipcHooked = false;
+
+function domReady() {
+ getUtils().log("Hooked dom-ready");
+ domReadyHooked = true;
+ if(ipcHooked) {
+ load(true);
+ }
+}
+
+function load(reload) {
+ getUtils().log(reload ? "Reloading" : "Loading");
+ getUtils().execJs("var betterDiscordIPC = require('electron').ipcRenderer;");
+ if(!reload) {
+ if(_cfg.updater.LatestVersion > _cfg.version) {
+ getUtils().alert("Update Available", "An update for BetterDiscord is available("+_cfg.updater.LatestVersion+")! BetterDiscord.net");
+ }
+ getUtils().log("Hooking ipc async");
+ _bdIpc.on('asynchronous-message', function(event, arg) { ipcAsyncMessage(event, arg); });
+ getUtils().log("Hooked ipc async");
+ }
+ initLoaders();
+}
+
+function initLoaders() {
+ try {
+ getUtils().mkdirSync(_cfg.dataPath);
+ getUtils().mkdirSync(_cfg.dataPath + "plugins/");
+ getUtils().mkdirSync(_cfg.dataPath + "themes/");
+ getUtils().execJs('var themesupport2 = true');
+
+ loadPlugins();
+ loadThemes();
+ loadApp();
+ }catch(err) {
+ exit(err);
+ }
+}
+
+function loadPlugins() {
+ var pluginPath = _cfg.dataPath + "plugins/";
+ _fs.readdir(pluginPath, function(err, files) {
+ if(err) {
+ getUtils().log(err);
+ getUtils().alert(err);
+ return;
}
- if(loadMe.type == 'javascript') {
- _this.getUtils().injectJavaScriptSync(url, loadMe.message);
- }else if(loadMe.type == 'css') {
- _this.getUtils().injectStylesheetSync(url, loadMe.message);
- }else if(loadMe.type == 'json') {
- _this.getUtils().download(loadMe.domain, loadMe.url, function(data) {
- _this.getUtils().execJs('var ' + loadMe.variable + ' = ' + data + ';');
- _this.getUtils().sendIcpAsync(loadMe.message);
- });
- }else if(loadMe.type == 'emotedata') {
- if(loadMe.variable != "emotesTwitch") {
- _this.getUtils().execJs('var ' + loadMe.variable + ' = {};');//jic
- }
- var exists = _fs.existsSync(loadMe.localpath);
+ var pluginErrors = [];
- if(exists && !_cacheExpired && loadMe.cacheable) {
- _this.loadLocalEData(loadMe);
- //_this.injectEmoteData(loadMe, _fs.readFileSync(loadMe.localpath, loadMe.encoding));
- } else {
- _this.loadRemoteEData(loadMe);
+ getUtils().injectVarRaw("bdplugins", "{}");
+
+ files.forEach(function(fileName) {
+ if(!fileName.endsWith(".plugin.js")) {
+ getUtils().log("Invalid plugin detected: " + fileName);
+ return;
}
+
+ var plugin = _fs.readFileSync(pluginPath + fileName, 'utf8');
+ var meta = plugin.split(_eol)[0];
+
+ if (meta.indexOf('META') < 0) {
+ getUtils().warn('Plugin META not found in file: ' + fileName);
+ pluginErrors.push(fileName + " Reason: Plugin META not found");
+ return;
+ }
+ var pluginVar = meta.substring(meta.lastIndexOf('//META') + 6, meta.lastIndexOf('*//'));
+ var parse;
+ try {
+ parse = JSON.parse(pluginVar);
+ }catch(err) {
+ getUtils().warn("Failed to parse plugin META in file: " + fileName + "("+err+")");
+ pluginErrors.push(fileName + " Reason: Failed to parse plugin META (" + err + ")");
+ return;
+ }
+
+ if(parse["name"] == undefined) {
+ getUtils().warn("Undefined plugin name in file: " + fileName);
+ pluginErrors.push(fileName + " Reason: invalid plugin name");
+ return;
+ }
+
+ getUtils().log("Loading plugin: " + parse["name"]);
+ getUtils().execJs(plugin);
+ getUtils().execJs('(function() { var plugin = new ' + parse["name"] + '(); bdplugins[plugin.getName()] = { "plugin": plugin, "enabled": false } })();')
+ });
+
+ if(pluginErrors.length > 0) {
+ getUtils().alert("The following plugin(s) could not be loaded", pluginErrors.join("
"));
}
+
+ });
+}
+
+function loadThemes() {
+ var themePath = _cfg.dataPath + "themes/";
+ _fs.readdir(themePath, function(err, files) {
+ if(err) {
+ getUtils().log(err);
+ getUtils().alert(err);
+ return;
+ }
+
+ var themeErrors = [];
+
+ getUtils().injectVarRaw("bdthemes", "{}");
+
+ files.forEach(function(fileName) {
+ if(!fileName.endsWith(".theme.css")) {
+ getUtils().log("Invalid theme detected " + fileName);
+ return;
+ }
+ var theme = _fs.readFileSync(themePath + fileName, 'utf8');
+ var split = theme.split(_eol);
+ var meta = split[0];
+ if(meta.indexOf('META') < 0) {
+ getUtils().warn("Theme META not found in file: " + fileName);
+ themeErrors.push(fileName + " Reason: Theme META not found");
+ return;
+ }
+ var themeVar = meta.substring(meta.lastIndexOf('//META') + 6, meta.lastIndexOf('*//'));
+ var themeInfo;
+ try {
+ themeInfo = JSON.parse(themeVar);
+ }catch(err) {
+ getUtils().warn("Failed to parse theme META in file: " + fileName + "("+err+")");
+ themeErrors.push(fileName + " Reason: Failed to parse theme META (" + err + ")");
+ return;
+ }
+
+ if(themeInfo['name'] == undefined) {
+ getUtils().warn("Missing theme name in file: " + fileName);
+ themeErrors.push(fileName + " Reason: Missing theme name");
+ return;
+ }
+ if(themeInfo['author'] == undefined) {
+ themeInfo['author'] = "Unknown";
+ getUtils().warn("Missing author name in file: " + fileName);
+ }
+ if(themeInfo['description'] == undefined) {
+ themeInfo['description'] = "No_Description";
+ getUtils().warn("Missing description in file: " + fileName);
+ }
+ if(themeInfo['version'] == undefined) {
+ themeInfo['version'] = "Unknown";
+ getUtils().warn("Missing version in file: " + fileName);
+ }
+
+ getUtils().log("Loading theme: " + themeInfo['name']);
+ split.splice(0, 1);
+ theme = split.join(_eol);
+ theme = theme.replace(/(\r\n|\n|\r)/gm, '');
+
+ _mainWindow.webContents.executeJavaScript('(function() { bdthemes["' + themeInfo['name'] + '"] = { "enabled": false, "name": "' + themeInfo['name'] + '", "css": "' + escape(theme) + '", "description": "' + themeInfo['description'] + '", "author":"' + themeInfo['author'] + '", "version":"' + themeInfo['version'] + '" } })();');
+ });
+
+ if(themeErrors.length > 0) {
+ getUtils().alert("The following theme(s) could not be loaded", themeErrors.join("
"));
+ }
+ });
+}
+
+function loadApp() {
+ getUtils().execJs('var loadingNode = document.createElement("DIV");');
+ getUtils().execJs('loadingNode.innerHTML = \' BetterDiscord - Loading Libraries : \'');
+ getUtils().execJs('var flex = document.getElementsByClassName("flex-vertical flex-spacer")[0]; flex.appendChild(loadingNode);');
+ getUtils().injectVar('bdVersion', _cfg.version);
+ getUtils().injectVar('bdCdn', _cfg.CDN);
+
+ getUtils().updateLoading("Loading Resource (jQuery)", 0, 100);
+ getUtils().injectJavaScriptSync("//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js", "load-jQueryCookie");
+}
+
+function ipcAsyncMessage(event, arg) {
+
+ if(typeof(arg) === "object") {
+ switch(arg.arg) {
+ case "opendir":
+ if(arg.path == "plugindir") {
+ getUtils().openDir(_cfg.dataPath + "/plugins");
+ break;
+ }
+ if(arg.path == "themedir") {
+ getUtils().openDir(_cfg.dataPath + "/themes");
+ break;
+ }
+ if(arg.path == "datadir") {
+ getUtils().openDir(_cfg.dataPath);
+ break;
+ }
+ getUtils().openDir(arg.path);
+ break;
+ }
+ return;
+ }
+
+ if(_extData.hasOwnProperty(arg)) {
+ loadExtData(_extData[arg]);
}
if(arg == "start-bd") {
- _this.getUtils().saveLogs(_dataPath);
- _this.getUtils().updateLoading("Starting Up", 100, 100);
- _this.getUtils().execJs('var mainCore; var startBda = function() { mainCore = new Core(); mainCore.init(); }; startBda();');
+ getUtils().updateLoading("Starting Up", 100, 100);
+ getUtils().execJs('var mainCore; var startBda = function() { mainCore = new Core(); mainCore.init(); }; startBda();');
//Remove loading node
setTimeout(function() {
- _this.getUtils().execJs('$("#bd-status").parent().parent().hide();');
+ getUtils().execJs('$("#bd-status").parent().parent().hide();');
}, 2000);
+ getUtils().saveLogs(_cfg.dataPath);
}
-};
+}
-BetterDiscord.prototype.loadRemoteEData = function(loadMe) {
- _this.getUtils().log("Downloading " + loadMe.resource + " from " + loadMe.domain + loadMe.url );
- if(loadMe.https) {
- _this.getUtils().download(loadMe.domain, loadMe.url, function(data) {
- var parsedEmoteData = _this.parseEmoteData(loadMe, data);
+var loadCounter = 0;
+function loadExtData(extData) {
+
+ loadCounter++;
+
+ getUtils().updateLoading("Loading Resource (" + extData.resource + ")", loadCounter / Object.keys(_extData).length * 100, 100);
+
+ var url = (_cfg.local && extData.localurl != null) ? extData.localurl : extData.url;
+
+ try {
+ switch(extData.type) {
+ case 'javascript':
+ getUtils().injectJavaScriptSync(url, extData.message);
+ break;
+ case 'css':
+ getUtils().injectStylesheetSync(url, extData.message);
+ break;
+ case 'json':
+ getUtils().download(extData.domain, extData.url, function(data) {
+ getUtils().injectVar(extData.variable, data);
+ getUtils().sendIcpAsync(extData.message);
+ });
+ break;
+ case 'emotedata':
+ if(extData.variable != "emotesTwitch") {
+ getUtils().injectVarRaw(extData.variable, "{}");
+ }
+ var exists = _fs.existsSync(extData.localpath);
+ if(exists && !_cfg.cache.expired && extData.cacheable) {
+ loadEmoteData(extData, true);
+ } else {
+ loadEmoteData(extData, false);
+ }
+ break;
+ }
+ }catch(err) {
+ getUtils().warn(err);
+ getUtils().alert("Something went wrong :( Attempting to run.", err);
+ getUtils().sendIcpAsync(extData.message);
+ }
+}
+
+function loadEmoteData(extData, local) {
+ if(local) {
+ getUtils().log("Reading " + extData.resource + " from file");
+ var data = _fs.readFileSync(extData.localpath, extData.encoding);
+
+ if(testJSON(extData, data)) {
+ injectEmoteData(extData, data);
+ } else {
+ getUtils().log("Deleting cached file " + extData.resource);
+ _fs.unlinkSync(extData.localpath);
+ getUtils().sendIcpAsync(extData.self);
+ }
+ return;
+ }
+
+ if(extData.https) {
+ getUtils().download(extData.domain, extData.url, function(data) {
+ var parsedEmoteData = parseEmoteData(extData, data);
if(parsedEmoteData == null) {
- _this.getUtils().sendIcpAsync(loadMe.fallback);
+ getUtils().sendIcpAsync(extData.fallback);
return true;
}
- _this.saveEmoteData(loadMe, parsedEmoteData);
- _this.injectEmoteData(loadMe, parsedEmoteData);
+ saveEmoteData(extData, parsedEmoteData);
+ injectEmoteData(extData, parsedEmoteData);
});
- return true;
+ return;
}
- _this.getUtils().downloadHttp(loadMe.url, function(data) {
- var parsedEmoteData = _this.parseEmoteData(loadMe, data);
- _this.saveEmoteData(loadMe, parsedEmoteData);
- _this.injectEmoteData(loadMe, parsedEmoteData);
+ getUtils().downloadHttp(extData.url, function(data) {
+ var parsedEmoteData = parseEmoteData(extData, data);
+ if(parsedEmoteData == null) {
+ getUtils().sendIcpAsync(extData.fallback);
+ return true;
+ }
+ saveEmoteData(extData, parsedEmoteData);
+ injectEmoteData(extData, parsedEmoteData);
});
-};
+}
-BetterDiscord.prototype.loadLocalEData = function(loadMe) {
- _this.getUtils().log("Reading " + loadMe.resource + " from file");
- var data = _fs.readFileSync(loadMe.localpath, loadMe.encoding);
-
- if(_this.testJSON(loadMe, data)) {
- _this.injectEmoteData(loadMe, data);
- } else {
- _this.getUtils().log("Deleting cached file " + loadMe.resource);
- _fs.unlinkSync(loadMe.localpath);
- _this.getUtils().sendIcpAsync(loadMe.self);
- }
-};
-
-BetterDiscord.prototype.testJSON = function(loadMe, data) {
- _this.getUtils().log("Validating " + loadMe.resource);
+function testJSON(extData, data) {
+ getUtils().log("Validating " + extData.resource);
try {
var json = JSON.parse(data);
- _this.getUtils().log(loadMe.resource + " is valid");
+ getUtils().log(extData.resource + " is valid");
return true;
}catch(err) {
- _this.getUtils().log(loadMe.resource + " is invalid");
+ getUtils().warn(extData.resource + " is invalid");
return false;
}
-};
+ return false;
+}
-BetterDiscord.prototype.parseEmoteData = function(loadMe, emoteData) {
+function injectEmoteData(extData, data) {
+ if(data == null) {
+ getUtils().sendIcpAsync(extData.message);
+ return;
+ }
- _this.getUtils().log("Parsing: " + loadMe.resource);
+ if(data.parse) {
+ getUtils().injectVarRaw(extData.variable, 'JSON.parse(\'' + data + '\');');
+ } else {
+ getUtils().injectVarRaw(extData.variable, data);
+ }
+
+ getUtils().sendIcpAsync(extData.message);
+}
+
+function saveEmoteData(extData, data) {
+ try {
+ getUtils().log("Saving resource to file " + extData.resource);
+ _fs.writeFileSync(extData.localpath, data, extData.encoding);
+ } catch(err) {
+ getUtils().err("Failed to save resource to file " + extData.resource);
+ }
+}
+
+function parseEmoteData(extData, data) {
+ getUtils().log("Parsing: " + extData.resource);
var returnData;
- switch(loadMe.specialparser) {
-
+ switch(extData.specialparser) {
case 0: //Twitch Global Emotes
- //returnData = emoteData.replace(/\$/g, "\\$").replace(/'/g, "\\'").replace(/"/g, "\\\""); We don't need this anymore
- return emoteData;
+ return data;
break;
case 1: //Twitch Subscriber Emotes
returnData = {};
- if(!_this.testJSON(loadMe, emoteData)) {
+ if(!testJSON(extData, data)) {
return null;
}
- emoteData = JSON.parse(emoteData);
+ data = JSON.parse(data);
- var channels = emoteData["channels"];
+ var channels = data["channels"];
for(var channel in channels) {
var emotes = channels[channel]["emotes"];
for(var i = 0 ; i < emotes.length ; i++) {
@@ -597,19 +698,19 @@ BetterDiscord.prototype.parseEmoteData = function(loadMe, emoteData) {
returnData = JSON.stringify(returnData);
break;
case 2: //FFZ Emotes
- returnData = emoteData;
+ returnData = data;
break;
case 3: //BTTV Emotes
returnData = {};
- if(!_this.testJSON(loadMe, emoteData)) {
+ if(!testJSON(extData, data)) {
return null;
}
- emoteData = JSON.parse(emoteData);
+ data = JSON.parse(data);
- for(var emote in emoteData.emotes) {
- emote = emoteData.emotes[emote];
+ for(var emote in data.emotes) {
+ emote = data.emotes[emote];
var url = emote.url;
var code = emote.regex;
@@ -619,25 +720,23 @@ BetterDiscord.prototype.parseEmoteData = function(loadMe, emoteData) {
returnData = JSON.stringify(returnData);
break;
case 4:
- returnData = emoteData;
+ returnData = data;
break;
}
return returnData;
-};
+}
-BetterDiscord.prototype.saveEmoteData = function(loadMe, emoteData) {
- _fs.writeFileSync(loadMe.localpath, emoteData, loadMe.encoding);
-};
+function getUtils() {
+ return _utils2;
+}
-BetterDiscord.prototype.injectEmoteData = function(loadMe, emoteData) {
- if(emoteData != null) {
- if(loadMe.parse) {
- _this.getUtils().execJs('var ' + loadMe.variable + ' = JSON.parse(\'' + emoteData + '\');');
- } else {
- _this.getUtils().execJs('var ' + loadMe.variable + ' = ' + emoteData + ';');
- }
- }
- _this.getUtils().sendIcpAsync(loadMe.message);
-};
+function exit(reason) {
+ _error = true;
+ getUtils().log("Exiting. Reason: " + reason);
+ getUtils().saveLogs(_cfg.dataPath);
+ getUtils().alert("Something went wrong :(", reason);
+}
+
+BetterDiscord.prototype.init = function() {}//Compatibility
exports.BetterDiscord = BetterDiscord;
\ No newline at end of file
diff --git a/lib/Utils.js b/lib/Utils.js
index 8d2950ca..ba00d379 100644
--- a/lib/Utils.js
+++ b/lib/Utils.js
@@ -1,8 +1,8 @@
/* BetterDiscordApp Utils and Helper functions
- * Version: 1.4
+ * Version: 1.5
* Author: Jiiks | http://jiiks.net
* Date: 25/08/2015 - 09:19
- * Last Updated: 20/04/2016
+ * Last Updated: 06/05/2016
* https://github.com/Jiiks/BetterDiscordApp
*/
@@ -224,7 +224,7 @@ Utils.prototype.mkdirSync = function(path) {
}
};
-Utils.prototype.try = function(func, attempts, attempt, message, success, err) {
+Utils.prototype.attemptSync = function(func, attempts, attempt, message, success, err) {
var self = this;
attempt = attempt || 0;
attempt++;
@@ -235,9 +235,8 @@ Utils.prototype.try = function(func, attempts, attempt, message, success, err) {
}
setTimeout(function() {
- self.warn(message + ", retrying #" + attempt);
-
if(!func()) {
+ self.warn(message + ", retrying #" + attempt);
self.try(func, attempts, attempt, message, success, err);
return;
}
@@ -246,6 +245,28 @@ Utils.prototype.try = function(func, attempts, attempt, message, success, err) {
}, 1000);
};
+Utils.prototype.attempt = function(func, attempts, attempt, message, success, err) {
+ var self = this;
+ attempt = attempt || 0;
+ attempt++;
+
+ if(attempt > attempts) {
+ err();
+ return;
+ }
+
+ setTimeout(function() {
+ func(function(ok) {
+ if(!ok) {
+ self.warn(message + ", retrying #" + attempt);
+ self.try(func, attempts, attempt, message, success, err);
+ return;
+ }
+ success();
+ });
+ }, 1000);
+};
+
Utils.prototype.openDir = function(path) {
switch(process.platform) {
case "win32":
diff --git a/lib/config.json b/lib/config.json
index 4f3e5493..41ac52da 100644
--- a/lib/config.json
+++ b/lib/config.json
@@ -23,7 +23,7 @@
"repo": "Jiiks",
"branch": null,
"beta": false,
- "local": true,
+ "local": false,
"localServer": "http://localhost",
"version": "0.2.8",
"updater": null,