1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-09-17 18:26:57 +00:00

Merge branch 'master' into socketdev

This commit is contained in:
Kane York 2015-11-01 14:48:03 -08:00
commit 796966c3b9
13 changed files with 371 additions and 85 deletions

1
.gitignore vendored
View file

@ -6,5 +6,6 @@ Extension Building
*.iml
script.js
script.min.js
credentials.json
/socketserver/cmd/socketserver/socketserver

View file

@ -13,7 +13,13 @@ var fs = require('fs'),
// Templates
var jsEscape = require('gulp-js-escape'),
wrap = require('gulp-wrap'),
declare = require('gulp-declare');
declare = require('gulp-declare'),
minifyCss = require('gulp-minify-css');
// Deploy Dependencies
var ftp = require('vinyl-ftp'),
request = require('request');
// Server Dependencies
@ -56,7 +62,25 @@ gulp.task('templates', ['prepare'], function() {
});
gulp.task('scripts', ['prepare', 'templates'], function() {
gulp.task('styles', ['prepare'], function() {
gulp.src(['build/styles/**/*.css'])
.pipe(minifyCss())
.pipe(jsEscape())
.pipe(declare({
root: 'exports',
noRedeclare: true,
processName: function(filePath) {
var match = filePath.match(/build[\\\/]styles[\\\/](.*)\.css$/);
return declare.processNameByPath((match && match.length > 1) ? match[1] : filePath);
}
}))
.pipe(concat('styles.js'))
.pipe(gulp.dest('build/'))
.on('error', util.log)
});
gulp.task('scripts', ['prepare', 'templates', 'styles'], function() {
gulp.src(['build/main.js'])
.pipe(browserify())
.pipe(concat('script.js'))
@ -76,6 +100,79 @@ gulp.task('watch', ['default', 'server'], function() {
gulp.task('default', ['scripts']);
// Deploy
gulp.task('upload', ['default'], function() {
// Load credentials from an external file.
var contents = fs.readFileSync('credentials.json', 'utf8'),
cred = JSON.parse(contents);
cred.log = util.log;
// Create the connection.
var conn = ftp.create(cred);
// What we're transfering.
var ftp_path = cred.remote_path,
globs = [
"script.min.js",
"style.css",
"dark.css",
"changelog.html"
];
util.log(cred.remote_path);
return gulp.src(globs, {base: '.', buffer: false})
.pipe(conn.newerOrDifferentSize(ftp_path))
.pipe(conn.dest(ftp_path))
.on('error', util.log);
});
gulp.task('clear_cache', ['upload'], function() {
// Load credentials from an external file.
var contents = fs.readFileSync('credentials.json', 'utf8'),
cred = JSON.parse(contents);
// Build the URLs.
var base = "://cdn.frankerfacez.com/script/",
files = [],
globs = [
"script.min.js",
"style.css",
"dark.css",
"changelog.html"
];
for(var i=0; i < globs.length; i++) {
files.push("http" + base + globs[i]);
files.push("https" + base + globs[i]);
}
request({
method: 'DELETE',
uri: "https://api.cloudflare.com/client/v4/zones/" + cred.cloudflare_zone + "/purge_cache",
headers: {
"X-Auth-Email": cred.cloudflare_email,
"X-Auth-Key": cred.cloudflare_key
},
json: {
"files": files
}
}, function(error, request, body) {
if ( error )
return util.log("[FAIL] Error: " + error);
else if ( request.statusCode !== 200 )
return util.log("[FAIL] Non-200 Status: " + request.statusCode);
util.log("[SUCCESS] Cache cleared.");
});
});
gulp.task('deploy', ['upload', 'clear_cache']);
// Server
gulp.task('server', function() {

View file

@ -15,11 +15,13 @@
"gulp-footer": "^1.0.5",
"gulp-header": "^1.2.2",
"gulp-js-escape": "^1.0.1",
"gulp-minify-css": "^1.2.1",
"gulp-rename": "^1.2.0",
"gulp-uglify": "^1.0.2",
"gulp-util": "^3.0.2",
"gulp-wrap": "^0.11.0",
"request": "^2.51.0"
"request": "^2.65.0",
"vinyl-ftp": "^0.4.5"
},
"repository": {
"type": "git",

View file

@ -1,15 +1,19 @@
var SVGPATH = '<path d="m120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4.16 11.01 5.05 2.08 3.61 6.12 5.46 8.19 9.07 3.6 5.67 7.09 11.66 8.28 18.36 1.61 9.51 7.07 17.72 12.69 25.35 3.43 7.74 1.97 16.49 3.6 24.62 2.23 5.11 4.09 10.39 6.76 15.31 1.16 2 4.38 0.63 4.77-1.32 1.2-7.1-2.39-13.94-1.97-21.03 0.38-3.64-0.91-7.48 0.25-10.99 2.74-3.74 4.57-8.05 7.47-11.67 3.55-5.47 10.31-8.34 16.73-7.64 2.26 2.89 5.13 5.21 7.58 7.92 2.88 4.3 6.52 8.01 9.83 11.97 1.89 2.61 3.06 5.64 4.48 8.52 2.81 4.9 4 10.5 6.63 15.49 2.16 6.04 5.56 11.92 5.37 18.5 0.65 1.95 0.78 4 0.98 6.03 1.01 3.95 2.84 8.55 0.63 12.42-2.4 5.23-7.03 8.97-11.55 12.33-6.06 4.66-11.62 10.05-18.37 13.75-4.06 2.65-8.24 5.17-12.71 7.08-3.59 1.57-6.06 4.94-9.85 6.09-2.29 1.71-3.98 4.51-6.97 5.02-4.56 1.35-8.98-3.72-13.5-1.25-2.99 1.83-6.19 3.21-9.39 4.6-8.5 5.61-18.13 9.48-28.06 11.62-8.36-0.2-16.69 0.62-25.05 0.47-3.5-1.87-7.67-1.08-11.22-2.83-6.19-1.52-10.93-6.01-16.62-8.61-2.87-1.39-5.53-3.16-8.11-4.99-2.58-1.88-4.17-4.85-6.98-6.44-3.83-0.11-6.54 3.42-10.24 3.92-2.31 0.28-4.64 0.32-6.96 0.31-3.5-3.65-5.69-8.74-10.59-10.77-5.01-3.68-10.57-6.67-14.84-11.25-2.52-2.55-5.22-4.87-8.24-6.8-4.73-4.07-7.93-9.51-11.41-14.62-3.08-4.41-5.22-9.73-4.6-15.19 0.65-8.01 0.62-16.18 2.55-24.02 4.06-10.46 11.15-19.34 18.05-28.06 3.71-5.31 9.91-10.21 16.8-8.39 3.25 1.61 5.74 4.56 7.14 7.89 1.19 2.7 3.49 4.93 3.87 7.96 0.97 5.85 1.6 11.86 0.74 17.77-1.7 6.12-2.98 12.53-2.32 18.9 0.01 2.92 2.9 5.36 5.78 4.57 3.06-0.68 3.99-4.07 5.32-6.48 1.67-4.06 4.18-7.66 6.69-11.23 3.61-5.28 5.09-11.57 7.63-17.37 2.07-4.56 1.7-9.64 2.56-14.46 0.78-7.65-0.62-15.44 0.7-23.04 1.32-3.78 1.79-7.89 3.8-11.4 3.01-3.66 6.78-6.63 9.85-10.26 1.72-2.12 4.21-3.32 6.55-4.6 7.89-2.71 15.56-6.75 24.06-7z"/>',
DEBUG = localStorage.ffzDebugMode == "true" && document.body.classList.contains('ffz-dev'),
WS_SERVERS = DEBUG ? ["localhost:8001", "catbag.frankerfacez.com"] : ["catbag.frankerfacez.com"],
SERVER = DEBUG ? "//localhost:8000/" : "//cdn.frankerfacez.com/";
module.exports = {
DEBUG: DEBUG,
SERVER: SERVER,
WS_SERVERS: WS_SERVERS,
API_SERVER: "//api.frankerfacez.com/",
API_SERVER_2: "//direct-api.frankerfacez.com/",
WS_SERVER_POOLS: {
1: ["ws://catbag.frankerfacez.com/", "ws://andknuckles.frankerfacez.com/"],
2: ["ws://localhost:8001/"]
},
KNOWN_CODES: {
"#-?[\\\\/]": "#-/",
":-?(?:7|L)": ":-7",

View file

@ -456,8 +456,14 @@ FFZ.prototype._modify_cindex = function(view) {
el = stat_el && stat_el.querySelector('span'),
player_cont = f.players && f.players[channel_id],
player = player_cont && player_cont.ffz_player,
player = undefined, stats = undefined;
try {
player = player_cont && player_cont.ffz_player;
stats = player && player.stats;
} catch(err) {
f.error("Channel ffzUpdatePlayerStats: player.stats: " + err);
}
if ( ! container || ! f.settings.player_stats || ! stats || stats.hlsLatencyBroadcaster === 'NaN' || stats.hlsLatencyBroadcaster === NaN ) {
if ( stat_el )
@ -508,8 +514,14 @@ FFZ.prototype._modify_cindex = function(view) {
el = stat_el && stat_el.querySelector('span'),
player_cont = f.players && f.players[hosted_id],
player = player_cont && player_cont.ffz_player,
player = undefined, stats = undefined;
try {
player = player_cont && player_cont.ffz_player;
stats = player && player.stats;
} catch(err) {
f.error("Channel ffzUpdatePlayerStats: player.stats: " + err);
}
if ( ! container || ! f.settings.player_stats || ! stats || stats.hlsLatencyBroadcaster === 'NaN' || stats.hlsLatencyBroadcaster === NaN ) {

View file

@ -98,6 +98,36 @@ FFZ.settings_info.minimal_chat = {
};
FFZ.settings_info.chat_batching = {
type: "select",
options: {
0: "No Batching",
250: "Minor (0.25s)",
500: "Normal (0.5s)",
750: "Large (0.75s)",
1000: "Extreme (1s)"
},
value: 0,
category: "Chat Appearance",
no_bttv: true,
name: "Chat Message Batching",
help: "Display chat messages in batches to improve performance in <em>extremely</em> fast chats.",
process_value: function(val) {
if ( typeof val === "string" )
return parseInt(val) || 0;
return val;
},
on_update: function(val) {
if ( this._roomv )
this._roomv.ffzUpdateStatus();
}
};
FFZ.settings_info.chat_delay = {
type: "select",
options: {

View file

@ -159,14 +159,23 @@ FFZ.prototype._modify_player = function(player) {
return;
player = tp2.getPlayer();
if ( ! player )
if ( ! player || ! player.getVideo )
// We can't get a valid player. :-(
return;
}
this.set('ffz_player', player);
// Only set up the stats hooks if we need stats.
if ( ! player.getVideo() )
var has_video;
try {
has_video = player.getVideo();
} catch(err) {
f.error("Player2 ffzPostPlayer: getVideo: " + err);
}
if ( ! has_video )
this.ffzInitStats();
},
@ -186,7 +195,7 @@ FFZ.prototype._modify_player = function(player) {
player.ffz_stats = player.getStatsEnabled();
} catch(err) {
// Assume stats are off.
f.log("player ffzInitStats: getStatsEnabled still doesn't work: " + err);
f.error("Player2 ffzInitStats: getStatsEnabled still doesn't work: " + err);
player.ffz_stats = false;
}

View file

@ -190,6 +190,7 @@ FFZ.prototype._modify_rview = function(view) {
slow_badge = cont.querySelector('#ffz-stat-slow'),
banned_badge = cont.querySelector('#ffz-stat-banned'),
delay_badge = cont.querySelector('#ffz-stat-delay'),
batch_badge = cont.querySelector('#ffz-stat-batch'),
btn = cont.querySelector('button');
if ( f.has_bttv || ! f.settings.room_status ) {
@ -199,6 +200,10 @@ FFZ.prototype._modify_rview = function(view) {
sub_badge.parentElement.removeChild(sub_badge);
if ( slow_badge )
slow_badge.parentElement.removeChild(slow_badge);
if ( delay_badge )
delay_badge.parentElement.removeChild(delay_badge);
if ( batch_badge )
batch_badge.parentElement.removeChild(batch_badge);
if ( btn )
btn.classList.remove('ffz-waiting');
@ -209,7 +214,7 @@ FFZ.prototype._modify_rview = function(view) {
r9k_badge = document.createElement('span');
r9k_badge.className = 'ffz room-state stat float-right';
r9k_badge.id = 'ffz-stat-r9k';
r9k_badge.innerHTML = 'R9K';
r9k_badge.innerHTML = 'R<span>9K</span>';
r9k_badge.title = "This room is in R9K-mode.";
cont.appendChild(r9k_badge);
jQuery(r9k_badge).tipsy({gravity:"s", offset:15});
@ -219,7 +224,7 @@ FFZ.prototype._modify_rview = function(view) {
sub_badge = document.createElement('span');
sub_badge.className = 'ffz room-state stat float-right';
sub_badge.id = 'ffz-stat-sub';
sub_badge.innerHTML = 'SUB';
sub_badge.innerHTML = 'S<span>UB</span>';
sub_badge.title = "This room is in subscribers-only mode.";
cont.appendChild(sub_badge);
jQuery(sub_badge).tipsy({gravity:"s", offset:15});
@ -229,8 +234,7 @@ FFZ.prototype._modify_rview = function(view) {
slow_badge = document.createElement('span');
slow_badge.className = 'ffz room-state stat float-right';
slow_badge.id = 'ffz-stat-slow';
slow_badge.innerHTML = 'SLOW';
slow_badge.title = "This room is in slow mode. You may send messages every 120 seconds.";
slow_badge.innerHTML = 'S<span>LOW</span>';
cont.appendChild(slow_badge);
jQuery(slow_badge).tipsy({gravity:"s", offset:15});
}
@ -239,7 +243,7 @@ FFZ.prototype._modify_rview = function(view) {
banned_badge = document.createElement('span');
banned_badge.className = 'ffz room-state stat float-right';
banned_badge.id = 'ffz-stat-banned';
banned_badge.innerHTML = 'BAN';
banned_badge.innerHTML = 'B<span>AN</span>';
banned_badge.title = "You have been banned from talking in this room.";
cont.appendChild(banned_badge);
jQuery(banned_badge).tipsy({gravity:"s", offset:15});
@ -249,21 +253,54 @@ FFZ.prototype._modify_rview = function(view) {
delay_badge = document.createElement('span');
delay_badge.className = 'ffz room-state stat float-right';
delay_badge.id = 'ffz-stat-delay';
delay_badge.innerHTML = 'DELAY';
delay_badge.title = "You have enabled artificial chat delay. Messages are displayed after 0.3 seconds.";
delay_badge.innerHTML = 'D<span>ELAY</span>';
cont.appendChild(delay_badge);
jQuery(delay_badge).tipsy({gravity:"s", offset:15});
}
r9k_badge.classList.toggle('hidden', !(room && room.get('r9k')));
sub_badge.classList.toggle('hidden', !(room && room.get('subsOnly')));
banned_badge.classList.toggle('hidden', !(room && room.get('ffz_banned')));
if ( ! batch_badge ) {
batch_badge = document.createElement('span');
batch_badge.className = 'ffz room-state stat float-right';
batch_badge.id = 'ffz-stat-batch';
batch_badge.innerHTML = 'B<span>ATCH</span>';
cont.appendChild(batch_badge);
jQuery(batch_badge).tipsy({gravity:"s", offset:15});
}
slow_badge.classList.toggle('hidden', !(room && room.get('slowMode')));
var vis_count = 0,
r9k_vis = room && room.get('r9k'),
sub_vis = room && room.get('subsOnly'),
ban_vis = room && room.get('ffz_banned'),
slow_vis = room && room.get('slowMode'),
delay_vis = f.settings.chat_delay !== 0,
batch_vis = f.settings.chat_batching !== 0;
if ( r9k_vis ) vis_count += 1;
if ( sub_vis ) vis_count += 1;
if ( ban_vis ) vis_count += 1;
if ( slow_vis ) vis_count += 1;
if ( delay_vis ) vis_count += 1;
if ( batch_vis ) vis_count += 1;
r9k_badge.classList.toggle('truncated', vis_count > 3);
sub_badge.classList.toggle('truncated', vis_count > 3);
banned_badge.classList.toggle('truncated', vis_count > 3);
slow_badge.classList.toggle('truncated', vis_count > 3);
delay_badge.classList.toggle('truncated', vis_count > 3);
batch_badge.classList.toggle('truncated', vis_count > 3);
r9k_badge.classList.toggle('hidden', ! r9k_vis);
sub_badge.classList.toggle('hidden', ! sub_vis);
banned_badge.classList.toggle('hidden', ! ban_vis);
slow_badge.classList.toggle('hidden', ! slow_vis);
slow_badge.title = "This room is in slow mode. You may send messages every " + utils.number_commas(room && room.get('slow')||120) + " seconds.";
delay_badge.title = "You have enabled artificial chat delay. Messages are displayed after " + (f.settings.chat_delay/1000) + " seconds.";
delay_badge.classList.toggle('hidden', f.settings.chat_delay === 0);
delay_badge.classList.toggle('hidden', ! delay_vis);
batch_badge.title = "You have enabled chat message batching. Messages are displayed in " + (f.settings.chat_batching/1000) + " second increments.";
batch_badge.classList.toggle('hidden', ! batch_vis);
if ( btn ) {
btn.classList.toggle('ffz-waiting', (room && room.get('slowWait') || 0));
@ -1022,7 +1059,7 @@ FFZ.prototype._modify_room = function(room) {
// Artificial chat delay
pushMessage: function(msg) {
if ( f.settings.chat_delay !== 0 || (this.ffzPending && this.ffzPending.length) ) {
if ( f.settings.chat_batching !== 0 || f.settings.chat_delay !== 0 || (this.ffzPending && this.ffzPending.length) ) {
if ( ! this.ffzPending )
this.ffzPending = [];
@ -1056,11 +1093,21 @@ FFZ.prototype._modify_room = function(room) {
// Instead of just blindly looping every x seconds, we want to calculate the time until
// the next message should be displayed, and then set the timeout for that. We'll
// end up looping a bit more frequently, but it'll make chat feel more responsive.
// If we have a pending flush, don't reschedule. It wouldn't change.
if ( this._ffz_pending_flush )
clearTimeout(this._ffz_pending_flush);
return;
/*if ( this._ffz_pending_flush )
clearTimeout(this._ffz_pending_flush);*/
if ( this.ffzPending && this.ffzPending.length ) {
var delay = 50 + Math.max(0, (f.settings.chat_delay + (this.ffzPending[0].time||0)) - (now || Date.now()));
// We need either the amount of chat delay past the first message, if chat_delay is on, or the
// amount of time from the last batch.
var delay = Math.max(
(f.settings.chat_delay !== 0 ? 50 + Math.max(0, (f.settings.chat_delay + (this.ffzPending[0].time||0)) - (now || Date.now())) : 0),
(f.settings.chat_batching !== 0 ? Math.max(0, f.settings.chat_batching - ((now || Date.now()) - (this._ffz_last_batch||0))) : 0));
this._ffz_pending_flush = setTimeout(this.ffzPendingFlush.bind(this), delay);
}
},
@ -1068,13 +1115,14 @@ FFZ.prototype._modify_room = function(room) {
ffzPendingFlush: function() {
this._ffz_pending_flush = null;
var now = Date.now();
var now = this._ffz_last_batch = Date.now();
for (var i = 0, l = this.ffzPending.length; i < l; i++) {
var msg = this.ffzPending[i];
if ( msg.removed )
continue;
if ( f.settings.chat_delay + msg.time > now )
if ( f.settings.chat_delay !== 0 && (f.settings.chat_delay + msg.time > now) )
break;
this.ffzActualPushMessage(msg);

View file

@ -22,7 +22,7 @@ FFZ.get = function() { return FFZ.instance; }
// Version
var VER = FFZ.version_info = {
major: 3, minor: 5, revision: 42,
major: 3, minor: 5, revision: 50,
toString: function() {
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
}

View file

@ -3,50 +3,106 @@ var FFZ = window.FrankerFaceZ,
FFZ.prototype._ws_open = false;
FFZ.prototype._ws_delay = 0;
FFZ.prototype._ws_last_iframe = 0;
FFZ.prototype._ws_host_idx = Math.floor(Math.random() * constants.WS_SERVERS.length) + 1;
if (constants.DEBUG) {
FFZ.prototype._ws_host_idx = 0;
}
FFZ.prototype._ws_host_idx = -1;
FFZ.prototype._ws_current_pool = -1;
FFZ.ws_commands = {};
FFZ.ws_on_close = [];
// ----------------
// Socket Creation
// Settings
// ----------------
// Attempt to authenticate to the socket server as a real browser by loading the root page.
// e.g. cloudflare ddos check
FFZ.prototype.ws_iframe = function() {
this._ws_last_iframe = Date.now();
var ifr = document.createElement('iframe'),
f = this;
var ffz_socket_seed;
ifr.src = 'http://catbag.frankerfacez.com';
ifr.style.visibility = 'hidden';
document.body.appendChild(ifr);
setTimeout(function() {
document.body.removeChild(ifr);
if ( ! f._ws_open )
f.ws_create();
}, 2000);
try {
ffz_socket_seed = JSON.parse(localStorage.ffz_socket_seed);
} catch(err) { }
if ( ! ffz_socket_seed ) {
ffz_socket_seed = Math.random();
localStorage.ffz_socket_seed = JSON.stringify(ffz_socket_seed);
}
FFZ.prototype.ws_create = function() {
// Disable sockets for now.
return;
FFZ.settings_info.socket_server_pool = {
type: "select",
options: {
0: "Disabled",
1: "Production",
2: "Development"
},
value: ffz_socket_seed > 0.65 ? 1 : 0,
process_value: function(val) {
if ( typeof val === "string" )
return parseInt(val) || 0;
return val;
},
visible: function() { return (localStorage.hasOwnProperty('ffz_socket_server_pool') && this.settings.socket_server_pool !== 1) || this.settings.developer_mode || (Date.now() - parseInt(localStorage.ffzLastDevMode || "0")) < 604800000; },
category: "Debugging",
name: "Socket Server Cluster",
help: "Select which cluster of socket servers to connect to.",
on_update: function(val) {
if ( val === this._ws_current_pool )
return;
try {
this._ws_sock.close();
} catch(err) { }
this._ws_open = false;
this._ws_delay = 0;
this._ws_host_idx = -1;
if ( this._ws_recreate_timer ) {
clearTimeout(this._ws_recreate_timer);
this._ws_recreate_timer = null;
}
if ( val === 0 )
return;
this.ws_create();
}
};
// ----------------
// Socket Creation
// ----------------
FFZ.prototype.ws_create = function() {
var f = this, ws;
this._ws_last_req = 0;
this._ws_callbacks = {};
this._ws_last_req = 1;
this._ws_callbacks = {1: f._ws_on_hello.bind(f)};
this._ws_pending = this._ws_pending || [];
this._ws_recreate_timer = null;
var pool_id = this.settings.socket_server_pool,
pool = constants.WS_SERVER_POOLS[pool_id];
this._ws_current_pool = pool_id;
if ( ! pool )
return;
if ( this._ws_host_idx < 0 )
this._ws_host_idx = Math.floor(Math.random() * pool.length);
var server = pool[this._ws_host_idx];
this.log("Using Socket Server: " + server + " [" + pool_id + ":" + this._ws_host_idx + "]");
try {
ws = this._ws_sock = new WebSocket("ws://" + constants.WS_SERVERS[this._ws_host_idx] + "/");
ws = this._ws_sock = new WebSocket(pool[this._ws_host_idx]);
} catch(err) {
this._ws_exists = false;
return this.log("Error Creating WebSocket: " + err);
@ -57,10 +113,10 @@ FFZ.prototype.ws_create = function() {
ws.onopen = function(e) {
f._ws_open = true;
f._ws_delay = 0;
f._ws_last_iframe = Date.now();
f.log("Socket connected.");
f.log("Socket Connected.");
f.ws_send("hello", ["ffz_" + FFZ.version_info, localStorage.ffzClientId], f._ws_on_hello.bind(f));
// Hard-code the first command.
ws.send("1 hello " + JSON.stringify(["ffz_" + FFZ.version_info, localStorage.ffzClientId]));
var user = f.get_user();
if ( user )
@ -70,7 +126,6 @@ FFZ.prototype.ws_create = function() {
if ( f.is_dashboard ) {
var match = location.pathname.match(/\/([^\/]+)/);
if ( match ) {
f.ws_send("sub", "room." + match[1]);
f.ws_send("sub", "channel." + match[1]);
}
}
@ -124,13 +179,16 @@ FFZ.prototype.ws_create = function() {
if ( ! f._ws_offline_time ) {
f._ws_offline_time = new Date().getTime();
}
// Cycle selected server
f._ws_host_idx = (f._ws_host_idx + 1) % constants.WS_SERVERS.length;
}
ws.onclose = function(e) {
var was_open = f._ws_open;
f.log("Socket closed. (Code: " + e.code + ", Reason: " + e.reason + ")");
// If a recreate is already scheduled, this is expected.
if ( f._ws_recreate_timer )
return;
f._ws_open = false;
if ( ! f._ws_offline_time ) {
f._ws_offline_time = new Date().getTime();
@ -145,14 +203,11 @@ FFZ.prototype.ws_create = function() {
}
}
// Cycle selected server
f._ws_host_idx = (f._ws_host_idx + 1) % constants.WS_SERVERS.length;
if ( f._ws_delay > 10000 ) {
var ua = navigator.userAgent.toLowerCase();
if ( Date.now() - f._ws_last_iframe > 1800000 && !(ua.indexOf('chrome') === -1 && ua.indexOf('safari') !== -1) )
return f.ws_iframe();
}
// Cycle selected server if our last attempt to connect didn't
// actually connect.
if ( ! was_open )
// Actually, let's get a random new server instead.
f._ws_host_idx = -1; //(f._ws_host_idx + 1) % pool.length;
// We never ever want to not have a socket.
if ( f._ws_delay < 60000 )
@ -161,7 +216,7 @@ FFZ.prototype.ws_create = function() {
// Randomize delay.
f._ws_delay = (Math.floor(Math.random()*60)+30)*1000;
setTimeout(f.ws_create.bind(f), f._ws_delay);
f._ws_recreate_timer = setTimeout(f.ws_create.bind(f), f._ws_delay);
}
ws.onmessage = function(e) {
@ -193,7 +248,7 @@ FFZ.prototype.ws_create = function() {
delete f._ws_callbacks[request];
} else {
var success = cmd === 'True',
var success = cmd === 'ok',
has_callback = typeof f._ws_callbacks[request] === "function";
if ( ! has_callback )
@ -251,7 +306,7 @@ FFZ.prototype._ws_on_hello = function(success, data) {
localStorage.ffzClientId = data;
this.log("Client ID: " + data);
var survey = {},
/*var survey = {},
set = survey['settings'] = {};
for(var key in FFZ.settings_info)
@ -271,10 +326,35 @@ FFZ.prototype._ws_on_hello = function(success, data) {
survey['language'] = navigator.language;
survey['platform'] = navigator.platform;
this.ws_send("survey", [survey]);
this.ws_send("survey", [survey]);*/
}
// ----------------
// Reconnect Logic
// ----------------
FFZ.ws_commands.reconnect = function() {
this.log("Socket Reconnect Command Received");
// Set the socket as closed and close it.
this._ws_open = false;
this._ws_sock.close();
// Socket Close Callbacks
for(var i=0; i < FFZ.ws_on_close.length; i++) {
try {
FFZ.ws_on_close[i].bind(this)();
} catch(err) {
this.log("Error on Socket Close Callback: " + err);
}
}
// Randomize the reconnect delay to avoid a complete hammering.
this._ws_delay = Math.floor(Math.random() * 5) * 1000;
this._ws_recreate_timer = setTimeout(this.ws_create.bind(this), this._ws_delay);
}
// ----------------
// Authorization

View file

@ -850,6 +850,7 @@ span.ffz-handle:after { left: 8px }
/* Chat Mentions */
.ember-chat .mentioned:empty,
.ember-chat .mentioning:empty {
display: none;
@ -1155,7 +1156,7 @@ body:not(.ffz-chat-purge-icon) .ember-chat .mod-icons .purge { display: none; }
.ffz-chat-background .ember-chat-container.dark .ember-chat .chat-messages .chat-line.ffz-mentioned.ffz-alternate:before {
background-color: rgba(255,0,0, 0.3);
}
*/
/* The New Whispers */
@ -1643,6 +1644,8 @@ body.ffz-minimal-chat-input .ember-chat .chat-interface .textarea-contain textar
margin-right: 15px;
}
.ffz.room-state.truncated span { font-size: 8px; }
.button.primary.ffz-waiting:not(:hover) {
background-color: rgba(0,0,0,0.1);
color: #32323e;
@ -1932,28 +1935,28 @@ li[data-name="following"] a {
.ffz-legacy-mod-badges .ember-chat .badges .moderator,
.ffz-legacy-badges .ember-chat .badges .moderator {
background-color: #068c10;
background-image: url('legacy-mod.png');
background-image: url('//cdn.frankerfacez.com/script/legacy-mod.png');
}
.ffz-legacy-badges .ember-chat .badges .staff {
background-color: #6441a5;
background-image: url('legacy-staff.png');
background-image: url('//cdn.frankerfacez.com/script/legacy-staff.png');
}
.ffz-legacy-badges .ember-chat .badges .broadcaster {
background-color: #000;
background-image: url('legacy-broadcaster.png');
background-image: url('//cdn.frankerfacez.com/script/legacy-broadcaster.png');
}
.ffz-legacy-badges .ember-chat .badges .admin {
background-color: #ff0303;
background-image: url('legacy-admin.png');
background-image: url('//cdn.frankerfacez.com/script/legacy-admin.png');
}
.ffz-legacy-turbo-badges .ember-chat .badges .turbo,
.ffz-legacy-badges .ember-chat .badges .turbo {
background-color: #6441a3;
background-image: url('legacy-turbo.png');
background-image: url('//cdn.frankerfacez.com/script/legacy-turbo.png');
}
/* High Contrast Chat */

View file

@ -1,5 +1,6 @@
var FFZ = window.FrankerFaceZ,
constants = require("../constants");
constants = require("../constants"),
styles = require("../styles");
// ---------------------

View file

@ -1,17 +1,16 @@
var FFZ = window.FrankerFaceZ,
constants = require('../constants');
constants = require('../constants'),
styles = require('../styles');
FFZ.prototype.setup_css = function() {
document.body.classList.toggle('ffz-flip-dashboard', this.settings.flip_dashboard);
this.log("Injecting main FrankerFaceZ CSS.");
var s = this._main_style = document.createElement('link');
var s = this._main_style = document.createElement('style');
s.textContent = styles.style;
s.id = "ffz-ui-css";
s.setAttribute('rel', 'stylesheet');
s.setAttribute('href', constants.SERVER + "script/style.css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
s.onerror = "this.href = this.href + '_';"
document.head.appendChild(s);