Skip to content

Commit

Permalink
Add more hooks to the server (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChillerDragon committed Feb 21, 2024
1 parent 6de22ba commit a789574
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 11 deletions.
32 changes: 22 additions & 10 deletions lib/game_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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
Expand Down Expand Up @@ -41,19 +42,17 @@ def call_hook(hook_sym, context, optional = nil)
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..])

# TODO: check version and password
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

Expand All @@ -63,6 +62,8 @@ def on_ready(_chunk, packet)
# - 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
Expand All @@ -75,6 +76,8 @@ def on_start_info(chunk, packet)
#
# 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
Expand All @@ -99,6 +102,8 @@ def on_enter_game(_chunk, packet)
# - 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)
Expand Down Expand Up @@ -136,12 +141,17 @@ def on_input(chunk, packet)
# - 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

Expand All @@ -156,6 +166,8 @@ def on_shutdown
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|
Expand Down
52 changes: 52 additions & 0 deletions lib/messages/cl_info.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 96 additions & 0 deletions lib/messages/cl_input.rb
Original file line number Diff line number Diff line change
@@ -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
42 changes: 41 additions & 1 deletion lib/teeworlds_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,15 @@ def initialize(options = {})
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
Expand Down Expand Up @@ -106,6 +114,38 @@ def on_shutdown(&block)
@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
Expand Down

0 comments on commit a789574

Please sign in to comment.