Unhardcode the last packet (startinfo)
Also support bigger integers than 63 :)
This commit is contained in:
parent
2c8e6aeb8f
commit
57a8f0bcc7
|
@ -4,7 +4,7 @@ require_relative 'bytes'
|
|||
|
||||
class NetChunk
|
||||
attr_reader :next, :data, :msg, :sys, :flags
|
||||
@@sent_vital_chunks = 1
|
||||
@@sent_vital_chunks = 0
|
||||
|
||||
def initialize(data)
|
||||
@next = nil
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
# randomize this
|
||||
MY_TOKEN = [0x73, 0x34, 0xB4, 0xA0]
|
||||
|
||||
MSG_TOKEN = [0x04, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x05] + MY_TOKEN + Array.new(512, 0x00)
|
||||
MSG_INFO = [0x40, 0x19, 0x01, 0x03, 0x30, 0x2E, 0x37, 0x20, 0x38, 0x30, 0x32, 0x66, # @...0.7 802f
|
||||
0x31, 0x62, 0x65, 0x36, 0x30, 0x61, 0x30, 0x35, 0x36, 0x36, 0x35, 0x66, # 1be60a05665f
|
||||
0x00, 0x00, 0x85, 0x1C]
|
||||
MSG_STARTINFO = [0x41, 0x19, 0x03, 0x36, 0x6E, 0x61, 0x6D, 0x65 , 0x6C, 0x65, 0x73, 0x73, # A..6nameless
|
||||
0x20, 0x6D, 0x65, 0x00, 0x00, 0x40, 0x67, 0x72 , 0x65, 0x65, 0x6E, 0x73, # me..@greens
|
||||
0x77, 0x61, 0x72, 0x64, 0x00, 0x64, 0x75, 0x6F , 0x64, 0x6F, 0x6E, 0x6E, # ward.duodonn
|
||||
0x79, 0x00, 0x00, 0x73, 0x74, 0x61, 0x6E, 0x64 , 0x61, 0x72, 0x64, 0x00, # y..standard
|
||||
0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64 , 0x00, 0x73, 0x74, 0x61, # standard.sta
|
||||
0x6E, 0x64, 0x61, 0x72, 0x64, 0x00, 0x01, 0x01 , 0x00, 0x00, 0x00, 0x00, # ndard.......
|
||||
0x80, 0xFC, 0xAF, 0x05, 0xEB, 0x83, 0xD0, 0x0A , 0x80, 0xFE, 0x07, 0x80, # ............
|
||||
0xFE, 0x07, 0x80, 0xFE, 0x07, 0x80, 0xFE, 0x07]
|
||||
GAME_VERSION = "0.7.5"
|
||||
GAME_NETVERSION_HASH_FORCED = "802f1be60a05665f"
|
||||
GAME_NETVERSION = "0.7 " + GAME_NETVERSION_HASH_FORCED
|
||||
CLIENT_VERSION = 0x0705
|
||||
|
||||
NETMSG_NULL = 0
|
||||
NETMSG_INFO = 1
|
||||
|
|
|
@ -1,62 +1,87 @@
|
|||
require_relative 'array'
|
||||
|
||||
class Packer
|
||||
# poor mans int packer
|
||||
# homebrew not covering
|
||||
# the full tw fancyness
|
||||
#
|
||||
# Format: ESDDDDDD EDDDDDDD EDD... Extended, Data, Sign
|
||||
def self.pack_int(num)
|
||||
if num > 63 || num < -63
|
||||
# the first byte can fit 6 bits
|
||||
# because the first two bits are extended and sign
|
||||
# so if you have a number bigger than 63
|
||||
# it needs two bytes
|
||||
# which are also least significant byte first etc
|
||||
# so we do not support that YET
|
||||
#
|
||||
# the first too big number 64 is represented as those bits
|
||||
# 10000000 00000001
|
||||
# ^^^ ^ ^ ^
|
||||
# ||\ / \ /
|
||||
# || \ / \ /
|
||||
# || \ \/
|
||||
# || \ /
|
||||
# || \ /
|
||||
# || \ /
|
||||
# || \/
|
||||
# || /\
|
||||
# || / \
|
||||
# || / \
|
||||
# || 00000001 000000
|
||||
# || |
|
||||
# || v
|
||||
# || 64
|
||||
# ||
|
||||
# |positive
|
||||
# extended
|
||||
raise "Numbers greater than 63 are not supported yet"
|
||||
end
|
||||
# the first byte can fit 6 bits
|
||||
# because the first two bits are extended and sign
|
||||
# so if you have a number bigger than 63
|
||||
# it needs two bytes
|
||||
# which are also least significant byte first etc
|
||||
# so we do not support that YET
|
||||
#
|
||||
# the first too big number 64 is represented as those bits
|
||||
# 10000000 00000001
|
||||
# ^^^ ^ ^ ^
|
||||
# ||\ / \ /
|
||||
# || \ / \ /
|
||||
# || \ \/
|
||||
# || \ /
|
||||
# || \ /
|
||||
# || \ /
|
||||
# || \/
|
||||
# || /\
|
||||
# || / \
|
||||
# || / \
|
||||
# || 00000001 000000
|
||||
# || |
|
||||
# || v
|
||||
# || 64
|
||||
# ||
|
||||
# |positive
|
||||
# extended
|
||||
sign = '0'
|
||||
if num.negative?
|
||||
sign = '1'
|
||||
num += 1
|
||||
end
|
||||
num = num.abs
|
||||
if num > 63 || num < -63
|
||||
return self.pack_big_int(sign, num)
|
||||
end
|
||||
ext = '0'
|
||||
bits = ext + sign + num.to_s(2).rjust(6, '0')
|
||||
[bits.to_i(2)]
|
||||
end
|
||||
|
||||
def self.pack_big_int(sign, num)
|
||||
num_bits = num.to_s(2)
|
||||
first = '1' + sign + num_bits[-6..]
|
||||
|
||||
num_bits = num_bits[0..-7]
|
||||
bytes = []
|
||||
num_bits.chars.groups_of(7).each do |seven_bits|
|
||||
# mark all as extended
|
||||
bytes << '1' + seven_bits.join('').rjust(7, '0')
|
||||
end
|
||||
# least significant first
|
||||
bytes = bytes.reverse
|
||||
# mark last byte as unextended
|
||||
bytes[-1][0] = '0'
|
||||
([first] + bytes).map { |b| b.to_i(2) }
|
||||
end
|
||||
|
||||
def self.pack_str(str)
|
||||
str.chars.map(&:ord) + [0x00]
|
||||
end
|
||||
end
|
||||
|
||||
def todo_make_this_rspec_test
|
||||
# single byte int
|
||||
p Packer.pack_int(1) == [1]
|
||||
p Packer.pack_int(3) == [3]
|
||||
p Packer.pack_int(16) == [16]
|
||||
p Packer.pack_int(63) == [63]
|
||||
|
||||
p Packer.pack_int(3) == [3]
|
||||
# negative single byte
|
||||
p Packer.pack_int(-1) == [64]
|
||||
p Packer.pack_int(-2) == [65]
|
||||
|
||||
# todo
|
||||
# p Packer.pack_int(64) == [64]
|
||||
# multi byte int
|
||||
p Packer.pack_int(64) == [128, 1]
|
||||
p Packer.pack_int(99999999999999999) == [191, 131, 255, 147, 246, 194, 215, 232, 88]
|
||||
|
||||
# string
|
||||
p Packer.pack_str("A") == [65, 0]
|
||||
end
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@ class TwClient
|
|||
end
|
||||
end
|
||||
@ticks = 0
|
||||
@client_token = MY_TOKEN.map { |b| b.to_s(16) }.join('')
|
||||
# me trying to write cool code
|
||||
@client_token = (1..4).to_a.map { |_| rand(0..255) }
|
||||
@client_token = @client_token.map { |b| b.to_s(16) }.join('')
|
||||
puts "client token #{@client_token}"
|
||||
@netbase = NetBase.new
|
||||
@netbase.client_token = @client_token
|
||||
|
@ -99,7 +101,15 @@ class TwClient
|
|||
end
|
||||
|
||||
def send_info()
|
||||
send_msg(MSG_INFO)
|
||||
data = []
|
||||
data += Packer.pack_str(GAME_NETVERSION)
|
||||
data += Packer.pack_str("password")
|
||||
data += Packer.pack_int(CLIENT_VERSION)
|
||||
msg = NetChunk.create_vital_header({vital: true}, data.size + 1) +
|
||||
[pack_msg_id(NETMSG_INFO, system: true)] +
|
||||
data
|
||||
|
||||
@netbase.send_packet(msg, 1)
|
||||
end
|
||||
|
||||
def send_msg_startinfo()
|
||||
|
@ -131,7 +141,7 @@ class TwClient
|
|||
|
||||
start_info.each do |key, value|
|
||||
if value.class == String
|
||||
data += value.chars.map(&:ord) + [0x00]
|
||||
data += Packer.pack_str(value)
|
||||
elsif value.class == Integer
|
||||
data += Packer.pack_int(value)
|
||||
else
|
||||
|
@ -177,7 +187,8 @@ class TwClient
|
|||
CHAT_ALL,
|
||||
64 # should use TARGET_SERVER (-1) instead of hacking 64 in here
|
||||
] +
|
||||
str.chars.map(&:ord) + [0x00])
|
||||
Packer.pack_str(str)
|
||||
)
|
||||
end
|
||||
|
||||
def send_input
|
||||
|
|
Loading…
Reference in a new issue