2019-06-20 17:14:03 -04:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
import RavenLogger from './raven';
|
|
|
|
|
|
|
|
import Logger from 'utilities/logging';
|
|
|
|
import Module from 'utilities/module';
|
|
|
|
|
|
|
|
import {DEBUG} from 'utilities/constants';
|
2021-02-11 19:40:12 -05:00
|
|
|
import {serializeBlob, deserializeBlob} from 'utilities/blobs';
|
2019-06-20 17:14:03 -04:00
|
|
|
|
|
|
|
import SettingsManager from './settings/index';
|
|
|
|
|
|
|
|
class FFZBridge extends Module {
|
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
const start_time = performance.now(),
|
|
|
|
VER = FFZBridge.version_info;
|
|
|
|
|
|
|
|
FFZBridge.instance = this;
|
|
|
|
|
|
|
|
this.name = 'ffz_bridge';
|
|
|
|
this.__state = 0;
|
|
|
|
this.__modules.core = this;
|
|
|
|
|
|
|
|
// ========================================================================
|
|
|
|
// Error Reporting and Logging
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
this.inject('raven', RavenLogger);
|
|
|
|
|
|
|
|
this.log = new Logger(null, null, null, this.raven);
|
2021-02-11 19:40:12 -05:00
|
|
|
this.log.label = 'FFZBridge';
|
2019-06-20 17:14:03 -04:00
|
|
|
this.log.init = true;
|
|
|
|
|
|
|
|
this.core_log = this.log.get('core');
|
|
|
|
|
|
|
|
this.log.info(`FrankerFaceZ Settings Bridge v${VER} (build ${VER.build}${VER.commit ? ` - commit ${VER.commit}` : ''})`);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================================================
|
|
|
|
// Core Systems
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
this.inject('settings', SettingsManager);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================================================
|
|
|
|
// Startup
|
|
|
|
// ========================================================================
|
|
|
|
|
|
|
|
this.enable().then(() => {
|
|
|
|
const duration = performance.now() - start_time;
|
|
|
|
this.core_log.info(`Initialization complete in ${duration.toFixed(5)}ms.`);
|
|
|
|
this.log.init = false;
|
|
|
|
}).catch(err => {
|
|
|
|
this.core_log.error(`An error occurred during initialization.`, err);
|
|
|
|
this.log.init = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static get() {
|
|
|
|
return FFZBridge.instance;
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:40:12 -05:00
|
|
|
async onEnable() {
|
2019-06-20 17:14:03 -04:00
|
|
|
window.addEventListener('message', this.onMessage.bind(this));
|
|
|
|
this.settings.provider.on('changed', this.onProviderChange, this);
|
2021-02-11 19:40:12 -05:00
|
|
|
this.settings.provider.on('changed-blob', this.onProviderBlobChange, this);
|
|
|
|
this.settings.provider.on('clear-blobs', this.onProviderClearBlobs, this);
|
|
|
|
|
|
|
|
await this.settings.awaitProvider();
|
|
|
|
await this.settings.provider.awaitReady();
|
|
|
|
|
2019-06-20 17:14:03 -04:00
|
|
|
this.send({
|
|
|
|
ffz_type: 'ready'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-02-11 19:40:12 -05:00
|
|
|
async onMessage(event) {
|
2019-06-20 17:14:03 -04:00
|
|
|
const msg = event.data;
|
|
|
|
if ( ! msg || ! msg.ffz_type )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( msg.ffz_type === 'load' ) {
|
|
|
|
const out = {};
|
|
|
|
for(const [key, value] of this.settings.provider.entries())
|
|
|
|
out[key] = value;
|
|
|
|
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'loaded',
|
|
|
|
data: out
|
|
|
|
});
|
2019-11-25 17:50:20 -05:00
|
|
|
|
2021-02-11 19:40:12 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
} else if ( msg.ffz_type === 'change' ) {
|
2019-11-25 17:50:20 -05:00
|
|
|
this.onChange(msg);
|
2021-02-11 19:40:12 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! msg.id )
|
|
|
|
return this.log.warn('Received command with no reply ID');
|
|
|
|
|
|
|
|
let reply, transfer;
|
|
|
|
|
|
|
|
try {
|
|
|
|
if ( msg.ffz_type === 'init-load' ) {
|
|
|
|
reply = {
|
|
|
|
blobs: this.settings.provider.supportsBlobs,
|
|
|
|
values: {}
|
|
|
|
};
|
|
|
|
|
|
|
|
for(const [key,value] of this.settings.provider.entries())
|
|
|
|
reply.values[key] = value;
|
|
|
|
|
|
|
|
} else if ( msg.ffz_type === 'set' )
|
|
|
|
this.settings.provider.set(msg.key, msg.value);
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'delete' )
|
|
|
|
this.settings.provider.delete(msg.key);
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'clear' )
|
|
|
|
this.settings.provider.clear();
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'get-blob' ) {
|
|
|
|
reply = await serializeBlob(await this.settings.provider.getBlob(msg.key));
|
|
|
|
if ( reply )
|
|
|
|
transfer = reply.buffer;
|
|
|
|
|
|
|
|
} else if ( msg.ffz_type === 'set-blob' ) {
|
|
|
|
const blob = deserializeBlob(msg.value);
|
|
|
|
await this.settings.provider.setBlob(msg.key, blob);
|
|
|
|
|
|
|
|
} else if ( msg.ffz_type === 'delete-blob' )
|
|
|
|
await this.settings.provider.deleteBlob(msg.key);
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'has-blob' )
|
|
|
|
reply = await this.settings.provider.hasBlob(msg.key);
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'clear-blobs' )
|
|
|
|
await this.settings.provider.clearBlobs();
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'blob-keys' )
|
|
|
|
reply = await this.settings.provider.blobKeys();
|
|
|
|
|
|
|
|
else if ( msg.ffz_type === 'flush' )
|
|
|
|
await this.settings.provider.flush();
|
|
|
|
|
|
|
|
else
|
|
|
|
return this.send({
|
|
|
|
ffz_type: 'reply-error',
|
|
|
|
id: msg.id,
|
|
|
|
error: 'bad-command'
|
|
|
|
});
|
|
|
|
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'reply',
|
|
|
|
id: msg.id,
|
|
|
|
reply
|
|
|
|
}, transfer);
|
|
|
|
|
|
|
|
} catch(err) {
|
|
|
|
this.log.error('Error handling command.', err);
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'reply-error',
|
|
|
|
id: msg.id
|
|
|
|
});
|
|
|
|
}
|
2019-06-20 17:14:03 -04:00
|
|
|
}
|
|
|
|
|
2021-02-11 19:40:12 -05:00
|
|
|
send(msg, blob) { // eslint-disable-line class-methods-use-this
|
2019-06-20 17:14:03 -04:00
|
|
|
try {
|
2021-02-11 19:40:12 -05:00
|
|
|
window.parent.postMessage(msg, '*', blob ? [blob] : undefined)
|
2019-06-20 17:14:03 -04:00
|
|
|
} catch(err) { this.log.error('send error', err); /* no-op */ }
|
|
|
|
}
|
|
|
|
|
2019-11-25 17:50:20 -05:00
|
|
|
onChange(msg) {
|
|
|
|
const key = msg.key,
|
|
|
|
value = msg.value,
|
|
|
|
deleted = msg.deleted;
|
|
|
|
|
|
|
|
if ( deleted )
|
|
|
|
this.settings.provider.delete(key);
|
|
|
|
else
|
|
|
|
this.settings.provider.set(key, value);
|
|
|
|
}
|
|
|
|
|
2019-06-20 17:14:03 -04:00
|
|
|
onProviderChange(key, value, deleted) {
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'change',
|
|
|
|
key,
|
|
|
|
value,
|
|
|
|
deleted
|
|
|
|
});
|
|
|
|
}
|
2021-02-11 19:40:12 -05:00
|
|
|
|
|
|
|
onProviderBlobChange(key, deleted) {
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'change-blob',
|
|
|
|
key,
|
|
|
|
deleted
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
onProviderClearBlobs() {
|
|
|
|
this.send({
|
|
|
|
ffz_type: 'clear-blobs'
|
|
|
|
});
|
|
|
|
}
|
2019-06-20 17:14:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
FFZBridge.Logger = Logger;
|
|
|
|
|
|
|
|
const VER = FFZBridge.version_info = {
|
|
|
|
major: __version_major__,
|
|
|
|
minor: __version_minor__,
|
|
|
|
revision: __version_patch__,
|
|
|
|
extra: __version_prerelease__?.length && __version_prerelease__[0],
|
|
|
|
commit: __git_commit__,
|
|
|
|
build: __webpack_hash__,
|
|
|
|
toString: () =>
|
|
|
|
`${VER.major}.${VER.minor}.${VER.revision}${VER.extra || ''}${DEBUG ? '-dev' : ''}`
|
|
|
|
}
|
|
|
|
|
|
|
|
window.FFZBridge = FFZBridge;
|
|
|
|
window.ffz_bridge = new FFZBridge();
|