|
// ==UserScript== |
|
// @name Twitch Commands |
|
// @namespace http://michaelowens.nl/ |
|
// @homepage https://gist.github.com/michaelowens/2eb554f8eba0e89d2ea24e67ebc7ae96 |
|
// @version 0.6 |
|
// @description Adds commands to twitch chat! Install FFZ & TamperMonkey first, then install script. |
|
// @author Xikeon (Michael Owens) |
|
// @match *://twitch.tv/* |
|
// @match *://www.twitch.tv/* |
|
// @updateURL https://gist.githubusercontent.com/michaelowens/2eb554f8eba0e89d2ea24e67ebc7ae96/raw/twitchcommands.user.js |
|
// ==/UserScript== |
|
/* jshint esnext:true, asi:true, -W097 */ |
|
/* globals $ */ |
|
'use strict'; |
|
|
|
class TwitchCommands { |
|
constructor () { |
|
this.loaded = false |
|
this.$chat = $('.chat_text_input') |
|
this.timeStarted = +new Date() |
|
this.forceStart = false |
|
this.FFZ = false |
|
this.log('Injected') |
|
|
|
this.waitForFFZ() |
|
} |
|
|
|
log (...params) { |
|
console.log('[Twitch Commands]', ...params) |
|
} |
|
|
|
waitForFFZ () { |
|
let secondsSinceStart = ((+new Date()) - this.timeStarted) / 1000 |
|
|
|
if (typeof unsafeWindow.FrankerFaceZ === 'function') { |
|
this.FFZ = true |
|
this.log('FFZ detected') |
|
this.bindToChatFFZ() |
|
this.setAutocompleteInfo() |
|
return |
|
} else if (secondsSinceStart > 10 && this.$chat.length) { |
|
this.log('Could not detect FFZ.') |
|
return |
|
} |
|
|
|
setTimeout(_ => this.waitForFFZ(), 500) |
|
} |
|
|
|
bindToChatFFZ () { |
|
this.getCommands() |
|
.forEach(command => { |
|
let name = command.replace('command_', '') |
|
unsafeWindow.FrankerFaceZ.chat_commands[name] = this[command].bind(this) |
|
}) |
|
} |
|
|
|
setAutocompleteInfo() { |
|
let cc = unsafeWindow.FrankerFaceZ.chat_commands |
|
|
|
cc.tccommands.label = '/tccommands' |
|
cc.tccommands.info = 'Show commands added by Twitch Commands' |
|
|
|
cc.pyramid.label = '/pyramid <size> <emote>' |
|
cc.pyramid.info = 'Make a pyramid of the given size and emote' |
|
|
|
cc.rainbow.label = '/rainbow <message>' |
|
cc.rainbow.info = 'Spam given message in rainbow colors' |
|
|
|
cc.brainpower.label = '/brainpower' |
|
cc.brainpower.info = 'Sends the brainpower meme' |
|
} |
|
|
|
getCommands () { |
|
return Object.getOwnPropertyNames(Object.getPrototypeOf(this)).filter(name => name.indexOf('command_') === 0) |
|
} |
|
|
|
getTimeBetweenMessages (e) { |
|
return this.isModeratorOrHigher(e) ? 100 : 1500 |
|
} |
|
|
|
isModeratorOrHigher (e) { |
|
return e && e.room.get('isModeratorOrHigher') |
|
} |
|
|
|
command_tccommands () { |
|
let commands = this.getCommands().map(name => '/' + name.replace('command_', '')) |
|
return `Twitch Commands: ${commands.join(', ')}` |
|
} |
|
|
|
command_pyramid (e, params) { |
|
var size = 0 |
|
var emote = '' |
|
|
|
if (!params || params.length < 2) { |
|
return 'Example usage: /pyramid 3 FrankerZ' |
|
} |
|
|
|
[size, emote] = params |
|
|
|
if (size < 2) { |
|
return 'Pyramid can\'t be smaller than 2 emoticons' |
|
} |
|
|
|
for (let i = 1; i < (size * 2); i++) { |
|
setTimeout(_ => { |
|
let n = (i > size) ? (size * 2) - i : i |
|
e.room.send((emote + ' ').repeat(n)) |
|
}, ((i - 1) * this.getTimeBetweenMessages(e))) |
|
} |
|
} |
|
|
|
command_rainbow (e, params) { |
|
if (!params || !params.length) { |
|
return 'Example usage: /rainbow SUB HYPE' |
|
} |
|
|
|
const colors = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#4B0082'], |
|
originalColor = e.room.chatColor, |
|
timeBetween = this.isModeratorOrHigher(e) ? 300 : 1500 |
|
|
|
let i = 0 |
|
|
|
for (let color of colors) { |
|
setTimeout(_ => { |
|
e.room.send(`/color ${color}`) |
|
setTimeout(_ => { |
|
e.room.send(`/me ${params.join(' ')}`) |
|
}, this.isModeratorOrHigher(e) ? 150 : 500) |
|
}, i * timeBetween) |
|
i++ |
|
} |
|
|
|
setTimeout(_ => { |
|
e.room.send(`/color ${originalColor}`) |
|
}, (i * timeBetween) + 1000) |
|
} |
|
|
|
command_brainpower (e) { |
|
e.room.send('O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee-ee-eee AAAAE-A-E-I-E-A-JO-ooo-oo-oo-oo EEEEO-A-AAA-AAAA') |
|
} |
|
} |
|
|
|
new TwitchCommands() |
Hi, I wanted to use multiple emote pyramids so I replaced line 98 of the script with this:
I don't think this has any adverse effects on regular use except it adds a trailing space which doesn't seem to make it through into the chat, either in between the emotes or after the message. You could get rid of the extra space in line 107 if you want to do this I guess. Thanks for the script!