├── .DS_Store ├── README.md ├── package.json ├── .gitignore ├── LICENSE └── app ├── keyHandler.js ├── key.py └── server.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sup/playrc/master/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yelp-plays 2 | Yelp IRC bot connected to an emulator 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TwitchPlaysX", 3 | "description": "Lets you use IRC to send inputs to a program and stream it, TwitchPlaysPokemon style", 4 | "version": "0.0.1", 5 | "dependencies": { 6 | "irc": "martynsmith/node-irc#605555e3dfe5eb92070f4520a22cedfbebd4dca8", 7 | "nconf": "^0.7.1", 8 | "printf": "~0.2.1" 9 | }, 10 | "scripts": { 11 | "start": "node ./app/server" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/hzoo/TwitchPlaysX.git" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | app/config.json 39 | app/config.js 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Charles Lai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/keyHandler.js: -------------------------------------------------------------------------------- 1 | config = require('./config.js'), 2 | lastTime = {}, 3 | throttledCommands = config.throttledCommands, 4 | regexThrottle = new RegExp('^(' + throttledCommands.join('|') + ')$', 'i'), 5 | regexFilter = new RegExp('^(' + config.filteredCommands.join('|') + ')$', 'i'); 6 | var PythonShell = require('python-shell'); 7 | 8 | for (var i = 0; i < throttledCommands.length; i++) { 9 | lastTime[throttledCommands[i]] = new Date().getTime(); 10 | } 11 | 12 | var defaultKeyMap = config.keymap || { 13 | 'up':'Up', 14 | 'u':'Up', 15 | 'left':'Left', 16 | 'l':'Left', 17 | 'h':'Left', 18 | 'down':'Down', 19 | 'd':'Down', 20 | 'j':'Down', 21 | 'right':'Right', 22 | 'r':'Right', 23 | 'k':'Right', 24 | 'a':'a', 25 | 'b':'b', 26 | 'start':'s', 27 | 's':'s' 28 | }; 29 | 30 | function sendKey(command) { 31 | //if doesn't match the filtered words 32 | if (!command.match(regexFilter)) { 33 | var allowKey = true, 34 | key = defaultKeyMap[command] || command; 35 | //throttle certain commands (not individually though) 36 | if (key.match(regexThrottle)) { 37 | var newTime = new Date().getTime(); 38 | if (newTime - lastTime[key] < config.timeToWait) { 39 | allowKey = false; 40 | } else { 41 | lastTime = newTime; 42 | } 43 | } 44 | if (allowKey) { 45 | var options = {args: [key]}; 46 | PythonShell.run('./app/key.py', options, function (err) { 47 | if (err) console.log(err); 48 | }); 49 | } 50 | } 51 | } 52 | 53 | exports.sendKey = sendKey; 54 | -------------------------------------------------------------------------------- /app/key.py: -------------------------------------------------------------------------------- 1 | import os, sys, time 2 | 3 | keyDelay = 0.1 4 | keymap = { 5 | "Up": "shift", 6 | "Left": "option", 7 | "Down": "control", 8 | "Right": "command", 9 | "b": "b", 10 | "a": "5", 11 | "s": "s", #start 12 | } 13 | 14 | def sendKey(button): 15 | time.sleep(keyDelay) 16 | actual_key = keymap[button] 17 | arrow_cmd = """osascript \ 18 | -e 'tell application "KiGB" to activate' \ 19 | -e 'delay 0.1' \ 20 | -e 'tell application "System Events" to key down {0}' \ 21 | -e 'delay 0.1' \ 22 | -e 'tell application "System Events" to key up {0}'""" 23 | buttn_cmd = """osascript \ 24 | -e 'tell application "KiGB" to activate' \ 25 | -e 'delay 0.1' \ 26 | -e 'tell application "System Events" to keystroke "{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"'""" 27 | if actual_key in ["b", "s"]: 28 | cmd = buttn_cmd 29 | else: 30 | cmd = arrow_cmd 31 | cmd = cmd.format(actual_key) 32 | os.system(cmd) 33 | return "done" 34 | 35 | if __name__ == "__main__": 36 | sendKey(sys.argv[1]) 37 | -------------------------------------------------------------------------------- /app/server.js: -------------------------------------------------------------------------------- 1 | var irc = require('irc'), 2 | printf = require('printf'), 3 | keyHandler = require('./keyHandler.js'), 4 | config = require('./config.js'); 5 | 6 | var client = new irc.Client(config.server, config.nick, { 7 | channels: [config.channel], 8 | port: config.port || 6697, 9 | sasl: false, 10 | nick: config.nick, 11 | userName: config.nick, 12 | password: config.password, 13 | //This has to be false, since SSL in NOT supported by twitch IRC (anymore?) 14 | // see: http://help.twitch.tv/customer/portal/articles/1302780-twitch-irc 15 | secure: true, 16 | floodProtection: config.floodProtection || false, 17 | floodProtectionDelay: config.floodProtectionDelay || 100, 18 | autoConnect: false, 19 | autoRejoin: true 20 | }); 21 | 22 | var commandRegex = config.regexCommands || 23 | new RegExp('^(' + config.commands.join('|') + ')$', 'i'); 24 | 25 | client.addListener('message' + config.channel, function(from, message) { 26 | if (message.match(commandRegex)) { 27 | 28 | if (config.printToConsole) { 29 | //format console output if needed 30 | var maxName = config.maxCharName, 31 | maxCommand = config.maxCharCommand, 32 | logFrom = from.substring(0, maxName), 33 | logMessage = message.substring(0, 6).toLowerCase(); 34 | //format log 35 | console.log(printf('%-' + maxName + 's % ' + maxCommand + 's', 36 | logFrom, logMessage)); 37 | } 38 | 39 | // Should the message be sent the program? 40 | if (config.sendKey) { 41 | keyHandler.sendKey(message.toLowerCase()); 42 | } 43 | } 44 | }); 45 | 46 | client.addListener('error', function(message) { 47 | console.log('error: ', message); 48 | }); 49 | 50 | client.connect(); 51 | console.log('Connecting...'); 52 | --------------------------------------------------------------------------------