@ -3,63 +3,26 @@ var queue = new Queue();
@@ -3,63 +3,26 @@ var queue = new Queue();
var minSpeedupQueueLength = 5 ;
queue . on ( 'queueLengthChanged' , function ( queue , oldLength , newLength ) {
if ( newLength > 5 ) {
var s = 1.0 + ( newLength - minSpeedupQueueLength + 1 ) / 10.0 ;
for ( var i in this . queue ) {
try {
console . log ( 'setting playback rate' , s ) ;
// this.queue.setPlaybackRate(s);
for ( var j in queue . queue ) {
if ( queue . queue [ i ] . data . sound ) {
queue . queue [ i ] . data . sound . setPlaybackRate ( s ) ;
}
if ( queue . queue [ i ] . data . speechSound ) {
queue . queue [ i ] . data . speechSound . setPlaybackRate ( s ) ;
}
}
} catch ( e ) {
// ignore
}
}
}
} ) ;
queue . on ( 'queueLengthChanged' , function ( event ) {
var s = 1.0 ;
var socket = null ;
function initWebsocket ( ) {
socket = new WebSocket ( config . socketUrl ) ;
socket . onopen = ( evt ) => {
console . log ( 'Connected to websocket' , config . socketUrl ) ;
} ;
socket . onclose = ( evt ) => {
console . error ( 'websocket closed' , evt , socket . readyState ) ;
socket . onopen = socket . onclose = socket . onerror = socket . onmessage = undefined ;
socket = null ;
setTimeout ( ( ) => { this . initWebsocket ( ) ; } , 1000 ) ;
} ;
socket . onerror = ( evt ) => {
console . error ( 'websocket error' , evt , socket . readyState ) ;
socket . onopen = socket . onclose = socket . onerror = socket . onmessage = undefined ;
socket = null ;
setTimeout ( ( ) => { this . initWebsocket ( ) ; } , 1000 ) ;
} ;
socket . onmessage = ( ev ) => {
var data ;
if ( event . newLength > minSpeedupQueueLength )
s += ( event . newLength - minSpeedupQueueLength + 1 ) / 10.0 ;
for ( var i in this . queue ) {
try {
data = JSON . parse ( ev . data ) ;
if ( this . queue [ i ] . data . sound )
this . queue [ i ] . data . sound . setPlaybackRate ( s ) ;
if ( this . queue [ i ] . data . speechSound )
this . queue [ i ] . data . speechSound . setPlaybackRate ( s ) ;
} catch ( e ) {
console . error ( 'Could not parse JSON' , ev . data , e ) ;
console . log ( 'could not set playback rate to' , s , e ) ;
// ignore
}
if ( data )
handleMessage ( data ) ;
} ;
}
initWebsocket ( ) ;
var lastChat ;
}
} ) ;
function getOffsetTop ( elem ) {
function getOffsetTop ( elem ) {
var offsetTop = 0 ;
do {
@ -235,377 +198,279 @@ function appendChat(chat) {
@@ -235,377 +198,279 @@ function appendChat(chat) {
console . log . apply ( null , con ) ;
}
function handleTwitchMessage ( msg ) {
if ( msg . text ) {
var text = msg . text . replace ( /^\s+/ , '' ) . replace ( /\s+$/ , '' ) . replace ( /\s+/g , ' ' ) ;
var content = [ ] , speak = '' ;
if ( msg . original . vars . emotes ) {
var emoteLocations = [ ] ;
var emotes = msg . original . vars . emotes . split ( '/' ) ;
var emoticonMap = { } ;
for ( var i in emotes ) {
var emoteData = emotes [ i ] . split ( ':' ) ;
var rangeMatch = emoteData [ 1 ] . split ( ',' ) ;
for ( var j in rangeMatch ) {
var range = rangeMatch [ j ] . split ( '-' ) ;
emoticonMap [ parseInt ( range [ 0 ] ) ] = emoteData [ 0 ] ;
emoteLocations . push ( parseInt ( range [ 0 ] ) ) ;
emoteLocations . push ( parseInt ( range [ 1 ] ) ) ;
}
}
emoteLocations . sort ( ( b , a ) => { return a - b ; } ) . reverse ( ) ;
var previ = 0 ;
for ( var i = 0 ; i < emoteLocations . length ; i += 2 ) {
var emoteStart = emoteLocations [ i ] ;
var emoteEnd = emoteLocations [ i + 1 ] ;
var between = msg . text . substr ( previ , emoteStart - previ ) ;
var emote = msg . text . substr ( emoteStart , emoteEnd - emoteStart + 1 ) ;
content . push ( between ) ;
speak += between ;
content . push ( {
type : 'image' ,
src : 'https://static-cdn.jtvnw.net/emoticons/v2/' + emoticonMap [ emoteStart ] + '/default/dark/1.0' ,
alt : emote ,
class : 'chatEmote'
} ) ;
previ = emoteEnd + 1 ;
}
var last = msg . text . substr ( previ ) ;
if ( last ) {
content . push ( last ) ;
speak += last ;
}
speak = speak . replace ( /^\s+/ , '' ) . replace ( /\s+$/ , '' ) . replace ( /\s+/g , ' ' ) ;
} else {
speak = text ;
content . push ( text ) ;
}
function getSpeechTextFromChat ( data ) {
if ( ! data . spans )
return null ;
appendChat ( {
id : msg . id ,
platform : msg . platform ,
displayName : msg . displayName ,
username : msg . username ,
avatar : null ,
speak : speak ,
content : content
} ) ;
let textSpans = [ ] ;
for ( let span of data . spans ) {
if ( typeof span === 'string' ) {
textSpans . push ( util . trim ( util . normalizeSpaces ( span ) ) ) ;
}
}
return textSpans . join ( ' ' ) ;
}
function handleDliveMessage ( msg ) {
var testMessages = {
Ban2 : { "__typename" : "ChatBan" , "type" : "Ban" , "id" : "chatban:dlive-woabgpyuop|kaspaa" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:dlive-woabgpyuop" , "username" : "dlive-woabgpyuop" , "displayname" : "M_o_h_a_m_a_d" , "avatar" : "https://image.dlivecdn.com/avatar/default7.png" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Member" , "subscribing" : false , "bannedBy" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:kaspaa" , "username" : "kaspaa" , "displayname" : "Kaspaa" , "avatar" : "https://images.prd.dlivecdn.com/avatar/efd649c5-0378-11ea-9529-e2443572cd01" , "partnerStatus" : "NONE" } , "bannedByRoomRole" : "Moderator" } ,
Ban : { "__typename" : "ChatBan" , "type" : "Ban" , "id" : "chatban:dlive-bzmuytbvmk|tctv" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:dlive-bzmuytbvmk" , "username" : "dlive-bzmuytbvmk" , "displayname" : "PERKY_PAWG_BREAST" , "avatar" : "https://image.dlivecdn.com/avatar/default8.png" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Member" , "subscribing" : false , "bannedBy" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:tctv" , "username" : "tctv" , "displayname" : "Tctv" , "avatar" : "https://images.prd.dlivecdn.com/avatar/9da26d8b-1ce5-11ea-9529-e2443572cd01" , "partnerStatus" : "AFFILIATE" } , "bannedByRoomRole" : "Moderator" } ,
Diamond : { "__typename" : "ChatGift" , "amount" : "1" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "DIAMOND" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "message" : "Hello Frens" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
ExtendSub : { "__typename" : "ChatExtendSub" , "id" : "b9e5e15b-d754-46a4-b71d-63571975b09f" , "length" : 3 , "month" : 1 , "role" : "None" , "roomRole" : "Member" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/f85df577-6e2f-11ea-8119-a272e850df75" , "badges" : [ ] , "displayname" : "PROPRBOY" , "effect" : null , "id" : "streamchatuser:proprboy" , "partnerStatus" : "NONE" , "username" : "proprboy" } , "subscribing" : true , "type" : "ExtendSub" } ,
ExtendSub2 : { "__typename" : "ChatExtendSub" , "type" : "ExtendSub" , "id" : "0ac2a31f-eba4-42cd-980d-e4e524165c9d" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:datdoctor" , "username" : "datdoctor" , "displayname" : "WilliamDunham" , "avatar" : "https://images.prd.dlivecdn.com/avatar/f3559b21-3b9e-11ea-9fd3-a272e850df75" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Member" , "subscribing" : true , "month" : 1 , "length" : 1 } ,
Follow : { "__typename" : "ChatFollow" , "id" : "f936fcb8-ebd5-4f88-9db6-6d4aa18e74d9" , "role" : "None" , "roomRole" : "Member" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/f7fda7f0-bc94-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "r-eVan" , "effect" : null , "id" : "streamchatuser:r-evan" , "partnerStatus" : "NONE" , "username" : "r-evan" } , "subscribing" : false , "type" : "Follow" } ,
GiftSub : { "__typename" : "ChatGiftSub" , "type" : "GiftSub" , "id" : "7c5741ce-4d68-4904-9a22-15c684bb936b" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:thomas42" , "username" : "thomas42" , "displayname" : "thomasthefam" , "avatar" : "https://images.prd.dlivecdn.com/avatar/69b8b18d-4432-11ea-9529-e2443572cd01" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : "https://images.prd.dlivecdn.com/effect/trxsmall" } , "role" : "None" , "roomRole" : "Moderator" , "subscribing" : true , "receiver" : "greenbaywacky" , "count" : null } ,
GiftSubReceive : { "__typename" : "ChatGiftSubReceive" , "type" : "GiftSubReceive" , "id" : "6253dfab-10e0-47fd-889e-c8ada929ac02" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:greenbaywacky" , "username" : "greenbaywacky" , "displayname" : "greenbaywacky" , "avatar" : "https://images.prd.dlivecdn.com/avatar/f7672f4e-63f2-11e9-bc94-460601ac0a66" , "partnerStatus" : "VERIFIED_PARTNER" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Moderator" , "subscribing" : true , "gifter" : "thomasthefam" } ,
Host : { "__typename" : "ChatHost" , "id" : "8ecb00e0-1061-4d52-804c-b5e7b5ef7ff4" , "role" : "None" , "roomRole" : "Member" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : false , "type" : "Host" , "viewer" : 2 } ,
IceCream : { "__typename" : "ChatGift" , "amount" : "1" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "ICE_CREAM" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
IceCreams : { "__typename" : "ChatGift" , "amount" : "3" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "ICE_CREAM" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
Lemon : { "__typename" : "ChatGift" , "amount" : "1" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "LEMON" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
Lemons : { "__typename" : "ChatGift" , "amount" : "5" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "LEMON" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
Mod : { "__typename" : "ChatModerator" , "type" : "Mod" , "id" : "4ba35866-7b3d-4922-b1e0-a25907f9555e" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:thestoryofdori" , "username" : "thestoryofdori" , "displayname" : "TheStoryOfDori13" , "avatar" : "https://images.prd.dlivecdn.com/avatar/1b0c639f-208d-11ea-bd1e-563a837bad22" , "partnerStatus" : "AFFILIATE" , "badges" : [ ] , "effect" : "https://images.prd.dlivecdn.com/effect/trx" } , "role" : "None" , "roomRole" : "Moderator" , "subscribing" : true , "add" : true } ,
Ninjaghini : { "__typename" : "ChatGift" , "amount" : "1" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "NINJAGHINI" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "message" : "Pee Pee poo Poo" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
Ninjet : { "__typename" : "ChatGift" , "amount" : "1" , "createdAt" : "1593804669046558744" , "expireDuration" : 0 , "gift" : "NINJET" , "id" : "5ac8bdb9-8e72-4418-8b37-d0e616e91098" , "message" : "Dee Dee Get Out Of My laboratory" , "recentCount" : 1 , "role" : "None" , "roomRole" : "Moderator" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/799c0ae0-a4e2-11ea-b737-e2443572cd01" , "badges" : [ ] , "displayname" : "FerociousChihuahua" , "effect" : null , "id" : "streamchatuser:ferociouschihuahua" , "partnerStatus" : "AFFILIATE" , "username" : "ferociouschihuahua" } , "subscribing" : true , "type" : "Gift" } ,
Subscription : { "__typename" : "ChatSubscription" , "type" : "Subscription" , "id" : "cc51028f-4042-45b5-9b64-8ce03fb0b5c5" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:dlive-51995646" , "username" : "dlive-51995646" , "displayname" : "GrimGriz" , "avatar" : "https://images.prd.dlivecdn.com/avatar/c8e244e6-5c97-11e9-ab17-865634f95b6b" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Member" , "subscribing" : true , "month" : 3 } ,
SubStreak : { "__typename" : "ChatSubStreak" , "id" : "3bd0a19e-8791-410d-b3b2-9f044ba33881" , "length" : 2 , "role" : "None" , "roomRole" : "Member" , "sender" : { "__typename" : "StreamchatUser" , "avatar" : "https://images.prd.dlivecdn.com/avatar/f85df577-6e2f-11ea-8119-a272e850df75" , "badges" : [ ] , "displayname" : "PROPRBOY" , "effect" : null , "id" : "streamchatuser:proprboy" , "partnerStatus" : "NONE" , "username" : "proprboy" } , "subscribing" : true , "type" : "SubStreak" } ,
TCValue : { "__typename" : "ChatTCValueAdd" , "type" : "TCValue" , "id" : "47f8158d-2006-418f-9954-99c160349a5d" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:vampirefrog" , "username" : "vampirefrog" , "displayname" : "vampirefrog" , "avatar" : "https://images.prd.dlivecdn.com/avatar/e3d74c4e-d4fc-11ea-8cd4-c20daac9fa96" , "partnerStatus" : "AFFILIATE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Owner" , "subscribing" : false , "amount" : "3000000" , "totalAmount" : "5139478" } ,
Timeout : { "__typename" : "ChatTimeout" , "type" : "Timeout" , "id" : "0320ec61-2679-4a3e-9f61-c09bcddad6a0" , "sender" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:dlive-woabgpyuop" , "username" : "dlive-woabgpyuop" , "displayname" : "M_o_h_a_m_a_d" , "avatar" : "https://image.dlivecdn.com/avatar/default7.png" , "partnerStatus" : "NONE" , "badges" : [ ] , "effect" : null } , "role" : "None" , "roomRole" : "Member" , "subscribing" : false , "bannedBy" : { "__typename" : "StreamchatUser" , "id" : "streamchatuser:cascadiannationalist" , "username" : "cascadiannationalist" , "displayname" : "CascadiaPNW" , "avatar" : "https://images.prd.dlivecdn.com/avatar/52b10bde-b03d-11ea-b737-e2443572cd01" , "partnerStatus" : "NONE" } , "minute" : 5 , "bannedByRoomRole" : "Moderator" } ,
ValueUpdated : { "id" : "1" , "payload" : { "data" : { "treasureChestMessageReceived" : { "__typename" : "TreasureChestValueUpdated" , "type" : "ValueUpdated" , "value" : "659998" } } } , "type" : "data" } ,
} ;
if ( msg . original . type == 'Message' && msg . original . sender . username == config . streamers [ 0 ] . username && testMessages [ msg . original . content ] ) {
msg . original = testMessages [ msg . original . content ] ;
msg . original . id = Queue . prototype . makeId ( 24 ) ;
function randomItem ( items ) {
if ( Array . isArray ( items ) ) {
return items [ Math . floor ( Math . random ( ) * items . length ) ] ;
}
var id = msg . original . id ;
var type = msg . original . type ;
var banned = [ 'tidylabs' ] ;
if ( msg . original . sender && msg . original . sender . username && banned . indexOf ( msg . original . sender . username ) > - 1 ) {
return ;
}
return items ;
}
if ( type == 'Message' ) {
var avatar = msg . original . sender . avatar ;
var displayName = msg . displayName ;
var text = msg . text . replace ( /^\s+/ , '' ) . replace ( /\s+$/ , '' ) . replace ( /\s+/g , ' ' ) ;
var m = text . match ( /:emote\/([^/]+)\/([^/]+)\/([^:]+):/ ) ;
if ( m && m [ 3 ] ) {
util . loadJSON ( config . stickerInfoUrl + '/' + m [ 3 ] , function ( response ) {
var chat = {
id : id ,
avatar : avatar ,
displayName : displayName ,
content : [
{ type : 'br' } ,
{
type : 'image' ,
src : 'https://images.prd.dlivecdn.com/emote/' + m [ 3 ] ,
alt : m [ 3 ] ,
class : 'chatSticker'
}
]
} ;
function handleMessage ( data ) {
switch ( data . type ) {
case 'chat' :
var avatar = data . avatar ;
var displayName = data . displayName ;
var text = data . text ;
var m = text . match ( /:emote\/([^/]+)\/([^/]+)\/([^:]+):/ ) ;
if ( m && m [ 3 ] ) {
util . loadJSON ( config . stickerInfoUrl + '/' + m [ 3 ] , function ( response ) {
var chat = {
id : data . id ,
avatar : avatar ,
displayName : displayName ,
content : [
{ type : 'br' } ,
{
type : 'image' ,
src : 'https://images.prd.dlivecdn.com/emote/' + m [ 3 ] ,
alt : m [ 3 ] ,
class : 'chatSticker'
}
]
} ;
if ( response && response . results && response . results [ 0 ] && response . results [ 0 ] . name ) {
chat . platform = data . platform ;
chat . username = data . username ;
chat . speak = chat . content [ 1 ] . alt = response . results [ 0 ] . name ;
}
if ( response && response . results && response . results [ 0 ] && response . results [ 0 ] . name ) {
chat . platform = msg . user . platform ;
chat . username = msg . user . username ;
chat . speak = chat . content [ 1 ] . alt = response . results [ 0 ] . name ;
appendChat ( chat ) ;
} ) ;
} else {
if ( text ) {
appendChat ( {
id : data . id ,
avatar : avatar ,
displayName : displayName ,
platform : data . platform ,
username : data . username ,
speak : getSpeechTextFromChat ( data ) ,
content : data . spans
} ) ;
}
}
break ;
case 'gift' :
if ( config . donations && config . donations [ data . platform ] && config . donations [ data . platform ] [ data . giftType ] ) {
var giftConfig = config . donations [ data . platform ] [ data . giftType ] ;
var string = giftConfig . string ;
if ( data . amount > 1 ) {
string = giftConfig . stringMulti . replace ( '#' , data . amount ) ;
}
appendChat ( chat ) ;
} ) ;
} else {
if ( text ) {
var content = [ ] , speak = '' ;
if ( msg . original . emojis ) {
var emotes = msg . original . emojis ;
var previ = 0 ;
for ( var i = 0 ; i < emotes . length ; i += 2 ) {
var emoteStart = emotes [ i ] ;
var emoteEnd = emotes [ i + 1 ] ;
var between = msg . text . substr ( previ , emoteStart - previ ) ;
var emote = msg . text . substr ( emoteStart , emoteEnd - emoteStart + 1 ) ;
content . push ( between ) ;
speak += between ;
content . push ( {
type : 'image' ,
src : 'https://images.prd.dlivecdn.com/emoji/' + emote ,
alt : emote ,
class : 'chatEmote'
} ) ;
previ = emoteEnd + 1 ;
}
var last = msg . text . substr ( previ ) ;
if ( last ) {
content . push ( last ) ;
speak += last ;
}
speak = speak . replace ( /^\s+/ , '' ) . replace ( /\s+$/ , '' ) . replace ( /\s+/g , ' ' ) ;
} else {
speak = text ;
content . push ( text ) ;
var images = [ ] ;
for ( var m = 0 ; m < data . amount ; m ++ ) {
images . push ( randomItem ( giftConfig . img ) ) ;
}
appendChat ( {
id : id ,
avatar : avatar ,
displayName : displayName ,
platform : msg . user . platform ,
username : msg . user . username ,
speak : speak ,
content : content
} ) ;
}
}
} else if ( type == 'Gift' ) {
var avatar = msg . original . sender . avatar ;
var displayName = msg . displayName ;
var gifts = {
'LEMON' : {
sound : config . sounds . lemon ,
string : 'donated a lemon' ,
stringMulti : 'donated # lemons' ,
img : 'img/cookie.png' ,
} ,
'ICE_CREAM' : {
sound : config . sounds . icecream ,
string : 'donated an ice cream' ,
stringMulti : 'donated # ice creams' ,
img : [ 'img/icecream1.png' , 'img/icecream2.png' , 'img/icecream3.png' , 'img/icecream4.png' ] ,
} ,
'DIAMOND' : {
sound : config . sounds . diamond ,
string : 'donated a diamond' ,
stringMulti : 'donated # diamonds' ,
img : 'img/diamond.png' ,
} ,
'NINJAGHINI' : {
sound : config . sounds . ninjaghini ,
string : 'donated a ninjaghini' ,
stringMulti : 'donated # ninjaghinis' ,
img : 'img/ninjaghini.png' ,
} ,
'NINJET' : {
sound : config . sounds . ninjet ,
string : 'donated a ninjet' ,
stringMulti : 'donated # ninjets' ,
img : 'img/ninjet.png' ,
}
} ;
if ( gifts [ msg . original . gift ] ) {
var gift = gifts [ msg . original . gift ] ;
var amount = parseInt ( msg . original . amount ) ;
var string = gift . string ;
if ( amount > 1 ) {
string = gift . stringMulti . replace ( '#' , msg . original . amount ) ;
}
var images = [ ] ;
for ( var m = 0 ; m < amount ; m ++ ) {
var img = gift . img ;
if ( Array . isArray ( img ) ) // pick a random image
img = img [ Math . floor ( Math . random ( ) * img . length ) ] ;
images . push ( img ) ;
}
var group = displayName + '-' + msg . original . gift ;
var groupDivs = document . getElementsByClassName ( group ) ;
var chatDiv = groupDivs && groupDivs . length && groupDivs [ groupDivs . length - 1 ] || null ;
if ( chatDiv && ( msg . original . gift == 'LEMON' || msg . original . gift == 'ICE_CREAM' ) ) {
for ( var c = 0 ; c < chatDiv . childNodes . length ; c ++ ) {
if ( chatDiv . childNodes [ c ] . className == 'chatImages' ) {
var html = chatDiv . childNodes [ c ] . innerHTML ;
for ( m = 0 ; m < images . length ; m ++ ) {
html += '<img src="' + util . escapeHtml ( images [ m ] ) + '" alt="" class="chatImage">' ;
var group = data . platform + '-' + data . displayName + '-' + data . giftType ;
var groupDivs = document . getElementsByClassName ( group ) ;
var chatDiv = groupDivs && groupDivs . length && groupDivs [ groupDivs . length - 1 ] || null ;
if ( chatDiv && giftConfig . group ) {
for ( var c = 0 ; c < chatDiv . childNodes . length ; c ++ ) {
if ( chatDiv . childNodes [ c ] . className == 'chatImages' ) {
var html = chatDiv . childNodes [ c ] . innerHTML ;
for ( m = 0 ; m < images . length ; m ++ ) {
html += '<img src="' + util . escapeHtml ( images [ m ] ) + '" alt="" class="chatImage">' ;
}
chatDiv . childNodes [ c ] . innerHTML = html ;
}
chatDiv . childNodes [ c ] . innerHTML = html ;
}
} else {
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
group : group ,
sound : randomItem ( giftConfig . sound ) ,
platform : data . platform ,
username : data . username ,
speak : data . message ,
image : images ,
content : [
string ,
{ type : 'br' } ,
data . message
]
} ) ;
}
} else {
appendChat ( {
id : id ,
avatar : avatar ,
displayName : displayName ,
group : group ,
sound : gift . sound ,
platform : msg . user . platform ,
username : msg . user . username ,
speak : msg . original . message ,
image : images ,
content : [
string ,
{ type : 'br' } ,
msg . original . message
]
} ) ;
}
}
} else if ( type == 'Delete' ) {
for ( var i in msg . original . ids ) {
soundManager . remove ( msg . original . ids [ i ] ) ;
}
console . log ( '%cDelete%c ' + msg . original . ids . join ( ', ' ) , 'color: red; font-weight: bold' , 'color: inherit; font-weight: normal' ) ;
} else if ( type == 'Host' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
sound : config . sounds . host ,
content : [
'hosted with ' + msg . original . viewer + ' viewers!'
]
} ) ;
} else if ( type == 'Follow' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
sound : config . sounds . follow ,
content : [
'just followed!'
]
} ) ;
} else if ( type == 'ExtendSub' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
sound : config . sounds . subscribe ,
content : [
'resubscribed for ' + ( msg . original . length ) + ' months'
]
} ) ;
} else if ( type == 'Ban' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
content : [
'was banned'
]
} ) ;
} else if ( type == 'Timeout' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
content : [
'was timed out for ' + msg . original . minute + ' minutes'
]
} ) ;
} else if ( type == 'SubStreak' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
content : [
'is celebrating a ' + msg . original . length + ' month sub streak'
]
} ) ;
} else if ( type == 'GiftSub' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
content : [
'gifted a one month subscription to ' + ( msg . original . receiver )
]
} ) ;
} else if ( type == 'GiftSubReceive' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
sound : config . sounds . subscribe ,
content : [
'received a one month subscription from ' + ( msg . original . gifter )
]
} ) ;
} else if ( type == 'TCValue' ) {
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
content : [
'added ' + ( msg . original . amount / 100000.0 ) + ' lemons to the chest'
]
} ) ;
} else if ( type == 'Subscription' ) {
console . log ( 'subscribe sound' , config . sounds . subscribe ) ;
appendChat ( {
id : id ,
avatar : msg . original . sender . avatar ,
displayName : msg . original . sender . displayname ,
sound : config . sounds . subscribe ,
content : [
'subscribed for ' + ( msg . original . month ) + ' month(s)'
]
} ) ;
} else {
appendChat ( {
id : id ,
avatar : msg . original . sender && msg . original . sender . avatar ,
displayName : msg . original . sender && msg . original . sender . displayname ,
content : [
type ,
JSON . stringify ( msg . original )
]
} ) ;
break ;
case 'delete' :
for ( var i in data . ids ) {
soundManager . remove ( data . ids [ i ] ) ;
}
console . log ( '%cDelete%c ' + data . ids . join ( ', ' ) , 'color: red; font-weight: bold' , 'color: inherit; font-weight: normal' ) ;
break ;
case 'ban' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
content : [
'was banned'
]
} ) ;
break ;
case 'timeout' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
content : [
'was timed out for ' + data . minutes + ' minutes'
]
} ) ;
break ;
case 'host' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . host ,
content : [
'hosted with ' + data . viewers + ' viewers!'
]
} ) ;
break ;
case 'follow' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . follow ,
content : [
'just followed!'
]
} ) ;
break ;
case 'moderator' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . mod ,
content : [
'is now a moderator!'
]
} ) ;
break ;
case 'resubscribe' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . subscribe ,
content : [
'resubscribed for ' + ( data . length ) + ' months' +
( data . months ? ' and is now on a ' + data . months + ' month sub streak' : '' )
]
} ) ;
break ;
case 'subStreak' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
content : [
'is celebrating a ' + data . length + ' month sub streak'
]
} ) ;
break ;
case 'giftSub' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
content : [
'gifted a one month subscription to ' + ( data . receiver )
]
} ) ;
break ;
case 'giftSubReceive' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . subscribe ,
content : [
'received a one month subscription from ' + ( data . gifter )
]
} ) ;
break ;
case 'chestValue' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
content : [
'added ' + data . amount + ' ' + data . currencyPlural + ' to the chest'
]
} ) ;
break ;
case 'subscribe' :
appendChat ( {
id : data . id ,
avatar : data . avatar ,
displayName : data . displayName ,
sound : config . sounds . subscribe ,
content : [
'subscribed for ' + ( data . months ) + ' month' + ( data . months == 1 ? '' : 's' )
]
} ) ;
break ;
default :
console . log ( data ) ;
break ;
}
}
function handleMessage ( msg ) {
if ( msg . platform == 'twitch' )
handleTwitchMessage ( msg ) ;
else if ( msg . platform == 'dlive' )
handleDliveMessage ( msg ) ;
else console . error ( 'Unknown platform' , msg . platform , msg ) ;
var socket = null ;
function initWebsocket ( ) {
socket = new WebSocket ( config . socketUrl ) ;
socket . onopen = ( evt ) => {
console . log ( 'Connected to websocket' , config . socketUrl ) ;
} ;
socket . onclose = ( evt ) => {
console . error ( 'websocket closed' , evt , socket . readyState ) ;
socket . onopen = socket . onclose = socket . onerror = socket . onmessage = undefined ;
socket = null ;
setTimeout ( ( ) => { this . initWebsocket ( ) ; } , 1000 ) ;
} ;
socket . onerror = ( evt ) => {
console . error ( 'websocket error' , evt , socket . readyState ) ;
socket . onopen = socket . onclose = socket . onerror = socket . onmessage = undefined ;
socket = null ;
setTimeout ( ( ) => { this . initWebsocket ( ) ; } , 1000 ) ;
} ;
socket . onmessage = ( ev ) => {
var data ;
try {
data = JSON . parse ( ev . data ) ;
} catch ( e ) {
console . error ( 'Could not parse JSON' , ev . data , e ) ;
}
if ( data )
handleMessage ( data ) ;
} ;
}
initWebsocket ( ) ;