Class: ServerConnection
- Inherits:
-
Object
show all
- Includes:
- Base64, Encryption
- Defined in:
- lib/game_2d/server_connection.rb
Overview
An instance of this class is created by ServerPort whenever an incoming connection is accepted.
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#add_npc(npc, at_tick) ⇒ Object
-
#add_player(player, at_tick) ⇒ Object
-
#answer_handshake(handshake) ⇒ Object
-
#answer_login(b64_password_hash, b64_iv) ⇒ Object
-
#answer_ping(ping) ⇒ Object
-
#close ⇒ Object
-
#debug_packet(direction, hash) ⇒ Object
-
#delete_entity(entity, at_tick) ⇒ Object
-
#disconnect! ⇒ Object
-
#initialize(port, game, server, id, remote_addr) ⇒ ServerConnection
constructor
A new instance of ServerConnection.
-
#on_packet(data, channel) ⇒ Object
-
#player ⇒ Object
-
#send_record(hash, reliable = false, channel = 0) ⇒ Object
-
#update_entities(entities, at_tick) ⇒ Object
-
#update_score(player, at_tick) ⇒ Object
Methods included from Encryption
#decrypt, #encrypt, #key=, #make_cipher, #make_password_hash
Constructor Details
#initialize(port, game, server, id, remote_addr) ⇒ ServerConnection
Returns a new instance of ServerConnection.
14
15
16
17
|
# File 'lib/game_2d/server_connection.rb', line 14
def initialize(port, game, server, id, remote_addr)
@port, @game, @server, @id, @remote_addr = port, game, server, id, remote_addr
puts "ServerConnection: New connection #{id} from #{remote_addr}"
end
|
Instance Attribute Details
#id ⇒ Object
Returns the value of attribute id.
19
20
21
|
# File 'lib/game_2d/server_connection.rb', line 19
def id
@id
end
|
#player_id ⇒ Object
Returns the value of attribute player_id.
19
20
21
|
# File 'lib/game_2d/server_connection.rb', line 19
def player_id
@player_id
end
|
Instance Method Details
#add_npc(npc, at_tick) ⇒ Object
67
68
69
|
# File 'lib/game_2d/server_connection.rb', line 67
def add_npc(npc, at_tick)
send_record :add_npcs => [ npc ], :at_tick => at_tick
end
|
#add_player(player, at_tick) ⇒ Object
71
72
73
|
# File 'lib/game_2d/server_connection.rb', line 71
def add_player(player, at_tick)
send_record :add_players => [ player ], :at_tick => at_tick
end
|
#answer_handshake(handshake) ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
32
|
# File 'lib/game_2d/server_connection.rb', line 21
def answer_handshake(handshake)
@player_name = handshake[:player_name]
dh_public_key = handshake[:dh_public_key]
client_public_key = handshake[:client_public_key]
dh = OpenSSL::PKey::DH.new(dh_public_key)
dh.generate_key!
self.key = dh.compute_key(OpenSSL::BN.new client_public_key)
response = {
:server_public_key => dh.pub_key.to_s
}
send_record response, true
end
|
#answer_login(b64_password_hash, b64_iv) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
# File 'lib/game_2d/server_connection.rb', line 34
def answer_login(b64_password_hash, b64_iv)
password_hash = decrypt(
strict_decode64(b64_password_hash),
strict_decode64(b64_iv))
player_data = @game.player_data(@player_name)
if player_data
unless password_hash == player_data[:password_hash]
$stderr.puts "Wrong password for #{@player_name} (#{password_hash} != #{player_data[:password_hash]})"
disconnect!
return
end
else
@game.store_player_data @player_name, :password_hash => password_hash
end
player = @game.add_player(@player_name)
@player_id = player.registry_id
@port.register_player @player_id, self
puts "#{player} logs in from #{@remote_addr} at <#{@game.tick}>"
end
|
#answer_ping(ping) ⇒ Object
63
64
65
|
# File 'lib/game_2d/server_connection.rb', line 63
def answer_ping(ping)
send_record :pong => ping
end
|
#close ⇒ Object
88
89
90
91
92
93
94
|
# File 'lib/game_2d/server_connection.rb', line 88
def close
return unless @player_id
@port.deregister_player @player_id
toast = player
puts "#{toast} -- #{@remote_addr} disconnected at <#{@game.tick}>"
@game.delete_entity toast
end
|
#debug_packet(direction, hash) ⇒ Object
126
127
128
129
130
131
|
# File 'lib/game_2d/server_connection.rb', line 126
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
|
#delete_entity(entity, at_tick) ⇒ Object
75
76
77
|
# File 'lib/game_2d/server_connection.rb', line 75
def delete_entity(entity, at_tick)
send_record :delete_entities => [ entity.registry_id ], :at_tick => at_tick
end
|
#disconnect! ⇒ Object
133
134
135
|
# File 'lib/game_2d/server_connection.rb', line 133
def disconnect!
@server.disconnect_client(@id)
end
|
#on_packet(data, channel) ⇒ Object
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# File 'lib/game_2d/server_connection.rb', line 96
def on_packet(data, channel)
hash = JSON.parse(data).fix_keys
debug_packet('Received', hash)
if handshake = hash.delete(:handshake)
answer_handshake(handshake)
elsif password_hash = hash.delete(:password_hash)
answer_login(password_hash, hash.delete(:iv))
elsif hash.delete(:save)
@game.save
elsif ping = hash.delete(:ping)
answer_ping ping
else
if hash[:player_id] = @player_id
@game.add_player_action hash
@port.broadcast_player_action hash, channel
else
$stderr.puts "Ignoring move #{hash.inspect}, no player_id for this connection"
end
end
end
|
#player ⇒ Object
59
60
61
|
# File 'lib/game_2d/server_connection.rb', line 59
def player
@game[@player_id]
end
|
#send_record(hash, reliable = false, channel = 0) ⇒ Object
118
119
120
121
122
123
124
|
# File 'lib/game_2d/server_connection.rb', line 118
def send_record(hash, reliable=false, channel=0)
debug_packet('Sending', hash)
send_str = hash.to_json
@server.send_packet(@id, send_str, reliable, channel)
@server.flush
end
|
#update_entities(entities, at_tick) ⇒ Object
79
80
81
|
# File 'lib/game_2d/server_connection.rb', line 79
def update_entities(entities, at_tick)
send_record :update_entities => entities, :at_tick => at_tick
end
|
#update_score(player, at_tick) ⇒ Object
84
85
86
|
# File 'lib/game_2d/server_connection.rb', line 84
def update_score(player, at_tick)
send_record :update_score => { player.registry_id => player.score }, :at_tick => at_tick
end
|