gambit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/AUTHORS +2 -0
  2. data/CHANGELOG +7 -0
  3. data/COPYING +340 -0
  4. data/INSTALL +23 -0
  5. data/LICENSE +7 -0
  6. data/README +25 -0
  7. data/Rakefile +87 -0
  8. data/TODO +6 -0
  9. data/examples/bird_wars/game.rb +434 -0
  10. data/examples/bird_wars/html/chest.rhtml +37 -0
  11. data/examples/bird_wars/html/combat.rhtml +38 -0
  12. data/examples/bird_wars/html/fight.rhtml +71 -0
  13. data/examples/bird_wars/html/fridge.rhtml +31 -0
  14. data/examples/bird_wars/html/help.rhtml +30 -0
  15. data/examples/bird_wars/html/house.rhtml +36 -0
  16. data/examples/bird_wars/html/images/albatross.jpg +0 -0
  17. data/examples/bird_wars/html/images/alka_seltzer_small.png +0 -0
  18. data/examples/bird_wars/html/images/bazooka_small.png +0 -0
  19. data/examples/bird_wars/html/images/bb_gun_small.png +0 -0
  20. data/examples/bird_wars/html/images/cat_small.png +0 -0
  21. data/examples/bird_wars/html/images/combat.png +0 -0
  22. data/examples/bird_wars/html/images/crossbow_small.png +0 -0
  23. data/examples/bird_wars/html/images/cuckoo.jpg +0 -0
  24. data/examples/bird_wars/html/images/fridge.png +0 -0
  25. data/examples/bird_wars/html/images/gull.jpg +0 -0
  26. data/examples/bird_wars/html/images/house.jpg +0 -0
  27. data/examples/bird_wars/html/images/items.png +0 -0
  28. data/examples/bird_wars/html/images/not_found.png +0 -0
  29. data/examples/bird_wars/html/images/note.jpg +0 -0
  30. data/examples/bird_wars/html/images/oil_small.png +0 -0
  31. data/examples/bird_wars/html/images/one_stone_small.png +0 -0
  32. data/examples/bird_wars/html/images/owl.jpg +0 -0
  33. data/examples/bird_wars/html/images/poisoned_seeds_small.png +0 -0
  34. data/examples/bird_wars/html/images/rice_small.png +0 -0
  35. data/examples/bird_wars/html/images/shotgun_small.png +0 -0
  36. data/examples/bird_wars/html/images/slingshot_small.png +0 -0
  37. data/examples/bird_wars/html/images/soda_rings_small.png +0 -0
  38. data/examples/bird_wars/html/images/spear_small.png +0 -0
  39. data/examples/bird_wars/html/images/stork.jpg +0 -0
  40. data/examples/bird_wars/html/images/weapons.png +0 -0
  41. data/examples/bird_wars/html/images/woodpecker.jpg +0 -0
  42. data/examples/bird_wars/html/images/you.jpg +0 -0
  43. data/examples/bird_wars/html/index.rhtml +13 -0
  44. data/examples/bird_wars/html/weapons.rhtml +35 -0
  45. data/examples/cli/blackjack.rb +86 -0
  46. data/examples/cli/go.rb +93 -0
  47. data/examples/cli/space_trader2/planet_data +12280 -0
  48. data/examples/cli/space_trader2/space_trader2.rb +248 -0
  49. data/examples/cli/space_trader2/world.rb +127 -0
  50. data/examples/cli/spacetrader.rb +262 -0
  51. data/examples/cli/yahtzee.rb +161 -0
  52. data/examples/galactic_courier/Rakefile +9 -0
  53. data/examples/galactic_courier/bin/galactic_courier.rb +44 -0
  54. data/examples/galactic_courier/html/console.rhtml +15 -0
  55. data/examples/galactic_courier/html/images/barren.jpg +0 -0
  56. data/examples/galactic_courier/html/images/industrial.jpg +0 -0
  57. data/examples/galactic_courier/html/images/jungle.jpg +0 -0
  58. data/examples/galactic_courier/html/images/oceanic.jpg +0 -0
  59. data/examples/galactic_courier/html/images/tundra.jpg +0 -0
  60. data/examples/galactic_courier/html/images/volcanic.jpg +0 -0
  61. data/examples/galactic_courier/lib/galaxy.rb +64 -0
  62. data/examples/galactic_courier/lib/planet.rb +30 -0
  63. data/examples/galactic_courier/lib/sector.rb +84 -0
  64. data/examples/galactic_courier/lib/station.rb +18 -0
  65. data/examples/galactic_courier/test/tc_galaxy.rb +24 -0
  66. data/examples/galactic_courier/test/tc_planet.rb +22 -0
  67. data/examples/galactic_courier/test/tc_sector.rb +55 -0
  68. data/examples/galactic_courier/test/ts_all.rb +12 -0
  69. data/examples/gambit_mail/html/compose.rhtml +39 -0
  70. data/examples/gambit_mail/html/index.rhtml +3 -0
  71. data/examples/gambit_mail/html/mailbox.rhtml +47 -0
  72. data/examples/gambit_mail/html/message.rhtml +34 -0
  73. data/examples/gambit_mail/mail.rb +75 -0
  74. data/lib/gambit.rb +10 -0
  75. data/lib/gambit/server.rb +269 -0
  76. data/lib/gambit/server/gambiterror.rb +28 -0
  77. data/lib/gambit/server/game.rb +185 -0
  78. data/lib/gambit/server/game/eventform.rb +174 -0
  79. data/lib/gambit/server/message.rb +85 -0
  80. data/lib/gambit/server/player.rb +40 -0
  81. data/lib/gambit/tools.rb +13 -0
  82. data/lib/gambit/tools/board.rb +275 -0
  83. data/lib/gambit/tools/cards.rb +11 -0
  84. data/lib/gambit/tools/cards/card.rb +158 -0
  85. data/lib/gambit/tools/cards/deck.rb +99 -0
  86. data/lib/gambit/tools/cards/hand.rb +86 -0
  87. data/lib/gambit/tools/cards/pile.rb +107 -0
  88. data/lib/gambit/tools/currency.rb +148 -0
  89. data/lib/gambit/tools/dice.rb +219 -0
  90. data/lib/gambit/tools/movehistory.rb +164 -0
  91. data/lib/gambit/tools/scorecard.rb +333 -0
  92. data/lib/gambit/viewable.rb +71 -0
  93. data/setup.rb +1360 -0
  94. data/test/tc_board.rb +167 -0
  95. data/test/tc_cards.rb +182 -0
  96. data/test/tc_currency.rb +99 -0
  97. data/test/tc_dice.rb +83 -0
  98. data/test/tc_error.rb +34 -0
  99. data/test/tc_event.rb +367 -0
  100. data/test/tc_game.rb +29 -0
  101. data/test/tc_message.rb +35 -0
  102. data/test/tc_movehistory.rb +38 -0
  103. data/test/tc_player.rb +60 -0
  104. data/test/tc_scorecard.rb +112 -0
  105. data/test/tc_views.rb +353 -0
  106. data/test/test_game.rb +19 -0
  107. data/test/test_view.rhtml +2 -0
  108. data/test/ts_all.rb +12 -0
  109. data/test/ts_server.rb +14 -0
  110. data/test/ts_tools.rb +14 -0
  111. metadata +183 -0
@@ -0,0 +1,22 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_planet.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-06-06.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "planet"
11
+
12
+ class TestPlanet < Test::Unit::TestCase
13
+ def test_creation
14
+ assert_not_nil(planet = Planet.new(:volcanic))
15
+ assert_equal(:volcanic, planet.type)
16
+
17
+ assert_not_nil(planet = Planet.random)
18
+ assert_instance_of(Planet, planet)
19
+ assert( [ :volcanic, :tundra, :oceanic,
20
+ :jungle, :industrial, :barren ].include?(planet.type) )
21
+ end
22
+ end
@@ -0,0 +1,55 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # tc_sector.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-06-06.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "sector"
11
+ require "planet"
12
+ require "station"
13
+
14
+ class TestSector < Test::Unit::TestCase
15
+ def test_creation
16
+ assert_not_nil(sector = Sector.new(:black_hole))
17
+ assert_equal(:black_hole, sector.feature)
18
+ assert_same(sector, sector.create_planet(Planet.new(:tundra)))
19
+ 4.times { assert_same(sector, sector << Planet.new(:jungle)) }
20
+ assert_raise(RuntimeError) { sector << Planet.new(:jungle) }
21
+ assert_equal(:tundra, sector[0].type)
22
+ assert_equal(:jungle, sector[rand(4) + 1].type)
23
+ assert_not_nil(sector.build_station(Station.random))
24
+ assert_raise(RuntimeError) { sector.build_station(Station.random) }
25
+ assert_equal(5, sector.size)
26
+
27
+ assert_not_nil(sector = Sector.random)
28
+ assert_instance_of(Sector, sector)
29
+ assert( [ :none, :nebula,
30
+ :asteroids, :black_hole ].include?(sector.feature) )
31
+ assert(sector.size >= 0)
32
+ assert(sector.size <= 5)
33
+ end
34
+
35
+ def test_linking
36
+ sectors = [Sector.random]
37
+ 2.times { sectors << Sector.random }
38
+ sectors.each_with_index { |sec, index| sec.name = index + 1 }
39
+ sectors.each { |sec| assert_equal(0, sec.links.size) }
40
+ sectors.first.link(sectors.last)
41
+ assert_equal(1, sectors.first.links.size)
42
+ assert_equal(1, sectors.last.links.size)
43
+ assert_equal(3, sectors.first.links.first.name)
44
+ assert_equal(1, sectors.last.links.first.name)
45
+
46
+ sectors[0].link(sectors[1], true)
47
+ sectors[1].link(sectors[2], true)
48
+ assert_equal(2, sectors[0].links.size)
49
+ assert_equal(1, sectors[1].links.size)
50
+ assert_equal(1, sectors[2].links.size)
51
+ assert_equal([3, 2], sectors[0].links.map { |sec| sec.name })
52
+ assert_equal([3], sectors[1].links.map { |sec| sec.name })
53
+ assert_equal([1], sectors[2].links.map { |sec| sec.name })
54
+ end
55
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # ts_all.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-06-06.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "test/unit"
9
+
10
+ require "tc_planet"
11
+ require "tc_sector"
12
+ require "tc_galaxy"
@@ -0,0 +1,39 @@
1
+ <html>
2
+ <head>
3
+ <title>Compose Mail</title>
4
+ <style> #Message { height: 300px; width: 400px; border: 2px solid; }
5
+ .event p { margin: 0 0 0 350; }
6
+ #To { margin: 0 20 0 36; border: 2px solid;
7
+ padding: 2px; }
8
+ #Subject { margin: 2 0 0 8; width: 400px; border: 2px solid;
9
+ padding: 2px; }
10
+ form dd {
11
+ margin: 5;
12
+ }
13
+
14
+ form dt {
15
+ float: left;
16
+ padding-right = 10px;
17
+ }
18
+
19
+ label { margin: 0 4 0 0; }
20
+ </style>
21
+ </head>
22
+ <body>
23
+ <%message = @message ||
24
+ Gambit::Server::Message.new(@player.name,"","","") %>
25
+ <% player = @player %>
26
+ <%= event(nil,"send_message") do
27
+ if message.to.eql?("")
28
+ menu "To", Gambit::Server::SERVER.players.keys - [player.name]
29
+ else
30
+ menu "To", message.to
31
+ end
32
+ hidden "From", message.from
33
+ text "Subject", "value" => message.subject
34
+ document "Message"
35
+ submit "Send"
36
+ end %>
37
+ </body>
38
+ </html>
39
+
@@ -0,0 +1,3 @@
1
+ <html><head><title>Mail System</title></head><body>
2
+ <%= event("Spam me!", "spam") %></body></html>
3
+
@@ -0,0 +1,47 @@
1
+ <html>
2
+ <head>
3
+ <title>Mailbox</title>
4
+ <style type="Text/CSS">
5
+ .message_short { padding: 2px; margin: 0px; width: 900px;}
6
+ .message_short li { list-style-type: none;
7
+ float: left;
8
+ border: 1px solid; padding: 0px 20px 0px 20px;}
9
+ .from_short { width: 200px; background-color: #dddddd; }
10
+ .subject_short { width: 200px; background-color: #eeeeee; }
11
+ .time_short { background-color: #dddddd; width: 275px; }
12
+ #mailbox_header_from { width: 200px; background-color: #f8f7d1 }
13
+ #mailbox_header_subject { width: 200px; background-color: #f8f7d1 }
14
+ #mailbox_header_time { width: 275px; background-color: #f8f7d1 }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <% @message = nil %>
19
+ <ul class="message_short">
20
+ <li id="mailbox_header_from">
21
+ <%= event("Sender","sort","sort_by" => "sender") %>
22
+ </li>
23
+ <li id="mailbox_header_subject">
24
+ <%= event("Subject","sort","sort_by" => "subject") %>
25
+ </li>
26
+ <li id="mailbox_header_time">
27
+ <%= event("Time","sort","sort_by" => "time") %>
28
+ </li>
29
+ </ul>
30
+ <% @player.mailbox.each do |mes| %>
31
+ <ul class="message_short">
32
+ <li class="from_short"> <%= mes.from %> </li>
33
+ <li class="subject_short">
34
+ <%= event(mes.subject, "show_message",
35
+ "id" => mes.object_id) %>
36
+ </li>
37
+ <li class="time_short"> <%= mes.time %> </li>
38
+ </ul>
39
+ <% end %>
40
+ <p style="clear: both; margin: 0 20 20 520;">
41
+ <br>
42
+ <a href="compose.rhtml"> Compose</a> |
43
+ <%= event("Delete All Messages", "delete_all") %>
44
+ </p>
45
+ </body>
46
+ </html>
47
+
@@ -0,0 +1,34 @@
1
+ <html>
2
+ <head>
3
+ <title>Mailbox</title>
4
+ <style type="Text/CSS">
5
+ .message { border: 1px ; width: 400px; }
6
+ .message td { border: 2px solid; padding: 4px }
7
+ a { text-decoration: none; color : #000000; }
8
+ ul { padding: 0 0 0 100; }
9
+ li { float: left; padding: 2 5 2 5; list-style: none;
10
+ border: 1px solid }
11
+ #time { text-align: center; background-color: #ffffff;}
12
+ #from { width: 50%; text-align: center; background-color: #cccccc;
13
+ vertical-align: top; }
14
+ #to { width: 50%; text-align: center; background-color: #cccccc;
15
+ vertical-align: top;}
16
+ #subject { text-align: center; background-color: #dddddd; }
17
+ #body { background-color: #aaaaaa; padding: 8px}
18
+ </style>
19
+ </head>
20
+ <body>
21
+ <%= @message.view(:gambit_html) %>
22
+ <ul>
23
+ <li>
24
+ <%= event("reply", "reply",
25
+ "id" => @message.object_id) %>
26
+ </li>
27
+ <li>
28
+ <%= event("delete","delete_message",
29
+ "id" => @message.object_id) %>
30
+ </li>
31
+ <li><a href="mailbox.rhtml">Return to mailbox</a></li>
32
+ </ul>
33
+ </body>
34
+ </html>
@@ -0,0 +1,75 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # mail.rb
4
+ #
5
+ # Created by Gregory Brown on 22005-06-05
6
+ # Copyright 2005 smtose.org. All rights reserved.
7
+
8
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "..", "lib"))
9
+ require "gambit"
10
+ require "gambit/server/message"
11
+
12
+ class Mail< Gambit::Server::Game
13
+ def initialize( )
14
+ super
15
+ end
16
+
17
+ def do_login( player, details )
18
+ "mailbox.rhtml"
19
+ end
20
+
21
+ def do_show_message( player, details )
22
+ @message = get_message(details["id"])
23
+ "message.rhtml"
24
+ end
25
+
26
+ def do_delete_message( player, details )
27
+ player.mailbox.delete(get_message(details["id"]))
28
+ "mailbox.rhtml"
29
+ end
30
+
31
+ def do_sort( player, details )
32
+ sort_by = details["sort_by"]
33
+ case sort_by
34
+ when("sender")
35
+ @player.mailbox.sort! { |a,b| a.from <=> b.from }
36
+ when("subject")
37
+ @player.mailbox.sort! { |a,b| a.subject <=> b.subject }
38
+ when("time")
39
+ @player.mailbox.sort! { |a,b| a.time <=> b.time }
40
+ end
41
+ "mailbox.rhtml"
42
+ end
43
+
44
+ def do_reply( player, details )
45
+ message = get_message(details["id"])
46
+ @message = Gambit::Server::Message.new(message.to, message.from,
47
+ "RE: " + message.subject,"")
48
+ return "compose.rhtml"
49
+ end
50
+
51
+ def do_send_message( player, details )
52
+ Gambit::Server::SERVER.players[details["To"]].mailbox <<
53
+ Gambit::Server::Message.new( details["From"],
54
+ details["To"],
55
+ details["Subject"],
56
+ details["Message"] )
57
+ return "mailbox.rhtml"
58
+ end
59
+
60
+ def do_delete_all( player, details )
61
+ player.mailbox.clear
62
+ return "mailbox.rhtml"
63
+ end
64
+
65
+ def do_configure(player, details)
66
+ super
67
+ return "mailbox.rhtml"
68
+ end
69
+
70
+ private
71
+
72
+ def get_message( id )
73
+ @player.mailbox.find { |m| m.object_id == id.to_i }
74
+ end
75
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # gambit.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-06-04.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "gambit/tools"
9
+ require "gambit/viewable"
10
+ require "gambit/server"
@@ -0,0 +1,269 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # server.rb
4
+ #
5
+ # Created by James Edward Gray II on 2005-06-03.
6
+ # Copyright 2005 Gray Productions. All rights reserved.
7
+
8
+ require "webrick"
9
+ require "erb"
10
+ require "monitor"
11
+ require "gambit/server/gambiterror"
12
+ require "gambit/server/game"
13
+ require "gambit/server/player"
14
+ require "gambit/viewable"
15
+
16
+ module Gambit
17
+ # The controller layer of the Gambit framework. (Docs coming soon...)
18
+ class Server < WEBrick::HTTPServer
19
+ include Gambit::Viewable
20
+ register_view(:game_listing, <<-END_GAME_LIST.gsub(/^\t{2}/, ""))
21
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
22
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
23
+ <html xmlns="http://www.w3.org/1999/xhtml">
24
+ <head>
25
+ <title>Game List</title>
26
+ </head><body>
27
+ <h1>Select a Game</h1>
28
+ % unless @server_message.nil?
29
+ <p class="notification"><%= @server_message %></p>
30
+ % @server_message = nil
31
+ % end
32
+ <ul>
33
+ % @games.each do |(id, game)|
34
+ <li><a href="/event/<%= id %>/login"><%= game.name %></a></li>
35
+ % end
36
+ </ul>
37
+ <p><a href="/server/new_game">Add a Game!</a>
38
+ <a href="/server/new_player">Create a Player!</a></p>
39
+ </body></html>
40
+ END_GAME_LIST
41
+ register_view(:new_player, <<-END_GAME_LIST.gsub(/^\t{2}/, ""))
42
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
43
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
44
+ <html xmlns="http://www.w3.org/1999/xhtml">
45
+ <head>
46
+ <title>New Player</title>
47
+ </head><body>
48
+ <h1>Create Your Player</h1>
49
+ % unless @server_message.nil?
50
+ <p class="notification"><%= @server_message %></p>
51
+ % @server_message = nil
52
+ % end
53
+ <form action="/server/create_player" method="post">
54
+ <dl>
55
+ <dt><label for="name">Name:</label></dt>
56
+ <dd><input type="text" id="name" name="name" /></dd>
57
+ <dt><label for="password">Password:</label></dt>
58
+ <dd><input type="password" id="password" name="password" /></dd>
59
+ <dt><label for="verify">Verify Password:</label></dt>
60
+ <dd><input type="password" id="verify" name="verify" /></dd>
61
+ </dl>
62
+ <p><input type="submit" value="Create" /> <input type="reset" /></p>
63
+ </form>
64
+ </body></html>
65
+ END_GAME_LIST
66
+
67
+ include MonitorMixin
68
+
69
+ def initialize( game_class,
70
+ port = 80, html_dir = "html", become_daemon = false )
71
+ super(:Port => port)
72
+
73
+ @html_dir = File.join(File.expand_path(File.dirname($0)), html_dir)
74
+ self.class.const_set(:SERVER, self)
75
+ @server_message = nil
76
+
77
+ @game_class = game_class
78
+ @games = Hash.new
79
+ @players = Hash.new
80
+
81
+ WEBrick::Daemon.start if become_daemon
82
+
83
+ mount_proc("/") { |req, resp| serve_file(req, resp, req.path) }
84
+ mount_proc("/view") { |req, resp| serve_view(req, resp) }
85
+ mount_proc("/event") { |req, resp| serve_event(req, resp) }
86
+ mount_proc("/server") { |req, resp| serve_server_event(req, resp) }
87
+
88
+ ['INT', 'TERM'].each { |signal| trap(signal) { shutdown } }
89
+ end
90
+
91
+ attr_reader :players
92
+
93
+ def login( req, resp, game, event = nil )
94
+ if cookie = req.cookies.find { |c| c.name == "player" }
95
+ cookie.expires = nil # defaults to end of session
96
+ resp.cookies << cookie
97
+ cookie.path = "/"
98
+ @players[cookie.value]
99
+ elsif (event == "login") and
100
+ not (req.query["login"].nil? or req.query["login"].empty?)
101
+ if player = @players[req.query["login"]]
102
+ if player.login?(req.query["password"])
103
+ cookie = WEBrick::Cookie.new( "player",
104
+ req.query["login"] )
105
+ cookie.expires = nil # defaults to end of session
106
+ resp.cookies << cookie
107
+ cookie.path = "/"
108
+
109
+ @players[cookie.value]
110
+ else
111
+ raise Gambit::Server::GambitError, "Invalid password."
112
+ end
113
+ else
114
+ raise Gambit::Server::GambitError, "Unknown name."
115
+ end
116
+ else
117
+ resp.body = game.view(:login)
118
+ raise WEBrick::HTTPStatus::OK
119
+ end
120
+ end
121
+
122
+ def serve_event( req, resp )
123
+ begin
124
+ if req.path =~ %r{/event/([^/]+)/([^/]+)}
125
+ game_name = $1.to_i
126
+ event_name = $2
127
+
128
+ if @games[game_name].nil?
129
+ raise Gambit::Server::GambitError, "Game not found!"
130
+ else
131
+ player = login( req, resp,
132
+ @games[game_name], event_name )
133
+ next_page = nil
134
+ synchronize do
135
+ next_page = @games[game_name].do_event( player,
136
+ event_name,
137
+ req.query )
138
+ end
139
+
140
+ if cookie = req.cookies.find { |c| c.name == "player" }
141
+ resp.cookies << cookie
142
+ end
143
+ resp.set_redirect( WEBrick::HTTPStatus::SeeOther,
144
+ "/view/#{game_name}/#{next_page}" )
145
+ raise WEBrick::HTTPStatus::SeeOther
146
+ end
147
+ else
148
+ raise Gambit::Server::GambitError, "Malformed Event!"
149
+ end
150
+ rescue Gambit::Server::GambitError => error
151
+ resp.body = error.view(:error_page)
152
+ raise WEBrick::HTTPStatus::OK
153
+ end
154
+ end
155
+
156
+ def serve_server_event( req, resp )
157
+ if req.path == "/server/new_game"
158
+ game = @game_class.new
159
+ if not @players.empty?
160
+ @games[game.object_id] = game
161
+ resp.body = game.view(:configure)
162
+ else
163
+ @server_message = "No users!"
164
+ resp.body = view(:game_listing)
165
+ end
166
+ raise WEBrick::HTTPStatus::OK
167
+ elsif req.path == "/server/new_player"
168
+ resp.body = view(:new_player)
169
+ raise WEBrick::HTTPStatus::OK
170
+ elsif req.path == "/server/create_player"
171
+ if @players.include?(req.query["name"])
172
+ @server_message = "Sorry, that name is taken."
173
+ resp.body = view(:new_player)
174
+ raise WEBrick::HTTPStatus::OK
175
+ elsif req.query["password"] != req.query["verify"]
176
+ @server_message = "The provided passwords do not match."
177
+ resp.body = view(:new_player)
178
+ raise WEBrick::HTTPStatus::OK
179
+ else
180
+ @server_message = "Player created."
181
+ @players[req.query["name"]] =
182
+ Gambit::Server::Player.new( req.query["name"],
183
+ req.query["password"] )
184
+ cookie = WEBrick::Cookie.new( "player",
185
+ req.query["name"] )
186
+ cookie.expires = nil # defaults to end of session
187
+ resp.cookies << cookie
188
+ cookie.path = "/"
189
+
190
+ resp.body = view(:game_listing)
191
+ raise WEBrick::HTTPStatus::OK
192
+ end
193
+ elsif req.path == "/server/test"
194
+ test_mode
195
+
196
+ cookie = WEBrick::Cookie.new("player", "tester")
197
+ cookie.expires = nil # defaults to end of session
198
+ resp.cookies << cookie
199
+ cookie.path = "/"
200
+
201
+ resp.body = view(:game_listing)
202
+ raise WEBrick::HTTPStatus::OK
203
+ else
204
+ resp.body = view(:game_listing)
205
+ raise WEBrick::HTTPStatus::OK
206
+ end
207
+ end
208
+
209
+ def serve_file( req, resp, file )
210
+ if file == "/"
211
+ resp.body = view(:game_listing)
212
+ raise WEBrick::HTTPStatus::OK
213
+ end
214
+
215
+ stats = File::stat(file)
216
+ mtime = stats.mtime
217
+ resp["etag"] = sprintf( "%x-%x-%x", stats.ino, stats.size,
218
+ stats.mtime.to_i )
219
+ mtype = WEBrick::HTTPUtils::mime_type(file, self[:MimeTypes])
220
+ resp["content-type"] = mtype
221
+ resp["content-length"] = stats.size
222
+ resp["last-modified"] = mtime.httpdate
223
+ resp.body = File.open(file, "rb")
224
+ raise WEBrick::HTTPStatus::OK
225
+ end
226
+
227
+ def serve_view( req, resp )
228
+ begin
229
+ if req.path =~ %r{/view/([^/]+)/(.+)}
230
+ game_name = $1.to_i
231
+ view_file = $2
232
+
233
+ erb_file = File.join(@html_dir, view_file)
234
+
235
+ if test(?e, erb_file)
236
+ player = login(req, resp, @games[game_name])
237
+ @games[game_name].player = player
238
+
239
+ if File.extname(erb_file) == ".rhtml"
240
+ erb_page = ERB.new( File.read(erb_file),
241
+ nil, "%<>" )
242
+ resp.body = erb_page.result(
243
+ @games[game_name].event_binding )
244
+ raise WEBrick::HTTPStatus::OK
245
+ else
246
+ serve_file(req, resp, erb_file)
247
+ end
248
+ else
249
+ raise Gambit::Server::GambitError, "View not found!"
250
+ end
251
+ else
252
+ raise Gambit::Server::GambitError, "Malformed View!"
253
+ end
254
+ rescue Gambit::Server::GambitError => error
255
+ resp.body = error.view(:error_page)
256
+ raise WEBrick::HTTPStatus::OK
257
+ end
258
+ end
259
+
260
+ def test_mode( )
261
+ game = @game_class.new
262
+ @games[game.object_id] = game
263
+ game.do_configure(nil, "game_name" => "Test Mode Game")
264
+ @players["tester"] = Gambit::Server::Player.new( "tester",
265
+ "test" )
266
+ @server_message = "Test mode active."
267
+ end
268
+ end
269
+ end