smartfox_jruby 0.2-java

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.
data/Doubleshot ADDED
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ require 'pathname'
3
+ require Pathname.new(File.dirname(File.expand_path(__FILE__))).join('lib/smartfox_jruby.rb')
4
+ Doubleshot.new do |config|
5
+
6
+ config.project = "smartfox_jruby"
7
+ config.version = SmartfoxJruby::VERSION
8
+
9
+ config.gem 'activesupport', '~> 3.2.8'
10
+ config.gem 'json'
11
+ config.gem 'rspec', '~> 2.10.0'
12
+
13
+ config.mvn_repository 'http://repo1.maven.org/maven2'
14
+ config.mvn_repository 'http://artifactory-innovations.i-free.ru/artifactory/ext-release-local'
15
+
16
+ config.jar 'com.smartfox2x.client:sfs2x-client-core:1.0.4'
17
+ config.jar 'com.smartfox2x.client:sfs2x-api-java:1.0.4'
18
+ config.jar 'org.slf4j:slf4j-log4j12:1.5.10'
19
+
20
+ config.gemspec do |spec|
21
+ spec.summary = "Smartfox client for jruby"
22
+ spec.description = <<-DESCRIPTION
23
+ Allows to connect and easily process messages from and to SmartFox game server
24
+ DESCRIPTION
25
+
26
+ spec.homepage = "https://github.com/smecsia/smartfox_jruby"
27
+ spec.author = "Ilya Sadykov"
28
+ spec.email = "smecsia@gmail.com"
29
+ spec.license = "Apache 2.0"
30
+ end
31
+
32
+ end
@@ -0,0 +1,152 @@
1
+ require 'java'
2
+ require 'active_support/all'
3
+ java_import com.smartfoxserver.v2.entities.data.ISFSObject
4
+ java_import com.smartfoxserver.v2.entities.data.SFSObject
5
+ java_import com.smartfoxserver.v2.entities.data.SFSArray
6
+ java_import java.util.Arrays
7
+ java_import 'sfs2x.client.core.IEventListener'
8
+ java_import 'sfs2x.client.core.SFSEvent'
9
+ java_import 'sfs2x.client.SmartFox'
10
+ java_import 'sfs2x.client.requests.LoginRequest'
11
+ java_import 'sfs2x.client.requests.ExtensionRequest'
12
+
13
+ module ISFSObject
14
+ def to_hash
15
+ HashWithIndifferentAccess.new(JSON.parse(to_json))
16
+ end
17
+
18
+ def to_s
19
+ to_json
20
+ end
21
+ end
22
+
23
+ module SmartfoxJruby::SFSUtil
24
+ class << self
25
+ def boxing(v, type)
26
+ case type
27
+ when :long
28
+ java.lang.Long.valueOf(v)
29
+ when :float
30
+ java.lang.Float.valueOf(v)
31
+ when :double
32
+ java.lang.Double.valueOf(v)
33
+ when :int
34
+ java.lang.Integer.valueOf(v)
35
+ when :boolean
36
+ java.lang.Boolean.valueOf(v)
37
+ else
38
+ v
39
+ end
40
+ end
41
+
42
+ def to_java_list(value, type)
43
+ list = java.util.ArrayList.new
44
+ value.to_java(type).each do |v|
45
+ list.add(boxing(v, type))
46
+ end
47
+ list
48
+ end
49
+ end
50
+ end
51
+
52
+ def SFSObject.from_hash(hash, opts = {})
53
+ res = SFSObject.new
54
+ opts ||= {}
55
+ hash.each_key do |key|
56
+ value = hash[key]
57
+ key = key.to_s
58
+ type = opts["#{key}_type".to_sym]
59
+ if value.is_a?(Hash)
60
+ res.putSFSObject(key, from_hash(value, opts[key.to_sym]))
61
+ elsif value.is_a?(Float)
62
+ if type == :double
63
+ res.putDouble(key, value.to_java(:double))
64
+ else
65
+ res.putFloat(key, value.to_java(:float))
66
+ end
67
+ elsif value.is_a?(Integer)
68
+ if type == :long
69
+ res.putLong(key, value.to_java(:long))
70
+ else
71
+ res.putInt(key, value.to_java(:int))
72
+ end
73
+ elsif value.is_a?(TrueClass) or value.is_a?(FalseClass)
74
+ res.putBool(key, value.to_java(:boolean))
75
+ elsif value.is_a?(String) or value.is_a?(Symbol)
76
+ res.putUtfString(key, value.to_java(:string))
77
+ elsif value.is_a?(Array)
78
+ unless value.empty?
79
+ if value[0].is_a?(Hash)
80
+ array = SFSArray.new
81
+ value.each { |hash|
82
+ array.addSFSObject(from_hash(hash, opts[key.to_sym]))
83
+ }
84
+ res.putSFSArray(key, array)
85
+ elsif value[0].is_a?(Float)
86
+ if type == :double
87
+ res.putDoubleArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :double))
88
+ else
89
+ res.putFloatArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :float))
90
+ end
91
+ elsif value[0].is_a?(Integer)
92
+ if type == :long
93
+ res.putLongArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :long))
94
+ else
95
+ res.putIntArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :int))
96
+ end
97
+ elsif value[0].is_a?(TrueClass) or value[0].is_a?(FalseClass)
98
+ res.putBoolArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :boolean))
99
+ elsif value[0].is_a?(String) or value[0].is_a?(Symbol)
100
+ res.putUtfStringArray(key, SmartfoxJruby::SFSUtil.to_java_list(value, :string))
101
+ end
102
+ end
103
+ end
104
+ end
105
+ res
106
+ end
107
+
108
+ class Hash
109
+ include ISFSObject
110
+
111
+ def to_sfsobject(opts = {})
112
+ SFSObject.from_hash(self, opts)
113
+ end
114
+
115
+ def method_missing(m, *args)
116
+ sfs_object = SFSObject.from_hash(self)
117
+ if sfs_object.respond_to?(m)
118
+ sfs_object.send(m, *args)
119
+ else
120
+ super
121
+ end
122
+ end
123
+ end
124
+
125
+ module Kernel
126
+ class WaitTimeoutException < Exception
127
+ end
128
+
129
+ def wait_with_timeout(timeout = 20, opts = {:sleep_time => 0.1})
130
+ timeout ||= 20
131
+ raise "Block is required!" unless block_given?
132
+ time = Time.now.to_i
133
+ finished = false
134
+ while (Time.now.to_i < time + timeout) && !finished
135
+ sleep opts[:sleep_time] || 0.01 # sleep for 10 ms to wait the response
136
+ finished = yield
137
+ end
138
+ raise WaitTimeoutException.new("Timeout while waiting!") unless finished
139
+ end
140
+ end
141
+
142
+ module Process
143
+ def self.alive?(pid)
144
+ return false unless pid
145
+ begin
146
+ Process.kill(0, pid)
147
+ true
148
+ rescue Errno::ESRCH
149
+ false
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,172 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/sfs_worker')
2
+
3
+ class SmartfoxJruby::SfsAdapter
4
+ include IEventListener
5
+ attr_reader :opts
6
+ attr_reader :smart_fox
7
+ attr_reader :worker
8
+ attr_reader :username
9
+ DEBUG = false
10
+
11
+ def initialize(opts = {})
12
+ @opts = opts
13
+ debug "initializing sfs adapter..."
14
+ @smart_fox = SmartFox.new(false)
15
+ @connected = false
16
+ @worker = opts[:worker]
17
+ @login_as = {}
18
+ @opts[:timeout] ||= 20
19
+ @opts[:logger] ||= Logger.new(STDOUT)
20
+ SFSEvent.constants.each do |evt|
21
+ evt_value = SFSEvent.const_get(evt)
22
+ debug "Registering event adapter to self for event '#{evt}' --> '#{evt_value}'..."
23
+ smart_fox.add_event_listener(evt_value, self)
24
+ end
25
+ end
26
+
27
+ def connect!(opt = {})
28
+ opts.reverse_merge!(opt)
29
+ raise "host and port are required to connect SfsAdapter!" if opts[:host].blank? || opts[:port].blank?
30
+ debug "connecting to smartfox at #{opts[:host]}:#{opts[:port]} ..."
31
+ smart_fox.connect(opts[:host], opts[:port])
32
+ end
33
+
34
+ def dispatch(event)
35
+ debug "got event #{event.type}: #{event}"
36
+ callback = "on_#{event.type.try(:underscore)}_event"
37
+ if respond_to?(callback, true)
38
+ send(callback, event)
39
+ else
40
+ debug "Unknown event caught #{event.type} (No method '#{callback}' in #{self})"
41
+ end
42
+ end
43
+
44
+ def disconnect!
45
+ smart_fox.disconnect
46
+ end
47
+
48
+ def process!(wrk = nil, &block)
49
+ wait_with_timeout(@opts[:timeout]) { connected? }
50
+ @worker = wrk || opts[:worker]
51
+ if block_given? && connected?
52
+ instance_eval(&block)
53
+ else
54
+ raise "Worker is null!" if @worker.blank?
55
+ raise "Not connected!" unless connected?
56
+ end
57
+ worker.perform!
58
+ end
59
+
60
+ def connected?
61
+ @connected
62
+ end
63
+
64
+ def on_connect(&block)
65
+ @on_connect ||= []
66
+ @on_connect << block if block_given?
67
+ end
68
+
69
+ def on_login(&block)
70
+ @on_login ||= []
71
+ @on_login << block if block_given?
72
+ end
73
+
74
+ def login_as(username, password, params = {})
75
+ params = input_params.to_sfsobject if params.is_a?(Hash)
76
+ @login_as ||= {:username => username, :password => password, :params => params}
77
+ end
78
+
79
+ private
80
+
81
+ ###############
82
+ ### HELPERS ###
83
+
84
+ def request(*args)
85
+ worker.request(*args)
86
+ end
87
+
88
+ def worker(opts = {})
89
+ @worker ||= SfsWorker::Worker.new(@smart_fox, opts)
90
+ @worker
91
+ end
92
+
93
+ def sfs_send(req)
94
+ smart_fox.send(req)
95
+ end
96
+
97
+ #########################
98
+ ### EVENTS PROCESSORS ###
99
+
100
+ def on_extension_response_event(event)
101
+ debug "extension_response #{event.arguments.get("cmd")}"
102
+ @worker.response(event.arguments.get("cmd"), event.arguments.get("params").try(:to_hash) || {}) unless @worker.blank?
103
+ end
104
+
105
+ def on_connection_event(event)
106
+ debug "on_connection #{event}"
107
+ @on_connect.each { |block|
108
+ block.call(event) if block.is_a?(Proc)
109
+ } unless @on_connect.blank?
110
+ sfs_send(LoginRequest.new(@login_as[:username], @login_as[:password], opts[:zone],
111
+ (@login_as[:params] || {}).to_sfsobject));
112
+ end
113
+
114
+ def on_login_event(event)
115
+ args = event.arguments.get("data").to_hash
116
+ user = event.arguments.get("user")
117
+ debug("on_login, args=#{args.to_json}")
118
+ unless user.blank?
119
+ info "connected as #{user.name}"
120
+ @username = user.name
121
+ @connected = true
122
+ @on_login.each { |block|
123
+ block.call(@username) if block.is_a?(Proc)
124
+ } unless @on_login.blank?
125
+ else
126
+ raise "login error '#{args[Aimy::Param.ERROR_MESSAGE]}'"
127
+ end
128
+ end
129
+
130
+ def on_login_error_event(event)
131
+ error("error while logging-in: #{event.arguments}")
132
+ end
133
+
134
+ def on_connection_lost_event(event)
135
+ # nothing to do
136
+ end
137
+
138
+ def on_handshake_event(event)
139
+ # nothing to do
140
+ end
141
+
142
+
143
+ #######################
144
+ ### SERVICE HELPERS ###
145
+
146
+ def logger
147
+ opts[:logger]
148
+ end
149
+
150
+ def debug_enabled?
151
+ opts[:debug] || DEBUG
152
+ end
153
+
154
+ def debug(msg)
155
+ logger.debug "#{msg}" if debug_enabled?
156
+ end
157
+
158
+ def info(msg)
159
+ logger.info "#{msg}"
160
+ end
161
+
162
+ def log(msg)
163
+ logger.info "#{msg}"
164
+ end
165
+
166
+ def error(msg)
167
+ logger.error "#{msg}"
168
+ end
169
+
170
+
171
+ end
172
+
@@ -0,0 +1,123 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/common')
2
+
3
+ java_import java.lang.Runtime
4
+ java_import java.lang.System
5
+
6
+ class SmartfoxJruby::SfsRunner
7
+
8
+ def initialize(home_dir, opts = {})
9
+ @home_dir = home_dir
10
+ @opts = opts
11
+ @launched = false
12
+ @fault = false
13
+ @pid = nil
14
+ end
15
+
16
+ def run!
17
+ Thread.new do
18
+ begin
19
+ info "Changing dir to #{work_dir}"
20
+ Dir.chdir(work_dir) do
21
+ info "Running cmd #{cmd}"
22
+ IO.popen(cmd) do |output|
23
+ @pid = output.pid
24
+ info "Running child with pid=#{output.pid}..."
25
+ output.each do |line|
26
+ debug(line.gsub(/\n/, ""))
27
+ @launched = true if line =~ /SmartFoxServer 2X \(.+\) READY!/
28
+ end
29
+ end
30
+ @fault = true
31
+ end
32
+ rescue Exception => e
33
+ error "#{e}"
34
+ end
35
+ end
36
+ end
37
+
38
+ def kill!
39
+ info "Checking running processes: #{pids.join(",")}"
40
+ pids.each { |pid|
41
+ pid = pid.try(:strip).try(:to_i)
42
+ info "Killing the process with pid=#{pid}..."
43
+ Process.kill("KILL", pid) if Process.alive?(pid)
44
+ wait_with_timeout(5) { !Process.alive?(pid) } rescue ""
45
+ }
46
+ end
47
+
48
+ def run_and_wait!(opts = {})
49
+ run!
50
+ wait_until_launched_or_fault(opts[:timeout])
51
+ end
52
+
53
+
54
+ def kill_and_wait!(opts = {})
55
+ kill!
56
+ wait_until_terminated(opts[:timeout])
57
+ end
58
+
59
+ def running?
60
+ !pids.blank? && pids.map { |pid| Process.alive?(pid.to_i) }.include?(true)
61
+ end
62
+
63
+ def launched?
64
+ @launched
65
+ end
66
+
67
+ def fault?
68
+ @fault
69
+ end
70
+
71
+ def wait_until_terminated(timeout = nil)
72
+ wait_with_timeout(timeout) { !running? }
73
+ end
74
+
75
+ def wait_until_launched_or_fault(timeout = nil)
76
+ wait_with_timeout(timeout) { launched? or fault? }
77
+ end
78
+
79
+ private
80
+
81
+ def pids
82
+ pids_out = `pgrep -f "#{work_dir}"`
83
+ (pids_out.try(:split, "\n")) || []
84
+ end
85
+
86
+ def error(msg)
87
+ @opts[:logger].error(msg) unless @opts[:logger].blank?
88
+ end
89
+
90
+ def debug(msg)
91
+ @opts[:logger].debug(msg) unless @opts[:logger].blank?
92
+ end
93
+
94
+ def info(msg)
95
+ @opts[:logger].info(msg) unless @opts[:logger].blank?
96
+ end
97
+
98
+ def work_dir
99
+ Pathname.new(@home_dir).join("SFS2X").to_s
100
+ end
101
+
102
+ def env
103
+ %W[].to_java :string
104
+ end
105
+
106
+ def cmd
107
+ %Q[#{java_bin} -cp #{classpath} #{java_opts} -Dsmartfox.work_dir="#{work_dir}" com.smartfoxserver.v2.Main]
108
+ end
109
+
110
+ def java_bin
111
+ Pathname.new(System.getProperty("java.home")).join("bin").join("java")
112
+ end
113
+
114
+ def java_opts
115
+ %Q[-XX:MaxPermSize=512m -Xms128m -Xms1024m]
116
+ end
117
+
118
+ def classpath
119
+ %Q[aimy:./:lib/*:lib/Jetty/*:extensions/__lib__/*]
120
+ end
121
+
122
+ end
123
+
@@ -0,0 +1,256 @@
1
+ require 'thread'
2
+ require File.expand_path(File.dirname(__FILE__) + '/common')
3
+
4
+ module SmartfoxJruby::SfsWorker
5
+ class Processor
6
+ attr_accessor :opts
7
+ attr_accessor :name
8
+ attr_accessor :chained
9
+ attr_accessor :current
10
+ attr_accessor :blocks
11
+
12
+ def initialize(name, opts = {}, &block)
13
+ @blocks = [block]
14
+ @name = name
15
+ @current = self
16
+ @chained = nil
17
+ @opts = opts
18
+ end
19
+
20
+ def chain(name, &block)
21
+ link.chained = Processor.new(name, @opts, &block)
22
+ self
23
+ end
24
+
25
+ def link
26
+ p = current
27
+ p = p.chained while (!p.try(:chained).blank?)
28
+ p
29
+ end
30
+
31
+ def append(&block)
32
+ unless link.blank?
33
+ link.blocks << block
34
+ else
35
+ current.blocks << block
36
+ end
37
+ self
38
+ end
39
+
40
+ def completed?
41
+ current.blank?
42
+ end
43
+
44
+ def mandatory?
45
+ @opts[:mandatory].nil? || @opts[:mandatory]
46
+ end
47
+
48
+ def event(name, data = {})
49
+ if @current.name.to_s == name.to_s
50
+ @current.blocks.each { |b| b.call(data) }
51
+ @current = (@current.chained.blank?) ? nil : @current.chained
52
+ return true
53
+ end
54
+ false
55
+ end
56
+
57
+ def to_s
58
+ "Proc[#{current.try(:name)}] --> #{current.try(:chained)}"
59
+ end
60
+ end
61
+
62
+ class Request
63
+ attr_reader :name
64
+ attr_reader :data
65
+
66
+ def initialize(name, data = {})
67
+ @name = name
68
+ @data = data
69
+ end
70
+
71
+ def to_extension_request
72
+ ExtensionRequest.new(@name.to_s, @data)
73
+ end
74
+
75
+ def to_s
76
+ "Req[#{@name}]#{data.to_json}"
77
+ end
78
+ end
79
+
80
+ class Response < Request
81
+ def to_s
82
+ "Resp[#{@name}]#{data.to_json}"
83
+ end
84
+ end
85
+
86
+ class ContextWorker
87
+
88
+ def request(name, data = {})
89
+ @worker.request(name, data, :context => @context)
90
+ end
91
+
92
+ def append_processor(opts = {}, &block)
93
+ @worker.append_processor(opts.merge(:context => @context), &block)
94
+ end
95
+
96
+ def expect(name, opts={}, &block)
97
+ @worker.expect(name, opts.merge(:context => @context), &block)
98
+ end
99
+
100
+ def initialize(context, worker)
101
+ @context = context
102
+ @worker = worker
103
+ end
104
+ end
105
+
106
+ class Worker
107
+ attr_reader :send_queue
108
+ attr_reader :events_queue
109
+ attr_reader :processors
110
+ attr_reader :smart_fox
111
+ attr_reader :opts
112
+
113
+ def initialize(smart_fox, opts = {})
114
+ @send_queue = []
115
+ @processors = []
116
+ @events_queue = []
117
+ @opts = opts
118
+ @opts[:timeout] ||= 20
119
+ @smart_fox = smart_fox
120
+ @mutex = Mutex.new
121
+ @send_qm = Mutex.new
122
+ end
123
+
124
+ def append_processor(opts = {}, &block)
125
+ debug "appending processor with context #{opts[:context]}"
126
+ if opts[:context]
127
+ context = opts[:context].append(&block)
128
+ else
129
+ context = processors.last.append(&block)
130
+ end
131
+ ContextWorker.new(context, self)
132
+ end
133
+
134
+ def request(name, data = {}, opts = {})
135
+ debug "create request #{name} with context #{opts[:context]}"
136
+ data = data.to_sfsobject(opts[:serialize_opts]) if data.is_a?(Hash)
137
+ req = Request.new(name, data)
138
+ if !opts[:context].blank? && opts[:context].is_a?(Processor)
139
+ debug "appending #{req} to processor #{opts[:context]}"
140
+ context = opts[:context].append {
141
+ @send_qm.synchronize { send_queue << req }
142
+ }
143
+ else
144
+ debug "adding #{req} to send_queue \n #{dump_state}"
145
+ context = req
146
+ @send_qm.synchronize { send_queue << req }
147
+ end
148
+ ContextWorker.new(context, self)
149
+ end
150
+
151
+ def expect(name, opts = {}, &block)
152
+ debug "Expecting to get response #{name} with context #{opts[:context]}"
153
+ unless opts[:context].blank?
154
+ if opts[:context].is_a?(Processor)
155
+ context = opts[:context].chain(name, &block)
156
+ elsif opts[:context].is_a?(Request)
157
+ context = Processor.new(name, :context => opts[:context], &block)
158
+ @mutex.synchronize { processors << context }
159
+ end
160
+ else
161
+ context = Processor.new(name, &block)
162
+ @mutex.synchronize { processors << context }
163
+ end
164
+ ContextWorker.new(context, self)
165
+ end
166
+
167
+ def response(name, data = {})
168
+ info "Got response #{name} (#{data.to_json})..."
169
+ @mutex.synchronize { events_queue << Response.new(name, data) }
170
+ end
171
+
172
+ def perform!
173
+ while !all_events_caught?
174
+ while !send_queue.blank?
175
+ req = nil
176
+ @send_qm.synchronize { req = send_queue.shift }
177
+ debug "sending request #{req.name}..."
178
+ smart_fox.send(req.to_extension_request) unless smart_fox.blank?
179
+ @last_act = Time.now.to_i
180
+ end
181
+ process_events
182
+ check_timeouts
183
+ end
184
+ end
185
+
186
+ def all_events_caught?
187
+ processors.blank? || processors.collect { |p| p.mandatory? }.blank?
188
+ end
189
+
190
+ def wait_all_events_caught
191
+ debug "Waiting all events being caught..."
192
+ begin
193
+ wait_with_timeout { all_events_caught? }
194
+ rescue WaitTimeoutException => e
195
+ raise "Failed to catch all the events:"+ dump_state
196
+ end
197
+ end
198
+
199
+ private
200
+
201
+ def dump_state
202
+ "events_queue = \n\t-#{events_queue.join("\n\t-")}" +
203
+ " \n processors = \n\t-#{processors.join("\n\t-")}" +
204
+ " \n send_queue = \n\t-#{send_queue.join("\n\t-")}"
205
+ end
206
+
207
+ def check_timeouts
208
+ if !@last_act.blank? && Time.now.to_i > @last_act + opts[:timeout]
209
+ raise "Worker timeout! Latest interaction was #{Time.now.to_i - @last_act} sec ago!\n #{dump_state}"
210
+ end
211
+ end
212
+
213
+ def process_events
214
+ wait_with_timeout { !events_queue.blank? } rescue nil
215
+ ei = 0
216
+ debug "Processing events..."
217
+ while ei < events_queue.size
218
+ event = events_queue[ei]
219
+ pi = 0
220
+ debug "Processing event #{event.name}..."
221
+ while pi < processors.size
222
+ processor = processors[pi]
223
+ debug "Trying processor #{processor.name}..."
224
+ if processor.event(event.name, event.data)
225
+ @last_act = Time.now.to_i
226
+ debug "Processor found #{processor}"
227
+ @mutex.synchronize { events_queue.delete_at(ei) }
228
+ ei -= 1
229
+ if processor.completed?
230
+ debug "Processor completed #{processor.name}."
231
+ @mutex.synchronize { processors.delete_at(pi) }
232
+ pi -= 1
233
+ end
234
+ end
235
+ pi += 1
236
+ end
237
+ ei += 1
238
+ end
239
+ debug "Events processing finished. #{dump_state}"
240
+ end
241
+
242
+ def debug(msg)
243
+ puts "[#{time}] DEBUG #{msg}" if opts[:debug]
244
+ end
245
+
246
+ def info(msg)
247
+ puts "[#{time}] INFO #{msg}"
248
+ end
249
+
250
+ def time
251
+ Time.now.strftime("%Y-%m-%d %H:%M:%S")
252
+ end
253
+ end
254
+ end
255
+
256
+
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'ostruct'
3
+ require 'pathname'
4
+ Dir[Pathname.new(File.dirname(File.expand_path(__FILE__))).join("#{File.basename(__FILE__)}").join("*.rb")].each { |f| require f }
5
+
6
+ ####################################################
7
+ # Main module
8
+ module SmartfoxJruby
9
+ # configurable constants
10
+ VERSION = "0.2"
11
+
12
+
13
+ end
14
+
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smartfox_jruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: '0.2'
6
+ platform: java
7
+ authors:
8
+ - Ilya Sadykov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 3.2.8
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.2.8
27
+ none: false
28
+ prerelease: false
29
+ type: :runtime
30
+ - !ruby/object:Gem::Dependency
31
+ name: json
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: !binary |-
37
+ MA==
38
+ none: false
39
+ requirement: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: !binary |-
44
+ MA==
45
+ none: false
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.10.0
55
+ none: false
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 2.10.0
61
+ none: false
62
+ prerelease: false
63
+ type: :runtime
64
+ - !ruby/object:Gem::Dependency
65
+ name: doubleshot
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: !binary |-
71
+ MA==
72
+ none: false
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: !binary |-
78
+ MA==
79
+ none: false
80
+ prerelease: false
81
+ type: :development
82
+ description: |2
83
+ Allows to connect and easily process messages from and to SmartFox game server
84
+ email: smecsia@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Doubleshot
90
+ - lib/smartfox_jruby/common.rb
91
+ - lib/smartfox_jruby/sfs_adapter.rb
92
+ - lib/smartfox_jruby/sfs_runner.rb
93
+ - lib/smartfox_jruby/sfs_worker.rb
94
+ - lib/smartfox_jruby.rb
95
+ homepage: https://github.com/smecsia/smartfox_jruby
96
+ licenses:
97
+ - Apache 2.0
98
+ post_install_message:
99
+ rdoc_options:
100
+ - "--line-numbers"
101
+ - "--main"
102
+ - README.textile
103
+ - "--title"
104
+ - smartfox_jruby Documentation
105
+ - lib
106
+ - README.textile
107
+ require_paths:
108
+ - lib
109
+ - target
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: !binary |-
115
+ MA==
116
+ none: false
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: !binary |-
122
+ MA==
123
+ none: false
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.24
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Smartfox client for jruby
130
+ test_files: []