cranberry 0.0.1.alpha

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45d5765f8fb9b824cef72f1c7afc4e73e29c0dae
4
+ data.tar.gz: 3703e3252b6ae3b029b2aff9ea7dbd2b9ad557ae
5
+ SHA512:
6
+ metadata.gz: 4b3340f503416aa2065e0dafe01a66b87e5a61b03470e3e8387cf2c89b42aa4d41b9e6da2c406646d7f047dbb218d5f10ba619ab2c1f083244568350d4201bd2
7
+ data.tar.gz: 9619ad55f4433842d28026baa450d32d78399187e24aba74ab30d06d9b96d66245da1d43d6601efebe4716c2354b45363f48dd0dc16235d7e080752044165721
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ # Ignore these stupid files
20
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ gem 'guard-rspec', require: false
8
+ gem 'terminal-notifier-guard' if RUBY_PLATFORM =~ /darwin/
9
+ end
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Caleb Tutty and Giles Thompson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ Cranberry Websocket Game Server
2
+ ===============================
3
+
4
+ _|_|_| _|
5
+ _| _| _|_| _|_|_| _|_|_| _|_|_| _|_| _| _|_| _| _|_| _| _|
6
+ _| _|_| _| _| _| _| _| _| _|_|_|_| _|_| _|_| _| _|
7
+ _| _| _| _| _| _| _| _| _| _| _| _| _|
8
+ _|_|_| _| _|_|_| _| _| _|_|_| _|_|_| _| _| _|_|_|
9
+ _|
10
+ _|_|
11
+
12
+ Cranberry is a WebSocket EventMachine-based server, that takes JSON strings as instructions.
13
+
14
+ This is not production ready, and still a work in progress. Check back soon!
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'cranberry'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install cranberry
29
+
30
+ ## Usage
31
+
32
+ To use run:
33
+
34
+ bin/cranberry
35
+
36
+
37
+ to use the front-end client-side interface, open ``public/index.html``
38
+
39
+ ## Roadmap
40
+
41
+ 0.0.1 stable
42
+
43
+ [ ] build up spec coverage
44
+
45
+ [ ] implement a command router for the Websocket onmessage events
46
+
47
+ [ ] experiment with a DSL for other projects to use the gem with
48
+
49
+
50
+ 1.0.0
51
+
52
+ [ ] make it awesome
53
+
54
+ ## Contributing
55
+
56
+ 1. Fork it
57
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
58
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
59
+ 4. Push to the branch (`git push origin my-new-feature`)
60
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # resolve bin path, ignoring symlinks
5
+ require 'pathname'
6
+ bin_file = Pathname.new(__FILE__).realpath
7
+
8
+ # add self to libpath
9
+ $:.unshift File.expand_path('../../lib', bin_file)
10
+
11
+ require 'cranberry'
12
+
13
+ Cranberry.run
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cranberry/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cranberry'
8
+ spec.version = Cranberry::VERSION
9
+ spec.authors = ['Caleb Tutty', 'Giles Thompson']
10
+ spec.email = ['caleb@prettymint.co.nz', 'iam@gilesthompson.co.nz']
11
+ spec.description = %q{Cranberry models game objects and maintains server-side state, allowing you to use client-side websockets to join and send JSON instructions}
12
+ spec.summary = %q{Cranberry is an EventMachine-driven Websockets multiplayer game server}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'eventmachine'
22
+ spec.add_dependency 'em-websocket'
23
+ spec.add_dependency 'json'
24
+ spec.add_dependency 'paint'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.3'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec'
29
+ end
@@ -0,0 +1,13 @@
1
+ # Gem dependencies
2
+ require 'bundler/setup'
3
+ Bundler.setup
4
+ require 'eventmachine'
5
+ require 'em-websocket'
6
+ require 'json'
7
+ require 'paint'
8
+
9
+ # Cranberry files
10
+ Dir[File.dirname(__FILE__) + '/cranberry/**/*.rb'].each do |file|
11
+ require file
12
+ end
13
+
@@ -0,0 +1,9 @@
1
+ module Cranberry
2
+
3
+ Configuration = Struct.new(:columns, :rows, :host, :port)
4
+
5
+ def self.configuration
6
+ @@configuration ||= Configuration.new(88, 20, "0.0.0.0", 8080)
7
+ end
8
+
9
+ end
@@ -0,0 +1,11 @@
1
+ module Cranberry
2
+ module Handlers
3
+ class Log
4
+
5
+ def self.received_message(message, socket_id)
6
+ puts "#{message}"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Cranberry
2
+ module Handlers
3
+ class Movement
4
+
5
+ def self.received_message(direction, socket_id)
6
+ puts "#{socket_id} wants to move #{direction}"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module Cranberry
2
+ module Models
3
+ class Grid
4
+ attr_reader :rows, :columns
5
+
6
+ def initialize(rows, columns)
7
+ @rows, @columns = rows, columns
8
+ @grid = Array.new(rows) do
9
+ Array.new(columns)
10
+ end
11
+ end
12
+
13
+ def method_missing(method_name, *args, &block)
14
+ @grid.send method_name, *args, &block
15
+ end
16
+
17
+ def place(player)
18
+ x = rand(@columns)
19
+ y = rand(@rows)
20
+ if @grid[y][x]
21
+ place(player)
22
+ else
23
+ @grid[y][x] = player
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ module Cranberry
2
+ module Models
3
+ class Player
4
+ attr_reader :socket_id, :socket
5
+ attr_accessor :name
6
+ attr_accessor :x_position, :y_position
7
+
8
+ def initialize(options = {})
9
+ @socket_id, @socket = options[:socket_id], options[:socket]
10
+ raise "Players require a socket id to be identifiable, and valid" unless @socket_id
11
+ @name = options[:name] || "anonymous user"
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Cranberry
2
+ module Models
3
+ class World
4
+ attr_accessor :players
5
+ attr_reader :grid
6
+
7
+ # Singleton instance
8
+ def self.instance
9
+ @instance ||= new
10
+ end
11
+
12
+ private_class_method :new
13
+
14
+ private
15
+
16
+ def initialize
17
+ # Players exist on connection
18
+ @players = []
19
+ # The grid is a matrix - an array of arrays
20
+ @grid = Grid.new(Cranberry.configuration[:rows], Cranberry.configuration[:columns])
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module Cranberry
2
+
3
+ #
4
+ # Cranberry expects message handlers to be defined within the cranberry/handlers directory
5
+ #
6
+
7
+ def self.route_message(message)
8
+ parsed_message = begin
9
+ JSON.parse message
10
+ rescue JSON::ParserError
11
+ { message: message, handler: 'Log' }
12
+ end
13
+ Object.const_get("Cranberry::Handlers::#{parsed_message['handler']}").received_message(parsed_message['message'], parsed_message['socket_id'])
14
+ end
15
+
16
+ end
@@ -0,0 +1,21 @@
1
+ module Cranberry
2
+
3
+ def self.run
4
+
5
+ EventMachine.run do
6
+
7
+ trap("TERM") { self.stop }
8
+ trap("INT") { self.stop }
9
+
10
+ WebSocketServer.start
11
+
12
+ end
13
+ end
14
+
15
+ def self.stop
16
+ UI.clear_terminal_screen
17
+ UI.display_termination_message
18
+ EventMachine.stop
19
+ end
20
+
21
+ end
@@ -0,0 +1,35 @@
1
+ module Cranberry
2
+ module UI
3
+ def self.banner
4
+ <<-EOF
5
+
6
+ _|_|_| _|
7
+ _| _| _|_| _|_|_| _|_|_| _|_|_| _|_| _| _|_| _| _|_| _| _|
8
+ _| _|_| _| _| _| _| _| _| _|_|_|_| _|_| _|_| _| _|
9
+ _| _| _| _| _| _| _| _| _| _| _| _| _|
10
+ _|_|_| _| _|_|_| _| _| _|_|_| _|_|_| _| _| _|_|_|
11
+ _|
12
+ _|_|
13
+ EOF
14
+ end
15
+
16
+ def self.display_welcome_message
17
+ puts Paint[self.banner, :red]
18
+ puts "-" * 90
19
+ puts "Cranberry Game Server listening for WebSockets on #{Cranberry.configuration[:port]}"
20
+ puts "-" * 90
21
+ print "\n\n"
22
+ end
23
+
24
+ def self.display_termination_message
25
+ print "\n"
26
+ puts "-" * 90
27
+ puts "Terminating Cranberry Game Server"
28
+ puts "-" * 90
29
+ end
30
+
31
+ def self.clear_terminal_screen
32
+ puts "\e[H\e[2J" # this may not be very cross-platform...
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ module Cranberry
2
+ module UI
3
+
4
+ class Console
5
+ def initialize(grid)
6
+ @grid, @columns, @rows = grid, grid.columns, grid.rows
7
+ end
8
+
9
+ def draw
10
+ print "\n"
11
+ draw_border
12
+ @rows.times.each_with_index do |row, row_index|
13
+ print '|'
14
+ @columns.times.each_with_index do |column, column_index|
15
+ cell = @grid[row_index][column_index]
16
+ if cell.nil?
17
+ print ' '
18
+ else
19
+ print 'x'
20
+ end
21
+ end
22
+ print '|'
23
+ print "\n"
24
+ end
25
+ draw_border
26
+ end
27
+
28
+ def draw_border
29
+ print '+'
30
+ @columns.times.each { print '-' }
31
+ print '+'
32
+ print "\n"
33
+ end
34
+
35
+ def reset_cursor
36
+ # http://stackoverflow.com/questions/14969458/deleting-multiple-lines-of-terminal-output-using-ruby
37
+ # Where \r moves the cursor to the start of the line, \e[A moves the cursor up one line, and \e[K
38
+ # clears from the cursor position to the end of the line. If you don't need anything further down
39
+ # the screen, you can also just send \e[J once you have the cursor where you want; that clears
40
+ # all the way to the end of the screen.
41
+ (@rows + 3).times { print "\e[A" }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Cranberry
2
+ VERSION = "0.0.1.alpha"
3
+ end
@@ -0,0 +1,36 @@
1
+ module Cranberry
2
+ module WebSocketServer
3
+ def self.start
4
+
5
+ console_ui = UI::Console.new(Models::World.instance.grid)
6
+ UI.display_welcome_message
7
+ console_ui.draw
8
+
9
+ EventMachine::WebSocket.run(host: Cranberry.configuration[:host], port: Cranberry.configuration[:port]) do |ws|
10
+
11
+ ws.onopen do |handshake|
12
+ world = Cranberry::Models::World.instance
13
+ player = Cranberry::Models::Player.new(socket_id: handshake.headers["Sec-WebSocket-Key"], socket: ws)
14
+ ws.send({ handler: 'Handshake', message: player.socket_id }.to_json)
15
+ world.grid.place player
16
+ world.players << player
17
+
18
+ console_ui.reset_cursor
19
+ console_ui.draw
20
+
21
+ end
22
+
23
+ ws.onmessage do |message|
24
+ Cranberry.route_message message
25
+ end
26
+
27
+ ws.onclose do
28
+ world = Cranberry::Models::World.instance
29
+ player = world.players.detect {|a| a.socket.signature == ws.signature}
30
+ world.players.delete player
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Cranberry</title>
6
+ <!-- <link type="text/css" rel="stylesheet" href="style.css"> -->
7
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
8
+ <script src="js/handlers/handshake.js"></script>
9
+ <script src="js/input.js"></script>
10
+ <script src="js/socket.js"></script>
11
+ </head>
12
+ <body>
13
+ </body>
14
+ </html>
@@ -0,0 +1,7 @@
1
+ // TODO move init stuff like this to a global file
2
+ window.Cranberry = new Object();
3
+ Cranberry.Handlers = new Object();
4
+
5
+ Cranberry.Handlers.Handshake = function (socket_id) {
6
+ window.Cranberry.socket_id = socket_id;
7
+ };
@@ -0,0 +1,17 @@
1
+ // object to hold movement key information
2
+ inputs = new Object();
3
+ // add wasd inputs to object with a handler of movement
4
+ inputs[119] = { key: 'w', handler: 'Movement', message: 'up' }
5
+ inputs[115] = { key: 's', handler: 'Movement', message: 'down' }
6
+ inputs[97] = { key: 'a', handler: 'Movement', message: 'left' }
7
+ inputs[100] = { key: 'd', handler: 'Movement', message: 'right' }
8
+
9
+ // jquery bindings listening for keypress events
10
+ $(function() {
11
+ $( "body" ).keypress(function(event) {
12
+ if(event.which in inputs) { // check for key in inputs object before proceeding
13
+ var input = inputs[event.which]; // assign an input from our object
14
+ window.sendMessage(input.message, input.handler); // send a movement message to the server, of handler 'movement'
15
+ }
16
+ });
17
+ });
@@ -0,0 +1,32 @@
1
+ window.socket = new WebSocket('ws://localhost:8080');
2
+
3
+ // Open the socket
4
+ socket.onopen = function(event) {
5
+
6
+ console.log(event);
7
+
8
+ // Send an initial message
9
+ socket.send(JSON.stringify({message: 'Client here, I\'ve just connected!', handler: 'Log'}));
10
+
11
+ // Listen for messages
12
+ socket.onmessage = function(event) {
13
+ parsed_message = JSON.parse(event.data);
14
+ Cranberry.Handlers[parsed_message.handler](parsed_message.message);
15
+ };
16
+
17
+ // Listen for socket closes
18
+ socket.onclose = function(event) {
19
+ console.log('Client notified socket has closed', event);
20
+ };
21
+
22
+ // To close the socket....
23
+ //socket.close()
24
+ };
25
+
26
+ window.sendMessage = function (message, handler) {
27
+ if(Cranberry.socket_id === undefined) {
28
+ alert('Cannot send any data to the server, handshake has failed.');
29
+ } else {
30
+ window.socket.send(JSON.stringify({ message: message, handler: handler, socket_id: Cranberry.socket_id }));
31
+ }
32
+ };
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>QUnit Example</title>
6
+ <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.12.0.css">
7
+ <script src="../socket.io/socket.io.js"></script>
8
+ </head>
9
+ <body>
10
+ <div id="qunit"></div>
11
+ <div id="qunit-fixture"></div>
12
+ <script src="http://code.jquery.com/qunit/qunit-1.12.0.js"></script>
13
+ <script src="socket.js"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,3 @@
1
+ test('connect to server', function() {
2
+ ok(1 == 1, 'indeed');
3
+ });
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry do
4
+
5
+ describe "banner" do
6
+ it "works"
7
+ end
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry::Models::Grid do
4
+
5
+ it "works"
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry::Models::Player do
4
+
5
+ it "works"
6
+
7
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry::Models::World do
4
+
5
+ it "is a singleton instance" do
6
+ world1, world2 = Cranberry::Models::World.instance, Cranberry::Models::World.instance
7
+ expect(world1.object_id).to eq(world2.object_id)
8
+ end
9
+
10
+ describe "it has a list of players" do
11
+
12
+ before :each do
13
+ @world = Cranberry::Models::World.instance
14
+ end
15
+
16
+ it "is an array" do
17
+ expect(@world.players).to be_a Array
18
+ end
19
+
20
+ end
21
+
22
+ describe "it has a grid" do
23
+
24
+ before :each do
25
+ @grid = Cranberry::Models::World.instance.grid
26
+ end
27
+
28
+ it "has a grid" do
29
+ expect(@grid).to be_a Cranberry::Models::Grid
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry do
4
+
5
+ describe "server" do
6
+ it "works"
7
+ end
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry::UI::Console do
4
+
5
+ it "works"
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cranberry::WebSocketServer do
4
+
5
+ describe "websocket" do
6
+ it "works"
7
+ end
8
+
9
+ end
@@ -0,0 +1,25 @@
1
+ ENV["RUBY_ENV"] ||= 'test'
2
+ require_relative '../lib/cranberry.rb'
3
+ require 'rspec/autorun'
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # Require this file using `require "spec_helper"` to ensure that it is only
8
+ # loaded once.
9
+ #
10
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
+
12
+ Dir[File.join(__FILE__, "support/*.rb")].each {|f| require f }
13
+
14
+ RSpec.configure do |config|
15
+ config.treat_symbols_as_metadata_keys_with_true_values = true
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+ end
25
+
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cranberry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Caleb Tutty
8
+ - Giles Thompson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: em-websocket
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: paint
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: '1.3'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: '1.3'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Cranberry models game objects and maintains server-side state, allowing
113
+ you to use client-side websockets to join and send JSON instructions
114
+ email:
115
+ - caleb@prettymint.co.nz
116
+ - iam@gilesthompson.co.nz
117
+ executables:
118
+ - cranberry
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - .gitignore
123
+ - .rspec
124
+ - Gemfile
125
+ - Gemfile.lock
126
+ - Guardfile
127
+ - LICENSE.txt
128
+ - README.md
129
+ - Rakefile
130
+ - bin/cranberry
131
+ - cranberry.gemspec
132
+ - lib/cranberry.rb
133
+ - lib/cranberry/configuration.rb
134
+ - lib/cranberry/handlers/log.rb
135
+ - lib/cranberry/handlers/movement.rb
136
+ - lib/cranberry/models/grid.rb
137
+ - lib/cranberry/models/player.rb
138
+ - lib/cranberry/models/world.rb
139
+ - lib/cranberry/router.rb
140
+ - lib/cranberry/server.rb
141
+ - lib/cranberry/ui/banner.rb
142
+ - lib/cranberry/ui/console.rb
143
+ - lib/cranberry/version.rb
144
+ - lib/cranberry/websocket_server.rb
145
+ - public/index.html
146
+ - public/js/handlers/handshake.js
147
+ - public/js/input.js
148
+ - public/js/socket.js
149
+ - public/js/spec/socket.html
150
+ - public/js/spec/socket.js
151
+ - spec/cranberry/banner_spec.rb
152
+ - spec/cranberry/models/grid_spec.rb
153
+ - spec/cranberry/models/player_spec.rb
154
+ - spec/cranberry/models/world_spec.rb
155
+ - spec/cranberry/server_spec.rb
156
+ - spec/cranberry/ui/console_spec.rb
157
+ - spec/cranberry/websocket_server_spec.rb
158
+ - spec/spec_helper.rb
159
+ homepage: ''
160
+ licenses:
161
+ - MIT
162
+ metadata: {}
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - '>'
175
+ - !ruby/object:Gem::Version
176
+ version: 1.3.1
177
+ requirements: []
178
+ rubyforge_project:
179
+ rubygems_version: 2.0.3
180
+ signing_key:
181
+ specification_version: 4
182
+ summary: Cranberry is an EventMachine-driven Websockets multiplayer game server
183
+ test_files:
184
+ - spec/cranberry/banner_spec.rb
185
+ - spec/cranberry/models/grid_spec.rb
186
+ - spec/cranberry/models/player_spec.rb
187
+ - spec/cranberry/models/world_spec.rb
188
+ - spec/cranberry/server_spec.rb
189
+ - spec/cranberry/ui/console_spec.rb
190
+ - spec/cranberry/websocket_server_spec.rb
191
+ - spec/spec_helper.rb
192
+ has_rdoc: