twitch_plays 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/config.yml +8 -6
- data/lib/twitch_plays/os/win.rb +151 -0
- data/lib/twitch_plays/os/x11.rb +21 -0
- data/lib/twitch_plays/os.rb +10 -0
- data/lib/twitch_plays/twitch_plays.rb +103 -133
- data/lib/twitch_plays/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f5eff287aae3d3f6221c28b55737e048175a81c
|
4
|
+
data.tar.gz: 599ed21f42926111ac564d491bb9ebbab2a781f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8db97deb045cbe09dc0e1eecea0b0747034d1c0eec1f2d86b505d86a91649454b25a12a24e2ddd4c1875bbffc9cbe168b35c01faf510b1ab24cce1ae6c24b0f8
|
7
|
+
data.tar.gz: 80e19829f0c751bb97d2094cbc1fae45c8df52fbbaf4cfff29f2f9a1976dc69792f96ce01fc6129a36a98c21b89f6a5670afbffa1fd13aa108f7fa5e1aaa2cd2
|
data/README.md
CHANGED
data/config.yml
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# CONNECTION INFO
|
2
|
-
:nick:
|
3
|
-
:password: #
|
2
|
+
:nick: twitchplaysbot # Twitch username in all lowercase
|
3
|
+
:password: # Get one at http://twitchapps.com/tmi/
|
4
4
|
:server: irc.twitch.tv
|
5
5
|
:port: 6667
|
6
|
-
:channel: '#
|
6
|
+
:channel: '#twitchplaysbot' # Twitch channel to listen on, all lowercase
|
7
7
|
|
8
8
|
:log_line_length: 35 # Enough to fit a twitch username, a space, and "democracy"
|
9
|
+
:use_touch: true
|
10
|
+
:touch_move_amount: 50 # How many pixels to move the mouse when a touchscreen move is performed
|
9
11
|
|
10
12
|
# KEYMAP
|
11
13
|
# key names are as in X's keysymdef.h, without the leading XK_
|
@@ -15,14 +17,14 @@
|
|
15
17
|
:down: Down
|
16
18
|
:left: Left
|
17
19
|
:right: Right
|
18
|
-
:a:
|
19
|
-
:b:
|
20
|
+
:a: d
|
21
|
+
:b: c
|
20
22
|
:x: s
|
21
23
|
:y: x
|
22
24
|
:l: z
|
23
25
|
:r: a
|
24
26
|
:start: Return
|
25
|
-
:select:
|
27
|
+
:select: Tab
|
26
28
|
:save_state: F1
|
27
29
|
|
28
30
|
# DEMOCRACY
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module TwitchPlays
|
4
|
+
module OS
|
5
|
+
module Win
|
6
|
+
module User32
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
INPUT_MOUSE = 0x00
|
10
|
+
INPUT_KEYBOARD = 0x01
|
11
|
+
|
12
|
+
MOUSEEVENTF_MOVE = 0x01
|
13
|
+
MOUSEEVENTF_LEFTDOWN = 0x02
|
14
|
+
MOUSEEVENTF_LEFTUP = 0x04
|
15
|
+
|
16
|
+
VK_BACK = 0x08
|
17
|
+
VK_TAB = 0x09
|
18
|
+
VK_RETURN = 0x0d
|
19
|
+
VK_SHIFT = 0x10
|
20
|
+
VK_CONTROL = 0x11
|
21
|
+
VK_SPACE = 0x20
|
22
|
+
VK_LEFT = 0x25
|
23
|
+
VK_UP = 0x26
|
24
|
+
VK_RIGHT = 0x27
|
25
|
+
VK_DOWN = 0x28
|
26
|
+
VK_F1 = 0x70
|
27
|
+
VK_F2 = 0x71
|
28
|
+
VK_F3 = 0x72
|
29
|
+
VK_F4 = 0x73
|
30
|
+
VK_F5 = 0x74
|
31
|
+
VK_F6 = 0x75
|
32
|
+
VK_F7 = 0x76
|
33
|
+
VK_F8 = 0x77
|
34
|
+
VK_F9 = 0x78
|
35
|
+
VK_F10 = 0x79
|
36
|
+
VK_F11 = 0x7a
|
37
|
+
VK_F12 = 0x7b
|
38
|
+
|
39
|
+
class MouseInput < FFI::Struct
|
40
|
+
layout(:dx, :long,
|
41
|
+
:dy, :long,
|
42
|
+
:mouse_data, :uint,
|
43
|
+
:flags, :uint,
|
44
|
+
:time, :uint,
|
45
|
+
:extra_info, :pointer)
|
46
|
+
end
|
47
|
+
|
48
|
+
class KeyboardInput < FFI::Struct
|
49
|
+
layout(:vk, :ushort,
|
50
|
+
:scan, :ushort,
|
51
|
+
:flags, :uint,
|
52
|
+
:time, :uint,
|
53
|
+
:extra_info, :pointer)
|
54
|
+
end
|
55
|
+
|
56
|
+
class InputEvent < FFI::Union
|
57
|
+
layout(:mi, MouseInput,
|
58
|
+
:ki, KeyboardInput)
|
59
|
+
end
|
60
|
+
|
61
|
+
class Input < FFI::Struct
|
62
|
+
layout(:type, :uint,
|
63
|
+
:evt, InputEvent)
|
64
|
+
end
|
65
|
+
|
66
|
+
ffi_lib 'user32'
|
67
|
+
ffi_convention :stdcall
|
68
|
+
|
69
|
+
attach_function :SendInput, [:uint, :pointer, :int], :uint
|
70
|
+
end
|
71
|
+
|
72
|
+
TRANSLATE_KEYS = {
|
73
|
+
'BackSpace' => User32::VK_BACK,
|
74
|
+
'Tab' => User32::VK_TAB,
|
75
|
+
'Return' => User32::VK_RETURN,
|
76
|
+
'Shift_L' => User32::VK_SHIFT,
|
77
|
+
'Shift_R' => User32::VK_SHIFT,
|
78
|
+
'Control_L' => User32::VK_CONTROL,
|
79
|
+
'Control_R' => User32::VK_CONTROL,
|
80
|
+
'space' => User32::VK_SPACE,
|
81
|
+
'Left' => User32::VK_LEFT,
|
82
|
+
'Up' => User32::VK_UP,
|
83
|
+
'Right' => User32::VK_RIGHT,
|
84
|
+
'Down' => User32::VK_DOWN,
|
85
|
+
'F1' => User32::VK_F1,
|
86
|
+
'F2' => User32::VK_F2,
|
87
|
+
'F3' => User32::VK_F3,
|
88
|
+
'F4' => User32::VK_F4,
|
89
|
+
'F5' => User32::VK_F5,
|
90
|
+
'F6' => User32::VK_F6,
|
91
|
+
'F7' => User32::VK_F7,
|
92
|
+
'F8' => User32::VK_F8,
|
93
|
+
'F9' => User32::VK_F9,
|
94
|
+
'F10' => User32::VK_F10,
|
95
|
+
'F11' => User32::VK_F11,
|
96
|
+
'F12' => User32::VK_F12
|
97
|
+
}
|
98
|
+
|
99
|
+
def self.press(key)
|
100
|
+
input = User32::Input.new
|
101
|
+
input[:type] = User32::INPUT_KEYBOARD
|
102
|
+
evt = input[:evt][:ki]
|
103
|
+
evt[:vk] = TRANSLATE_KEYS[key] || key.upcase.ord
|
104
|
+
evt[:scan] = 0
|
105
|
+
evt[:flags] = 0
|
106
|
+
evt[:time] = 0
|
107
|
+
evt[:extra_info] = 0
|
108
|
+
User32.SendInput(1, [input], User32::Input.size)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.touch_move(dx, dy)
|
112
|
+
input = User32::Input.new
|
113
|
+
input[:type] = User32::INPUT_MOUSE
|
114
|
+
evt = input[:evt][:mi]
|
115
|
+
evt[:dx] = dx
|
116
|
+
evt[:dy] = dy
|
117
|
+
evt[:mouse_data] = 0
|
118
|
+
evt[:flags] = User32::MOUSEEVENTF_MOVE
|
119
|
+
evt[:time] = 0
|
120
|
+
evt[:extra_info] = 0
|
121
|
+
User32.SendInput(1, [input], User32::Input.size)
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.touch_press
|
125
|
+
input = User32::Input.new
|
126
|
+
input[:type] = User32::INPUT_MOUSE
|
127
|
+
evt = input[:evt][:mi]
|
128
|
+
evt[:dx] = 0
|
129
|
+
evt[:dy] = 0
|
130
|
+
evt[:mouse_data] = 0
|
131
|
+
evt[:flags] = User32::MOUSEEVENTF_LEFTDOWN
|
132
|
+
evt[:time] = 0
|
133
|
+
evt[:extra_info] = 0
|
134
|
+
User32.SendInput(1, [input], User32::Input.size)
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.touch_release
|
138
|
+
input = User32::Input.new
|
139
|
+
input[:type] = User32::INPUT_MOUSE
|
140
|
+
evt = input[:evt][:mi]
|
141
|
+
evt[:dx] = 0
|
142
|
+
evt[:dy] = 0
|
143
|
+
evt[:mouse_data] = 0
|
144
|
+
evt[:flags] = User32::MOUSEEVENTF_LEFTUP
|
145
|
+
evt[:time] = 0
|
146
|
+
evt[:extra_info] = 0
|
147
|
+
User32.SendInput(1, [input], User32::Input.size)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TwitchPlays
|
2
|
+
module OS
|
3
|
+
module X11
|
4
|
+
def self.press(key)
|
5
|
+
`xdotool key #{key}`
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.touch_move(dx, dy)
|
9
|
+
`xdotool mousemove_relative --sync -- #{dx} #{dy}`
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.touch_press
|
13
|
+
`xdotool mousedown 1`
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.touch_release
|
17
|
+
`xdotool mouseup 1`
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,100 +1,30 @@
|
|
1
|
+
require_relative 'os'
|
1
2
|
require 'yaml'
|
2
|
-
require 'ffi' if RbConfig::CONFIG['host_os'] =~ /win/
|
3
3
|
require 'cinch'
|
4
4
|
|
5
5
|
module TwitchPlays
|
6
|
-
if RbConfig::CONFIG['host_os'] =~ /win/
|
7
|
-
module Win
|
8
|
-
extend FFI::Library
|
9
|
-
|
10
|
-
INPUT_KEYBOARD = 1
|
11
|
-
|
12
|
-
VK_BACK = 0x08
|
13
|
-
VK_TAB = 0x09
|
14
|
-
VK_RETURN = 0x0d
|
15
|
-
VK_SHIFT = 0x10
|
16
|
-
VK_CONTROL = 0x11
|
17
|
-
VK_SPACE = 0x20
|
18
|
-
VK_LEFT = 0x25
|
19
|
-
VK_UP = 0x26
|
20
|
-
VK_RIGHT = 0x27
|
21
|
-
VK_DOWN = 0x28
|
22
|
-
VK_F1 = 0x70
|
23
|
-
VK_F2 = 0x71
|
24
|
-
VK_F3 = 0x72
|
25
|
-
VK_F4 = 0x73
|
26
|
-
VK_F5 = 0x74
|
27
|
-
VK_F6 = 0x75
|
28
|
-
VK_F7 = 0x76
|
29
|
-
VK_F8 = 0x77
|
30
|
-
VK_F9 = 0x78
|
31
|
-
VK_F10 = 0x79
|
32
|
-
VK_F11 = 0x7a
|
33
|
-
VK_F12 = 0x7b
|
34
|
-
|
35
|
-
class KeyboardInput < FFI::Struct
|
36
|
-
layout(:vk, :ushort,
|
37
|
-
:scan, :ushort,
|
38
|
-
:flags, :uint,
|
39
|
-
:time, :uint,
|
40
|
-
:extra_info, :pointer)
|
41
|
-
end
|
42
|
-
|
43
|
-
class InputEvent < FFI::Union
|
44
|
-
layout :ki, KeyboardInput
|
45
|
-
|
46
|
-
class Input < FFI::Struct
|
47
|
-
layout(:type, :uint,
|
48
|
-
:evt, InputEvent)
|
49
|
-
end
|
50
|
-
|
51
|
-
ffi_lib 'user32'
|
52
|
-
ffi_convention :stdcall
|
53
|
-
|
54
|
-
attach_function :SendInput, [:uint, :pointer, :int], :uint
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
TRANSLATE_KEYS = {
|
59
|
-
'BackSpace' => Win::VK_BACK,
|
60
|
-
'Tab' => Win::VK_TAB,
|
61
|
-
'Return' => Win::VK_RETURN,
|
62
|
-
'Shift_L' => Win::VK_SHIFT,
|
63
|
-
'Shift_R' => Win::VK_SHIFT,
|
64
|
-
'Control_L' => Win::VK_CONTROL,
|
65
|
-
'Control_R' => Win::VK_CONTROL,
|
66
|
-
'space' => Win::VK_SPACE,
|
67
|
-
'Left' => Win::VK_LEFT,
|
68
|
-
'Up' => Win::VK_UP,
|
69
|
-
'Right' => Win::VK_RIGHT,
|
70
|
-
'Down' => Win::VK_DOWN,
|
71
|
-
'F1' => Win::VK_F1,
|
72
|
-
'F2' => Win::VK_F2,
|
73
|
-
'F3' => Win::VK_F3,
|
74
|
-
'F4' => Win::VK_F4,
|
75
|
-
'F5' => Win::VK_F5,
|
76
|
-
'F6' => Win::VK_F6,
|
77
|
-
'F7' => Win::VK_F7,
|
78
|
-
'F8' => Win::VK_F8,
|
79
|
-
'F9' => Win::VK_F9,
|
80
|
-
'F10' => Win::VK_F10,
|
81
|
-
'F11' => Win::VK_F11,
|
82
|
-
'F12' => Win::VK_F12
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
6
|
class Plugin
|
87
7
|
include Cinch::Plugin
|
88
8
|
|
9
|
+
plugin_name = 'TwitchPlaysPlugin'
|
89
10
|
listen_to :connect, method: :on_connect
|
90
11
|
listen_to :message, method: :on_message
|
91
12
|
|
92
13
|
def initialize(*args)
|
93
14
|
super
|
94
15
|
@keys = config[:keys]
|
16
|
+
@use_touch = config[:use_touch]
|
17
|
+
touch_move_amount = config[:touch_move_amount]
|
18
|
+
@touch_directions = {
|
19
|
+
touch_up: [0, -touch_move_amount],
|
20
|
+
touch_down: [0, touch_move_amount],
|
21
|
+
touch_left: [-touch_move_amount, 0],
|
22
|
+
touch_right: [touch_move_amount, 0]
|
23
|
+
}
|
95
24
|
@democracy_votes = 0
|
96
25
|
@anarchy_votes = 0
|
97
|
-
@
|
26
|
+
@use_democracy = config[:use_democracy]
|
27
|
+
@democracy_mode = @use_democracy && config[:start_in_democracy]
|
98
28
|
@democracy_ratio_needed = config[:democracy_ratio_needed]
|
99
29
|
@anarchy_ratio_needed = config[:anarchy_ratio_needed]
|
100
30
|
@button_votes = Hash.new(0)
|
@@ -113,66 +43,60 @@ module TwitchPlays
|
|
113
43
|
end
|
114
44
|
|
115
45
|
def start_democracy
|
46
|
+
return if @democracy_mode
|
116
47
|
@democracy_mode = true
|
117
48
|
puts '---STARTING DEMOCRACY MODE---'
|
118
49
|
@voting_thread = Thread.new do
|
119
50
|
while @democracy_mode
|
120
|
-
|
121
|
-
|
51
|
+
synchronize(:votes_mutex) do
|
52
|
+
@button_votes.clear
|
53
|
+
@total_votes = 0
|
54
|
+
end
|
122
55
|
sleep @voting_time
|
123
|
-
next if @total_votes
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
56
|
+
next if @total_votes.zero?
|
57
|
+
winner = synchronize(:votes_mutex) do
|
58
|
+
puts "VOTES:\n" + @button_votes.sort {|(_, count1), (_, count2)|
|
59
|
+
count1 <=> count2
|
60
|
+
}.first(5).map {|(btn, count)|
|
61
|
+
[btn, count.to_f / @total_votes * 100]
|
62
|
+
}.map {|(btn, percent)|
|
63
|
+
format_log_line(btn, "#{percent}%")
|
64
|
+
}.join("\n")
|
65
|
+
@button_votes.max_by {|(_, count)| count}[0]
|
66
|
+
end
|
67
|
+
case winner
|
68
|
+
when :touch_up, :touch_down, :touch_left, :touch_right
|
69
|
+
Output.touch_move(*@touch_directions[winner])
|
70
|
+
when :touch_press
|
71
|
+
Output.touch_press
|
72
|
+
when :touch_release
|
73
|
+
Output.touch_release
|
74
|
+
else
|
75
|
+
Output.press(@keys[winner])
|
76
|
+
end
|
136
77
|
end
|
137
78
|
end
|
138
79
|
end
|
139
80
|
|
140
81
|
def start_anarchy
|
82
|
+
return unless @democracy_mode
|
141
83
|
@democracy_mode = false
|
142
84
|
@voting_thread.join
|
85
|
+
@voting_thread = nil
|
143
86
|
puts '---STARTING ANARCHY MODE---'
|
144
87
|
end
|
145
88
|
|
146
|
-
case RbConfig::CONFIG['host_os']
|
147
|
-
when /linux/
|
148
|
-
def press(key)
|
149
|
-
`xdotool key #{key}`
|
150
|
-
end
|
151
|
-
when /win/
|
152
|
-
def press(key)
|
153
|
-
input = Win::Input.new
|
154
|
-
input[:type] = Win::INPUT_KEYBOARD
|
155
|
-
evt = input[:evt][:ki]
|
156
|
-
evt.vk = TRANSLATE_KEYS[key] || key.upcase.ord
|
157
|
-
evt.scan = 0
|
158
|
-
evt.flags = 0
|
159
|
-
evt.time = 0
|
160
|
-
evt.extra_info = 0
|
161
|
-
Win.SendInput(1, [input], Win::Input.size)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
89
|
def format_log_line(name, command)
|
166
90
|
"#{name}#{' ' * (@log_line_length - name.length - command.length)}#{command}"
|
167
91
|
end
|
168
92
|
|
169
93
|
def on_connect(msg)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
94
|
+
return unless @use_savestates
|
95
|
+
@savestate_thread = Thread.new do
|
96
|
+
key = @keys[:save_state]
|
97
|
+
loop do
|
98
|
+
sleep @savestate_interval
|
99
|
+
Output.press(key)
|
176
100
|
end
|
177
101
|
end
|
178
102
|
end
|
@@ -181,26 +105,69 @@ module TwitchPlays
|
|
181
105
|
message = msg.message
|
182
106
|
case message
|
183
107
|
when /^anarchy$/i
|
108
|
+
return unless @use_democracy
|
184
109
|
puts format_log_line(msg.user.nick, message.downcase)
|
185
|
-
|
186
|
-
|
187
|
-
|
110
|
+
synchronize(:votes_mutex) do
|
111
|
+
@anarchy_votes += 1
|
112
|
+
if @democracy_mode && calculate_ratio <= @anarchy_ratio_needed
|
113
|
+
start_anarchy
|
114
|
+
end
|
188
115
|
end
|
189
116
|
when /^democracy$/i
|
117
|
+
return unless @use_democracy
|
190
118
|
puts format_log_line(msg.user.nick, message.downcase)
|
191
|
-
|
192
|
-
|
193
|
-
|
119
|
+
synchronize(:votes_mutex) do
|
120
|
+
@democracy_votes += 1
|
121
|
+
if !@democracy_mode && calculate_ratio >= @democracy_ratio_needed
|
122
|
+
start_democracy
|
123
|
+
end
|
194
124
|
end
|
195
|
-
when /^up|down|left|right|a|b|x|y|l|r|start|select$/i
|
125
|
+
when /^(?:up|down|left|right|a|b|x|y|l|r|start|select)$/i
|
196
126
|
btn = $&.to_sym
|
127
|
+
return unless @keys.has_key?(btn)
|
128
|
+
if @democracy_mode
|
129
|
+
synchronize(:votes_mutex) do
|
130
|
+
@total_votes += 1
|
131
|
+
@button_votes[btn] += 1
|
132
|
+
end
|
133
|
+
return
|
134
|
+
end
|
135
|
+
puts format_log_line(msg.user.nick, message.downcase)
|
136
|
+
Output.press(@keys[btn])
|
137
|
+
when /^(?:touch_up|touch_down|touch_left|touch_right)$/i
|
138
|
+
return unless @use_touch
|
139
|
+
btn = $&.to_sym
|
140
|
+
if @democracy_mode
|
141
|
+
synchronize(:votes_mutex) do
|
142
|
+
@total_votes += 1
|
143
|
+
@button_votes[btn] += 1
|
144
|
+
end
|
145
|
+
return
|
146
|
+
end
|
147
|
+
puts format_log_line(msg.user.nick, message.downcase)
|
148
|
+
Output.touch_move(*@touch_directions[btn])
|
149
|
+
when /^touch_press$/i
|
150
|
+
return unless @use_touch
|
197
151
|
if @democracy_mode
|
198
|
-
|
199
|
-
|
152
|
+
synchronize(:votes_mutex) do
|
153
|
+
@total_votes += 1
|
154
|
+
@button_votes[$&.to_sym] += 1
|
155
|
+
end
|
200
156
|
return
|
201
157
|
end
|
202
|
-
puts format_log_line(msg.user.nick,
|
203
|
-
|
158
|
+
puts format_log_line(msg.user.nick, message.downcase)
|
159
|
+
Output.touch_press
|
160
|
+
when /^touch_release$/i
|
161
|
+
return unless @use_touch
|
162
|
+
if @democracy_mode
|
163
|
+
synchronize(:votes_mutex) do
|
164
|
+
@total_votes += 1
|
165
|
+
@button_votes[$&.to_sym] += 1
|
166
|
+
end
|
167
|
+
return
|
168
|
+
end
|
169
|
+
puts format_log_line(msg.user.nick, message.downcase)
|
170
|
+
Output.touch_release
|
204
171
|
end
|
205
172
|
end
|
206
173
|
end
|
@@ -218,6 +185,9 @@ module TwitchPlays
|
|
218
185
|
c.plugins.options[Plugin] = config
|
219
186
|
end
|
220
187
|
end
|
188
|
+
trap('INT') do
|
189
|
+
bot.quit
|
190
|
+
end
|
221
191
|
bot.start
|
222
192
|
end
|
223
193
|
end
|
data/lib/twitch_plays/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twitch_plays
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Steward
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cinch
|
@@ -51,6 +51,9 @@ files:
|
|
51
51
|
- bin/twitch_plays~
|
52
52
|
- config.yml
|
53
53
|
- lib/twitch_plays.rb
|
54
|
+
- lib/twitch_plays/os.rb
|
55
|
+
- lib/twitch_plays/os/win.rb
|
56
|
+
- lib/twitch_plays/os/x11.rb
|
54
57
|
- lib/twitch_plays/twitch_plays.rb
|
55
58
|
- lib/twitch_plays/version.rb
|
56
59
|
homepage: https://github.com/filialpails/twitch_plays
|
@@ -73,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
76
|
version: '0'
|
74
77
|
requirements: []
|
75
78
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.
|
79
|
+
rubygems_version: 2.3.0
|
77
80
|
signing_key:
|
78
81
|
specification_version: 4
|
79
82
|
summary: Yet another Twitch Plays Pokemon clone.
|