gamerocket 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37895025aecc1ccb572dc9432737f7a48afd3e44
4
+ data.tar.gz: 8cf474027374df10ffb4d511a74d3f9421b7d6f9
5
+ SHA512:
6
+ metadata.gz: 443abd226ecff43f51a2b4cd9ceb02ebfc6fdb9e1187dd37439482c2dccc94efed7916d3af3a05cfefee120026a3f784dd6b20682fefb1bafa00e0fed90bb091
7
+ data.tar.gz: 83e86b52cc1f95c066c5d64cdb1b07e8801ef93f77159e32563a3419868bc0cd749b4b9082c5165543d76f7465cda5fb955017d5f3f1dff484b4fec6c95a7313
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2012-2013 Work Bandits
4
+
5
+ Permission is hereby granted, free of charge, to any person
6
+ obtaining a copy of this software and associated documentation
7
+ files (the "Software"), to deal in the Software without
8
+ restriction, including without limitation the rights to use,
9
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the
11
+ Software is furnished to do so, subject to the following
12
+ conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,52 @@
1
+ = GameRocket Ruby Client Library
2
+
3
+ The GameRocket gem provides integration access to the GameRocket Gateway.
4
+
5
+ == Dependencies
6
+
7
+ * builder
8
+ * json
9
+ * base64
10
+ * cgi
11
+
12
+ == Quick Start Example
13
+
14
+ require "base64"
15
+ require "cgi"
16
+ require "date"
17
+ require "digest/sha2"
18
+ require "logger"
19
+ require "net/http"
20
+ require "net/https"
21
+ require "openssl"
22
+ require "stringio"
23
+ require "time"
24
+ require "zlib"
25
+
26
+ require "builder"
27
+ require "json"
28
+ require "gamerocket"
29
+
30
+ GameRocket::Configuration.environment = :development
31
+ GameRocket::Configuration.apiKey = "your_api_key"
32
+ GameRocket::Configuration.secretKey = "your_secret_key"
33
+
34
+ result = GameRocket::Player.create(
35
+ :name => "Bob",
36
+ :locale => "fr_FR"
37
+ )
38
+
39
+ if result.success?
40
+ p "success!"
41
+ else
42
+ p result.error
43
+ end
44
+
45
+ == Documentation
46
+
47
+ * Documentation[https://www.gamerocket.io:443/docs/ruby/guide/overview]
48
+
49
+
50
+ == License
51
+
52
+ See the LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rubygems/package_task'
10
+ require 'rdoc/task'
11
+ require 'rake/testtask'
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = 'gamerocket'
15
+ s.version = '1.0.0'
16
+ s.has_rdoc = true
17
+ s.extra_rdoc_files = ['README', 'LICENSE']
18
+ s.summary = 'Your summary here'
19
+ s.description = s.summary
20
+ s.author = 'Work Bandits'
21
+ s.email = 'contact@gamerocket.io'
22
+ # s.executables = ['your_executable_here']
23
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
24
+ s.require_path = "lib"
25
+ s.bindir = "bin"
26
+ s.add_dependency "builder", ">= 2.0.0"
27
+ s.add_dependency "json"
28
+ end
29
+
30
+ Gem::PackageTask.new(spec) do |p|
31
+ p.gem_spec = spec
32
+ p.need_tar = true
33
+ p.need_zip = true
34
+ end
35
+
36
+ Rake::RDocTask.new do |rdoc|
37
+ files =['README', 'LICENSE', 'lib/**/*.rb']
38
+ rdoc.rdoc_files.add(files)
39
+ rdoc.main = "README" # page to start on
40
+ rdoc.title = "gamerocket-ruby Docs"
41
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
42
+ rdoc.options << '--line-numbers'
43
+ end
44
+
45
+ Rake::TestTask.new do |t|
46
+ t.test_files = FileList['test/**/*.rb']
47
+ end
48
+
@@ -0,0 +1,26 @@
1
+ module GameRocket
2
+ class Achievement
3
+ include BaseModule
4
+
5
+ attr_accessor :id, :progression, :unlocked, :unlockedDate, :dynProp, :template
6
+
7
+ def initialize(gateway, attributes)
8
+ @gateway = gateway
9
+ if attributes.is_a?(Hash)
10
+ set_instance_variables_from_hash(attributes)
11
+ self.dynProp = attributes["dynProp"].is_a?(Hash) ? attributes["dynProp"] : {}
12
+ if attributes["template"].is_a?(Hash)
13
+ self.template = AchievementTemplate._new(attributes["template"])
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.find(player, id, params)
19
+ Configuration.gateway.achievement.find(player, id, params)
20
+ end
21
+
22
+ def self._new(*args)
23
+ self.new *args
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module GameRocket
2
+ class AchievementGateway
3
+
4
+ def initialize(gateway)
5
+ @gateway = gateway
6
+ @config = gateway.config
7
+ end
8
+
9
+ def find(player, id, params)
10
+ raise InvalidArgument, "Expected id to be set" if player.nil? || player == "" || id.nil? || id.to_s == ""
11
+ json = @config.http.get("/players/#{player}/achievements/#{id}", params)
12
+ if !json["achievement"].nil?
13
+ Achievement._new(@gateway, json["achievement"])
14
+ else
15
+ raise NotFoundError, "Achievement with id #{id} not found."
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module GameRocket
2
+ class AchievementTemplate
3
+ include BaseModule
4
+
5
+ attr_accessor :id, :ref, :name, :description, :image, :goal, :points, :dynProp
6
+
7
+ def initialize(attributes)
8
+ set_instance_variables_from_hash(attributes)
9
+ end
10
+
11
+ def self._new(*args)
12
+ self.new *args
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module GameRocket
2
+ class Action
3
+
4
+ attr_accessor :id, :ref, :name, :dynProp, :secured
5
+
6
+ def initialize(gateway, attributes)
7
+ @gateway = gateway
8
+ if !attributes.nil?
9
+ set_instance_variables_from_hash(attributes) if !attributes.nil?
10
+ self.dynProp = attributes[:dynProp].nil ? attributes[:dynProp] : {}
11
+ end
12
+ end
13
+
14
+ def self.find(id)
15
+ Configuration.gateway.action.find(id)
16
+ end
17
+
18
+ def self.run(id, attributes)
19
+ Configuration.gateway.action.run(id, attributes)
20
+ end
21
+
22
+ def self._new(*args)
23
+ self.new *args
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module GameRocket
2
+ class ActionGateway
3
+
4
+ def initialize(gateway)
5
+ @gateway = gateway
6
+ @config = gateway.config
7
+ end
8
+
9
+ def find(id)
10
+ raise InvalidArgument, "Expected id to be set" if id.nil? || id.to_s == ""
11
+ response = @config.http.get("/games/#{@config.apiKey}/actions/#{id}")
12
+ if !response["action"].nil?
13
+ Action._new(@gateway, response["action"])
14
+ else
15
+ raise NotFoundError, "Action with id #{id} not found."
16
+ end
17
+ end
18
+
19
+ def run(id, attributes)
20
+ response = @config.http.post("/games/#{@config.apiKey}/actions/#{id}/run", attributes)
21
+ if response["error"].nil?
22
+ SuccessfulResult.new(response)
23
+ else
24
+ ErrorResult.new(attributes, response)
25
+ end
26
+ rescue NotFoundError
27
+ raise NotFoundError, "Action with id #{id} not found."
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,36 @@
1
+ module GameRocket
2
+ module BaseModule
3
+ module Methods
4
+
5
+ def return_object_or_raise(object_to_return)
6
+ result = yield
7
+ if result.success?
8
+ result.send object_to_return
9
+ else
10
+ raise ValidationsFailed.new(result)
11
+ end
12
+ end
13
+
14
+ def copy_instance_variables_from_object(object)
15
+ object.instance_variables.each do |ivar|
16
+ instance_variable_set ivar, object.instance_variable_get(ivar)
17
+ end
18
+ end
19
+
20
+ def set_instance_variables_from_hash(hash)
21
+ hash.each do |key, value|
22
+ instance_variable_set "@#{key}", value
23
+ end
24
+ end
25
+
26
+ def singleton_class
27
+ class <<self; self; end
28
+ end
29
+ end
30
+
31
+ def self.included(klass)
32
+ klass.extend Methods
33
+ end
34
+ include Methods
35
+ end
36
+ end
@@ -0,0 +1,121 @@
1
+ module GameRocket
2
+ class Configuration
3
+ API_VERSION ="1"
4
+
5
+ class << self
6
+ attr_writer :custom_user_agent, :logger, :apiKey, :secretKey
7
+ end
8
+ attr_reader :apiKey, :secretKey
9
+
10
+ def self.expectant_reader(*attributes)
11
+ attributes.each do |attribute|
12
+ (class << self; self; end).send(:define_method, attribute) do
13
+ attribute_value = instance_variable_get("@#{attribute}")
14
+ raise ConfigurationError.new(attribute.to_s, "needs to be set") unless attribute_value
15
+ attribute_value
16
+ end
17
+ end
18
+ end
19
+ expectant_reader :environment, :apiKey, :secretKey
20
+
21
+ def self.environment=(env)
22
+ unless [:development, :production].include?(env)
23
+ raise ArgumentError, "#{env.inspect} is not a valid environment"
24
+ end
25
+ @environment = env
26
+ end
27
+
28
+ def self.gateway
29
+ GameRocket::Gateway.new(instantiate)
30
+ end
31
+
32
+ def self.instantiate
33
+ config = new(
34
+ :custom_user_agent => @custom_user_agent,
35
+ :environment => environment,
36
+ :logger => logger,
37
+ :apiKey => apiKey,
38
+ :secretKey => secretKey
39
+ )
40
+ end
41
+
42
+ def self.logger
43
+ @logger ||=_default_logger
44
+ end
45
+
46
+ def initialize(options = {})
47
+ [:environment, :apiKey, :secretKey, :custom_user_agent, :logger].each do |attr|
48
+ instance_variable_set "@#{attr}", options[attr]
49
+ end
50
+ end
51
+
52
+ def api_version
53
+ API_VERSION
54
+ end
55
+
56
+ def baseUrl
57
+ "#{protocol}://#{server}:#{port}/api/#{API_VERSION}"
58
+ end
59
+
60
+ def ca_file
61
+ case @environment
62
+ when :production
63
+ File.expand_path(File.join(File.dirname(_FILE_), "..", "ssl", "www_gamerocket_io.ca.crt" ))
64
+ end
65
+ end
66
+
67
+ def http
68
+ Http.new(self)
69
+ end
70
+
71
+ def logger
72
+ @logger ||=self.class._default_logger
73
+ end
74
+
75
+ def port
76
+ case @environment
77
+ when :development
78
+ ENV['GATEWAY_PORT'] || 8180
79
+ when :production
80
+ 443
81
+ end
82
+ end
83
+
84
+ def protocol
85
+ ssl? ? "https" : "http"
86
+ end.to_s
87
+
88
+ def server
89
+ case @environment
90
+ when :development
91
+ "localhost"
92
+ when :production
93
+ "www.gamerocket.io"
94
+ end
95
+ end
96
+
97
+ def ssl?
98
+ case @environment
99
+ when :development
100
+ false
101
+ when :production
102
+ true
103
+ end
104
+ end
105
+
106
+ def user_agent
107
+ base_user_agent = "GameRocket Ruby Gem #{GameRocket::Version::String}"
108
+ @custom_user_agent ? "#{base_user_agent} (#{@custom_user_agent}" : base_user_agent
109
+ end
110
+
111
+ def self._default_logger
112
+ logger = Logger.new(STDOUT)
113
+ logger.level = Logger::INFO
114
+ logger
115
+ end
116
+
117
+ def inspect
118
+ super.gsub(/@secretKey=\".*\"/, '@secrectKey="[FILTERED]"')
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,46 @@
1
+ module GameRocket
2
+ module Crypto
3
+
4
+ def self.sign(method, url, parameters, secretKey)
5
+ base_string = self.build_base_string(method, url, parameters)
6
+ self._sign(base_string, secretKey)
7
+ end
8
+
9
+ private
10
+ def self.build_base_string(method, url, parameters)
11
+ base_string = "#{method}&" + "#{CGI.escape("#{url.downcase}").gsub("+", "%20")}&"
12
+ if !parameters.nil?
13
+ parameters.each{|key, value|
14
+ if value.is_a?(Hash)
15
+ value.each{|key_bis, value_bis|
16
+ if value_bis.is_a?(Hash)
17
+ value_bis.each{ |key_ter, value_ter|
18
+ CGI.escape(value_ter).gsub("+", "%20")
19
+ }
20
+ value_bis = GameRocket::Util.hash_to_query_string(value_bis)
21
+ else
22
+ CGI.escape(value_bis).gsub("+", "%20")
23
+ end
24
+
25
+ }
26
+ value = GameRocket::Util.hash_to_query_string(value)
27
+ CGI.escape(value).gsub("+", "%20")
28
+ else
29
+ CGI.escape(value).gsub("+", "%20")
30
+ end
31
+
32
+ }
33
+ parameters = parameters.sort
34
+ querystring = GameRocket::Util.hash_to_query_string(parameters)
35
+ base_string += CGI.escape(querystring).gsub("+", "%20")
36
+ end
37
+
38
+ base_string
39
+ end
40
+
41
+ def self._sign(base_string, secretKey)
42
+ digest = Digest::SHA256.hexdigest(base_string + secretKey)
43
+ Base64.strict_encode64(digest)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ module GameRocket
2
+ class ErrorResult
3
+
4
+ attr_reader :error, :error_description
5
+
6
+ def initialize(gateway, json)
7
+ @error = json["error"]
8
+ @error_description = json["error_description"]
9
+ end
10
+
11
+ def success?
12
+ false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ module GameRocket
2
+ class GameRocketError < ::StandardError; end
3
+
4
+ class AuthenticationError < GameRocketError; end
5
+
6
+ class AuthorizationError < GameRocketError; end
7
+
8
+ class ConfigurationError < GameRocketError
9
+ def initialize(setting, message)
10
+ super "GameRocket::Configuration.#{setting} #{message}"
11
+ end
12
+ end
13
+
14
+ class DownForMaintenanceError < GameRocketError; end
15
+
16
+ class ForgedQueryString < GameRocketError; end
17
+
18
+ class InvalidArgument < GameRocketError; end
19
+
20
+ class InvalidSignature < GameRocketError; end
21
+
22
+ class NotFoundError < GameRocketError; end
23
+
24
+ class ServerError < GameRocketError; end
25
+
26
+ class SSLCertificateError < GameRocketError; end
27
+
28
+ class UnexpectedError < GameRocketError; end
29
+
30
+ class UpgradeRequiredError < GameRocketError; end
31
+
32
+ class ValidationsFailed < GameRocketError
33
+ attr_reader :error_result
34
+
35
+ def initialize(error_result)
36
+ @error_result = error_result
37
+ end
38
+
39
+ def inspect
40
+ "#<#{self.class} error_result: #{@error_result.inspect}>"
41
+ end
42
+
43
+ def to_s
44
+ inspect
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,22 @@
1
+ module GameRocket
2
+ class Game
3
+
4
+ attr_accessor :id, :name, :status, :dynProp
5
+
6
+ def initialize(gateway, attributes)
7
+ @gateway = gateway
8
+ if !attributes.nil?
9
+ set_instance_variables_from_hash(attributes)
10
+ self.dynProp = attributes[:dynProp].is_a?(Hash) ? attributes[:dynProp] : {}
11
+ end
12
+ end
13
+
14
+ def self.find(id)
15
+ Configuration.gateway.game.find(id)
16
+ end
17
+
18
+ def self._new(*args)
19
+ self.new *args
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module GameRocket
2
+ class GameGateway
3
+
4
+ def initialize(gateway)
5
+ @gateway = gateway
6
+ @config = gateway.config
7
+ end
8
+
9
+ def find(id)
10
+ raise InvalidArgument, "Expected id to be set" if id.nil? || id.to_s == ""
11
+ response = @config.http.get("/games/#{id}")
12
+ if !response["game"].nil?
13
+ Game._new(@gateway, response[:game])
14
+ else
15
+ raise NotFoundError, "Game with id #{id} not found."
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module GameRocket
2
+ class Gateway
3
+
4
+ attr_reader :config
5
+
6
+ def initialize(config)
7
+ if config.is_a?(Hash)
8
+ @config = Configuration.new config
9
+ elsif config.is_a?(GameRocket::Configuration)
10
+ @config = config
11
+ else
12
+ raise ArgumentError, "config is an invalid type"
13
+ end
14
+ end
15
+
16
+ def player
17
+ PlayerGateway.new(self)
18
+ end
19
+
20
+ def achievement
21
+ AchievementGateway.new(self)
22
+ end
23
+
24
+ def action
25
+ ActionGateway.new(self)
26
+ end
27
+
28
+ def game
29
+ GameGateway.new(self)
30
+ end
31
+
32
+ def purchase
33
+ PurchaseGateway.new(self)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,113 @@
1
+ module GameRocket
2
+ class Http
3
+
4
+ def initialize(config)
5
+ @config = config
6
+ end
7
+
8
+ def get(path, params = {})
9
+ params[:signature] = GameRocket::Crypto::sign('GET', @config.baseUrl + path, params, @config.secretKey)
10
+ qs = GameRocket::Util.hash_to_query_string(params)
11
+
12
+ response = _http_do Net::HTTP::Get, @config.baseUrl + path + "?" + qs
13
+ if response.code.to_i == 200 || response.code.to_i == 422
14
+ JSON.parse(_body(response))
15
+ else
16
+ Util.raise_exception_for_status_code(response.code)
17
+ end
18
+ end
19
+
20
+
21
+ def post(path, params = {})
22
+ params[:signature] = GameRocket::Crypto::sign('POST', @config.baseUrl + path, params, @config.secretKey)
23
+ qs = GameRocket::Util.hash_to_query_string(params)
24
+
25
+ response = _http_do Net::HTTP::Post, @config.baseUrl + path, qs
26
+ if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 422
27
+ JSON.parse(_body(response))
28
+ else
29
+ Util.raise_exception_for_status_code(response.code)
30
+ end
31
+ end
32
+
33
+ def put(path, params = {})
34
+ params[:signature] = GameRocket::Crypto::sign('PUT', @config.baseUrl + path, params, @config.secretKey)
35
+ qs = GameRocket::Util.hash_to_query_string(params)
36
+
37
+ response = _http_do Net::HTTP::Put, @config.baseUrl + path, qs
38
+ if response.code.to_i == 200 || response.code.to_i == 201 || response.code.to_i == 422
39
+ JSON.parse(_body(response))
40
+ else
41
+ Util.raise_exception_for_status_codes(response.code)
42
+ end
43
+ end
44
+
45
+ def delete(path, params = {})
46
+ params[:signature] = GameRocket::Crypto::sign('DELETE', @config.baseUrl + path, params, @config.secretKey)
47
+ qs = GameRocket::Util.hash_to_query_string(params)
48
+
49
+ response = _http_do Net::HTTP::Delete, @config.baseUrl + path + "?" + qs
50
+ if response.code.to_i == 200
51
+ JSON.parse(_body(response))
52
+ else
53
+ Util.raise_exception_for_status_code(response.code)
54
+ end
55
+ end
56
+
57
+ def _http_do(http_verb, path, body = nil)
58
+ connection = Net::HTTP.new(@config.server, @config.port)
59
+ connection.read_timeout = 60
60
+ if @config.ssl?
61
+ connection.use_ssl= true
62
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
63
+ connection.ca_file = @config.ca_file
64
+ connection.verify_callback = proc { |preverify_ok, ssl_context| _verify_ssl_certificate(preverify_ok, ssl_context) }
65
+ end
66
+ connection.start do |http|
67
+ request = http_verb.new("#{path}")
68
+ request["Accept"] = "application/json"
69
+ request["User-Agent"] = @config.user_agent
70
+ request["Accept-Encoding"] = "gzip"
71
+ request["X-ApiVersion"] = @config.api_version
72
+ @config.logger.debug "[GameRocket] [#{_current_time}] #{request.method} #{path}"
73
+ if body
74
+ request.body = body
75
+ @config.logger.debug body
76
+ end
77
+ response = http.request(request)
78
+ @config.logger.info "[GameRocket] [#{_current_time}] #{request.method} #{path} #{response.code}"
79
+ @config.logger.debug "[GameRocket] [#{_current_time}] #{response.code} #{response.message}"
80
+ if @config.logger.level == Logger::DEBUG
81
+ @config.logger.debug _body(response)
82
+ end
83
+ response
84
+ end
85
+ rescue OpenSSL::SSL::SSLError
86
+ raise GameRocket::SSLCertificateError
87
+ end
88
+
89
+ def _body(response)
90
+ if response.header["Content-Encoding"].nil?
91
+ response.body
92
+ elsif response.header["Content-Encoding"] == "gzip"
93
+ Zlib::GzipReader.new(StringIO.new(response.body)).read
94
+ else
95
+ raise UnexpectedError, "expected a gzipped response"
96
+ end
97
+ end
98
+
99
+ def _current_time
100
+ Time.now.utc.strftime("%d/%b/%Y %H:%M:%S %Z")
101
+ end
102
+
103
+ def _verify_ssl_certificate(preverify_ok, ssl_context)
104
+ if preverify_ok != true || ssl_context.error != 0
105
+ err_msg = "SSL Verification failed -- Preverify: #{preverify_ok}, Error: #{ssl_context.error_string} (#{ssl_context.error})"
106
+ @config.logger.error err_msg
107
+ false
108
+ else
109
+ true
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,52 @@
1
+ module GameRocket
2
+ class Player
3
+ include BaseModule
4
+
5
+ attr_accessor :id, :name, :emailHash, :totalPointsAchievements, :locale, :dynProp
6
+
7
+ def initialize(gateway, attributes)
8
+ @gateway = gateway
9
+ set_instance_variables_from_hash(attributes) unless attributes.nil?
10
+ end
11
+
12
+ def self.create(attributes = {})
13
+ Configuration.gateway.player.create(attributes)
14
+ end
15
+
16
+ def self.find(id)
17
+ Configuration.gateway.player.find(id)
18
+ end
19
+
20
+ def self.update(id, attributes)
21
+ Configuration.gateway.player.update(id, attributes)
22
+ end
23
+
24
+ def self.delete(id)
25
+ Configuration.gateway.player.delete(id)
26
+ end
27
+
28
+ def delete
29
+ @gateway.player.delete(id)
30
+ end
31
+
32
+ def ==(other)
33
+ return false unless other.is_a?(Player)
34
+ id == other.id
35
+ end
36
+
37
+ class << self
38
+ protected :new
39
+ end
40
+
41
+ def self._new(*args)
42
+ self.new *args
43
+ end
44
+
45
+ def self._attributes
46
+ [
47
+ :id, :name, :emailHash, :totalPointsAchievements, :locale, :dynProp
48
+ ]
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,61 @@
1
+ module GameRocket
2
+ class PlayerGateway
3
+
4
+ def initialize(gateway)
5
+ @gateway = gateway
6
+ @config = gateway.config
7
+ end
8
+
9
+ def self.createSignature
10
+ signature = ['name', 'locale']
11
+ signature
12
+ end
13
+
14
+ def create(attributes = {})
15
+ Util.verify_keys(PlayerGateway.createSignature, attributes)
16
+ result = _do_create "/games/" + GameRocket::Configuration::apiKey + "/players", attributes
17
+ end
18
+
19
+ def find(id)
20
+ raise ArgumentError, "id contains invalid characters" unless id.to_s =~ /\A[\w_]+\z/
21
+ raise ArgumentError, "id cannot be blank" if id.nil?|| id.to_s.strip ==""
22
+ json = @config.http.get("/players/#{id}")
23
+ if !json["player"].nil?
24
+ Player._new(@gateway, json["player"])
25
+ else
26
+ raise NotFoundError, "player with id#{id.inspect} not found"
27
+ end
28
+ end
29
+
30
+ def update(id, attributes)
31
+ _do_update(:put, "/players/#{id}", attributes)
32
+ end
33
+
34
+ def delete(id)
35
+ json = @config.http.delete("/players/#{id}")
36
+ SuccessfulResult.new
37
+ end
38
+
39
+ def _do_create(url, params = nil)
40
+ json = @config.http.post url, params
41
+ if json["player"]
42
+ SuccessfulResult.new(:player => Player._new(@gateway, json["player"]))
43
+ elsif json["error"]
44
+ ErrorResult.new(@gateway, json)
45
+ else
46
+ raise "expected :player or :error"
47
+ end
48
+ end
49
+
50
+ def _do_update(http_verb, url, params)
51
+ json = @config.http.send http_verb, url, params
52
+ if json["player"]
53
+ SuccessfulResult.new(:player => Player._new(@gateway, json["player"]))
54
+ elsif json["error"]
55
+ ErrorResult.new(@gateway, json)
56
+ else
57
+ raise UnexpectedError, "expected :player or :error"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module GameRocket
2
+ class Purchase
3
+
4
+ attr_accessor :id, :ref, :name, :price, :dynProp
5
+
6
+ def initialize(gateway, attributes)
7
+ @gateway = gateway
8
+ if !attributes.nil?
9
+ set_instance_variables_from_hash(attributes)
10
+ self.dynProp = attributes[:dynProp].is_a?(Hash) ? attributes[:dynProp] : {}
11
+ end
12
+ end
13
+
14
+ def self.find(id)
15
+ Configuration.gateway.purchase.find(id)
16
+ end
17
+
18
+ def self.buy(id, attributes)
19
+ Configuration.gateway.purchase.buy(id, attributes)
20
+ end
21
+
22
+ def self._new(*args)
23
+ self.new *args
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ module GameRocket
2
+ class PurchaseGateway
3
+
4
+ def initialize(gateway)
5
+ @gateway = gateway
6
+ @config = gateway.config
7
+ end
8
+
9
+ def find(id)
10
+ raise InvalidArgument, "Expected id to be set" if id.nil? || id.to_s == ""
11
+ response = @config.http.get("/games/#{@config.apiKey}/purchases/#{id}")
12
+ if !response["purchase"].nil?
13
+ Purchase._new(@gateway, response["purchase"])
14
+ else
15
+ raise NotFoundError, "Purchase with id #{id} not found."
16
+ end
17
+ end
18
+
19
+ def buy(id, attributes)
20
+ response = @config.http.post("/games/#{@config.apiKey}/purchases/#{id}/buy", attributes)
21
+ if response["error"].nil?
22
+ SuccessfulResult.new(response)
23
+ else
24
+ ErrorResult.new(@gateway, response)
25
+ end
26
+ rescue NotFoundError
27
+ raise NotFoundError, "Purchase with id #{id} not found."
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module GameRocket
2
+ class SuccessfulResult
3
+ include BaseModule
4
+
5
+ def initialize(attributes = {})
6
+ @attrs = attributes.keys
7
+ singleton_class.class_eval do
8
+ attributes.each do |key, value|
9
+ define_method key do
10
+ value
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ def success?
17
+ true
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,138 @@
1
+ module GameRocket
2
+ module Util
3
+
4
+ def self.extract_attribute_as_array(hash, attribute)
5
+ raise UnexpectedError.new("Unprocessable entity due to an invalid request") if hash.nil?
6
+ value = hash.has_key?(attribute) ? hash.delete(attribute) : []
7
+ value.is_a?(Array) ? value : [value]
8
+ end
9
+
10
+ def self.hash_to_query_string(hash, namespace = nil)
11
+ hash.collect do |key, value|
12
+ full_key = namespace ? "#{namespace}[#{key}]" : key
13
+ if value.is_a?(Hash)
14
+ hash_to_query_string(value, full_key)
15
+ else
16
+ if full_key.eql? :signature
17
+ full_key.to_s.to_str + "=" + value.to_s.to_str
18
+ else
19
+ url_encode(full_key) + "=" + url_encode(value)
20
+ end
21
+ end
22
+ end.sort * '&'
23
+ end
24
+
25
+ def self.parse_query_string(qs)
26
+ qs.split('&').inject({}) do |result, couplet|
27
+ pair = couplet.split('=')
28
+ result[CGI.unescape(pair[0]).to_sym] = CGI.unescapeHTML(pair[1] || '')
29
+ result
30
+ end
31
+ end
32
+
33
+ def self.url_decode(text)
34
+ CGI.escape text.to_s.to_str
35
+ end
36
+
37
+ def self.url_encode(text)
38
+ CGI.escape text.to_s.to_str
39
+ end
40
+
41
+ def self.symbolize_keys(hash)
42
+ hash.inject({}) do |new_hash, (key, value)|
43
+ if value.is_a?(Hash)
44
+ value = symbolize_keys(value)
45
+ elsif value.is_a?(Array) && value.all? { |v| v.is_a?(Hash) }
46
+ value = value.map {|v| symbolize_keys(v)}
47
+ end
48
+ new_hash.merge(key.to_sym => value)
49
+ end
50
+ end
51
+
52
+ def self.raise_exception_for_status_code(status_code, message=nil)
53
+ case status_code.to_i
54
+ when 401
55
+ raise AuthenticationError
56
+ when 403
57
+ raise AuthorizationError, message
58
+ when 404
59
+ raise NotFoundError
60
+ when 426
61
+ raise UpgradeRequiredError, "Please upgrade your client library."
62
+ when 500
63
+ raise ServerError
64
+ when 503
65
+ raise DownForMaintenanceError
66
+ else
67
+ raise UnexpectedError, "unexpected HTTP_RESPONSE #{status_code.to_i}"
68
+ end
69
+ end
70
+
71
+ def self.to_big_decimal(decimal)
72
+ case decimal
73
+ when BigDecimal, NilClass
74
+ decimal
75
+ when String
76
+ BigDecimal.new(decimal)
77
+ else
78
+ raise ArgumentError, "Argument must be a String or BigDecimal"
79
+ end
80
+ end
81
+
82
+ def self.verify_keys(valid_keys, hash)
83
+ flattened_valid_keys = _flatten_valid_keys(valid_keys)
84
+ invalid_keys = _flatten_hash_keys(hash) - flattened_valid_keys
85
+ invalid_keys = _remove_wildcard_keys(flattened_valid_keys, invalid_keys)
86
+ if invalid_keys.any?
87
+ sorted = invalid_keys.sort_by { |k| k.to_s}.join(", ")
88
+ raise ArgumentError, "invalid keys: #{sorted}"
89
+ end
90
+ end
91
+
92
+ def self._flatten_valid_keys(valid_keys, namespace = nil)
93
+ valid_keys.inject([]) do |result, key|
94
+ if key.is_a?(Hash)
95
+ full_key = key.keys[0]
96
+ full_key = (namespace ? "#{namespace}[#{full_key}]" : full_key)
97
+ nested_keys = key.values[0]
98
+ if nested_keys.is_a?(Array)
99
+ result += _flatten_valid_keys(nested_keys, full_key)
100
+ else
101
+ result << "#{full_key}[#{nested_keys}]"
102
+ end
103
+ else
104
+ result << (namespace ? "#{namespace}[#{key}]" : key.to_s)
105
+ end
106
+ result
107
+ end.sort
108
+ end
109
+
110
+ def self._flatten_hash_keys(element, namespace = nil)
111
+ element = [element] if element.is_a?(String)
112
+ element.inject([]) do |result, (key, value)|
113
+ full_key = (namespace ? "#{namespace}[#{key}]" : key.to_s)
114
+ if value.is_a?(Hash)
115
+ result += _flatten_hash_keys(value, full_key)
116
+ elsif value.is_a?(Array)
117
+ value.each do |item|
118
+ result += _flatten_hash_keys(item, full_key)
119
+ end
120
+ else
121
+ result << full_key
122
+ end
123
+ result
124
+ end.sort
125
+ end
126
+
127
+ def self._remove_wildcard_keys(valid_keys, invalid_keys)
128
+ wildcard_keys = valid_keys.select {|k| k.include? "[_any_key_]"}
129
+ return invalid_keys if wildcard_keys.empty?
130
+ wildcard_keys.map! { |wk| wk.sub "[_any]", ""}
131
+ invalid_keys.select do |invalid_key|
132
+ wildcard_keys.all? do |wildcard_key|
133
+ invalid_key.index(wildcard_key) != 0
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,9 @@
1
+ module GameRocket
2
+ module Version
3
+ Major = 1
4
+ Minor = 0
5
+ Tiny =0
6
+
7
+ String = "#{Major}.#{Minor}.#{Tiny}"
8
+ end
9
+ end
data/lib/gamerocket.rb ADDED
@@ -0,0 +1,45 @@
1
+ require "base64"
2
+ require "cgi"
3
+ require "date"
4
+ require "digest/sha2"
5
+ require "logger"
6
+ require "net/http"
7
+ require "net/https"
8
+ require "openssl"
9
+ require "stringio"
10
+ require "time"
11
+ require "zlib"
12
+
13
+ require "builder"
14
+ require "json"
15
+
16
+ require File.dirname(__FILE__) + "/gamerocket/exceptions"
17
+
18
+ require File.dirname(__FILE__) + "/gamerocket/base_module"
19
+
20
+ require File.dirname(__FILE__) + "/gamerocket/achievement"
21
+ require File.dirname(__FILE__) + "/gamerocket/achievement_gateway"
22
+ require File.dirname(__FILE__) + "/gamerocket/achievement_template"
23
+ require File.dirname(__FILE__) + "/gamerocket/action"
24
+ require File.dirname(__FILE__) + "/gamerocket/action_gateway"
25
+ require File.dirname(__FILE__) + "/gamerocket/game"
26
+ require File.dirname(__FILE__) + "/gamerocket/game_gateway"
27
+ require File.dirname(__FILE__) + "/gamerocket/purchase"
28
+ require File.dirname(__FILE__) + "/gamerocket/purchase_gateway"
29
+ require File.dirname(__FILE__) + "/gamerocket/player"
30
+ require File.dirname(__FILE__) + "/gamerocket/player_gateway"
31
+
32
+ require File.dirname(__FILE__) + "/gamerocket/gateway"
33
+ require File.dirname(__FILE__) + "/gamerocket/http"
34
+ require File.dirname(__FILE__) + "/gamerocket/successful_result"
35
+ require File.dirname(__FILE__) + "/gamerocket/error_result"
36
+
37
+ require File.dirname(__FILE__) + "/gamerocket/crypto"
38
+ require File.dirname(__FILE__) + "/gamerocket/util"
39
+ require File.dirname(__FILE__) + "/gamerocket/configuration"
40
+ require File.dirname(__FILE__) + "/gamerocket/version"
41
+
42
+
43
+ GameRocket::Configuration.environment = "your_environment"#:development or :production
44
+ GameRocket::Configuration.apiKey = "your_apiKey"#use your apiKey
45
+ GameRocket::Configuration.secretKey = "your_secret_key"#use your secretKey
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gamerocket
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Work Bandits
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: builder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Your summary here
42
+ email: contact@gamerocket.io
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - README
47
+ - LICENSE
48
+ files:
49
+ - LICENSE
50
+ - README
51
+ - Rakefile
52
+ - lib/gamerocket/game_gateway.rb
53
+ - lib/gamerocket/player_gateway.rb
54
+ - lib/gamerocket/base_module.rb
55
+ - lib/gamerocket/achievement_gateway.rb
56
+ - lib/gamerocket/achievement_template.rb
57
+ - lib/gamerocket/http.rb
58
+ - lib/gamerocket/purchase_gateway.rb
59
+ - lib/gamerocket/game.rb
60
+ - lib/gamerocket/purchase.rb
61
+ - lib/gamerocket/gateway.rb
62
+ - lib/gamerocket/version.rb
63
+ - lib/gamerocket/util.rb
64
+ - lib/gamerocket/action.rb
65
+ - lib/gamerocket/configuration.rb
66
+ - lib/gamerocket/crypto.rb
67
+ - lib/gamerocket/error_result.rb
68
+ - lib/gamerocket/successful_result.rb
69
+ - lib/gamerocket/exceptions.rb
70
+ - lib/gamerocket/player.rb
71
+ - lib/gamerocket/achievement.rb
72
+ - lib/gamerocket/action_gateway.rb
73
+ - lib/gamerocket.rb
74
+ homepage:
75
+ licenses: []
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 2.0.3
94
+ signing_key:
95
+ specification_version: 4
96
+ summary: Your summary here
97
+ test_files: []