Class: GameClient

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ GameClient

Returns a new instance of GameClient.



19
20
21
22
23
24
# File 'lib/game_client.rb', line 19

def initialize(client)
  @client = client
  @players = {}
  @ack_game_tick = -1
  @pred_game_tick = 0
end

Instance Attribute Details

#ack_game_tickObject

Returns the value of attribute ack_game_tick.



17
18
19
# File 'lib/game_client.rb', line 17

def ack_game_tick
  @ack_game_tick
end

#playersObject

Returns the value of attribute players.



17
18
19
# File 'lib/game_client.rb', line 17

def players
  @players
end

#pred_game_tickObject

Returns the value of attribute pred_game_tick.



17
18
19
# File 'lib/game_client.rb', line 17

def pred_game_tick
  @pred_game_tick
end

Instance Method Details

#call_hook(hook_sym, context, optional = nil) ⇒ Object

call_hook

@param: hook_sym [Symbol] name of the symbol to call @param: context [Context] context object to pass on data @param: optional [Any] optional 2nd parameter passed to the callback



32
33
34
35
36
37
38
39
# File 'lib/game_client.rb', line 32

def call_hook(hook_sym, context, optional = nil)
  @client.hooks[hook_sym].each do |hook|
    hook.call(context, optional)
    context.verify
    return nil if context.canceld?
  end
  context
end

#on_auth_offObject



52
53
54
55
56
57
# File 'lib/game_client.rb', line 52

def on_auth_off
  return if call_hook(:auth_off, Context.new(nil)).nil?

  @client.rcon_authed = false
  puts 'rcon logged out'
end

#on_auth_onObject



45
46
47
48
49
50
# File 'lib/game_client.rb', line 45

def on_auth_on
  return if call_hook(:auth_on, Context.new(nil)).nil?

  @client.rcon_authed = true
  puts 'rcon logged in'
end

#on_chat(chunk) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/game_client.rb', line 186

def on_chat(chunk)
  u = Unpacker.new(chunk.data[1..])
  data = {
    mode: u.get_int,
    client_id: u.get_int,
    target_id: u.get_int,
    message: u.get_string
  }
  data[:author] = @players[data[:client_id]]
  msg = ChatMesage.new(data)

  context = Context.new(nil, chunk:)
  call_hook(:chat, context, msg)
end

#on_client_drop(chunk) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/game_client.rb', line 118

def on_client_drop(chunk)
  message = SvClientDrop.new(chunk.data[1..])
  context = Context.new(
    nil,
    player: @players[message.client_id],
    chunk:,
    client_id: message.client_id,
    reason: message.reason,
    silent: message.silent?
  )
  return if call_hook(:client_drop, context).nil?

  @players.delete(context.data[:client_id])
end

#on_client_info(chunk) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/game_client.rb', line 83

def on_client_info(chunk)
  # puts "Got playerinfo flags: #{chunk.flags}"
  u = Unpacker.new(chunk.data[1..])
  player = Player.new(
    id: u.get_int,
    local: u.get_int,
    team: u.get_int,
    name: u.get_string,
    clan: u.get_string,
    country: u.get_int
  )
  # skinparts and the silent flag
  # are currently ignored

  context = Context.new(
    nil,
    player:,
    chunk:
  )
  return if call_hook(:client_info, context).nil?

  player = context.data[:player]
  if player.local?
    @client.local_client_id = player.id
    puts "Our client id is #{@client.local_client_id}"
  end
  @players[player.id] = player
end

#on_connectedObject



137
138
139
140
141
142
# File 'lib/game_client.rb', line 137

def on_connected
  context = Context.new(nil)
  return if call_hook(:connected, context).nil?

  @client.send_msg_start_info
end

#on_disconnect(data) ⇒ Object



144
145
146
147
148
149
# File 'lib/game_client.rb', line 144

def on_disconnect(data)
  context = Context.new(nil, reason: data)
  return if call_hook(:disconnect, context).nil?

  puts "got disconnect. reason='#{context.data[:reason]}'"
end

#on_emoticon(chunk) ⇒ Object



175
# File 'lib/game_client.rb', line 175

def on_emoticon(chunk); end

#on_input_timing(chunk) ⇒ Object



112
113
114
115
116
# File 'lib/game_client.rb', line 112

def on_input_timing(chunk)
  message = InputTiming.new(chunk.data[1..])
  context = Context.new(message, chunk:)
  call_hook(:input_timing, context)
end

#on_map_change(chunk) ⇒ Object



177
178
179
180
181
182
183
184
# File 'lib/game_client.rb', line 177

def on_map_change(chunk)
  context = Context.new(nil, chunk:)
  return if call_hook(:map_change, context).nil?

  # ignore mapdownload at all times
  # and claim to have the map
  @client.send_msg_ready
end

#on_maplist_entry_add(chunk) ⇒ Object



71
72
73
74
75
# File 'lib/game_client.rb', line 71

def on_maplist_entry_add(chunk)
  message = MaplistEntryAdd.new(chunk.data[1..])
  context = Context.new(message)
  call_hook(:maplist_entry_add, context)
end

#on_maplist_entry_rem(chunk) ⇒ Object



77
78
79
80
81
# File 'lib/game_client.rb', line 77

def on_maplist_entry_rem(chunk)
  message = MaplistEntryRem.new(chunk.data[1..])
  context = Context.new(message)
  call_hook(:maplist_entry_rem, context)
end

#on_rcon_cmd_add(chunk) ⇒ Object



59
60
61
62
63
# File 'lib/game_client.rb', line 59

def on_rcon_cmd_add(chunk)
  message = RconCmdAdd.new(chunk.data[1..])
  context = Context.new(message)
  call_hook(:rcon_cmd_add, context)
end

#on_rcon_cmd_rem(chunk) ⇒ Object



65
66
67
68
69
# File 'lib/game_client.rb', line 65

def on_rcon_cmd_rem(chunk)
  message = RconCmdRem.new(chunk.data[1..])
  context = Context.new(message)
  call_hook(:rcon_cmd_rem, context)
end

#on_rcon_line(chunk) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/game_client.rb', line 151

def on_rcon_line(chunk)
  message = RconLine.new(chunk.data[1..])
  context = Context.new(message)
  return if call_hook(:rcon_line, context).nil?

  puts "[rcon] #{context.message.command}"
end

#on_ready_to_enter(_chunk) ⇒ Object



133
134
135
# File 'lib/game_client.rb', line 133

def on_ready_to_enter(_chunk)
  @client.send_enter_game
end

#on_snapshot(chunk) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/game_client.rb', line 159

def on_snapshot(chunk)
  u = SnapshotUnpacker.new(@client)
  snapshot = u.snap_single(chunk)

  return if snapshot.nil?

  context = Context.new(nil, chunk:)
  return if call_hook(:snapshot, context, snapshot).nil?

  # ack every snapshot no matter how broken
  @ack_game_tick = snapshot.game_tick
  return unless (@pred_game_tick - @ack_game_tick).abs > 10

  @pred_game_tick = @ack_game_tick + 1
end

#on_tickObject



41
42
43
# File 'lib/game_client.rb', line 41

def on_tick
  call_hook(:tick, Context.new(nil))
end