smartfox_jruby 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+ gem 'jbundler', :git => 'https://github.com/mkristian/jbundler.git'
3
+
4
+ gem 'activesupport', '~> 3.2.8'
5
+ gem 'json'
6
+
7
+ group :test do
8
+ gem 'rspec', '~> 2.10.0'
9
+ end
data/Jarfile ADDED
@@ -0,0 +1,6 @@
1
+ repository :first, "http://artifactory-innovations.i-free.ru/artifactory/ext-release-local"
2
+
3
+ jar 'com.smartfox2x.client:sfs2x-client-core', '1.0.4'
4
+ jar 'com.smartfox2x.client:sfs2x-api-java', '1.0.4'
5
+ jar 'org.slf4j:slf4j-log4j12', '1.5.10'
6
+ #jar 'net.sf.json-lib:json-lib:jar:jdk5:2.2.3'
@@ -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.1"
11
+
12
+
13
+ end
14
+
@@ -0,0 +1,25 @@
1
+ require 'pathname'
2
+ require Pathname.new(File.dirname(File.expand_path(__FILE__))).join('lib/smartfox_jruby.rb')
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'smartfox_jruby'
6
+ s.version = SmartfoxJruby::VERSION
7
+ s.date = '2013-02-08'
8
+ s.authors = ["Ilya Sadykov"]
9
+ s.email = 'i.sadykov@gmail.com'
10
+ s.homepage = ""
11
+ s.summary = %q{Smartfox client for jruby}
12
+ s.description = %q{Allows to connect and easily process messages from and to SmartFox game server}
13
+
14
+ s.add_development_dependency 'rspec', '~> 2.10.0'
15
+ s.add_runtime_dependency 'activesupport', '~> 3.2.8'
16
+ s.add_runtime_dependency 'json'
17
+ s.add_runtime_dependency "jar 'org.slf4j:slf4j-api:1.5.10'"
18
+ s.add_runtime_dependency "jar 'com.smartfox2x.client:sfs2x-client-core:1.0.4'"
19
+ s.add_runtime_dependency "jar 'com.smartfox2x.client:sfs2x-api-java:1.0.4'"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
24
+ s.require_paths = %w(lib)
25
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smartfox_jruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: "0.1"
6
+ platform: ruby
7
+ authors:
8
+ - Ilya Sadykov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-02-08 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.10.0
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 3.2.8
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: jar 'org.slf4j:slf4j-api:1.5.10'
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: jar 'com.smartfox2x.client:sfs2x-client-core:1.0.4'
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :runtime
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: jar 'com.smartfox2x.client:sfs2x-api-java:1.0.4'
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :runtime
80
+ version_requirements: *id006
81
+ description: Allows to connect and easily process messages from and to SmartFox game server
82
+ email: i.sadykov@gmail.com
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files: []
88
+
89
+ files:
90
+ - Gemfile
91
+ - Jarfile
92
+ - lib/smartfox_jruby.rb
93
+ - lib/smartfox_jruby/common.rb
94
+ - lib/smartfox_jruby/sfs_adapter.rb
95
+ - lib/smartfox_jruby/sfs_runner.rb
96
+ - lib/smartfox_jruby/sfs_worker.rb
97
+ - smartfox_jruby.gemspec
98
+ homepage: ""
99
+ licenses: []
100
+
101
+ post_install_message:
102
+ rdoc_options: []
103
+
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: "0"
118
+ requirements: []
119
+
120
+ rubyforge_project:
121
+ rubygems_version: 1.8.24
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: Smartfox client for jruby
125
+ test_files: []
126
+