Class: GameMachine::GameSystems::TeamManager

Inherits:
Actor::Base
  • Object
show all
Includes:
Commands, Models
Defined in:
server/lib/game_machine/game_systems/team_manager.rb

Constant Summary

Constants inherited from Actor::Base

Actor::Base::ON_RECEIVE_HOOKS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Commands

#commands

Methods inherited from Actor::Base

aspect, aspects, find, find_by_address, find_distributed, find_distributed_local, find_remote, hashring, local_path, logger, model_filter, #onReceive, player_controller, #receive_message, #schedule_message, #schedule_message_once, #sender, set_player_controller

Instance Attribute Details

#team_handlerObject (readonly)

Returns the value of attribute team_handler


7
8
9
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 7

def team_handler
  @team_handler
end

Class Method Details

.match_id_for(team_names) ⇒ Object


14
15
16
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 14

def self.match_id_for(team_names)
  team_names.sort.join('_')
end

Instance Method Details

#can_add_member?(team_name, player_id) ⇒ Boolean

Returns:

  • (Boolean)

90
91
92
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 90

def can_add_member?(team_name,player_id)
  team_handler.can_add_member?(team_name, player_id)
end

#can_create_team?(team_name, player_id) ⇒ Boolean

Returns:

  • (Boolean)

94
95
96
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 94

def can_create_team?(team_name,player_id)
  team_handler.can_create_team?(team_name, player_id)
end

#chat_channel(topic, flags) ⇒ Object


18
19
20
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 18

def chat_channel(topic,flags)
  MessageLib::ChatChannel.new.set_name(topic).set_flags(flags)
end

#create_player_team(team_name, player_id) ⇒ Object


50
51
52
53
54
55
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 50

def create_player_team(team_name,player_id)
  player_team_id = "player_team_#{player_id}"
  player_team = PlayerTeam.new(:id => player_team_id, :name => team_name)
  scope(player_team)
  player_team.save
end

#create_team(message) ⇒ Object


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 120

def create_team(message)

  # no team name that equals player name
  if player_exists?(message.name)
    return false
  end

  # reserved key
  if message.name == 'teams'
    return false
  end

  unless can_create_team?(message.name,message.player_id)
    return false
  end

  if team = Team.find(scope_key(message.name))
    send_team_joined(team.name,message.player_id)
    return false
  end

  message.max_members ||= default_max_members

  min_for_match = message.min_for_match >= 1 ? message.min_for_match : 1
  
  team = Team.new(
    :id => message.name,
    :team_id => team_id(message.name),
    :name => message.name,
    :owner => message.owner,
    :access => message.access,
    :max_members => message.max_members,
    :min_for_match => min_for_match,
    :destroy_on_owner_leave => destroy_on_owner_leave?,
    :members => [message.owner],
    :locked => false,
    :requirements => message.requirements
  )

  create_player_team(team.name,message.player_id)
  if team.access == 'private'
    team.invite_id = Uniqueid.generate_token(team.name)
  end

  scope(team)
  team.save
  commands.datastore.call_dbproc(:team_add_team,scope_key('teams'),team.to_storage_entity,false)
  join_chat(team.name,team.owner)
  send_team_joined(team.name,message.player_id)
  team_handler.team_created(team,message)
  handler_update_teams
end

#default_max_membersObject


86
87
88
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 86

def default_max_members
  100
end

#define_update_procsObject


474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 474

def define_update_procs
  commands.datastore.define_dbproc(:team_update_team) do |id,current_entity,update_entity|
    if current_entity.nil?
      teams = Teams.new(:teams => [],:id => id)
    else
      teams = Teams.from_entity(current_entity,:json_storage)
    end

    team = Team.from_entity(update_entity,:json_storage)
    team_to_update = teams.teams.select {|t| t.name == team.name}.first
    if team_to_update
      teams.teams.delete_if {|t| t.name == team.name}
      teams.teams << team
    end
    teams.to_storage_entity
  end

  commands.datastore.define_dbproc(:team_add_team) do |id,current_entity,update_entity|
    if current_entity.nil?
      teams = Teams.new(:teams => [],:id => id)
    else
      teams = Teams.from_entity(current_entity,:json_storage)
    end

    team = Team.from_entity(update_entity,:json_storage)
    teams.teams.delete_if {|t| t.name == team.name}
    teams.teams << team
    teams.to_storage_entity
  end

  commands.datastore.define_dbproc(:team_remove_team) do |id,current_entity,update_entity|
    if current_entity.nil?
      teams = Teams.new(:teams => [],:id => id)
    else
      teams = Teams.from_entity(current_entity,:json_storage)
    end

    team = Team.from_entity(update_entity,:json_storage)
    teams.teams.delete_if {|t| t.name == team.name}
    teams.to_storage_entity
  end

end

#destroy_on_owner_leave?Boolean

Returns:

  • (Boolean)

102
103
104
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 102

def destroy_on_owner_leave?
  team_handler.destroy_on_owner_leave?
end

#destroy_player_team(player_id) ⇒ Object


74
75
76
77
78
79
80
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 74

def destroy_player_team(player_id)
  player_team_id = "player_team_#{player_id}"
  if player_team = PlayerTeam.find(scope_key(player_team_id))
    scope(player_team)
    player_team.destroy
  end
end

#destroy_team(message, force = false) ⇒ Object


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 184

def destroy_team(message,force=false)
  if team = Team.find(scope_key(message.name))
    if team.owner == message.player_id || force
      team.members.each do |member|
        leave_chat(message.name,member)
        destroy_player_team(member)
        send_team_left(team.name,member)
      end
      commands.datastore.call_dbproc(:team_remove_team,scope_key('teams'),team.to_storage_entity,false)
      scope(team)
      team.destroy
      handler_update_teams

      # team destroyed ends match
      if team.match_id
        end_match(EndMatch.new(:match_id => team.match_id))
      end
    end
  end
  unless force
    send_team_left(message.name,message.player_id)
  end
end

#end_match(message) ⇒ Object


324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 324

def end_match(message)
  if message.player_id
    return
  end

  if match = Match.find(message.match_id)
    match.teams.each do |team|
      if team = Team.find(scope_key(team.name))
        team.match_id = nil
        scope(team)
        team.save
      end
    end
    match.destroy
  end
end

#find_match(message) ⇒ Object


384
385
386
387
388
389
390
391
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 384

def find_match(message)
  if team = Team.find(scope_key(message.team_name))
    if s = handler_find_match(team)
      self.class.logger.debug "Match found: #{s}"
      start_match(s)
    end
  end
end

#flagsObject


26
27
28
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 26

def flags
  'subscribers'
end

#game_id(player_id) ⇒ Object


408
409
410
411
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 408

def game_id(player_id)
  player_service = GameMachine::JavaLib::PlayerService.get_instance
  player_service.get_game_id(player_id)
end

#handler_find_match(team) ⇒ Object


110
111
112
113
114
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 110

def handler_find_match(team)
  if teams = Teams.find(scope_key('teams'))
    team_handler.match!(teams,team)
  end
end

#handler_match_started(match) ⇒ Object


116
117
118
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 116

def handler_match_started(match)
  team_handler.match_started(match)
end

#handler_teams_filter(teams, teams_request) ⇒ Object


106
107
108
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 106

def handler_teams_filter(teams,teams_request)
  team_handler.teams_filter(teams,teams_request)
end

#handler_update_teamsObject


98
99
100
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 98

def handler_update_teams
  team_handler.update_teams(scope_key('teams'))
end

#join_chat(topic, player_id) ⇒ Object


36
37
38
39
40
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 36

def join_chat(topic,player_id)
  join_chat = MessageLib::JoinChat.new.add_chat_channel(chat_channel(topic,flags))
  entity = player_entity(player_id).set_join_chat(join_chat)
  ChatManager.find.tell(entity)
end

#join_team(message, invite_accepted = false) ⇒ Object


230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 230

def join_team(message,invite_accepted=false)
  unless can_add_member?(message.name,message.player_id)
    return false
  end

  if team = Team.find(scope_key(message.name))

    if team.locked
      return
    end

    if (team.max_members.nil? || team.max_members == 0)
      team.max_members = default_max_members
    end

    if team.members.size >= team.max_members
      return
    end

    if team.access == 'public' || invite_accepted
      unless team.members.include?(message.player_id)
        team.members << message.player_id
        scope(team)
        team.save
        create_player_team(team.name,message.player_id)
        commands.datastore.call_dbproc(:team_update_team,scope_key('teams'),team.to_storage_entity,false)
      end
      join_chat(team.name,message.player_id)
      send_team_joined(message.name,message.player_id)
    end
  end
end

#leave_chat(topic, player_id) ⇒ Object


30
31
32
33
34
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 30

def leave_chat(topic,player_id)
  leave_chat = MessageLib::LeaveChat.new.add_chat_channel(chat_channel(topic,flags))
  entity = player_entity(player_id).set_leave_chat(leave_chat)
  ChatManager.find.tell(entity)
end

#leave_team(message) ⇒ Object


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 263

def leave_team(message)
  if team = Team.find(scope_key(message.name))
    if message.player_id == team.owner && destroy_on_owner_leave?
      destroy_team(
        DestroyTeam.new(
          :name => team.name,
          :player_id => message.player_id
        )
      )
      return
    end


    # Last member, just destroy
    if team.members.include?(message.player_id) && team.members.size == 1
      destroy_team(
        DestroyTeam.new(
          :name => team.name,
          :player_id => message.player_id
        ),
        true
      )
      return
    end

    team.members.delete_if {|member| member == message.player_id}

    # Reassign owner if they leave
    if team.owner == message.player_id
      team.owner = team.members.first
    end

    scope(team)
    team.save

    commands.datastore.call_dbproc(:team_update_team,scope_key('teams'),team.to_storage_entity,false)
    destroy_player_team(message.player_id)
    send_team_left(message.name,message.player_id)
    leave_chat(message.name,message.player_id)
  else
    send_team_left(message.name,message.player_id)
  end
end

#lock_team(message) ⇒ Object


208
209
210
211
212
213
214
215
216
217
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 208

def lock_team(message)
  if team = Team.find(scope_key(message.name))
    if team.owner == message.player_id
      team.locked = true
      scope(team)
      team.save
      commands.datastore.call_dbproc(:team_update_team,scope_key('teams'),team.to_storage_entity,false)
    end
  end
end

#member_disconnected(message) ⇒ Object


173
174
175
176
177
178
179
180
181
182
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 173

def member_disconnected(message)
  player_team_id = "player_team_#{message.player_id}"
  if player_team = PlayerTeam.find(scope_key(player_team_id))
    leave = LeaveTeam.new(
      :name => player_team.name,
      :player_id => message.player_id
    )
    leave_team(leave)
  end
end

#on_receive(message) ⇒ Object


418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 418

def on_receive(message)
  if message.respond_to?(:player_id)
    @player_id = message.player_id
  else
    @player_id = nil
  end

  if message.is_a?(CreateTeam)
    create_team(message)
    send_team(message)
  elsif message.is_a?(PlayerSkills)
    set_player_skills(message)
  elsif message.is_a?(LockTeam)
    lock_team(message)
  elsif message.is_a?(UnlockTeam)
    unlock_team(message)
  elsif message.is_a?(DestroyTeam)
    destroy_team(message)
  elsif message.is_a?(TeamInvite)
    team_invite(message)
  elsif message.is_a?(TeamAcceptInvite)
    team_accept_invite(message)
  elsif message.is_a?(JoinTeam)
    join_team(message)
    send_team(message)
  elsif message.is_a?(LeaveTeam)
    leave_team(message)
  elsif message.is_a?(TeamsRequest)
    teams_request(message)
  elsif message.is_a?(FindMatch)
    find_match(message)
  elsif message.is_a?(StartMatch)
    start_match(message)
  elsif message.is_a?(EndMatch)
    end_match(message)
  elsif message.is_a?(MessageLib::ClientManagerEvent)
    if message.event == 'disconnected'
      member_disconnected(message)
      self.class.logger.debug "#{self.class.name} #{message.player_id} removed from team(disconnected)"
    end
  else
    unhandled(message)
  end
end

#player_entity(player_id) ⇒ Object


22
23
24
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 22

def player_entity(player_id)
  MessageLib::Entity.new.set_player(MessageLib::Player.new.set_id(player_id))
end

#player_exists?(player_id) ⇒ Boolean

Returns:

  • (Boolean)

413
414
415
416
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 413

def player_exists?(player_id)
  player_service = GameMachine::JavaLib::PlayerService.get_instance
  player_service.find(player_id)
end

#post_init(*args) ⇒ Object


8
9
10
11
12
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 8

def post_init(*args)
  @team_handler = Application.config.handlers.team.constantize.new
  define_update_procs
  commands.misc.client_manager_register(self.class.name)
end

#scope(model) ⇒ Object


398
399
400
401
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 398

def scope(model)
  return if model.id.match(/\^\^/)
  model.id = "#{game_id(@player_id)}^^#{model.id}"
end

#scope_key(str) ⇒ Object


394
395
396
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 394

def scope_key(str)
  "#{game_id(@player_id)}^^#{str}"
end

#send_team(message) ⇒ Object


57
58
59
60
61
62
63
64
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 57

def send_team(message)
  player_team_id = "player_team_#{message.player_id}"
  if player_team = PlayerTeam.find(scope_key(player_team_id))
    if team = Team.find(scope_key(player_team.name))
      commands.player.send_message(team,message.player_id)
    end
  end
end

#send_team_joined(team_name, player_id) ⇒ Object


42
43
44
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 42

def send_team_joined(team_name,player_id)
  commands.player.send_message(TeamJoined.new(:name => team_name),player_id)
end

#send_team_left(team_name, player_id) ⇒ Object


46
47
48
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 46

def send_team_left(team_name,player_id)
  commands.player.send_message(TeamLeft.new(:name => team_name),player_id)
end

#set_player_skills(message) ⇒ Object


463
464
465
466
467
468
469
470
471
472
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 463

def set_player_skills(message)
  unless team_handler.player_can_set_skills?
    return
  end

  player_skills_id = "player_skills_#{message.player_id}"
  player_skills = PlayerSkills.new(:id => player_skills_id, :skills => message.skills.marshal_dump)
  scope(player_skills)
  player_skills.save
end

#start_match(message) ⇒ Object

Called internally or from another actor to start an already defined match


342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 342

def start_match(message)
  # Don't accept requests from clients
  if message.player_id
    return
  end

  match_id = self.class.match_id_for(message.team_names)
  if match = Match.find(match_id)
    self.class.logger.info "Match #{match_id} already created"
    return
  end

  teams = message.team_names.collect {|name| Team.find(scope_key(name))}.compact
  teams = teams.map {|team| unscope(team)}
  if teams.size != message.team_names.size
    self.class.logger.info "#{self.class.name} Unable to find all teams for match"
    return
  end

  server = Akka.instance.hashring.node_for(scope_key(match_id))
  server = server.sub('akka.tcp://[email protected]','').split(':').first

  match = Match.new(
    :id => match_id,
    :teams => teams,
    :server => server,
    :game_handler => message.game_handler
  )

  teams.each do |team|
    team.match_id = match_id
    team.match_server = server
    scope(team)
    team.save
    commands.datastore.call_dbproc(:team_update_team,scope_key('teams'),team.to_storage_entity,false)
  end

  match.save
  handler_match_started(match)
  self.class.logger.debug "Match #{match} started"
end

#team_accept_invite(message) ⇒ Object


316
317
318
319
320
321
322
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 316

def team_accept_invite(message)
  if team = Team.find(scope_key(message.name))
    if message.invite_id == team.invite_id
      join_team(JoinTeam.new(:name => team.name, :player_id => message.player_id),true)
    end
  end
end

#team_id(team_name) ⇒ Object


82
83
84
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 82

def team_id(team_name)
  Uniqueid.generate_token(team_name)
end

#team_invite(message) ⇒ Object


307
308
309
310
311
312
313
314
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 307

def team_invite(message)
  if team = Team.find(scope_key(message.name))
    if message.player_id == team.owner
      message.invite_id = team.invite_id
      commands.player.send_message(message,message.invitee)
    end
  end
end

#teams_request(message) ⇒ Object


66
67
68
69
70
71
72
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 66

def teams_request(message)
  if teams = Teams.find(scope_key('teams'))
    teams = handler_teams_filter(teams,message)
    commands.player.send_message(teams,message.player_id)
  end
  send_team(message)
end

#unlock_team(message) ⇒ Object


219
220
221
222
223
224
225
226
227
228
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 219

def unlock_team(message)
  if team = Team.find(scope_key(message.name))
    if team.owner == message.player_id
      team.locked = false
      scope(team)
      team.save
      commands.datastore.call_dbproc(:team_update_team,scope_key('teams'),team.to_storage_entity,false)
    end
  end
end

#unscope(model) ⇒ Object


403
404
405
406
# File 'server/lib/game_machine/game_systems/team_manager.rb', line 403

def unscope(model)
  model.id.sub!(/^#{game_id(@player_id)}\^\^/,'')
  model
end