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
-
#authenticated? ⇒ Boolean
-
#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
-
#to_s ⇒ 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
18
|
# 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}"
@authenticated = false
end
|
Instance Attribute Details
#authenticated ⇒ Object
Returns the value of attribute authenticated.
20
21
22
|
# File 'lib/game_2d/server_connection.rb', line 20
def authenticated
@authenticated
end
|
#id ⇒ Object
Returns the value of attribute id.
20
21
22
|
# File 'lib/game_2d/server_connection.rb', line 20
def id
@id
end
|
#player_id ⇒ Object
Returns the value of attribute player_id.
21
22
23
|
# File 'lib/game_2d/server_connection.rb', line 21
def player_id
@player_id
end
|
#player_name ⇒ Object
Returns the value of attribute player_name.
20
21
22
|
# File 'lib/game_2d/server_connection.rb', line 20
def player_name
@player_name
end
|
Instance Method Details
#add_npc(npc, at_tick) ⇒ Object
81
82
83
|
# File 'lib/game_2d/server_connection.rb', line 81
def add_npc(npc, at_tick)
send_record :add_npcs => [ npc ], :at_tick => at_tick
end
|
#add_player(player, at_tick) ⇒ Object
85
86
87
|
# File 'lib/game_2d/server_connection.rb', line 85
def add_player(player, at_tick)
send_record :add_players => [ player ], :at_tick => at_tick
end
|
#answer_handshake(handshake) ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/game_2d/server_connection.rb', line 24
def answer_handshake(handshake)
if authenticated?
warn "#{self} cannot re-handshake"
disconnect!
return
end
@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
42
43
44
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
|
# File 'lib/game_2d/server_connection.rb', line 42
def answer_login(b64_password_hash, b64_iv)
if authenticated?
warn "#{self} cannot re-login"
disconnect!
return
end
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]
warn "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
@authenticated = true
@port.register_player @player_name, self
player = @game.add_player(@player_name)
@player_id = player.registry_id
puts "#{player} logs in from #{@remote_addr} at <#{@game.tick}>"
end
|
#answer_ping(ping) ⇒ Object
77
78
79
|
# File 'lib/game_2d/server_connection.rb', line 77
def answer_ping(ping)
send_record :pong => ping
end
|
#authenticated? ⇒ Boolean
22
|
# File 'lib/game_2d/server_connection.rb', line 22
def authenticated?; @authenticated; end
|
#close ⇒ Object
102
103
104
|
# File 'lib/game_2d/server_connection.rb', line 102
def close
@game.send_player_gone player
end
|
#debug_packet(direction, hash) ⇒ Object
136
137
138
139
140
141
|
# File 'lib/game_2d/server_connection.rb', line 136
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
89
90
91
|
# File 'lib/game_2d/server_connection.rb', line 89
def delete_entity(entity, at_tick)
send_record :delete_entities => [ entity.registry_id ], :at_tick => at_tick
end
|
#disconnect! ⇒ Object
143
144
145
|
# File 'lib/game_2d/server_connection.rb', line 143
def disconnect!
@server.disconnect_client(@id)
end
|
#on_packet(data, channel) ⇒ Object
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/game_2d/server_connection.rb', line 106
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 ping = hash.delete(:ping)
answer_ping ping
elsif !authenticated?
warn "Ignoring #{hash.inspect}, not authenticated"
elsif hash.delete(:save)
@game.save
else
hash[:player_name] = @player_name
hash[:player_id] = @player_id
@game.add_player_action hash
@port.broadcast_player_action hash, channel
end
end
|
#player ⇒ Object
73
74
75
|
# File 'lib/game_2d/server_connection.rb', line 73
def player
@game[@player_id]
end
|
#send_record(hash, reliable = false, channel = 0) ⇒ Object
128
129
130
131
132
133
134
|
# File 'lib/game_2d/server_connection.rb', line 128
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
|
#to_s ⇒ Object
147
148
149
|
# File 'lib/game_2d/server_connection.rb', line 147
def to_s
"#{@player_name || '??'} ##{@id} from #{@remote_addr}"
end
|
#update_entities(entities, at_tick) ⇒ Object
93
94
95
|
# File 'lib/game_2d/server_connection.rb', line 93
def update_entities(entities, at_tick)
send_record :update_entities => entities, :at_tick => at_tick
end
|
#update_score(player, at_tick) ⇒ Object
98
99
100
|
# File 'lib/game_2d/server_connection.rb', line 98
def update_score(player, at_tick)
send_record :update_score => { player.player_name => player.score }, :at_tick => at_tick
end
|