room 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/VERSION +1 -1
  2. data/bin/room +16 -2
  3. data/lib/room.rb +84 -18
  4. data/room.gemspec +4 -3
  5. data/rooms/tweets.rb +260 -0
  6. metadata +6 -5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
data/bin/room CHANGED
@@ -30,6 +30,7 @@ opts.parse! ARGV
30
30
 
31
31
  if ARGV.length > 0
32
32
  if ARGV[0] == "for" && !ARGV[1].nil?
33
+ @room = ARGV[1]
33
34
  @filename = find_room ARGV[1]
34
35
  unless @filename
35
36
  puts "room \"#{ARGV[1]}\" not found"
@@ -39,24 +40,37 @@ if ARGV.length > 0
39
40
  usage
40
41
  end
41
42
  else
43
+ @room = "beginners"
42
44
  @filename = find_room "beginners"
43
45
  end
44
46
 
45
- reload! @filename
47
+ reload! @room, @filename
48
+
49
+ if Array === $state[:history]
50
+ $state[:history].each { |h| Readline::HISTORY.push h }
51
+ else
52
+ $state[:history] = []
53
+ end
46
54
 
47
55
  3.times { Printer.puts }
48
56
 
57
+ trap("INT", "SIG_IGN")
58
+
49
59
  Room.do "look"
50
60
  loop do
51
61
  line = if $secretive
52
62
  $secretive = false
53
63
  HighLine.new.ask("> ") { |q| q.echo = false }
54
64
  else
55
- Readline.readline("> ", true)
65
+ x = Readline.readline("> ", true)
66
+ $state[:history] << x if x
67
+ x
56
68
  end
57
69
 
58
70
  break unless line
59
71
  Room.do line.chomp
72
+
73
+ save!
60
74
  end
61
75
 
62
76
  Printer.puts "\nThe world is your cantaloupe."
data/lib/room.rb CHANGED
@@ -1,13 +1,58 @@
1
1
 
2
2
  require "thread"
3
3
 
4
- def reload! filename=nil
4
+ $state = {}
5
+
6
+ def reload! room_name = nil, filename = nil
5
7
  $commands = {}
8
+
9
+ $room_name ||= room_name
6
10
  $last_filename ||= filename
7
11
 
8
- old_count = Room.rooms.keys.length
9
12
  load $last_filename
10
- Room.rooms.keys.length - old_count
13
+ load!
14
+
15
+ $state[:here] ||= $starting_room
16
+ end
17
+
18
+ def prefs_paths
19
+ dir_path = File.expand_path("~/.room")
20
+ file_path = File.join(dir_path, $room_name)
21
+ [dir_path, file_path]
22
+ end
23
+
24
+ def no_save!
25
+ $no_save = true
26
+ end
27
+
28
+ def save! obj = $state
29
+ return if $no_save
30
+
31
+ dir_path, file_path = prefs_paths
32
+ begin
33
+ Dir::mkdir dir_path unless File.exist? dir_path
34
+ File.open(file_path, "wb") { |f| f.write Marshal.dump(obj || {}) }
35
+ @previous_save_error = false
36
+ rescue Exception => e
37
+ unless @previous_save_error
38
+ Printer.puts "[warning: couldn't save state: #{e}]"
39
+ @previous_save_error = true
40
+ end
41
+ end
42
+ end
43
+
44
+ def load!
45
+ _, file_path = prefs_paths
46
+ return unless File.exist? file_path
47
+ begin
48
+ $state = Marshal.load(File.read(file_path))
49
+ @previous_load_error = false
50
+ rescue Exception => e
51
+ unless @previous_load_error
52
+ Printer.puts "[warning: couldn't load state: #{e}]"
53
+ @previous_load_error = true
54
+ end
55
+ end
11
56
  end
12
57
 
13
58
  class String
@@ -60,7 +105,7 @@ class Room
60
105
  end
61
106
 
62
107
  def inventory
63
- $inventory ||= []
108
+ $state[:inventory] ||= []
64
109
  end
65
110
 
66
111
  def have? item
@@ -78,10 +123,6 @@ class Room
78
123
  def do action
79
124
  Printer.puts
80
125
  if action.strip == ""
81
- elsif action == "reload!"
82
- d = reload!
83
- Printer.puts "A great wave of relief washes over you."
84
- Printer.puts "The world seems larger by about #{d}." if d > 0
85
126
  elsif (r = self.class.commands.detect { |c, m| c =~ action })
86
127
  command, method = r
87
128
  args = command.match(action).to_a.drop(1)
@@ -120,22 +161,46 @@ class Room
120
161
  $commands[key] ||= DEFAULT_COMMANDS.dup
121
162
  end
122
163
 
123
- def rooms
124
- $rooms ||= {}
164
+ def room key
165
+ $state[:rooms] ||= {}
166
+ $state[:rooms][key] = room_keys[key].new if $state[:rooms][key].nil? && room_keys[key]
167
+ $state[:rooms][key]
168
+ end
169
+
170
+ def room_keys
171
+ $room_keys ||= {}
172
+ end
173
+
174
+ def here
175
+ room $state[:here]
125
176
  end
126
177
 
127
178
  def go key, look = true
128
- if rooms[key]
129
- $here = rooms[key]
130
- "\n" + $here.look if look
179
+ if room key
180
+ $state[:here] = key
181
+ "\n" + here.look if look
131
182
  else
132
- $here.unknown_room key
183
+ here.unknown_room key
133
184
  end
134
185
  end
135
186
 
136
187
  def do action
137
- if $here
138
- $here.do action
188
+ if action == "debug!"
189
+ Printer.puts
190
+ Printer.puts $state.inspect
191
+ elsif action == "restart!"
192
+ $state = { :here => $starting_room }
193
+ Printer.puts
194
+ Printer.puts " ....."
195
+ Printer.puts "Your mind, a wild monkey."
196
+ Printer.puts " ....,.,"
197
+ Room.do "look"
198
+ elsif action == "reload!"
199
+ reload!
200
+ Printer.puts
201
+ Printer.puts "A great wave of relief washes over you."
202
+ elsif here
203
+ here.do action
139
204
  else
140
205
  Printer.puts
141
206
  Printer.puts "Where am I?"
@@ -153,8 +218,9 @@ class Room
153
218
  end
154
219
 
155
220
  def inherited subclass
156
- rooms[subclass.key] = subclass.new
157
- $here ||= rooms[subclass.key]
221
+ room_keys[subclass.key] = subclass
222
+ $starting_room ||= subclass.key
223
+ $state[:here] ||= $starting_room
158
224
  end
159
225
 
160
226
  def method_added name
data/room.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{room}
8
- s.version = "0.1.3"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tom Lieber"]
12
- s.date = %q{2011-04-01}
12
+ s.date = %q{2011-04-18}
13
13
  s.default_executable = %q{room}
14
14
  s.description = %q{the game is making the game}
15
15
  s.email = %q{tom@alltom.com}
@@ -27,7 +27,8 @@ Gem::Specification.new do |s|
27
27
  "bin/room",
28
28
  "lib/room.rb",
29
29
  "room.gemspec",
30
- "rooms/beginners.rb"
30
+ "rooms/beginners.rb",
31
+ "rooms/tweets.rb"
31
32
  ]
32
33
  s.homepage = %q{http://github.com/alltom/room}
33
34
  s.require_paths = ["lib"]
data/rooms/tweets.rb ADDED
@@ -0,0 +1,260 @@
1
+
2
+ $ALPHA = "sx8vQ9ZGi4F96dnuNThg"
3
+ $OMEGA = "ZkS8eDam8tTF6tBGxi4A3sxhTTYE0EyCGHb9dAHM"
4
+
5
+ $failed_requires = []
6
+ %w{ oauth twitter uri }.each do |n|
7
+ begin
8
+ require n
9
+ rescue LoadError
10
+ $failed_requires << n
11
+ end
12
+ end
13
+
14
+ begin
15
+ require "launchy"
16
+ rescue LoadError
17
+ end
18
+
19
+
20
+ def request_token
21
+ $request_token ||= begin
22
+ OAuth::Consumer.new($ALPHA, $OMEGA,
23
+ :site => 'http://twitter.com/',
24
+ :request_token_path => '/oauth/request_token',
25
+ :access_token_path => '/oauth/access_token',
26
+ :authorize_path => '/oauth/authorize'
27
+ ).get_request_token
28
+ rescue Exception => e
29
+ nil
30
+ end
31
+ end
32
+
33
+ def authorize_url
34
+ request_token.authorize_url
35
+ end
36
+
37
+ def authorize pin
38
+ begin
39
+ access = request_token.get_access_token(:oauth_verifier => pin)
40
+
41
+ $state[:twitter_token] = access.token
42
+ $state[:twitter_secret] = access.secret
43
+
44
+ Twitter.configure do |config|
45
+ config.consumer_key = $ALPHA
46
+ config.consumer_secret = $OMEGA
47
+ config.oauth_token = $state[:twitter_token]
48
+ config.oauth_token_secret = $state[:twitter_secret]
49
+ end
50
+ rescue Exception
51
+ nil
52
+ end
53
+ end
54
+
55
+ def tweet_display_format message
56
+ message.gsub("\n", " \\ ").gsub("\"", "'")
57
+ end
58
+
59
+ def latest_tweets
60
+ tweets = begin
61
+ Twitter.home_timeline($state[:last_tweet_id] ? { :since_id => $state[:last_tweet_id] } : {}).reverse
62
+ rescue Twitter::Unauthorized
63
+ raise
64
+ rescue Exception => e
65
+ Printer.puts "[warning: couldn't fetch tweets: #{e.inspect} #{e.class}]"
66
+ []
67
+ end
68
+
69
+ $state[:last_tweet_id] = tweets.last.id unless tweets.length == 0
70
+
71
+ tweets
72
+ end
73
+
74
+ class Entrance < Room
75
+ def look
76
+ immediate(
77
+ "You pull into the crowded parking lot, shove a" |
78
+ "cinderblock under your car tire, and look up." |
79
+ "The metallic blue neon sign above the door reads:" |
80
+ "" |
81
+ " DICK'S BAR" |
82
+ " \"we all like the same things\"" |
83
+ "" |
84
+ "You sure hope so." |
85
+ "" |
86
+ "You attempt to open the door, but it won't budge." |
87
+ "Instead, you see flickers of movement behind two" |
88
+ "holes in the door about eyes' width apart. You squat" |
89
+ "to look into them and see someone rummaging..." |
90
+ ""
91
+ )
92
+
93
+ if $failed_requires.length > 0
94
+ which = $failed_requires.first
95
+ return "\"Hm, that's strange,\" you hear a voice say." |
96
+ "\"Someone must have done something with my #{which.upcase} gem...\"" |
97
+ "" |
98
+ "For no reason, your eyes roll back into your head and" |
99
+ "you slip out of existence. Should've installed the #{which.upcase} gem!" |
100
+ go("purgatory")
101
+ end
102
+
103
+ unless request_token
104
+ return Purgatory.intro("The Twitter API could not be reached!") |
105
+ go("purgatory")
106
+ end
107
+
108
+ "\"Here. Use this.\" A long piece of paper slides beneath the door." |
109
+ "" |
110
+ "Type 'look' to look around, but eventually you're going to have to" |
111
+ "pick up that piece of paper." |
112
+ quietly_go("entrance2")
113
+ end
114
+ end
115
+
116
+ class Entrance2 < Room
117
+ def look
118
+ "You're standing in front of Dick's Bar and" |
119
+ (if have? :paper
120
+ "you really want to read the piece of paper you're holding."
121
+ else
122
+ "you really want to pick up the piece of paper on the ground."
123
+ end)
124
+ end
125
+
126
+ def pick_up_that_piece_of_paper
127
+ if have? :paper
128
+ huh?
129
+ else
130
+ take :paper
131
+ "You pick up the piece of paper and stuff it in your pocket!" |
132
+ "But aren't you curious what's on it?"
133
+ end
134
+ end
135
+ dup :pick_up_the_piece_of_paper, :pick_up_piece_of_paper, :pick_up_the_paper, :pick_up_paper
136
+ dup :get_the_piece_of_paper, :get_piece_of_paper, :get_the_paper, :get_paper
137
+
138
+ def read_the_paper
139
+ if have? :paper
140
+ "The paper contains the following message:" |
141
+ "" |
142
+ " #{authorize_url}" |
143
+ " SAY YOUR PIN" |
144
+ "" |
145
+ "And that's all."
146
+ else
147
+ huh?
148
+ end
149
+ end
150
+ dup :read_paper, :look_paper
151
+
152
+ def say_XXX pin
153
+ return huh? unless have? :paper
154
+ return huh? if pin !~ /^[0-9]+$/
155
+
156
+ immediate "You speak your pin and the eyes disappear for a moment."
157
+ immediate
158
+
159
+ if authorize(pin)
160
+ immediate "And then... the door swings open and the doorman ushers"
161
+ immediate "you inside. \"Come on, come on.\" The door shuts tight behind you."
162
+ immediate
163
+ immediate
164
+ go("bar")
165
+ else
166
+ "\"That is incorrect,\" the voice says and the eyes examine" |
167
+ "you suspiciously. They seem to peer into your very soul and you" |
168
+ "feel nervous." |
169
+ "" |
170
+ "\"Try again.\""
171
+ end
172
+ end
173
+ dup :XXX
174
+ end
175
+
176
+ class Purgatory < Room
177
+ def self.intro reason
178
+ "BANG! Before you can settle into a virtual persona, a" |
179
+ "crack appears in the sky and the universe splits into two!" |
180
+ reason + " And now... well..."
181
+ end
182
+
183
+ def look
184
+ @jokes ||= ["What's brown and sticky? A stick! Hahahaha!"]
185
+ "You are stuck in purgatory. There is nothing to do here but #{@jokes.length > 0 ? "crack a joke or " : ""}'restart!'."
186
+ end
187
+
188
+ def laugh
189
+ "You laugh and that makes you feel a little bit better, but still..." | look
190
+ end
191
+
192
+ def crack_a_joke
193
+ if joke = @jokes.shift
194
+ joke
195
+ else
196
+ "You are out of jokes."
197
+ end
198
+ end
199
+
200
+ def quit
201
+ exit
202
+ end
203
+ dup :q
204
+ end
205
+
206
+ class Bar < Room
207
+ def look
208
+ @tweet_buffer ||= []
209
+
210
+ immediate "The bar."
211
+
212
+ @last_check ||= Time.now - 15
213
+ if Time.now - @last_check > 10
214
+ @tweet_buffer += latest_tweets
215
+ @last_check = Time.now
216
+ end
217
+
218
+ if @tweet_buffer.length > 0
219
+ "\n" + @tweet_buffer.shift(3 + rand(2)).map do |tweet|
220
+ "#{tweet.user.name} says, \"#{tweet_display_format tweet.text}\""
221
+ end.join("\n\n") + "\n"
222
+ else
223
+ "The room is, for the moment, silent."
224
+ end
225
+
226
+ rescue Twitter::Unauthorized
227
+ "" |
228
+ "Out of nowhere, the a bouncer grabs you by the ear and" |
229
+ "pulls you outside. Apparently the jig is up? Time to" |
230
+ "re-authenticate. Like your grandma always said: 'OAuth is," |
231
+ "like, the best thing ever.'" |
232
+ go("entrance2")
233
+ end
234
+
235
+ def say_XXX message
236
+ if message.length > 140
237
+ "The words get caught in your mouth; you're gargling air." |
238
+ "You remember the sign on the wall: '140 characters at a time'." |
239
+ "You were #{message.length - 140} over. :("
240
+ else
241
+ immediate "You proclaim to everyone in the room, \"#{tweet_display_format message}\""
242
+
243
+ begin
244
+ Twitter.update(message)
245
+ ""
246
+ rescue Exception
247
+ "But no one could hear you. Hello? Is this thing on?"
248
+ end
249
+ end
250
+ end
251
+
252
+ def XXX action
253
+ if defined?(Launchy) && action.strip == URI.extract(action).first
254
+ Launchy.open(URI.extract(action).first)
255
+ "You feel elevated to another plane."
256
+ else
257
+ huh?
258
+ end
259
+ end
260
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: room
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 3
10
- version: 0.1.3
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tom Lieber
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-01 00:00:00 -07:00
18
+ date: 2011-04-18 00:00:00 -07:00
19
19
  default_executable: room
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -83,6 +83,7 @@ files:
83
83
  - lib/room.rb
84
84
  - room.gemspec
85
85
  - rooms/beginners.rb
86
+ - rooms/tweets.rb
86
87
  has_rdoc: true
87
88
  homepage: http://github.com/alltom/room
88
89
  licenses: []