ang 9.19.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.txt +88 -0
- data/README.md +86 -0
- data/Rakefile.rb +228 -0
- data/Star.bmp +0 -0
- data/Star.png +0 -0
- data/Starfighter.bmp +0 -0
- data/Starfighter2.bmp +0 -0
- data/VERSION +1 -0
- data/ang.gemspec +48 -0
- data/bin/ang +5 -0
- data/bin/angm +5 -0
- data/bin/angm_net_test +3 -0
- data/commit.rb +11 -0
- data/main.rb +379 -0
- data/main_screencast.rb +324 -0
- data/net/Star.bmp +0 -0
- data/net/Starfighter.bmp +0 -0
- data/net/agent.rb +339 -0
- data/net/essai.rb +10 -0
- data/net/missile.rb +51 -0
- data/net/multicast_test.rb +74 -0
- data/net/net.rb +199 -0
- data/net/player.rb +166 -0
- data/net/star.rb +76 -0
- data/net/tools.rb +58 -0
- metadata +93 -0
data/net/Star.bmp
ADDED
Binary file
|
data/net/Starfighter.bmp
ADDED
Binary file
|
data/net/agent.rb
ADDED
@@ -0,0 +1,339 @@
|
|
1
|
+
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
###########################################################################
|
3
|
+
# agent.rb : planetoide game multi player
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
# install ruby
|
6
|
+
# install Gosu > gem install gosu
|
7
|
+
# download this > gem install ang
|
8
|
+
# run > angm
|
9
|
+
###########################################################################
|
10
|
+
if RUBY_VERSION >= "2.0.0"
|
11
|
+
puts "Sorry, not ready for ruiby 2..."
|
12
|
+
exit(0)
|
13
|
+
end
|
14
|
+
require 'thread'
|
15
|
+
require 'timeout'
|
16
|
+
begin
|
17
|
+
require 'gosu'
|
18
|
+
rescue Exception => e
|
19
|
+
puts "Not completly installed !\nPlease do : \n> gem install gosu"
|
20
|
+
sleep(3)
|
21
|
+
exit(0)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
##################### Tuning ##########################
|
26
|
+
|
27
|
+
KK= 0.5
|
28
|
+
KKI= KK / 1
|
29
|
+
SX=1280 / KK # window size width
|
30
|
+
SY=900 / KK # height
|
31
|
+
|
32
|
+
$INITIALE_SCORE=3000
|
33
|
+
$NB_STAR=55
|
34
|
+
$RANGE_STAR_SIZE=(10..50) # more planet / bigger planets ==>> harder game!
|
35
|
+
$NET_TRANSMIT=80
|
36
|
+
$NB_PLANET=6
|
37
|
+
$NB_PL=$NB_STAR+$NB_PLANET
|
38
|
+
$ACCELERATION_WHEIGHT=2
|
39
|
+
|
40
|
+
#######################################################
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
$id=((Time.now.to_f*1000).to_i)* 100 + rand(100)
|
45
|
+
sleep(0.01*($id%100))
|
46
|
+
Thread.abort_on_exception=true
|
47
|
+
|
48
|
+
STDOUT.sync=true
|
49
|
+
def log(*txt) puts "%-80s | %s" % [txt.join(" "),caller[0].to_s.split(':in',2)[0]] end
|
50
|
+
|
51
|
+
|
52
|
+
require_relative 'tools.rb'
|
53
|
+
require_relative 'net.rb'
|
54
|
+
require_relative 'star.rb'
|
55
|
+
require_relative 'player.rb'
|
56
|
+
require_relative 'missile.rb'
|
57
|
+
|
58
|
+
|
59
|
+
###########################################################################
|
60
|
+
# W i n d o w
|
61
|
+
###########################################################################
|
62
|
+
|
63
|
+
class GameWindow < Gosu::Window
|
64
|
+
attr_reader :star,:ping
|
65
|
+
def initialize
|
66
|
+
super((SX*KKI).to_i, (SY*KKI).to_i, false)
|
67
|
+
# "KbRangeBegin", "KbEscape", "KbF1",..., "KbF12", "Kb1", ... "Kb0", "KbA",... "KbZ",
|
68
|
+
# "KbTab", "KbReturn", "KbSpace", "KbLeftShift", "KbRightShift", "KbLeftControl",
|
69
|
+
# "KbRightControl", "KbLeftAlt", "KbRightAlt", "KbLeftMeta", "KbRightMeta",
|
70
|
+
# "KbBackspace", "KbLeft", "KbRight", "KbUp", "KbDown", "KbHome", "KbEnd",
|
71
|
+
# "KbInsert", "KbDelete", "KbPageUp", "KbPageDown", "KbEnter", "KbNumpad1", ... "KbNumpad0",
|
72
|
+
# "KbNumpadAdd", "KbNumpadSubtract", "KbNumpadMultiply", "KbNumpadDivide",
|
73
|
+
# "KbRangeEnd", "KbNum"]
|
74
|
+
|
75
|
+
@text_field = Gosu::TextInput.new()
|
76
|
+
@text_field.text = "Input..."
|
77
|
+
self.text_input=@text_field
|
78
|
+
@comment=""
|
79
|
+
|
80
|
+
self.caption = "Gosu Tutorial Game"
|
81
|
+
@player_anim= Gosu::Image::load_tiles(self, "Starfighter.bmp", 50,50, false)
|
82
|
+
|
83
|
+
@lp=[]; 100.times { x=rand(SX) ; y=rand(SY); @lp<<x;@lp<<y }
|
84
|
+
@players={}
|
85
|
+
|
86
|
+
@player = Player.new(self,@player_anim,true)
|
87
|
+
@player.warp(SX*KKI/2,SY*KKI/2)
|
88
|
+
|
89
|
+
@font = Gosu::Font.new(self, Gosu::default_font_name, (20/KK).round)
|
90
|
+
@font2 = Gosu::Font.new(self, Gosu::default_font_name, (40/KK).round)
|
91
|
+
|
92
|
+
@star_anim = Gosu::Image::load_tiles(self, "Star.bmp", 100,100, false)
|
93
|
+
|
94
|
+
@ping=0
|
95
|
+
@start=0
|
96
|
+
@mouse=nil
|
97
|
+
self.go("Multiplayer version, in development ! Start")
|
98
|
+
NetClient.init(self)
|
99
|
+
Thread.new {
|
100
|
+
sleep 3
|
101
|
+
if @players.size>0
|
102
|
+
master=@players.keys.sort.first
|
103
|
+
NetClient.connect() if master<$id
|
104
|
+
end
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
######################## Game global state
|
109
|
+
def egow(text)
|
110
|
+
@text=text
|
111
|
+
@start=@ping+800
|
112
|
+
go1(text)
|
113
|
+
end
|
114
|
+
def ego(text)
|
115
|
+
return if @ping < @start
|
116
|
+
@text=text
|
117
|
+
@start=@ping+200
|
118
|
+
Thread.new { sleep 4 ; self.go("Start...") }
|
119
|
+
end
|
120
|
+
def go(text)
|
121
|
+
display_comment "Avaler les points rouges, consommer le moins d'energie possible..."
|
122
|
+
@start=@ping+200
|
123
|
+
@text=text
|
124
|
+
go1(text)
|
125
|
+
end
|
126
|
+
def go1(text)
|
127
|
+
@stars = Array.new
|
128
|
+
@missiles=[]
|
129
|
+
@player.restart
|
130
|
+
@global_score=0
|
131
|
+
@touch={}
|
132
|
+
$NB_PLANET.times { @stars.push( Star.new(@stars,false,@star_anim) ) }
|
133
|
+
$NB_STAR.times { @stars.push( Star.new(@stars,true,@star_anim) ) }
|
134
|
+
if @players.size>0
|
135
|
+
NetClient.connect()
|
136
|
+
end
|
137
|
+
end
|
138
|
+
def pending?(d=0) (@start+d > @ping) end
|
139
|
+
|
140
|
+
def finish()
|
141
|
+
egow("Game Over...")
|
142
|
+
end
|
143
|
+
def looser() egow("Game Over") end
|
144
|
+
def winner(n)
|
145
|
+
return unless NetClient.is_master
|
146
|
+
NetClient.send_success()
|
147
|
+
ego("Success, Very good")
|
148
|
+
end
|
149
|
+
def receive_success(id)
|
150
|
+
ego("Success, Very good")
|
151
|
+
end
|
152
|
+
def receive_echec(id)
|
153
|
+
ego("Game over...")
|
154
|
+
end
|
155
|
+
def recho(*args) end
|
156
|
+
|
157
|
+
def send_positions(id)
|
158
|
+
stars=@stars.map { |s| s.get_pos() }
|
159
|
+
NetClient.send_position([id,stars])
|
160
|
+
end
|
161
|
+
def get_positions(id,data)
|
162
|
+
id_dest,stars=data
|
163
|
+
if id_dest==$id
|
164
|
+
stars.zip(@stars) { |pos,star| star.set_pos(pos) }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def star_deleted(index)
|
169
|
+
@stars.delete_if { |star| star.index() == index}
|
170
|
+
end
|
171
|
+
|
172
|
+
def init_player(id)
|
173
|
+
player = Player.new(self,@player_anim,false)
|
174
|
+
player.warp(320, 240)
|
175
|
+
@players[id]=player
|
176
|
+
end
|
177
|
+
def del_player(id) @players.delete(id) end
|
178
|
+
######################## Global interactions : mouse/keyboard
|
179
|
+
|
180
|
+
########### Server+client
|
181
|
+
|
182
|
+
def update_payers(id,data)
|
183
|
+
if @players[id]
|
184
|
+
@touch.delete(id) if @touch[id]
|
185
|
+
@players[id].update_by_net(data)
|
186
|
+
else
|
187
|
+
init_player(id)
|
188
|
+
@players[id].update_by_net(data)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
########### client
|
193
|
+
|
194
|
+
def button_down(id)
|
195
|
+
if id == Gosu::KbEscape
|
196
|
+
NetClient.is_stoping()
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def interactions_client()
|
201
|
+
k=nil
|
202
|
+
(@player.turn_left;k=Gosu::KbLeft) if button_down? Gosu::KbLeft or button_down? Gosu::GpLeft
|
203
|
+
(@player.turn_right;k=Gosu::KbRight) if button_down? Gosu::KbRight or button_down? Gosu::GpRight
|
204
|
+
(@player.accelerate(true);k=Gosu::KbUp) if button_down? Gosu::KbUp or button_down? Gosu::GpButton0
|
205
|
+
(@player.accelerate(false);k=Gosu::KbDown)if button_down? Gosu::KbDown or button_down? Gosu::GpButton1
|
206
|
+
if @missiles.select {|m| m.local }.size<= 20
|
207
|
+
(@player.fire_missile();k=Gosu::KbNumpad0) if button_down? Gosu::KbNumpad0 or button_down? Gosu::KbInsert
|
208
|
+
end
|
209
|
+
if k==nil
|
210
|
+
@kbcars
|
211
|
+
end
|
212
|
+
end
|
213
|
+
def watchdog()
|
214
|
+
t=false
|
215
|
+
@touch.keys.each { |id| (t=true; @players.delete(id)) if @players[id] }
|
216
|
+
NetClient.reinit_master(@players.keys) if t
|
217
|
+
@players.keys.each { |id| @touch[id]=true }
|
218
|
+
end
|
219
|
+
def add_missile(m)
|
220
|
+
@missiles << m
|
221
|
+
end
|
222
|
+
def new_missile(data)
|
223
|
+
@missiles << Missile.new(self,@player_anim,false,*data)
|
224
|
+
end
|
225
|
+
def end_missile(id)
|
226
|
+
@missiles.reject! {|m| m.id==id}
|
227
|
+
end
|
228
|
+
######################## Global draw : update()/draw() are invoked continuously by Gosu engine
|
229
|
+
|
230
|
+
def update()
|
231
|
+
@ping+=1
|
232
|
+
watchdog() if @ping%60==0
|
233
|
+
@player.clear()
|
234
|
+
NetClient.event_invoke()
|
235
|
+
now=Time.now.to_f
|
236
|
+
@players.each { |id,pl| pl.move(@stars,now) } if @player.score>0
|
237
|
+
@stars.each { |star| star.move(self,@stars) }
|
238
|
+
return if @ping<@start
|
239
|
+
missiles_behavior(now)
|
240
|
+
|
241
|
+
if @player.score>0
|
242
|
+
interactions_client()
|
243
|
+
@player.move(@stars,now)
|
244
|
+
@player.collect_stars(@stars)
|
245
|
+
end
|
246
|
+
@global_score=@player.score+@players.values.inject(0) { |sum,pl| (sum+pl.score) }
|
247
|
+
winner(@global_score) if 0 == (@stars.select { |s| s.type }.size )
|
248
|
+
end
|
249
|
+
def missiles_behavior(now)
|
250
|
+
@missiles.reject! do |m|
|
251
|
+
next(true) if m.move(@stars,now)
|
252
|
+
m.draw(self,@stars)
|
253
|
+
next(false ) unless m.local
|
254
|
+
if m.collision_players(@player)
|
255
|
+
NetClient.end_missile([m.id])
|
256
|
+
@player.dead
|
257
|
+
true
|
258
|
+
elsif idpl=@players.detect {|id,player| m.collision_players(player) }
|
259
|
+
NetClient.end_missile([m.id])
|
260
|
+
idpl[1].dead
|
261
|
+
true
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def draw
|
267
|
+
scale(KKI,KKI) {
|
268
|
+
draw_background
|
269
|
+
@players.each {|id,p| p.draw(self,@stars) }
|
270
|
+
@player.draw(self,@stars)
|
271
|
+
@stars.each { |star| star.draw() }
|
272
|
+
@missiles.each { |m| m.draw(self,@stars) }
|
273
|
+
draw_variable_background()
|
274
|
+
}
|
275
|
+
end
|
276
|
+
def draw_background
|
277
|
+
@lp.each_slice(2) do |x,y|
|
278
|
+
draw_triangle(
|
279
|
+
x, y, 0xAAFFFFFF,
|
280
|
+
x+(4..8).rand, y+(4..8).rand, 0xAAFFFFFF,
|
281
|
+
x+(4..8).rand, y, 0xAAFFFFFF)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
def draw_text(text,option)
|
285
|
+
w=option[:font].text_width(@text, option[:scale])
|
286
|
+
h=10*option[:scale];
|
287
|
+
option[:font].draw(text,
|
288
|
+
option[:x]<0 ? -option[:x] : (option[:x]-w/2),
|
289
|
+
option[:y]<0 ? -option[:y] : (option[:y]-h/2),
|
290
|
+
ZOrder::UI,
|
291
|
+
option[:scale],option[:scale],option[:color])
|
292
|
+
end
|
293
|
+
def draw_variable_background()
|
294
|
+
if @ping<@start
|
295
|
+
draw_text(@text+ " ! !",x: SX/2,y: SY/2,scale: 1,color: 0xf0f0f000,font: @font2)
|
296
|
+
draw_text("",x: 10,y: 10,scale: 1,color: 0xffffff00,font: @font)
|
297
|
+
else
|
298
|
+
#----------- barr graph energies reserve level
|
299
|
+
h=5+(@player.score/2000.0)*(SY-10)
|
300
|
+
draw_quad(5, 5, 0xBB55FF55, 20/KK, 5, 0xBB55FF55, 20/KK, h, 0xBBFFFF55, 5 , h , 0xBBFFFF55)
|
301
|
+
i=2
|
302
|
+
@players.each { |id,player|
|
303
|
+
h=5+(player.score/2000.0)*(SY-10)
|
304
|
+
draw_quad(
|
305
|
+
20/KK*i , 5, 0xBB55FF55,
|
306
|
+
20/KK*(i+1), 5, 0xBB55FF55,
|
307
|
+
20/KK*(i+1), h, 0xBBFF9090+i*0x1010,
|
308
|
+
20/KK*i , h , 0xBBFF9090+i*0x1010)
|
309
|
+
i+=1
|
310
|
+
}
|
311
|
+
|
312
|
+
#------------ textual energie reserve level
|
313
|
+
draw_text("Global Score: #{@global_score}", x: -25/KK,y: 10/KK,scale: 1,color: 0xffffff00,font: @font)
|
314
|
+
#------------ is Master
|
315
|
+
if NetClient.is_master
|
316
|
+
draw_text("Master", x: 25/KK,y: 20/KK,scale: 1,color: 0xffffff00,font: @font)
|
317
|
+
end
|
318
|
+
#----------------- Input
|
319
|
+
if @comment.size>0
|
320
|
+
draw_text(@comment, x: SX/2,y: SY-100,scale: 1,color: 0xffeeeeee,font: @font)
|
321
|
+
end
|
322
|
+
s=@text_field.text
|
323
|
+
if s && s.size>0
|
324
|
+
if s =~/\.$/
|
325
|
+
@text_field.text=""
|
326
|
+
NetClient.comment(s[0..-1])
|
327
|
+
end
|
328
|
+
draw_text("Input (end with '.') : "+ s,x: SX/4,y: SY-100,scale: 1,color: 0xffeeeeee,font: @font)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
def display_comment(text)
|
333
|
+
@comment=text
|
334
|
+
Thread.new { sleep 10; @comment="" }
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
$game=GameWindow.new
|
339
|
+
$game.show
|
data/net/essai.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require '../../utils.rb'
|
2
|
+
require 'zlib'
|
3
|
+
message = (0..100).to_a.map { |i| i**2*1.1234}.inspect.gsub(", ",",")
|
4
|
+
p message.size
|
5
|
+
p message[0..100]
|
6
|
+
message1=""
|
7
|
+
1.upto(9) { |level|
|
8
|
+
n=chrono(nil,100) { message1= Zlib::Deflate.new(level).deflate(message, Zlib::FINISH) }
|
9
|
+
puts "#{message1.size} #{level} #{n}"
|
10
|
+
}
|
data/net/missile.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
###########################################################################
|
3
|
+
# P l a y e r
|
4
|
+
###########################################################################
|
5
|
+
class Missile < Player
|
6
|
+
def initialize(window,animation,local,id,x,y,vx,vy,weight)
|
7
|
+
super(window,animation,local)
|
8
|
+
@id=id if id
|
9
|
+
@age=0
|
10
|
+
@r=weight
|
11
|
+
@vangle = 0.0
|
12
|
+
@angle=Math.atan2(vx,vy)
|
13
|
+
@x,@y,@vel_x,@vel_y = x,y,vx,vy
|
14
|
+
@vx,@vy=[0,0]
|
15
|
+
@now=Time.now.to_f * 1000
|
16
|
+
@top=0
|
17
|
+
@app.add_missile(self)
|
18
|
+
NetClient.new_missile([@id,x,y,vx,vy,weight]) unless id
|
19
|
+
end
|
20
|
+
def clear() @pos=5 end
|
21
|
+
def restart() end
|
22
|
+
|
23
|
+
def warp(x, y) @x, @y = x, y ; end
|
24
|
+
|
25
|
+
def move(stars,now)
|
26
|
+
@age+=1
|
27
|
+
return(true) if @x >= SX+@r || @x+@r <= 0 || @y+@r >= SY || @y+@r <= 0
|
28
|
+
vx,vy=newton(stars)
|
29
|
+
@vel_x+=vx
|
30
|
+
@vel_y+=vy
|
31
|
+
@vel_x.minmax(-50,+50)
|
32
|
+
@vel_y.minmax(-50,+50)
|
33
|
+
@x += @vel_x
|
34
|
+
@y += @vel_y
|
35
|
+
@angle=Math.atan2(@vel_y,@vel_x)
|
36
|
+
n=now*1000
|
37
|
+
@now=now
|
38
|
+
dead if local && stars.any? { |star| ! star.type && Gosu::distance(@x, @y, star.x, star.y) < (15+star.r)/2 }
|
39
|
+
return(false)
|
40
|
+
end
|
41
|
+
def update_by_net(data) end
|
42
|
+
def draw(app,stars)
|
43
|
+
img = @animation[@local ? 8 : 9]
|
44
|
+
img.draw_rot(@x, @y, ZOrder::Player, 90.0+@angle*180.0/3.14159)
|
45
|
+
end
|
46
|
+
# test missile collision with some player(s)
|
47
|
+
def collision_players(player)
|
48
|
+
@age>(60*5) && local && Gosu::distance(@x, @y, player.x, player.y) < (7+player.r)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
|
2
|
+
###########################################################################
|
3
|
+
# multicast_test.rb : CLI tool for checking angm multicast communications
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
# Usage
|
6
|
+
# term1> ruby multi_cast_text.rb
|
7
|
+
# temr2> ruby multi_cast_text.rb
|
8
|
+
# otherhost> ruby multi_cast_text.rb
|
9
|
+
###########################################################################
|
10
|
+
require 'thread'
|
11
|
+
require 'timeout'
|
12
|
+
require_relative 'net.rb'
|
13
|
+
|
14
|
+
|
15
|
+
$id=((Time.now.to_f*1000).to_i)* 100 + rand(100)
|
16
|
+
Thread.abort_on_exception=true
|
17
|
+
|
18
|
+
STDOUT.sync=true
|
19
|
+
def log(*txt) puts "%-80s " % [txt.join(" ")] end
|
20
|
+
|
21
|
+
|
22
|
+
puts <<EEND
|
23
|
+
*****************************************************
|
24
|
+
Multicast Test
|
25
|
+
|
26
|
+
Checking Multicast group used by ANGM :
|
27
|
+
MULTICAST_ADDR = #{MCast::MULTICAST_ADDR}
|
28
|
+
PORT = #{MCast::PORT}
|
29
|
+
Interface = #{MCast::BIND_ADDR}
|
30
|
+
|
31
|
+
If multicast do not work :
|
32
|
+
* check your route table, a entry should exist on 224.0.0.0
|
33
|
+
* check if virtual host are configured,
|
34
|
+
* check multihoming (alias ip)
|
35
|
+
if host ip showed in trace is not a ip binded in your physical
|
36
|
+
interface, your multicast will work strangly...
|
37
|
+
|
38
|
+
My ID is #{$id}. this value is second parameter of
|
39
|
+
each message sended/received (startup time in ms * 100 + random(100)
|
40
|
+
hoping ot will be unic on the network...
|
41
|
+
|
42
|
+
*****************************************************
|
43
|
+
|
44
|
+
EEND
|
45
|
+
sleep 4
|
46
|
+
class App
|
47
|
+
def initialize
|
48
|
+
NetClient.init(self)
|
49
|
+
NetClient.set_trace(true)
|
50
|
+
Thread.new { loop { NetClient.wait_and_invoke() } }
|
51
|
+
Thread.new {
|
52
|
+
loop {
|
53
|
+
#NetClient.connect()
|
54
|
+
log "\n\Sending echo..."
|
55
|
+
NetClient.echo([$id,(Time.now.to_f*1000).to_i])
|
56
|
+
sleep 4
|
57
|
+
}
|
58
|
+
}
|
59
|
+
Thread.new { sleep 4 ; puts "\n\nEnd Traces\n\n"; NetClient.set_trace(false) }
|
60
|
+
end
|
61
|
+
def method_missing(name,*args)
|
62
|
+
if name==:recho
|
63
|
+
id_sender,id_demander,time=*args
|
64
|
+
log("Echo timing for #{id_sender} : #{(Time.now.to_f*1000).to_i - time} ms") if id_demander==$id
|
65
|
+
else
|
66
|
+
log(("%15s : %s" % ["<#{name}>",args.inspect])[0..100]) if name!=:move && name!=:update_payers
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
app=App.new
|
72
|
+
sleep
|
73
|
+
|
74
|
+
|