2015-08-28 09:52:36 +02:00
/ * B e t t e r D i s c o r d A p p E n t r y
2016-05-06 20:34:40 +02:00
* Version : 3.0
2015-08-28 09:52:36 +02:00
* Author : Jiiks | http : //jiiks.net
* Date : 27 / 08 / 2015 - 15 : 51
2016-05-06 20:34:40 +02:00
* Last Update : 06 / 05 / 2016
2015-08-28 09:52:36 +02:00
* https : //github.com/Jiiks/BetterDiscordApp
* /
2015-11-02 23:29:26 +01:00
2016-05-06 20:34:40 +02:00
'use strict' ;
2015-10-26 05:12:39 +01:00
var _fs = require ( "fs" ) ;
2015-08-28 09:52:36 +02:00
var _config = require ( "./config.json" ) ;
var _utils = require ( "./utils" ) ;
2016-05-06 20:34:40 +02:00
var _utils2 ;
var _bdIpc = require ( 'electron' ) . ipcMain ;
var _error = false ;
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
var _eol = require ( 'os' ) . EOL ;
2015-11-30 20:46:20 +01:00
2015-08-28 09:52:36 +02:00
var _mainWindow ;
2015-11-02 23:29:26 +01:00
2016-05-06 20:34:40 +02:00
var _cfg = { } ;
var _extData = { } ;
2015-10-27 22:14:09 +01:00
2017-01-09 06:42:14 +01:00
var bdStorage = { } ;
var bdPluginStorage = { } ;
bdStorage . defaults = {
data : { }
} ;
bdPluginStorage . defaults = {
data : { }
} ;
function initStorage ( ) {
if ( ! _fs . existsSync ( _cfg . dataPath + "/bdstorage.json" ) ) {
bdStorage . data = bdStorage . defaults . data ;
_fs . writeFileSync ( _cfg . dataPath + "/bdstorage.json" , JSON . stringify ( bdStorage , null , 4 ) ) ;
} else {
bdStorage . data = JSON . parse ( _fs . readFileSync ( _cfg . dataPath + "/bdStorage.json" ) ) ;
}
} ;
bdStorage . get = function ( i , m , pn ) {
2017-01-09 07:32:58 +01:00
2017-01-09 06:42:14 +01:00
if ( m ) return bdStorage . data [ i ] || "" ;
2017-01-09 07:15:00 +01:00
if ( bdPluginStorage [ pn ] !== undefined ) {
return bdPluginStorage [ pn ] [ i ] || undefined ;
}
if ( _fs . existsSync ( _cfg . dataPath + "/plugins/" + pn + ".config.json" ) ) {
bdPluginStorage [ pn ] = JSON . parse ( _fs . readFileSync ( _cfg . dataPath + "/plugins/" + pn + ".config.json" ) ) ;
return bdPluginStorage [ pn ] [ i ] || undefined ;
}
2017-01-09 07:32:58 +01:00
return undefined ;
2017-01-09 06:42:14 +01:00
} ;
bdStorage . set = function ( i , v , m , pn ) {
if ( m ) {
bdStorage . data [ i ] = v ;
_fs . writeFileSync ( _cfg . dataPath + "/bdstorage.json" , JSON . stringify ( bdStorage . data , null , 4 ) ) ;
} else {
2017-01-09 07:15:00 +01:00
if ( bdPluginStorage [ pn ] === undefined ) bdPluginStorage [ pn ] = { } ;
bdPluginStorage [ pn ] [ i ] = v ;
_fs . writeFileSync ( _cfg . dataPath + "/plugins/" + pn + ".config.json" , JSON . stringify ( bdPluginStorage [ pn ] , null , 4 ) ) ;
2017-01-09 06:42:14 +01:00
}
return true ;
} ;
2017-01-09 07:32:58 +01:00
2015-08-28 09:52:36 +02:00
function BetterDiscord ( mainWindow ) {
_mainWindow = mainWindow ;
2016-05-06 20:34:40 +02:00
_cfg = _config . cfg ;
_cfg . version = _config . Core . Version ;
_cfg . os = process . platform ;
_utils2 = new _utils . Utils ( mainWindow ) ;
hook ( ) ;
createAndCheckData ( ) ;
2015-08-28 09:52:36 +02:00
}
2016-05-06 20:34:40 +02:00
function createAndCheckData ( ) {
getUtils ( ) . log ( "Checking data/cache" ) ;
2015-11-03 00:06:58 +01:00
2016-05-06 20:34:40 +02:00
_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' ;
2015-11-02 23:29:26 +01:00
2015-10-26 05:12:39 +01:00
try {
2016-05-06 20:34:40 +02:00
getUtils ( ) . mkdirSync ( _cfg . dataPath ) ;
2015-10-26 05:12:39 +01:00
2016-05-06 20:34:40 +02:00
if ( _fs . existsSync ( _cfg . userFile ) ) {
_cfg . userCfg = JSON . parse ( _fs . readFileSync ( _cfg . userFile ) ) ;
2015-10-26 05:12:39 +01:00
}
2016-05-06 20:34:40 +02:00
if ( _cfg . userCfg . cache == null ) {
_cfg . userCfg . cache = new Date ( ) ;
2015-10-26 05:12:39 +01:00
} else {
2015-11-30 20:46:20 +01:00
var currentDate = new Date ( ) ;
2016-05-06 20:34:40 +02:00
var cacheDate = new Date ( _cfg . userCfg . cache ) ;
2015-11-30 20:46:20 +01:00
//Check if cache is expired
2016-05-06 20:34:40 +02:00
if ( Math . abs ( currentDate . getDate ( ) - cacheDate . getDate ( ) ) > _cfg . cache . days ) {
_cfg . userCfg . cache = currentDate ;
2015-11-30 20:46:20 +01:00
} else {
2016-05-06 20:34:40 +02:00
_cfg . cache . expired = false ;
2015-10-26 05:12:39 +01:00
}
}
2015-11-30 20:46:20 +01:00
//Write new cache date if expired
2016-05-06 20:34:40 +02:00
if ( _cfg . cache . expired ) {
getUtils ( ) . log ( "Cache expired or null" ) ;
_fs . writeFileSync ( _cfg . userFile , JSON . stringify ( _cfg . userCfg ) ) ;
2015-11-30 20:46:20 +01:00
}
2016-05-06 20:34:40 +02:00
init ( ) ;
} catch ( err ) {
getUtils ( ) . err ( err ) ;
exit ( err . message ) ;
2015-11-30 20:46:20 +01:00
}
2016-05-06 20:34:40 +02:00
}
2015-10-26 05:12:39 +01:00
2016-05-06 20:34:40 +02:00
function init ( ) {
if ( _cfg . branch == null ) {
_cfg . branch = _cfg . beta ? "beta" : "master" ;
}
2015-10-26 05:12:39 +01:00
2016-05-06 20:34:40 +02:00
if ( _cfg . repo == null ) {
_cfg . repo = "Jiiks" ;
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Using repository: " + _cfg . repo + " and branch: " + _cfg . branch ) ;
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Getting latest hash" ) ;
getUtils ( ) . attempt ( getHash , 3 , 0 , "Failed to load hash" , initUpdater , function ( ) {
exit ( "Failed to load hash after 3 attempts" ) ;
} ) ;
2017-01-09 06:42:14 +01:00
initStorage ( ) ;
2016-05-06 20:34:40 +02:00
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
function getHash ( callback ) {
getUtils ( ) . download ( "api.github.com" , "/repos/" + _cfg . repo + "/BetterDiscordApp/commits/" + _cfg . branch , function ( data ) {
2015-11-03 00:06:58 +01:00
try {
2016-05-06 20:34:40 +02:00
_cfg . hash = JSON . parse ( data ) . sha ;
getUtils ( ) . injectVar ( "_bdhash" , _cfg . hash ) ;
2015-11-30 20:46:20 +01:00
} catch ( err ) {
2017-01-09 06:42:14 +01:00
callback ( false , err ) ;
2015-11-30 20:46:20 +01:00
return ;
}
2016-05-06 20:34:40 +02:00
if ( _cfg . hash == undefined ) {
2017-01-09 06:42:14 +01:00
callback ( false , "_cfg.hash == undefined" ) ;
2015-11-30 20:46:20 +01:00
return ;
2015-11-03 00:06:58 +01:00
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Hash: " + _cfg . hash ) ;
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
callback ( true ) ;
2015-08-29 21:20:11 +02:00
} ) ;
2016-05-06 20:34:40 +02:00
}
2015-12-18 16:23:08 +01:00
2016-05-06 20:34:40 +02:00
function initUpdater ( ) {
getUtils ( ) . log ( "Getting updater" ) ;
getUtils ( ) . attempt ( getUpdater , 3 , 0 , "Failed to load updater" , waitForDom , function ( ) {
2017-01-09 06:42:14 +01:00
exit ( "Failed to load updater after 3 attempts." ) ;
2016-05-06 20:34:40 +02:00
} ) ;
}
2015-08-29 21:20:11 +02:00
2016-05-06 20:34:40 +02:00
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 ) {
2017-01-09 06:42:14 +01:00
callback ( false , err ) ;
2016-05-06 20:34:40 +02:00
return ;
}
2015-12-18 16:23:08 +01:00
2016-05-06 20:34:40 +02:00
if ( _cfg . updater == undefined ) {
2017-01-09 06:42:14 +01:00
callback ( false , "_cfg.updater == undefined" ) ;
return ;
}
if ( _cfg . updater . LatestVersion == undefined ) {
callback ( false , "_cfg.updater.LatestVersion == undefined" ) ;
2016-05-06 20:34:40 +02:00
return ;
}
2015-12-18 16:23:08 +01:00
2017-01-09 06:42:14 +01:00
if ( _cfg . updater . CDN == undefined ) {
callback ( false , "_cfg.updater.CDN == undefined" ) ;
2016-05-06 20:34:40 +02:00
return ;
2015-12-11 03:46:03 +01:00
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Latest Version: " + _cfg . updater . LatestVersion ) ;
getUtils ( ) . log ( "Using CDN: " + _cfg . updater . CDN ) ;
updateExtData ( ) ;
callback ( true ) ;
} ) ;
}
2015-12-11 03:46:03 +01:00
2016-05-06 20:34:40 +02:00
function updateExtData ( ) {
getUtils ( ) . log ( "Updating ext data" ) ;
_extData = {
'load-jQueryCookie' : {
2015-11-30 20:46:20 +01:00
'type' : 'javascript' ,
2016-05-06 20:34:40 +02:00
'resource' : 'jQueryCookie' ,
2015-11-30 20:46:20 +01:00
'domain' : 'cdnjs.cloudflare.com' ,
'url' : '//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js' ,
'localurl' : null ,
'message' : 'load-mainCSS' ,
'cacheable' : false ,
'variable' : null
} ,
'load-mainCSS' : {
'type' : 'css' ,
'resource' : 'Main CSS' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '//' + _cfg . updater . CDN + '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/css/main.min.css' ,
'localurl' : _cfg . localServer + '/BetterDiscordApp/css/main.css' ,
2015-11-30 20:46:20 +01:00
'message' : 'load-mainJS' ,
'cacheable' : false ,
'variable' : null
} ,
'load-mainJS' : {
'type' : 'javascript' ,
'resource' : 'Main JS' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
2017-01-09 07:32:58 +01:00
'url' : '//' + _cfg . updater . CDN + '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/js/main.js' ,
2017-01-09 06:42:14 +01:00
'localurl' : _cfg . localServer + '/BetterDiscordApp/js/main.js?v=1.1' ,
2016-05-06 20:34:40 +02:00
'message' : 'load-emoteData-twitchGlobal' ,
2015-11-30 20:46:20 +01:00
'cacheable' : false ,
'variable' : null
} ,
'load-publicServers' : {
'type' : 'json' ,
'resource' : 'Public Servers' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/data/serverlist.json' ,
2015-11-30 20:46:20 +01:00
'localurl' : null ,
'message' : 'load-emoteData-twitchGlobal' ,
'cacheable' : false ,
'variable' : 'publicServers'
} ,
'load-emoteData-twitchGlobal' : {
'type' : 'emotedata' ,
'resource' : 'Twitch Global Emotedata' ,
2016-02-10 03:09:44 +01:00
'domain' : 'twitchemotes.com' ,
2016-02-10 03:04:44 +01:00
'url' : '/api_cache/v2/global.json' ,
2015-11-30 20:46:20 +01:00
'localurl' : null ,
'message' : 'load-emoteData-twitchSub' ,
'cacheable' : true ,
'variable' : 'emotesTwitch' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_twitch_global.json" ,
2015-11-30 20:46:20 +01:00
'encoding' : "utf8" ,
2016-02-10 03:04:44 +01:00
'https' : true ,
2016-03-30 03:37:03 +02:00
'parse' : false ,
'specialparser' : 0 ,
'fallback' : 'load-emoteData-twitchGlobal-fallback' ,
'self' : 'load-emoteData-twitchGlobal'
} ,
'load-emoteData-twitchGlobal-fallback' : {
'type' : 'emotedata' ,
'resource' : 'Twitch Global Emotedata' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/data/emotedata_twitch_global.json' ,
2016-03-30 03:37:03 +02:00
'localurl' : null ,
'message' : 'load-emoteData-twitchSub' ,
'cacheable' : true ,
'variable' : 'emotesTwitch' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_twitch_global.json" ,
2016-03-30 03:37:03 +02:00
'encoding' : "utf8" ,
'https' : true ,
'parse' : false ,
'specialparser' : 0 ,
'fallback' : 'load-emoteData-twitchSub' ,
'self' : 'load-emoteData-twitchGlobal-fallback'
2015-11-30 20:46:20 +01:00
} ,
'load-emoteData-twitchSub' : {
'type' : 'emotedata' ,
'resource' : 'Twitch Subscriber Emotedata' ,
2016-02-10 03:09:44 +01:00
'domain' : 'twitchemotes.com' ,
2016-02-10 03:04:44 +01:00
'url' : '/api_cache/v2/subscriber.json' ,
2015-11-30 20:46:20 +01:00
'localurl' : null ,
'message' : 'load-emoteData-ffz' ,
'cacheable' : true ,
'variable' : 'subEmotesTwitch' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_twitch_subscriber.json" ,
2015-11-30 20:46:20 +01:00
'encoding' : "utf8" ,
2016-02-10 03:04:44 +01:00
'https' : true ,
2015-11-30 20:46:20 +01:00
'parse' : true ,
2016-03-30 03:37:03 +02:00
'specialparser' : 1 ,
'fallback' : 'load-emoteData-twitchSub-fallback' ,
'self' : 'load-emoteData-twitchSub'
} ,
'load-emoteData-twitchSub-fallback' : {
'type' : 'emotedata' ,
'resource' : 'Twitch Subscriber Emotedata' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/data/emotedata_twitch_subscriber.json' ,
2016-03-30 03:37:03 +02:00
'localurl' : null ,
'message' : 'load-emoteData-ffz' ,
'cacheable' : true ,
'variable' : 'subEmotesTwitch' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_twitch_subscriber.json" ,
2016-03-30 03:37:03 +02:00
'encoding' : "utf8" ,
'https' : true ,
'parse' : true ,
'specialparser' : 1 ,
'fallback' : 'load-emoteData-ffz' ,
'self' : 'load-emoteData-twitchSub-fallback'
2015-11-30 20:46:20 +01:00
} ,
'load-emoteData-ffz' : {
'type' : 'emotedata' ,
'resource' : 'FrankerFaceZ Emotedata' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/data/emotedata_ffz.json' ,
2015-11-30 20:46:20 +01:00
'localurl' : null ,
'message' : 'load-emoteData-bttv' ,
'cacheable' : true ,
'variable' : 'emotesFfz' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_ffz.json" ,
2015-11-30 20:46:20 +01:00
'encoding' : "utf8" ,
'https' : true ,
'parse' : true ,
2016-03-30 03:37:03 +02:00
'specialparser' : 2 ,
'fallback' : 'load-emoteData-bttv' ,
'self' : 'load-emoteData-ffz'
2015-11-30 20:46:20 +01:00
} ,
'load-emoteData-bttv' : {
'type' : 'emotedata' ,
'resource' : 'BTTV Emotedata' ,
'domain' : 'api.betterttv.net' ,
'url' : '/emotes' ,
'localurl' : null ,
2015-12-10 04:01:24 +01:00
'message' : 'load-emoteData-bttv-2' ,
2015-11-30 20:46:20 +01:00
'cacheable' : true ,
'variable' : 'emotesBTTV' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_bttv.json" ,
2015-11-30 20:46:20 +01:00
'encoding' : "utf8" ,
'https' : true ,
'parse' : false ,
2016-03-30 03:37:03 +02:00
'specialparser' : 3 ,
'fallback' : 'load-emoteData-bttv-2' ,
'self' : 'load-emoteData-bttv'
2015-12-10 04:01:24 +01:00
} ,
'load-emoteData-bttv-2' : {
'type' : 'emotedata' ,
'resource' : 'BTTV Emotedata' ,
2016-05-06 20:34:40 +02:00
'domain' : _cfg . updater . CDN ,
'url' : '/' + _cfg . repo + '/BetterDiscordApp/' + _cfg . hash + '/data/emotedata_bttv.json' ,
2015-12-10 04:01:24 +01:00
'localurl' : null ,
'message' : 'start-bd' ,
'cacheable' : true ,
'variable' : 'emotesBTTV2' ,
2016-05-06 20:34:40 +02:00
'localpath' : _cfg . dataPath + "/emotes_bttv_2.json" ,
2015-12-10 04:01:24 +01:00
'encoding' : "utf8" ,
'https' : true ,
'parse' : false ,
2016-03-30 03:37:03 +02:00
'specialparser' : 4 ,
'fallback' : 'start-bd' ,
'self' : 'load-emoteData-bttv-2'
2015-10-26 05:12:39 +01:00
}
2015-11-30 20:46:20 +01:00
} ;
2016-03-30 03:37:03 +02:00
}
2015-08-29 21:20:11 +02:00
2016-05-06 20:34:40 +02:00
function hook ( ) {
try {
var webContents = getUtils ( ) . getWebContents ( ) ;
getUtils ( ) . log ( "Hooking dom-ready" ) ;
webContents . on ( 'dom-ready' , domReady ) ;
webContents . on ( 'did-finish-loading' , function ( ) {
if ( domReadyHooked ) {
return ;
}
getUtils ( ) . log ( "Hooking did-finish-loading failsafe" ) ;
domReady ( ) ;
getUtils ( ) . log ( "Hooked did-finish-loading failsafe" ) ;
} ) ;
2015-08-29 21:20:11 +02:00
2016-05-06 20:34:40 +02:00
} catch ( err ) {
exit ( err ) ;
}
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
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 + ")! <a href='https://betterdiscord.net' target='_blank'>BetterDiscord.net</a>" ) ;
2015-11-30 20:46:20 +01:00
}
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Hooking ipc async" ) ;
_bdIpc . on ( 'asynchronous-message' , function ( event , arg ) { ipcAsyncMessage ( event , arg ) ; } ) ;
2017-01-09 06:42:14 +01:00
_bdIpc . on ( 'synchronous-message' , function ( event , arg ) { ipcSyncMessage ( event , arg ) ; } ) ;
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( "Hooked ipc async" ) ;
}
initLoaders ( ) ;
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
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 ;
}
var pluginErrors = [ ] ;
getUtils ( ) . injectVarRaw ( "bdplugins" , "{}" ) ;
files . forEach ( function ( fileName ) {
if ( ! fileName . endsWith ( ".plugin.js" ) ) {
getUtils ( ) . log ( "Invalid plugin detected: " + fileName ) ;
return ;
2016-03-30 03:37:03 +02:00
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
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 ( "<br>" ) ) ;
}
} ) ;
}
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' ) ;
2016-05-06 23:44:48 +02:00
var split = theme . split ( "\n" ) ;
2016-05-06 20:34:40 +02:00
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 ;
2015-10-26 05:12:39 +01:00
}
2016-05-06 20:34:40 +02:00
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 ) ;
2016-05-06 23:44:48 +02:00
theme = split . join ( "\n" ) ;
2016-05-06 20:34:40 +02:00
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 ( "<br>" ) ) ;
2015-11-30 20:46:20 +01:00
}
2016-05-06 20:34:40 +02:00
} ) ;
}
function loadApp ( ) {
getUtils ( ) . execJs ( 'var loadingNode = document.createElement("DIV");' ) ;
getUtils ( ) . execJs ( 'loadingNode.innerHTML = \' <div style="height:30px;width:100%;background:#282B30;"><div style="padding-right:10px; float:right"> <span id="bd-status" style="line-height:30px;color:#E8E8E8;">BetterDiscord - Loading Libraries : </span><progress id="bd-pbar" value="10" max="100"></progress></div></div> \'' ) ;
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" ) ;
}
2017-01-09 06:42:14 +01:00
function ipcSyncMessage ( event , arg ) {
if ( typeof ( arg ) === "object" ) {
switch ( arg . arg ) {
case "storage" :
if ( arg . cmd == "get" ) {
event . returnValue = bdStorage . get ( arg . var , true ) ;
}
if ( arg . cmd == "set" ) {
bdStorage . set ( arg . var , arg . data , true ) ;
event . returnValue = "saved" ;
}
break ;
case "pluginstorage" :
if ( arg . cmd == "get" ) {
2017-01-09 07:32:58 +01:00
event . returnValue = bdStorage . get ( arg . var , false , arg . pn ) || null ;
2017-01-09 06:42:14 +01:00
}
if ( arg . cmd == "set" ) {
bdStorage . set ( arg . var , arg . data , false , arg . pn ) ;
event . returnValue = "saved" ;
}
break ;
}
}
}
2016-05-06 20:34:40 +02:00
2017-01-09 06:42:14 +01:00
function ipcAsyncMessage ( event , arg ) {
2016-05-06 20:34:40 +02:00
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 ;
2017-01-09 06:42:14 +01:00
case "storage" :
if ( arg . cmd == "set" ) {
bdStorage . set ( arg . var , arg . data ) ;
break ;
}
if ( arg . cmd == "get" ) {
var get = bdStorage . get ( arg . var ) ;
event . sender . send ( 'asynchronous-reply' , get ) ;
break ;
}
break ;
2016-05-06 20:34:40 +02:00
}
return ;
}
if ( _extData . hasOwnProperty ( arg ) ) {
loadExtData ( _extData [ arg ] ) ;
2015-11-30 20:46:20 +01:00
}
if ( arg == "start-bd" ) {
2016-05-06 20:34:40 +02:00
getUtils ( ) . updateLoading ( "Starting Up" , 100 , 100 ) ;
getUtils ( ) . execJs ( 'var mainCore; var startBda = function() { mainCore = new Core(); mainCore.init(); }; startBda();' ) ;
2015-11-30 20:46:20 +01:00
//Remove loading node
setTimeout ( function ( ) {
2016-05-06 20:34:40 +02:00
getUtils ( ) . execJs ( '$("#bd-status").parent().parent().hide();' ) ;
2015-11-30 20:46:20 +01:00
} , 2000 ) ;
2016-05-06 20:34:40 +02:00
getUtils ( ) . saveLogs ( _cfg . dataPath ) ;
2015-11-30 20:46:20 +01:00
}
2016-05-06 20:34:40 +02:00
}
var loadCounter = 0 ;
function loadExtData ( extData ) {
loadCounter ++ ;
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
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 ) ;
2016-03-30 03:37:03 +02:00
if ( parsedEmoteData == null ) {
2016-05-06 20:34:40 +02:00
getUtils ( ) . sendIcpAsync ( extData . fallback ) ;
2016-03-30 03:37:03 +02:00
return true ;
}
2016-05-06 20:34:40 +02:00
saveEmoteData ( extData , parsedEmoteData ) ;
injectEmoteData ( extData , parsedEmoteData ) ;
2016-03-30 03:37:03 +02:00
} ) ;
2016-05-06 20:34:40 +02:00
return ;
2016-03-30 03:37:03 +02:00
}
2016-05-06 20:34:40 +02:00
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 ) ;
2016-03-30 03:37:03 +02:00
} ) ;
2016-05-06 20:34:40 +02:00
}
2016-03-30 03:37:03 +02:00
2016-05-06 20:34:40 +02:00
function testJSON ( extData , data ) {
getUtils ( ) . log ( "Validating " + extData . resource ) ;
2016-03-30 03:37:03 +02:00
try {
var json = JSON . parse ( data ) ;
2016-05-06 20:34:40 +02:00
getUtils ( ) . log ( extData . resource + " is valid" ) ;
2016-03-30 03:37:03 +02:00
return true ;
} catch ( err ) {
2016-05-06 20:34:40 +02:00
getUtils ( ) . warn ( extData . resource + " is invalid" ) ;
2016-03-30 03:37:03 +02:00
return false ;
}
2016-05-06 20:34:40 +02:00
return false ;
}
function injectEmoteData ( extData , data ) {
if ( data == null ) {
getUtils ( ) . sendIcpAsync ( extData . message ) ;
return ;
}
if ( data . parse ) {
getUtils ( ) . injectVarRaw ( extData . variable , 'JSON.parse(\'' + data + '\');' ) ;
} else {
getUtils ( ) . injectVarRaw ( extData . variable , data ) ;
}
getUtils ( ) . sendIcpAsync ( extData . message ) ;
}
2016-03-30 03:37:03 +02:00
2016-05-06 20:34:40 +02:00
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 ) ;
}
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
function parseEmoteData ( extData , data ) {
getUtils ( ) . log ( "Parsing: " + extData . resource ) ;
2015-11-30 20:46:20 +01:00
var returnData ;
2016-05-06 20:34:40 +02:00
switch ( extData . specialparser ) {
2015-11-30 20:46:20 +01:00
case 0 : //Twitch Global Emotes
2016-05-06 20:34:40 +02:00
return data ;
2015-11-30 20:46:20 +01:00
break ;
case 1 : //Twitch Subscriber Emotes
returnData = { } ;
2016-05-06 20:34:40 +02:00
if ( ! testJSON ( extData , data ) ) {
2016-03-30 03:37:03 +02:00
return null ;
}
2016-05-06 20:34:40 +02:00
data = JSON . parse ( data ) ;
2016-03-30 03:37:03 +02:00
2016-05-06 20:34:40 +02:00
var channels = data [ "channels" ] ;
2015-11-30 20:46:20 +01:00
for ( var channel in channels ) {
var emotes = channels [ channel ] [ "emotes" ] ;
for ( var i = 0 ; i < emotes . length ; i ++ ) {
var code = emotes [ i ] [ "code" ] ;
var id = emotes [ i ] [ "image_id" ] ;
returnData [ code ] = id ;
}
}
returnData = JSON . stringify ( returnData ) ;
break ;
case 2 : //FFZ Emotes
2016-05-06 20:34:40 +02:00
returnData = data ;
2015-11-30 20:46:20 +01:00
break ;
case 3 : //BTTV Emotes
returnData = { } ;
2016-03-30 03:37:03 +02:00
2016-05-06 20:34:40 +02:00
if ( ! testJSON ( extData , data ) ) {
2016-03-30 03:37:03 +02:00
return null ;
}
2016-05-06 20:34:40 +02:00
data = JSON . parse ( data ) ;
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
for ( var emote in data . emotes ) {
emote = data . emotes [ emote ] ;
2015-11-30 20:46:20 +01:00
var url = emote . url ;
var code = emote . regex ;
returnData [ code ] = url ;
}
returnData = JSON . stringify ( returnData ) ;
break ;
2015-12-10 04:01:24 +01:00
case 4 :
2016-05-06 20:34:40 +02:00
returnData = data ;
2015-12-10 04:01:24 +01:00
break ;
2015-11-30 20:46:20 +01:00
}
return returnData ;
2016-05-06 20:34:40 +02:00
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
function getUtils ( ) {
return _utils2 ;
}
2015-11-30 20:46:20 +01:00
2016-05-06 20:34:40 +02:00
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
2015-08-28 09:52:36 +02:00
2016-03-30 03:37:03 +02:00
exports . BetterDiscord = BetterDiscord ;