Class: ClientConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/game_2d/client_connection.rb

Overview

The client creates one of these. It is then used for all communication with the server.

Constant Summary collapse

ACTION_DELAY =

We tell the server to execute all actions this many ticks in the future, to give the message time to propagate around the fleet

6

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port, game, player_name, timeout = 2000) ⇒ ClientConnection

1/10 of a second



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/game_2d/client_connection.rb', line 17

def initialize(host, port, game, player_name, timeout=2000)
  # remote host address, remote host port, channels, download bandwidth, upload bandwidth
  @socket = _create_connection(host, port, 2, 0, 0)
  @game = game
  @player_name = player_name

  @socket.on_connection(method(:on_connect))
  @socket.on_disconnection(method(:on_close))
  @socket.on_packet_receive(method(:on_packet))

  @socket.connect(timeout)
end

Instance Attribute Details

#engineObject

Returns the value of attribute engine.



10
11
12
# File 'lib/game_2d/client_connection.rb', line 10

def engine
  @engine
end

#player_nameObject (readonly)

Returns the value of attribute player_name.



9
10
11
# File 'lib/game_2d/client_connection.rb', line 9

def player_name
  @player_name
end

Instance Method Details

#_create_connection(*args) ⇒ Object



30
31
32
# File 'lib/game_2d/client_connection.rb', line 30

def _create_connection(*args)
  ENet::Connection.new(*args)
end

#debug_packet(direction, hash) ⇒ Object



114
115
116
117
118
119
# File 'lib/game_2d/client_connection.rb', line 114

def debug_packet(direction, hash)
  return unless $debug_traffic
  at_tick = hash[:at_tick] || 'NO TICK'
  keys = hash.keys - [:at_tick]
  puts "#{direction} #{keys.join(', ')} <#{at_tick}>"
end

#disconnectObject



126
# File 'lib/game_2d/client_connection.rb', line 126

def disconnect; @socket.disconnect(200); end

#on_closeObject



40
41
42
43
# File 'lib/game_2d/client_connection.rb', line 40

def on_close
  puts "Client disconnected by server"
  @game.shutdown
end

#on_connectObject



34
35
36
37
38
# File 'lib/game_2d/client_connection.rb', line 34

def on_connect
  puts "Connected to server - sending handshake"
  # send handshake reliably
  send_record( { :handshake => { :player_name => @player_name } }, true)
end

#on_packet(data, channel) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/game_2d/client_connection.rb', line 45

def on_packet(data, channel)
  hash = JSON.parse(data).fix_keys
  debug_packet('Received', hash)

  pong = hash[:pong]
  if pong
    stop = Time.now.to_f
    puts "Ping took #{stop - pong[:start]} seconds"
  end

  at_tick = hash[:at_tick]
  fail "No at_tick in #{hash.inspect}" unless at_tick

  world = hash[:world]
  if world
    @engine.establish_world(world, at_tick)
  end

  delta_keys = [
    :add_players, :add_npcs, :delete_entities, :update_entities, :update_score, :move
  ]
  @engine.add_delta(hash) if delta_keys.any? {|k| hash.has_key? k}

  you_are = hash[:you_are]
  if you_are
    # The 'world' response includes deltas for add_players and add_npcs
    # Need to process those first, as one of the players is us
    @engine.apply_all_deltas(at_tick)

    @engine.create_local_player you_are
  end

  registry, highest_id = hash[:registry], hash[:highest_id]
  @engine.sync_registry(registry, highest_id, at_tick) if registry
end

#online?Boolean

Returns:

  • (Boolean)


125
# File 'lib/game_2d/client_connection.rb', line 125

def online?; @socket.online?; end

#send_actions_atObject



81
82
83
# File 'lib/game_2d/client_connection.rb', line 81

def send_actions_at
  @engine.tick + ACTION_DELAY
end

#send_create_npc(npc) ⇒ Object



94
95
96
97
98
# File 'lib/game_2d/client_connection.rb', line 94

def send_create_npc(npc)
  delta = { :at_tick => send_actions_at, :create_npc => npc }
  send_record delta
  @engine.add_delta delta
end

#send_move(move, args = {}) ⇒ Object



85
86
87
88
89
90
91
92
# File 'lib/game_2d/client_connection.rb', line 85

def send_move(move, args={})
  return unless move
  args[:move] = move.to_s
  delta = { :at_tick => send_actions_at, :move => args }
  send_record delta
  delta[:move][:player_id] = @engine.player_id
  @engine.add_delta delta
end

#send_pingObject



104
105
106
# File 'lib/game_2d/client_connection.rb', line 104

def send_ping
  send_record :ping => { :start => Time.now.to_f }
end

#send_record(data, reliable = false) ⇒ Object



108
109
110
111
112
# File 'lib/game_2d/client_connection.rb', line 108

def send_record(data, reliable=false)
  debug_packet('Sending', data)
  @socket.send_packet(data.to_json, reliable, 0)
  @socket.flush
end

#send_saveObject



100
101
102
# File 'lib/game_2d/client_connection.rb', line 100

def send_save
  send_record :save => true
end

#updateObject



121
122
123
# File 'lib/game_2d/client_connection.rb', line 121

def update
  @socket.update(0) # non-blocking
end