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:
commit
796966c3b9
13 changed files with 371 additions and 85 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,5 +6,6 @@ Extension Building
|
|||
*.iml
|
||||
script.js
|
||||
script.min.js
|
||||
credentials.json
|
||||
|
||||
/socketserver/cmd/socketserver/socketserver
|
||||
|
|
101
gulpfile.js
101
gulpfile.js
|
@ -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() {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 || "");
|
||||
}
|
||||
|
|
170
src/socket.js
170
src/socket.js
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -1,5 +1,6 @@
|
|||
var FFZ = window.FrankerFaceZ,
|
||||
constants = require("../constants");
|
||||
constants = require("../constants"),
|
||||
styles = require("../styles");
|
||||
|
||||
|
||||
// ---------------------
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue