Add more hooks to the server (#9)
This commit is contained in:
parent
6de22bae6d
commit
a7895747b6
|
@ -9,6 +9,7 @@ require_relative 'messages/server_settings'
|
|||
require_relative 'messages/start_info'
|
||||
require_relative 'messages/cl_say'
|
||||
require_relative 'messages/cl_emoticon'
|
||||
require_relative 'messages/cl_info'
|
||||
|
||||
class GameServer
|
||||
attr_accessor :pred_game_tick, :ack_game_tick, :map
|
||||
|
@ -41,19 +42,17 @@ class GameServer
|
|||
end
|
||||
|
||||
def on_emoticon(chunk, _packet)
|
||||
message = ClEmoticon.new(chunk.data[1..])
|
||||
p message
|
||||
msg = ClEmoticon.new(chunk.data[1..])
|
||||
return if call_hook(:emote, Context.new(msg, chunk:, packet:)).nil?
|
||||
end
|
||||
|
||||
def on_info(chunk, packet)
|
||||
u = Unpacker.new(chunk.data[1..])
|
||||
net_version = u.get_string
|
||||
password = u.get_string
|
||||
client_version = u.get_int
|
||||
puts "vers=#{net_version} vers=#{client_version} pass=#{password}"
|
||||
msg = ClInfo.new(chunk.data[1..])
|
||||
|
||||
return if call_hook(:info, Context.new(msg, chunk:, packet:)).nil?
|
||||
|
||||
# TODO: check version and password
|
||||
|
||||
puts "vers=#{msg.net_version} vers=#{msg.client_version} pass=#{msg.password}"
|
||||
@server.send_map(packet.client)
|
||||
end
|
||||
|
||||
|
@ -63,6 +62,8 @@ class GameServer
|
|||
# - server settings
|
||||
# - ready
|
||||
#
|
||||
return if call_hook(:ready, Context.new(nil, chunk: nil, packet:)).nil?
|
||||
|
||||
@server.send_server_settings(packet.client, ServerSettings.new.to_a)
|
||||
@server.send_ready(packet.client)
|
||||
end
|
||||
|
@ -75,6 +76,8 @@ class GameServer
|
|||
#
|
||||
# We only send ready to enter for now
|
||||
info = StartInfo.new(chunk.data[1..])
|
||||
return if call_hook(:start_info, Context.new(info, chunk: nil, packet:)).nil?
|
||||
|
||||
packet.client.player.set_start_info(info)
|
||||
info_str = info.to_s
|
||||
puts "got start info: #{info_str}" if @verbose
|
||||
|
@ -99,6 +102,8 @@ class GameServer
|
|||
# - game info
|
||||
# - client info
|
||||
# - snap single
|
||||
return if call_hook(:enter_game, Context.new(nil, chunk: nil, packet:)).nil?
|
||||
|
||||
packet.client.in_game = true
|
||||
@server.send_server_info(packet.client, ServerInfo.new.to_a)
|
||||
@server.send_game_info(packet.client, GameInfo.new.to_a)
|
||||
|
@ -136,12 +141,17 @@ class GameServer
|
|||
# - input_timing
|
||||
# - snap (empty)
|
||||
|
||||
# we do nothing for now
|
||||
# TODO: do something
|
||||
msg = ClInput.new(chunk.data[1..])
|
||||
return if call_hook(:input, Context.new(msg, chunk:, packet:)).nil?
|
||||
|
||||
dir = msg.direction
|
||||
puts "#{packet.client.player.id} tried to move #{dir}" unless dir.zero?
|
||||
end
|
||||
|
||||
def on_client_drop(client, reason = nil)
|
||||
reason = reason.nil? ? '' : " (#{reason})"
|
||||
return if call_hook(:client_drop, Context.new(nil, chunk:, packet:, reason:)).nil?
|
||||
|
||||
puts "'#{client.player.name}' left the game#{reason}"
|
||||
end
|
||||
|
||||
|
@ -156,6 +166,8 @@ class GameServer
|
|||
end
|
||||
|
||||
def on_tick
|
||||
return if call_hook(:tick, Context.new(nil, chunk:, packet:)).nil?
|
||||
|
||||
now = Time.now
|
||||
timeout_ids = []
|
||||
@server.clients.each do |id, client|
|
||||
|
|
52
lib/messages/cl_info.rb
Normal file
52
lib/messages/cl_info.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../packer'
|
||||
|
||||
##
|
||||
# ClInfo
|
||||
#
|
||||
# Client -> Server
|
||||
class ClInfo
|
||||
attr_accessor :net_version, :password, :client_version
|
||||
|
||||
def initialize(hash_or_raw)
|
||||
if hash_or_raw.instance_of?(Hash)
|
||||
init_hash(hash_or_raw)
|
||||
else
|
||||
init_raw(hash_or_raw)
|
||||
end
|
||||
end
|
||||
|
||||
def init_raw(data)
|
||||
u = Unpacker.new(data)
|
||||
@net_version = u.get_string
|
||||
@password = u.get_string
|
||||
@client_version = u.get_int
|
||||
end
|
||||
|
||||
def init_hash(attr)
|
||||
@net_version = attr[:net_version] || 'TODO: fill default'
|
||||
@password = attr[:password] || 'TODO: fill default'
|
||||
@client_version = attr[:client_version] || 0
|
||||
end
|
||||
|
||||
def to_h
|
||||
{
|
||||
net_version: @net_version,
|
||||
password: @password,
|
||||
client_version: @client_version
|
||||
}
|
||||
end
|
||||
|
||||
# basically to_network
|
||||
# int array the Client sends to the Server
|
||||
def to_a
|
||||
Packer.pack_str(@net_version) +
|
||||
Packer.pack_str(@password) +
|
||||
Packer.pack_int(@client_version)
|
||||
end
|
||||
|
||||
def to_s
|
||||
to_h
|
||||
end
|
||||
end
|
96
lib/messages/cl_input.rb
Normal file
96
lib/messages/cl_input.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../packer'
|
||||
|
||||
##
|
||||
# ClInput
|
||||
#
|
||||
# Client -> Server
|
||||
class ClInput
|
||||
attr_accessor :ack_game_tick, :prediction_tick, :size, :direction, :target_x, :target_y, :jump, :fire, :hook, :player_flags, :wanted_weapon, :next_weapon, :prev_weapon, :ping
|
||||
|
||||
def initialize(hash_or_raw)
|
||||
if hash_or_raw.instance_of?(Hash)
|
||||
init_hash(hash_or_raw)
|
||||
else
|
||||
init_raw(hash_or_raw)
|
||||
end
|
||||
end
|
||||
|
||||
def init_raw(data)
|
||||
u = Unpacker.new(data)
|
||||
@ack_game_tick = u.get_int
|
||||
@prediction_tick = u.get_int
|
||||
@size = u.get_int
|
||||
@direction = u.get_int
|
||||
@target_x = u.get_int
|
||||
@target_y = u.get_int
|
||||
@jump = u.get_int
|
||||
@fire = u.get_int
|
||||
@hook = u.get_int
|
||||
@player_flags = u.get_int
|
||||
@wanted_weapon = u.get_int
|
||||
@next_weapon = u.get_int
|
||||
@prev_weapon = u.get_int
|
||||
@ping = u.get_int
|
||||
end
|
||||
|
||||
def init_hash(attr)
|
||||
@ack_game_tick = attr[:ack_game_tick] || 0
|
||||
@prediction_tick = attr[:prediction_tick] || 0
|
||||
@size = attr[:size] || 0
|
||||
@direction = attr[:direction] || 0
|
||||
@target_x = attr[:target_x] || 0
|
||||
@target_y = attr[:target_y] || 0
|
||||
@jump = attr[:jump] || 0
|
||||
@fire = attr[:fire] || 0
|
||||
@hook = attr[:hook] || 0
|
||||
@player_flags = attr[:player_flags] || 0
|
||||
@wanted_weapon = attr[:wanted_weapon] || 0
|
||||
@next_weapon = attr[:next_weapon] || 0
|
||||
@prev_weapon = attr[:prev_weapon] || 0
|
||||
@ping = attr[:ping] || 0
|
||||
end
|
||||
|
||||
def to_h
|
||||
{
|
||||
ack_game_tick: @ack_game_tick,
|
||||
prediction_tick: @prediction_tick,
|
||||
size: @size,
|
||||
direction: @direction,
|
||||
target_x: @target_x,
|
||||
target_y: @target_y,
|
||||
jump: @jump,
|
||||
fire: @fire,
|
||||
hook: @hook,
|
||||
player_flags: @player_flags,
|
||||
wanted_weapon: @wanted_weapon,
|
||||
next_weapon: @next_weapon,
|
||||
prev_weapon: @prev_weapon,
|
||||
ping: @ping
|
||||
}
|
||||
end
|
||||
|
||||
# basically to_network
|
||||
# int array the Client sends to the Server
|
||||
def to_a
|
||||
Packer.pack_int(@ack_game_tick) +
|
||||
Packer.pack_int(@prediction_tick) +
|
||||
Packer.pack_int(@size) +
|
||||
Packer.pack_int(@direction) +
|
||||
Packer.pack_int(@target_x) +
|
||||
Packer.pack_int(@target_y) +
|
||||
Packer.pack_int(@jump) +
|
||||
Packer.pack_int(@fire) +
|
||||
Packer.pack_int(@hook) +
|
||||
Packer.pack_int(@player_flags) +
|
||||
Packer.pack_int(@wanted_weapon) +
|
||||
Packer.pack_int(@next_weapon) +
|
||||
Packer.pack_int(@prev_weapon) +
|
||||
Packer.pack_int(@ping)
|
||||
end
|
||||
|
||||
def to_s
|
||||
to_h
|
||||
end
|
||||
end
|
|
@ -78,7 +78,15 @@ class TeeworldsServer
|
|||
chat: [],
|
||||
rcon_auth: [],
|
||||
rcon_cmd: [],
|
||||
shutdown: []
|
||||
shutdown: [],
|
||||
emote: [],
|
||||
info: [],
|
||||
ready: [],
|
||||
start_info: [],
|
||||
enter_game: [],
|
||||
input: [],
|
||||
client_drop: [],
|
||||
tick: []
|
||||
}
|
||||
@thread_running = false
|
||||
@is_shutting_down = false
|
||||
|
@ -106,6 +114,38 @@ class TeeworldsServer
|
|||
@hooks[:shutdown].push(block)
|
||||
end
|
||||
|
||||
def on_emote(&block)
|
||||
@hooks[:emote].push(block)
|
||||
end
|
||||
|
||||
def on_info(&block)
|
||||
@hooks[:info].push(block)
|
||||
end
|
||||
|
||||
def on_ready(&block)
|
||||
@hooks[:ready].push(block)
|
||||
end
|
||||
|
||||
def on_start_info(&block)
|
||||
@hooks[:start_info].push(block)
|
||||
end
|
||||
|
||||
def on_enter_game(&block)
|
||||
@hooks[:enter_game].push(block)
|
||||
end
|
||||
|
||||
def on_input(&block)
|
||||
@hooks[:input].push(block)
|
||||
end
|
||||
|
||||
def on_client_drop(&block)
|
||||
@hooks[:client_drop].push(block)
|
||||
end
|
||||
|
||||
def on_tick(&block)
|
||||
@hooks[:tick].push(block)
|
||||
end
|
||||
|
||||
def main_loop
|
||||
loop do
|
||||
break if @is_shutting_down
|
||||
|
|
Loading…
Reference in a new issue