Skip to content

Commit

Permalink
Fix some server crashes and implement emoticons
Browse files Browse the repository at this point in the history
  • Loading branch information
ChillerDragon committed Feb 21, 2024
1 parent 0d52e58 commit 05867af
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
11 changes: 7 additions & 4 deletions lib/game_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
require_relative 'messages/cl_say'
require_relative 'messages/cl_emoticon'
require_relative 'messages/cl_info'
require_relative 'messages/cl_input'

class GameServer
attr_accessor :pred_game_tick, :ack_game_tick, :map
Expand Down Expand Up @@ -41,9 +42,11 @@ def call_hook(hook_sym, context, optional = nil)
context
end

def on_emoticon(chunk, _packet)
def on_emoticon(chunk, packet)
msg = ClEmoticon.new(chunk.data[1..])
call_hook(:emote, Context.new(msg, chunk:, packet:)).nil?
return if call_hook(:emote, Context.new(msg, chunk:, packet:)).nil?

@server.send_emoticon(packet.client.player.id, msg.emoticon)
end

def on_info(chunk, packet)
Expand Down Expand Up @@ -150,7 +153,7 @@ def on_input(chunk, packet)

def on_client_drop(client, reason = nil)
reason = reason.nil? ? '' : " (#{reason})"
return if call_hook(:client_drop, Context.new(nil, chunk:, packet:, reason:)).nil?
return if call_hook(:client_drop, Context.new(nil, client:, reason:)).nil?

puts "'#{client.player.name}' left the game#{reason}"
end
Expand All @@ -166,7 +169,7 @@ def on_shutdown
end

def on_tick
return if call_hook(:tick, Context.new(nil, chunk:, packet:)).nil?
return if call_hook(:tick, Context.new(nil)).nil?

now = Time.now
timeout_ids = []
Expand Down
48 changes: 48 additions & 0 deletions lib/messages/sv_emoticon.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require_relative '../packer'

##
# SvEmoticon
#
# Server -> Client
class SvEmoticon
attr_accessor :client_id, :emoticon

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)
@client_id = u.get_int
@emoticon = u.get_int
end

def init_hash(attr)
@client_id = attr[:client_id] || 0
@emoticon = attr[:emoticon] || 0
end

def to_h
{
client_id: @client_id,
emoticon: @emoticon
}
end

# basically to_network
# int array the Server sends to the Client
def to_a
Packer.pack_int(@client_id) +
Packer.pack_int(@emoticon)
end

def to_s
to_h
end
end
35 changes: 35 additions & 0 deletions lib/teeworlds_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require_relative 'packer'
require_relative 'game_server'
require_relative 'models/token'
require_relative 'messages/sv_emoticon'

class Client
attr_accessor :id, :addr, :vital_sent, :last_recv_time, :token, :player, :in_game, :authed
Expand Down Expand Up @@ -309,6 +310,40 @@ def send_map(client)
@netbase.send_packet(msg, chunks: 1, client:)
end

##
# sends emoticon to all connected clients
#
# emote ids:
# 0 - oop!
# 1 - alert
# 2 - heart
# 3 - tear
# 4 - ...
# 5 - music
# 6 - sorry
# 7 - ghost
# 8 - annoyed
# 9 - angry
# 10 - devil
# 11 - swearing
# 12 - zzZ
# 13 - WTF
# 14 - happy
# 15 - ??
#
# @param client_id [Integer] id of the client who sent the emoticon
# @param emoticon [Integer] emoticon id see list above
def send_emoticon(client_id, emoticon)
emote = SvEmoticon.new(client_id:, emoticon:)
data = emote.to_a
@clients.each_value do |client|
msg = NetChunk.create_header(vital: true, size: 1, client:) +
[pack_msg_id(NETMSGTYPE_SV_EMOTICON, system: false)] +
data
@netbase.send_packet(msg, chunks: 1, client:)
end
end

def send_rcon_auth_on(client)
msg = NetChunk.create_header(vital: true, size: 1, client:) +
[pack_msg_id(NETMSG_RCON_AUTH_ON, system: true)]
Expand Down

0 comments on commit 05867af

Please sign in to comment.