1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00

3.5.41 to 3.5.50. Viewer list sorting is now optional. CSS is now embedded in the script to prevent loading issues. Started testing new socket server. Added chat batching option to display new messages in batches for performance reasons. Changed socket server rotation logic. Added error checks for Stream Latency. Socket protocol now uses ok instead of True. Added deploy and clear_cache commands to gulp for convenience.

This commit is contained in:
SirStendec 2015-11-01 17:28:19 -05:00
parent 05db9ea5eb
commit 10da2b4fd5
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);