-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0601e12
Showing
4 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require "sinatra" | ||
|
||
get "/" do | ||
erb :index | ||
end | ||
|
||
get "/twitch" do | ||
erb :twitch, locals: { params: params, request: request } | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
require "socket" | ||
require "dotenv" | ||
Dotenv.load | ||
|
||
class String | ||
def squish | ||
self.strip.gsub(/\s{2,}/, " ") | ||
end | ||
end | ||
|
||
class TwitchPlaysAKB1149 | ||
PING_MESSAGE = "PING :tmi.twitch.tv".freeze | ||
PONG_MESSAGE = "PONG :tmi.twitch.tv".freeze | ||
COMMAND_MAP = { | ||
"up".freeze => "Up".freeze, | ||
"Up".freeze => "Up".freeze, | ||
"上".freeze => "Up".freeze, | ||
"うえ".freeze => "Up".freeze, | ||
"down".freeze => "Down".freeze, | ||
"Down".freeze => "Down".freeze, | ||
"下".freeze => "Down".freeze, | ||
"した".freeze => "Down".freeze, | ||
"left".freeze => "Left".freeze, | ||
"left".freeze => "Left".freeze, | ||
"左".freeze => "Left".freeze, | ||
"ひだり".freeze => "Left".freeze, | ||
"right".freeze => "Right".freeze, | ||
"Right".freeze => "Right".freeze, | ||
"右".freeze => "Right".freeze, | ||
"みぎ".freeze => "Right".freeze, | ||
"circle".freeze => "x".freeze, | ||
"まる".freeze => "x".freeze, | ||
"丸".freeze => "x".freeze, | ||
"○".freeze => "x".freeze, | ||
"◯".freeze => "x".freeze, | ||
"x".freeze => "z".freeze, | ||
"ばつ".freeze => "z".freeze, | ||
"バツ".freeze => "z".freeze, | ||
"×".freeze => "z".freeze, | ||
"✕".freeze => "z".freeze, | ||
"❌".freeze => "z".freeze, | ||
"square".freeze => "a".freeze, | ||
"しかく".freeze => "a".freeze, | ||
"四角".freeze => "a".freeze, | ||
"□".freeze => "a".freeze, | ||
"triangle".freeze => "s".freeze, | ||
"三角".freeze => "s".freeze, | ||
"さんかく".freeze => "s".freeze, | ||
"△".freeze => "s".freeze, | ||
"START".freeze => "space".freeze, | ||
"start".freeze => "space".freeze, | ||
"SELECT".freeze => "Return".freeze, | ||
"select".freeze => "Return".freeze, | ||
"L".freeze => "q".freeze, | ||
"l".freeze => "q".freeze, | ||
"R".freeze => "w".freeze, | ||
"w".freeze => "w".freeze, | ||
}.freeze | ||
|
||
def initialize(server, port, channel) | ||
@socket = TCPSocket.open(server, port) | ||
@channel = channel | ||
@log = File.open("chat.log", "w") | ||
|
||
activate_ppsspp_window | ||
relay_message "PASS oauth:#{ENV[:OAUTH_TOKEN]}" | ||
relay_message "NICK #{ENV[:TWITCH_USERNAME]}" | ||
relay_message "JOIN ##{channel}" | ||
relay_message "PRIVMSG ##{channel} :おれ、参上・・・!!" | ||
end | ||
|
||
def run | ||
until socket.eof? do | ||
activate_ppsspp_window unless ppsspp_window_activated? | ||
message = socket.gets | ||
|
||
if message == PING_MESSAGE | ||
relay_message PONG_MESSAGE | ||
elsif message =~ /PRIVMSG/ | ||
chat_message = message.split(":").last.squish | ||
|
||
if has_quit_permissions?(message) && chat_message == "stopgame" | ||
quit | ||
elsif COMMAND_MAP[chat_message] | ||
run_command(COMMAND_MAP[chat_message]) | ||
end | ||
|
||
log.puts "[#{Time.now}] #{message}" | ||
else | ||
log.puts "[#{Time.now}] #{message}" | ||
end | ||
end | ||
end | ||
|
||
def quit | ||
relay_message "PART ##{channel}" | ||
log.close | ||
socket.close | ||
exit 0 | ||
end | ||
|
||
attr_reader :channel, :log, :socket | ||
|
||
private | ||
|
||
def has_quit_permissions?(message) | ||
sender = message.split("PRIVMSG").first | ||
!!(sender =~ /#{channel}@#{channel}\.tmi\.twitch\.tv/) | ||
end | ||
|
||
def relay_message(message) | ||
puts "< #{message}" | ||
socket.puts message | ||
end | ||
|
||
def ppsspp_window_ids | ||
`xdotools search --class PPSSPP`.split("\n") | ||
end | ||
|
||
def activate_ppsspp_window | ||
if ppsspp_window_ids.any? | ||
`xdotool search --class PPSSPP windowactivate %@ 2> /dev/null` | ||
else | ||
abort("PPSSPP is not running!") | ||
end | ||
end | ||
|
||
def ppsspp_window_activated? | ||
ppsspp_window_ids.include?(`xdotool getactivewindow`.strip) | ||
end | ||
|
||
def run_command(command) | ||
`xdotool search --class "PPSSPP" key --window %@ #{command}` | ||
end | ||
end | ||
|
||
SERVER = "irc.twitch.tv".freeze | ||
PORT = 6667 | ||
CHANNEL = "missingno15".freeze | ||
|
||
akb1149 = TwitchPlaysAKB1149.new(SERVER, PORT, CHANNEL) | ||
|
||
Signal.trap("INT") { akb1149.quit } | ||
Signal.trap("TERM") { akb1149.quit } | ||
|
||
akb1149.run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Twitch Oauth</title> | ||
</head> | ||
|
||
<body id="superbody64"> | ||
<form name="oauth-generator-form" id="oauth-generator"> | ||
Client ID <input id="client-id" type="text" name="client-id" required> | ||
<br><br> | ||
|
||
Select all the necessary scopes: | ||
<br><br> | ||
<input type="checkbox" name="user_read" value="user_read"> Read access to non-public user information, such as email address. | ||
<br> | ||
<input type="checkbox" name="user_blocks_edit" value="user_blocks_edit"> Ability to ignore or unignore on behalf of a user. | ||
<br> | ||
<input type="checkbox" name="user_blocks_read" value="user_blocks_read"> Read access to a user's list of ignored users. | ||
<br> | ||
<input type="checkbox" name="user_follows_edit" value="user_follows_edit"> Access to manage a user's followed channels. | ||
<br> | ||
<input type="checkbox" name="channel_read" value="channel_read"> Read access to non-public channel information, including email address and stream key. | ||
<br> | ||
<input type="checkbox" name="channel_editor" value="channel_editor"> Write access to channel metadata (game, status, etc). | ||
<br> | ||
<input type="checkbox" name="channel_commercial" value="channel_commercial"> Access to trigger commercials on channel. | ||
<br> | ||
<input type="checkbox" name="channel_stream" value="channel_stream"> Ability to reset a channel's stream key. | ||
<br> | ||
<input type="checkbox" name="channel_subscriptions" value="channel_subscriptions"> Read access to all subscribers to your channel. | ||
<br> | ||
<input type="checkbox" name="user_subscriptions" value="user_subscriptions"> Read access to subscriptions of a user. | ||
<br> | ||
<input type="checkbox" name="channel_check_subscription" value="channel_check_subscription"> Read access to check if a user is subscribed to your channel. | ||
<br> | ||
<input type="checkbox" name="chat_login" value="chat_login"> Ability to log into chat and send messages. | ||
|
||
<br><br> | ||
<input type="submit" value="Generate URL to create OAuth token"> | ||
</form> | ||
|
||
<br><br> | ||
|
||
<script> | ||
var form = document.getElementById("oauth-generator"); | ||
|
||
form.addEventListener("submit", function(event){ | ||
event.preventDefault(); | ||
|
||
var scopes = []; | ||
var clientId = document.getElementById("client-id").value; | ||
|
||
var scopeCheckboxes = document.querySelectorAll("input[type='checkbox']"); | ||
|
||
for (i = 0; i < scopeCheckboxes.length; i++) { | ||
if (scopeCheckboxes[i].checked === true) { | ||
scopes.push(scopeCheckboxes[i].value) | ||
} | ||
} | ||
|
||
var body = document.getElementById("superbody64"); | ||
var oldOauthLink = document.getElementById("oauth-link"); | ||
|
||
if (oldOauthLink != null){ body.removeChild(oldOauthLink) } | ||
|
||
var oauthLink = document.createElement("a"); | ||
|
||
oauthLink.id = "oauth-link"; | ||
oauthLink.text = "Click to generate OAuth token for client id: " + clientId; | ||
oauthLink.href = "https://api.twitch.tv/kraken/oauth2/authorize" + | ||
"?response_type=token" + | ||
"&client_id=" + clientId + | ||
"&redirect_uri=http://localhost:4567/twitch" + | ||
"&scope=" + scopes.join("+") | ||
|
||
body.appendChild(oauthLink); | ||
}); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Twitch OAuth Redirected</title> | ||
|
||
<body> | ||
<p>Response <%= response %> </p> | ||
<p>Params <%= params %> </p> | ||
</body> | ||
</head> | ||
</html> |