carps 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. data/COPYING +674 -0
  2. data/GEM_DESCRIPTION +10 -0
  3. data/History.txt +4 -0
  4. data/Manifest.txt +156 -0
  5. data/PostInstall.txt +20 -0
  6. data/README.rdoc +141 -0
  7. data/Rakefile +28 -0
  8. data/bin/carps +123 -0
  9. data/bin/carps_init +29 -0
  10. data/bin/carps_ipc_test +44 -0
  11. data/bin/carps_mod_saver_test +71 -0
  12. data/bin/carps_mod_test +62 -0
  13. data/config/website.yml +2 -0
  14. data/features/character_sheet.feature +40 -0
  15. data/features/crash.feature +15 -0
  16. data/features/crypt.feature +22 -0
  17. data/features/dice.feature +173 -0
  18. data/features/dm.feature +36 -0
  19. data/features/dmll.feature +51 -0
  20. data/features/edit.feature +10 -0
  21. data/features/email.feature +29 -0
  22. data/features/interface.feature +17 -0
  23. data/features/ipc.feature +10 -0
  24. data/features/mailbox.feature +33 -0
  25. data/features/mod.feature +31 -0
  26. data/features/parser.feature +9 -0
  27. data/features/persistent_protocol.feature +14 -0
  28. data/features/player.feature +22 -0
  29. data/features/player_turn.feature +29 -0
  30. data/features/random.feature +15 -0
  31. data/features/rule.feature +19 -0
  32. data/features/safety.feature +13 -0
  33. data/features/sessions.feature +16 -0
  34. data/features/start_dm.feature +18 -0
  35. data/features/start_player.feature +8 -0
  36. data/features/step_definitions/common_steps.rb +170 -0
  37. data/features/steps/character_sheet.rb +89 -0
  38. data/features/steps/crash.rb +27 -0
  39. data/features/steps/crypt.rb +166 -0
  40. data/features/steps/dice.rb +91 -0
  41. data/features/steps/dm.rb +147 -0
  42. data/features/steps/dmll.rb +47 -0
  43. data/features/steps/edit.rb +7 -0
  44. data/features/steps/email.rb +108 -0
  45. data/features/steps/general.rb +5 -0
  46. data/features/steps/interface.rb +64 -0
  47. data/features/steps/ipc.rb +22 -0
  48. data/features/steps/mailbox.rb +126 -0
  49. data/features/steps/mod.rb +25 -0
  50. data/features/steps/parser.rb +23 -0
  51. data/features/steps/persistent_protocol.rb +29 -0
  52. data/features/steps/player.rb +82 -0
  53. data/features/steps/player_turn.rb +56 -0
  54. data/features/steps/random.rb +47 -0
  55. data/features/steps/rule.rb +53 -0
  56. data/features/steps/safety.rb +17 -0
  57. data/features/steps/sessions.rb +37 -0
  58. data/features/steps/start_dm.rb +46 -0
  59. data/features/steps/start_player.rb +65 -0
  60. data/features/steps/timeout.rb +32 -0
  61. data/features/steps/type_verification.rb +36 -0
  62. data/features/steps/wizard.rb +123 -0
  63. data/features/support/common.rb +29 -0
  64. data/features/support/env.rb +14 -0
  65. data/features/support/matchers.rb +11 -0
  66. data/features/timeout.feature +11 -0
  67. data/features/type_verification.feature +48 -0
  68. data/features/wizard.feature +50 -0
  69. data/lib/carps/crypt/accept_handshake.rb +40 -0
  70. data/lib/carps/crypt/default_messages.rb +29 -0
  71. data/lib/carps/crypt/handshake.rb +41 -0
  72. data/lib/carps/crypt/mailbox.rb +265 -0
  73. data/lib/carps/crypt/mailer.rb +220 -0
  74. data/lib/carps/crypt/peer.rb +123 -0
  75. data/lib/carps/crypt/public_key.rb +60 -0
  76. data/lib/carps/crypt.rb +23 -0
  77. data/lib/carps/email/config.rb +122 -0
  78. data/lib/carps/email/imap.rb +156 -0
  79. data/lib/carps/email/smtp.rb +119 -0
  80. data/lib/carps/email/string.rb +30 -0
  81. data/lib/carps/email.rb +21 -0
  82. data/lib/carps/mod/action.rb +36 -0
  83. data/lib/carps/mod/answers.rb +76 -0
  84. data/lib/carps/mod/client_turn.rb +88 -0
  85. data/lib/carps/mod/dice.rb +360 -0
  86. data/lib/carps/mod/dm/interface.rb +160 -0
  87. data/lib/carps/mod/dm/mod.rb +409 -0
  88. data/lib/carps/mod/dm/reporter.rb +112 -0
  89. data/lib/carps/mod/dm/resource.rb +88 -0
  90. data/lib/carps/mod/dm/room.rb +33 -0
  91. data/lib/carps/mod/interface.rb +73 -0
  92. data/lib/carps/mod/launch.rb +108 -0
  93. data/lib/carps/mod/mod.rb +52 -0
  94. data/lib/carps/mod/player/interface.rb +76 -0
  95. data/lib/carps/mod/player/mod.rb +109 -0
  96. data/lib/carps/mod/question.rb +63 -0
  97. data/lib/carps/mod/rule.rb +112 -0
  98. data/lib/carps/mod/sheet/character.rb +82 -0
  99. data/lib/carps/mod/sheet/editor.rb +97 -0
  100. data/lib/carps/mod/sheet/new_sheet.rb +71 -0
  101. data/lib/carps/mod/sheet/schema.rb +84 -0
  102. data/lib/carps/mod/sheet/type.rb +161 -0
  103. data/lib/carps/mod/sheet/verifier.rb +41 -0
  104. data/lib/carps/mod/status_report.rb +51 -0
  105. data/lib/carps/mod.rb +40 -0
  106. data/lib/carps/protocol/keyword.rb +104 -0
  107. data/lib/carps/protocol/message.rb +138 -0
  108. data/lib/carps/protocol.rb +19 -0
  109. data/lib/carps/service/client_parser.rb +34 -0
  110. data/lib/carps/service/dm/config.rb +76 -0
  111. data/lib/carps/service/dm/mailer.rb +70 -0
  112. data/lib/carps/service/dm/new_game.rb +101 -0
  113. data/lib/carps/service/dm/start.rb +47 -0
  114. data/lib/carps/service/game.rb +101 -0
  115. data/lib/carps/service/interface.rb +174 -0
  116. data/lib/carps/service/invite.rb +79 -0
  117. data/lib/carps/service/mod.rb +43 -0
  118. data/lib/carps/service/player/config.rb +78 -0
  119. data/lib/carps/service/player/mailer.rb +49 -0
  120. data/lib/carps/service/player/start.rb +60 -0
  121. data/lib/carps/service/server_parser.rb +33 -0
  122. data/lib/carps/service/session.rb +96 -0
  123. data/lib/carps/service/start/config.rb +71 -0
  124. data/lib/carps/service/start/interface.rb +101 -0
  125. data/lib/carps/service/start/mailer.rb +46 -0
  126. data/lib/carps/service.rb +35 -0
  127. data/lib/carps/test.rb +34 -0
  128. data/lib/carps/ui/colour.rb +28 -0
  129. data/lib/carps/ui/error.rb +39 -0
  130. data/lib/carps/ui/highlight.rb +32 -0
  131. data/lib/carps/ui/question.rb +63 -0
  132. data/lib/carps/ui/warn.rb +37 -0
  133. data/lib/carps/ui.rb +21 -0
  134. data/lib/carps/util/config.rb +162 -0
  135. data/lib/carps/util/editor.rb +147 -0
  136. data/lib/carps/util/error.rb +75 -0
  137. data/lib/carps/util/files.rb +48 -0
  138. data/lib/carps/util/init.rb +93 -0
  139. data/lib/carps/util/process.rb +150 -0
  140. data/lib/carps/util/timeout.rb +31 -0
  141. data/lib/carps/util/windows.rb +29 -0
  142. data/lib/carps/util.rb +24 -0
  143. data/lib/carps/wizard/dm.rb +41 -0
  144. data/lib/carps/wizard/player.rb +40 -0
  145. data/lib/carps/wizard/steps.rb +494 -0
  146. data/lib/carps/wizard/wizard.rb +126 -0
  147. data/lib/carps/wizard.rb +21 -0
  148. data/lib/carps.rb +45 -0
  149. data/permission +16 -0
  150. data/script/console +10 -0
  151. data/script/destroy +14 -0
  152. data/script/generate +14 -0
  153. data/tasks/readme_site.rake +28 -0
  154. data/test/test_carps.rb +11 -0
  155. data/test/test_helper.rb +3 -0
  156. data/website/index.html +271 -0
  157. metadata +304 -0
@@ -0,0 +1,122 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ require "carps/email/imap"
20
+ require "carps/email/smtp"
21
+
22
+ require "carps/util/config"
23
+
24
+ require "carps/ui/question"
25
+
26
+ require "carps/crypt/mailer"
27
+ require "carps/crypt/mailbox"
28
+
29
+ require "yaml"
30
+
31
+ class Hash
32
+ # Like member? but for array of members.
33
+ def members? elements
34
+ present = elements.map {|field| member? field}
35
+ present.all?
36
+ end
37
+ end
38
+
39
+ module CARPS
40
+
41
+ # Class to read email config.
42
+ class EmailConfig < SystemConfig
43
+
44
+ def EmailConfig.filepath
45
+ "email.yaml"
46
+ end
47
+
48
+ def initialize address, same_pass, imap_options, smtp_options
49
+ load_resources address, same_pass, imap_options, smtp_options
50
+ end
51
+
52
+ # Parse the email config file
53
+ def parse_yaml conf
54
+ address = read_conf conf, "address"
55
+ same_pass = read_conf conf, "same_pass"
56
+ imap = read_conf conf, "imap"
57
+ unless imap.members?(["user", "server", "port", "tls", "certificate", "verify", "login", "cram_md5"])
58
+ raise Expected, "Expected IMAP section to be valid."
59
+ end
60
+ smtp = read_conf conf, "smtp"
61
+ unless smtp.members?(["user", "server", "port", "tls", "starttls", "login", "cram_md5"])
62
+ raise Expected, "Expected SMTP section to be valid."
63
+ end
64
+ # Untaint the imap and smtp data
65
+ untaint_all imap
66
+ untaint_all smtp
67
+ [address, same_pass, imap, smtp]
68
+ end
69
+
70
+ # Connect to the imap and smtp servers
71
+ def load_resources address, same_pass, imap_settings, smtp_settings
72
+ @file_struct = {"address" => address, "same_pass" => same_pass, "imap" => imap_settings, "smtp" => smtp_settings}
73
+ @address = address
74
+ smtp_password = ""
75
+ imap_password = ""
76
+ if same_pass
77
+ imap_password = smtp_password = UI::secret("Enter password for #{address}:")
78
+ else
79
+ imap_password = UI::secret "Enter password for IMAP account at #{address}:"
80
+ smtp_password = UI::secret "Enter password for SMTP account at #{address}:"
81
+ end
82
+ @imap = IMAP.new imap_settings, imap_password
83
+ @smtp = SMTP.new smtp_settings, smtp_password
84
+ end
85
+
86
+ # Relentlessly continue until we can connect to IMAP and SMTP
87
+ def connect!
88
+ @smtp.with_connection {|smtp|}
89
+ @imap.with_connection {|imap|}
90
+ end
91
+
92
+ # Emit options as hash
93
+ def emit
94
+ @file_struct
95
+ end
96
+
97
+ # Expose the IMAP client
98
+ def imap
99
+ @imap
100
+ end
101
+
102
+ # Expose the SMTP client
103
+ def smtp
104
+ @smtp
105
+ end
106
+
107
+ # Return the high level mail client
108
+ def mailer message_parser, session_manager
109
+ mailbox = Mailbox.new @smtp, @imap, message_parser, session_manager
110
+ Mailer.new @address, mailbox
111
+ end
112
+
113
+ # Untaint every value in a hash
114
+ def untaint_all hsh
115
+ hsh.each_value do |val|
116
+ val.untaint
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,156 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+
19
+ require "carps/email"
20
+
21
+ require "carps/protocol/message"
22
+
23
+ require "carps/ui/warn"
24
+
25
+ require "carps/email/string"
26
+
27
+ require "carps/util/timeout"
28
+
29
+
30
+ require "net/imap"
31
+
32
+ module CARPS
33
+
34
+ # Administer IMAP connections
35
+ class IMAP
36
+
37
+ # Initialize with a hash of IMAP settings and password
38
+ #
39
+ # Uh, poorly documented. See source.
40
+ def initialize settings, password
41
+ @port = settings["port"]
42
+ @server = settings["server"]
43
+ @tls = settings["tls"]
44
+ @username = settings["user"]
45
+ @cert = settings["certificate"]
46
+ @verify = settings["verify"]
47
+ @login = settings["login"]
48
+ @cram_md5 = settings["cram_md5"]
49
+ @password = password
50
+ end
51
+
52
+ # Are the settings okay?
53
+ def ok?
54
+ good = false
55
+ begin
56
+ attempt_connection
57
+ good = true
58
+ rescue StandardError => e
59
+ UI::put_error e.to_s
60
+ end
61
+ good
62
+ end
63
+
64
+ # Return the a list of email message bodies
65
+ #
66
+ # Blocks until messages become available
67
+ def read
68
+ if $DEBUG
69
+ puts "Reading mail."
70
+ end
71
+ mails = []
72
+ # Block 'till we get one
73
+ while mails.empty?
74
+ with_connection do |imap|
75
+ imap.select("inbox")
76
+ # Get all mails
77
+ messages = imap.search(["ALL"])
78
+ if messages.empty?
79
+ sleep delay
80
+ else
81
+ mails = imap.fetch messages, "BODY[TEXT]"
82
+ mails = mails.map do |mail|
83
+ from_mail mail.attr["BODY[TEXT]"]
84
+ end
85
+ # Delete all mails
86
+ messages.each do |message_id|
87
+ imap.store(message_id, "+FLAGS", [:Deleted])
88
+ end
89
+ imap.expunge
90
+ end
91
+ end
92
+ end
93
+ mails
94
+ end
95
+
96
+ # Perform an action with an IMAP connection
97
+ def with_connection
98
+ imap = nil
99
+ begin
100
+ imap = attempt_connection
101
+ yield imap
102
+ rescue Net::IMAP::NoResponseError => e
103
+ if e.message =~ /(A|a)uthentication failed/
104
+ UI::put_error e.message, false
105
+ @password = UI::secret "Enter IMAP password for #{@username}"
106
+ else
107
+ warn_delay
108
+ end
109
+ UI::put_error e.message, false
110
+ rescue StandardError => e
111
+ warn_delay
112
+ UI::put_error e.message, false
113
+ ensure
114
+ if imap
115
+ imap.logout
116
+ imap.disconnect
117
+ end
118
+ end
119
+ end
120
+
121
+
122
+ private
123
+
124
+ # Attempt a connection
125
+ def attempt_connection
126
+ imap = nil
127
+ CARPS::timeout 30, "IMAP connection attempt" do
128
+ if not @tls or @password.empty?
129
+ UI::warn "IMAP connection is insecure."
130
+ end
131
+ imap = Net::IMAP.new @server, @port, @tls, @certs, @verify
132
+ if @cram_md5
133
+ imap.authenticate "CRAM-MD5", @username, @password
134
+ elsif @login
135
+ imap.authenticate "LOGIN", @username, @password
136
+ else
137
+ imap.login @username, @password
138
+ end
139
+ end
140
+ imap
141
+ end
142
+
143
+
144
+ def delay
145
+ 30
146
+ end
147
+
148
+ # Warn that we're going to delay before trying again
149
+ def warn_delay
150
+ UI::warn "Could not connect to IMAP server", "Attempting to reconnect in 10 seconds."
151
+ sleep 10
152
+ end
153
+
154
+ end
155
+
156
+ end
@@ -0,0 +1,119 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/ui"
19
+
20
+ require "carps/email"
21
+
22
+ require "carps/util"
23
+
24
+ require "net/smtp"
25
+
26
+ require "socket"
27
+
28
+ module CARPS
29
+ # SMTP connection
30
+ class SMTP
31
+
32
+ # Connects to the server
33
+ def initialize settings, password
34
+ @port = settings["port"]
35
+ @username = settings["user"]
36
+ @password = password
37
+ @server = settings["server"]
38
+ @starttls = settings["starttls"]
39
+ @tls = settings["tls"]
40
+ @login = settings["login"]
41
+ @cram_md5 = settings["cram_md5"]
42
+ end
43
+
44
+ # Send an email message
45
+ #
46
+ # Untaints its arguments
47
+ def send to, message
48
+ to.untaint
49
+ message.untaint
50
+ if $DEBUG
51
+ puts "Sending mail to #{to}"
52
+ end
53
+ with_connection do |smtp|
54
+ message = to_mail "Content-Type: application/octet-stream\r\n" + message
55
+ smtp.send_message message, @username, [to]
56
+ end
57
+ end
58
+
59
+ # Are the settings okay?
60
+ def ok?
61
+ good = false
62
+ begin
63
+ with_attempt_connection {}
64
+ good = true
65
+ rescue StandardError => e
66
+ UI::put_error e.to_s
67
+ end
68
+ good
69
+ end
70
+
71
+ # Perform an action with a connection
72
+ def with_connection &todo
73
+ until false
74
+ begin
75
+ with_attempt_connection &todo
76
+ return
77
+ rescue Net::SMTPAuthenticationError => e
78
+ UI::put_error e.message, false
79
+ @password = UI::secret "Enter SMTP password for #{@username}:"
80
+ rescue StandardError => e
81
+ UI::warn "Could not connect to SMTP server", "Attempting to reconnect in 10 seconds."
82
+ UI::put_error e.message, false
83
+ sleep 10
84
+ end
85
+ end
86
+ end
87
+
88
+
89
+
90
+ private
91
+
92
+ def with_attempt_connection &todo
93
+ CARPS::timeout 30, "SMTP connection attempt" do
94
+ # Create smtp object
95
+ smtp = Net::SMTP.new @server, @port
96
+ # Security measures
97
+ if @starttls
98
+ smtp.enable_starttls
99
+ elsif @tls
100
+ smtp.enable_tls
101
+ end
102
+
103
+ auth = :plain
104
+ if @login
105
+ auth = :login
106
+ elsif @cram_md5
107
+ auth = :cram_md5
108
+ end
109
+
110
+ if not (@starttls or @tls) or @password.empty?
111
+ UI::warn "SMTP connection is insecure."
112
+ end
113
+ smtp.start Socket.gethostname, @username, @password, auth, &todo
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "base64"
19
+
20
+ module CARPS
21
+
22
+ def to_mail msg
23
+ Base64.encode64 msg
24
+ end
25
+
26
+ def from_mail msg
27
+ Base64.decode64 msg
28
+ end
29
+
30
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/email/config"
19
+ require "carps/email/imap"
20
+ require "carps/email/smtp"
21
+ require "carps/email/string"
@@ -0,0 +1,36 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module CARPS
19
+
20
+ # Actions taken when a rule is applied.
21
+ #
22
+ # Subclasses must provide methods:
23
+ #
24
+ # summary, returns string. The idea is to describe the effects of this Action.
25
+ #
26
+ # execute which takes the dice result and then the parameters given to the Rule. The idea is to manipulate them here.
27
+ class Action
28
+
29
+ def apply *params
30
+ puts summary
31
+ execute *params
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/protocol"
19
+
20
+ require "carps/ui"
21
+
22
+ require "highline"
23
+
24
+ require "yaml"
25
+
26
+ module CARPS
27
+
28
+ # A series of answers to questions asked by the DM.
29
+ class Answers < Message
30
+
31
+ # Extend the protocol
32
+ protoval :answers
33
+
34
+ # The answers hash gives the initial answers
35
+ def initialize answers_hash = {}
36
+ @answers = answers_hash
37
+ end
38
+
39
+ # Parse
40
+ def Answers.parse blob
41
+ yaml, blob = find K.answers, blob
42
+ answers = YAML::load yaml
43
+ [Answers.new(answers), blob]
44
+ end
45
+
46
+ # Emit
47
+ def emit
48
+ V.answers @answers.to_yaml
49
+ end
50
+
51
+ # Set an answer to a question
52
+ def answer question, response
53
+ @answers[question] = response
54
+ end
55
+
56
+ # Display answers
57
+ def display
58
+ if @answers.empty?
59
+ UI::highlight "#{from} did not return any answers."
60
+ else
61
+ UI::highlight "#{from}'s answers:"
62
+ h = HighLine.new
63
+ @answers.each do |que, ans|
64
+ puts ""
65
+ puts h.color(que, :green)
66
+ ans.each_line do |ln|
67
+ puts "> " + ln
68
+ end
69
+ end
70
+ puts ""
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ # A status report, followed by a list of questions
19
+
20
+ require "carps/protocol"
21
+
22
+ require "carps/mod"
23
+
24
+ module CARPS
25
+
26
+ class ClientTurn < Message
27
+
28
+ # Extend the protocol
29
+ protoword :client_turn
30
+
31
+ # Create a client turn
32
+ def initialize sheet, status, questions
33
+ @sheet = sheet
34
+ @status = status
35
+ @questions = questions
36
+ end
37
+
38
+ # Expose the character sheet
39
+ def sheet
40
+ @sheet
41
+ end
42
+
43
+ # Parse
44
+ def ClientTurn.parse blob
45
+ forget, blob = find K.client_turn, blob
46
+ sheet, blob = Sheet::NewSheet.parse blob
47
+ status, blob = StatusReport.parse blob
48
+ more = true
49
+ questions = []
50
+ while more
51
+ begin
52
+ que, blob = Question.parse blob
53
+ questions.push que
54
+ rescue Expected
55
+ more = false
56
+ end
57
+ end
58
+ [ClientTurn.new(sheet, status, questions), blob]
59
+ end
60
+
61
+ # Emit
62
+ def emit
63
+ question_text = (@questions.map {|q| q.emit}).join
64
+ status = @status.emit
65
+ K.client_turn + @sheet.emit + status + question_text
66
+ end
67
+
68
+ # Preview the turn
69
+ def preview
70
+ @status.display
71
+ @questions.each do |q|
72
+ q.preview
73
+ end
74
+ end
75
+
76
+ # Take the turn, return list of answers
77
+ def take
78
+ @status.display
79
+ answers = Answers.new
80
+ @questions.each do |q|
81
+ q.ask answers
82
+ end
83
+ answers
84
+ end
85
+
86
+ end
87
+
88
+ end