summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--constants.gd27
-rw-r--r--extractor/grf.gd38
-rw-r--r--login.gd42
-rw-r--r--network/character_server.gd48
-rw-r--r--network/login_server.gd27
-rw-r--r--network/map_server.gd30
-rw-r--r--network/network.gd17
-rw-r--r--packets/character_selection_success_packet.gd19
-rw-r--r--packets/character_server_login_packet.gd3
-rw-r--r--packets/character_server_login_success_packet.gd24
-rw-r--r--packets/couple_status_packet.gd29
-rw-r--r--packets/login_server_login_packet.gd3
-rw-r--r--packets/login_server_login_success_packet.gd30
-rw-r--r--packets/map_server_login_packet.gd3
-rw-r--r--packets/map_server_login_success_packet.gd18
-rw-r--r--packets/new_mail_status_packet.gd19
-rw-r--r--packets/packet.gd2
-rw-r--r--packets/parameter_change_packet.gd24
-rw-r--r--packets/quest.gd54
-rw-r--r--packets/quest_details.gd65
-rw-r--r--packets/quest_list_packet.gd26
-rw-r--r--packets/request_character_list_packet.gd3
-rw-r--r--packets/request_character_list_success_packet.gd18
-rw-r--r--packets/select_character_packet.gd3
-rw-r--r--packets/update_attack_range_packet.gd19
25 files changed, 473 insertions, 118 deletions
diff --git a/constants.gd b/constants.gd
index a275dc5..13c245a 100644
--- a/constants.gd
+++ b/constants.gd
@@ -8,7 +8,28 @@ enum Gender {
Server,
}
-static var Packet_DB = {
- LoginServerLoginPacket.header: LoginServerLoginPacket,
- LoginServerLoginSuccessPacket.new().header: LoginServerLoginSuccessPacket,
+enum StatusType {
+ Weight,
+ MaximumWeight,
+ MovementSpeed,
+ BaseLevel,
+ JobLevel,
+}
+
+static var PacketDB = {
+ LoginServerLoginPacket.HEADER: LoginServerLoginPacket,
+ LoginServerLoginSuccessPacket.HEADER: LoginServerLoginSuccessPacket,
+ CharacterServerLoginPacket.HEADER: CharacterServerLoginPacket,
+ CharacterServerLoginSuccessPacket.HEADER: CharacterServerLoginSuccessPacket,
+ RequestCharacterListPacket.HEADER: RequestCharacterListPacket,
+ RequestCharacterListSuccessPacket.HEADER: RequestCharacterListSuccessPacket,
+ SelectCharacterPacket.HEADER: SelectCharacterPacket,
+ CharacterSelectionSuccessPacket.HEADER: CharacterSelectionSuccessPacket,
+ MapServerLoginPacket.HEADER: MapServerLoginPacket,
+ MapServerLoginSuccessPacket.HEADER: MapServerLoginSuccessPacket,
+ ParameterChangePacket.HEADER: ParameterChangePacket,
+ CoupleStatusPacket.HEADER: CoupleStatusPacket,
+ UpdateAttackRangePacket.HEADER: UpdateAttackRangePacket,
+ NewMailStatusPacket.HEADER: NewMailStatusPacket,
+ QuestListPacket.HEADER: QuestListPacket,
}
diff --git a/extractor/grf.gd b/extractor/grf.gd
index 8cb03c1..27dcab0 100644
--- a/extractor/grf.gd
+++ b/extractor/grf.gd
@@ -1,4 +1,40 @@
class_name GRF
+
class Header:
- var signature: int
+ static var byte_length: int = 46
+
+ ## Byte Length: 15
+ ## Master of Magic
+ var signature: String
+
+ ## Byte Length: 15
+ var encryption: PackedByteArray
+
+ ## Byte Type: u32
+ ## Byte Length: 4
+ var file_table_offset: int
+
+ ## Byte Type: u32
+ ## Byte Length: 4
+ var reserved_files: int
+
+ ## Byte Type: u32
+ ## Byte Length: 4
+ var file_count: int
+
+ ## Byte Type: u32
+ ## Byte Length: 4
+ var version: int
+
+
+ static func from_file(file: FileAccess):
+ var header = Header.new()
+ header.signature = file.get_buffer(15).get_string_from_utf8()
+ header.encryption = file.get_buffer(15)
+ header.file_table_offset = file.get_buffer(4).decode_u32(0)
+ header.reserved_files = file.get_buffer(4).decode_u32(0)
+ header.file_count = file.get_buffer(4).decode_u32(0)
+ header.version = file.get_buffer(4).decode_u32(0)
+
+ return header
diff --git a/login.gd b/login.gd
index 97daf51..3e69981 100644
--- a/login.gd
+++ b/login.gd
@@ -19,7 +19,9 @@ func switch_screen(screen: Node):
func _on_login_pressed() -> void:
- account_information = Network.login_server.login(%Username.text, %Password.text)
+ Network.login_server.login(%Username.text, %Password.text)
+
+ account_information = await Network.login_server.logged_in
character_server_information = account_information.character_server_information
for node in %CharacterServerList.get_children():
@@ -28,9 +30,7 @@ func _on_login_pressed() -> void:
for info: CharacterServerInformation in character_server_information:
var select_character_server = Button.new()
select_character_server.text = info.server_name
- select_character_server.pressed.connect(func():
- _on_character_server_login_pressed(info)
- )
+ select_character_server.pressed.connect(_on_character_server_login_pressed.bind(info))
%CharacterServerList.add_child(select_character_server)
switch_screen(%CharacterServer)
@@ -42,15 +42,16 @@ func _on_character_server_login_pressed(character_server_info: CharacterServerIn
character_server_info.server_port
)
- var _response = Network.character_server.login(
+ Network.character_server.login(
account_information.account_id,
account_information.login_id1,
account_information.login_id2,
account_information.gender
)
- print(inst_to_dict(_response))
+ var _response = await Network.character_server.logged_in
- var response = Network.character_server.request_character_list()
+ Network.character_server.request_character_list()
+ var response: RequestCharacterListSuccessPacket = await Network.character_server.requested_character_list
for slot_idx in response.character_information.size():
var info: CharacterInformation = response.character_information[slot_idx]
@@ -66,18 +67,21 @@ func _on_character_server_login_pressed(character_server_info: CharacterServerIn
func _on_character_selected_pressed(slot_idx: int):
- var success = Network.character_server.select_character(slot_idx)
+ Network.character_server.select_character(slot_idx)
- Network.map_server = MapServer.new(
- success.get_map_server_ip(),
- success.map_server_port
- )
-
- var _response = Network.map_server.login(
- account_information.account_id,
- current_character_information.character_id,
- account_information.login_id1,
- account_information.gender
- )
+ var packet = await Network.character_server.selected_character
+ if packet is CharacterSelectionSuccessPacket:
+ Network.map_server = MapServer.new(
+ packet.get_map_server_ip(),
+ packet.map_server_port
+ )
+
+ Network.map_server.login(
+ account_information.account_id,
+ current_character_information.character_id,
+ account_information.login_id1,
+ account_information.gender
+ )
+ var _response = await Network.map_server.logged_in
# TODO: switch to game :)
diff --git a/network/character_server.gd b/network/character_server.gd
index e710639..f629283 100644
--- a/network/character_server.gd
+++ b/network/character_server.gd
@@ -1,6 +1,11 @@
class_name CharacterServer
+signal received_packet(packet: Packet)
+signal logged_in(packet: CharacterServerLoginSuccessPacket)
+signal requested_character_list(packet: RequestCharacterListSuccessPacket)
+signal selected_character(packet: CharacterSelectionSuccessPacket)
+
var host: String
var port: int = 6121
var stream: PacketPeerStream = PacketPeerStream.new()
@@ -17,7 +22,20 @@ func _init(host: String, port: int = 6121) -> void:
peer.poll()
-func login(account_id: int, login_id1: int, login_id2: int, gender: Constants.Gender) -> CharacterServerLoginSuccessPacket:
+## Emits [signal received_packet].
+func listen() -> void:
+ if peer.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED:
+ var raw_packet: PackedByteArray = peer.get_partial_data(2)[1]
+ if raw_packet.size() > 0:
+ raw_packet += peer.get_data(peer.get_available_bytes())[1]
+ var header = raw_packet.decode_u16(0)
+ var packet_type = Constants.PacketDB[header]
+ var packet = packet_type.from_bytes(raw_packet)
+
+ received_packet.emit(packet)
+
+
+func login(account_id: int, login_id1: int, login_id2: int, gender: Constants.Gender):
var character_server_login_packet = CharacterServerLoginPacket.new()
character_server_login_packet.account_id = account_id
character_server_login_packet.login_id1 = login_id1
@@ -26,29 +44,31 @@ func login(account_id: int, login_id1: int, login_id2: int, gender: Constants.Ge
peer.put_data(character_server_login_packet.to_bytes())
- var success = CharacterServerLoginSuccessPacket.from_bytes_via_peer(peer)
- print(inst_to_dict(success))
+ peer.get_data(4) # in-between packet
- return success
+ var packet = await received_packet
+ if packet is CharacterServerLoginSuccessPacket:
+ print(inst_to_dict(packet))
+ logged_in.emit(packet)
-func request_character_list() -> RequestCharacterListSuccessPacket:
+func request_character_list():
var request_character_list_packet = RequestCharacterListPacket.new()
peer.put_data(request_character_list_packet.to_bytes())
- var success = RequestCharacterListSuccessPacket.from_bytes_via_peer(peer)
- print(inst_to_dict(success))
-
- return success
+ var packet = await received_packet
+ if packet is RequestCharacterListSuccessPacket:
+ print(inst_to_dict(packet), inst_to_dict(packet.character_information[0]))
+ requested_character_list.emit(packet)
-func select_character(slot: int) -> CharacterSelectionSuccessPacket:
+func select_character(slot: int):
var select_character_packet = SelectCharacterPacket.new()
select_character_packet.selected_slot = slot
peer.put_data(select_character_packet.to_bytes())
- var success = CharacterSelectionSuccessPacket.from_bytes_via_peer(peer)
- print(inst_to_dict(success))
-
- return success
+ var packet = await received_packet
+ if packet is CharacterSelectionSuccessPacket:
+ print(inst_to_dict(packet))
+ selected_character.emit(packet)
diff --git a/network/login_server.gd b/network/login_server.gd
index bb7c093..6d878c4 100644
--- a/network/login_server.gd
+++ b/network/login_server.gd
@@ -1,6 +1,9 @@
class_name LoginServer
+signal received_packet(packet: Packet)
+signal logged_in(packet: LoginServerLoginSuccessPacket)
+
var host: String
var port: int = 6900
var stream: PacketPeerStream = PacketPeerStream.new()
@@ -17,15 +20,27 @@ func _init(host: String, port: int = 6900) -> void:
peer.poll()
-func login(username: String, password: String) -> LoginServerLoginSuccessPacket:
+## Emits [signal received_packet].
+func listen() -> void:
+ if peer.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED:
+ var raw_packet: PackedByteArray = peer.get_partial_data(2)[1]
+ if raw_packet.size() > 0:
+ raw_packet += peer.get_data(peer.get_available_bytes())[1]
+ var header = raw_packet.decode_u16(0)
+ var packet_type = Constants.PacketDB[header]
+ var packet = packet_type.from_bytes(raw_packet)
+
+ received_packet.emit(packet)
+
+
+func login(username: String, password: String):
var login_server_login_packet = LoginServerLoginPacket.new()
login_server_login_packet.username = username
login_server_login_packet.password = password
peer.put_data(login_server_login_packet.to_bytes())
- var success = LoginServerLoginSuccessPacket.from_bytes_via_peer(peer)
- var character_server_information: CharacterServerInformation = success.character_server_information[0]
- print(inst_to_dict(success), inst_to_dict(character_server_information))
-
- return success
+ var packet = await received_packet
+ if packet is LoginServerLoginSuccessPacket:
+ print(inst_to_dict(packet))
+ logged_in.emit(packet)
diff --git a/network/map_server.gd b/network/map_server.gd
index af46c6c..f4dacc1 100644
--- a/network/map_server.gd
+++ b/network/map_server.gd
@@ -1,6 +1,9 @@
class_name MapServer
+signal received_packet(packet: Packet)
+signal logged_in(packet: MapServerLoginSuccessPacket)
+
var host: String
var port: int = 5121
var stream: PacketPeerStream = PacketPeerStream.new()
@@ -17,7 +20,24 @@ func _init(host: String, port: int = 5121) -> void:
peer.poll()
-func login(account_id: int, character_id: int, login_id1: int, gender: Constants.Gender) -> MapServerLoginSuccessPacket:
+## Emits [signal received_packet].
+func listen() -> void:
+ if peer.get_status() == StreamPeerTCP.Status.STATUS_CONNECTED:
+ var raw_packet: PackedByteArray = peer.get_partial_data(2)[1]
+
+ if raw_packet.size() > 0:
+ var header = raw_packet.decode_u16(0)
+ var packet_type = Constants.PacketDB[header]
+ if packet_type.BYTE_LENGTH > 0:
+ raw_packet += peer.get_data(packet_type.BYTE_LENGTH - 2)[1]
+ else:
+ raw_packet += peer.get_data(peer.get_available_bytes())[1]
+ var packet = packet_type.from_bytes(raw_packet)
+
+ received_packet.emit(packet)
+
+
+func login(account_id: int, character_id: int, login_id1: int, gender: Constants.Gender):
var map_server_login_packet = MapServerLoginPacket.new()
map_server_login_packet.account_id = account_id
map_server_login_packet.character_id = character_id
@@ -29,7 +49,7 @@ func login(account_id: int, character_id: int, login_id1: int, gender: Constants
peer.get_data(6) # in-between packet
peer.get_data(4) # in-between packet
- var success = MapServerLoginSuccessPacket.from_bytes_via_peer(peer)
- print(inst_to_dict(success))
-
- return success
+ var packet = await received_packet
+ if packet is MapServerLoginSuccessPacket:
+ print(inst_to_dict(packet))
+ logged_in.emit(packet)
diff --git a/network/network.gd b/network/network.gd
index 25607a2..1e665a3 100644
--- a/network/network.gd
+++ b/network/network.gd
@@ -109,7 +109,16 @@ func _ready() -> void:
#print(msls.get_position())
var file = FileAccess.open("res://data/data.grf", FileAccess.READ)
- var signature = file.get_buffer("Master of Magic".length())
- print(signature.get_string_from_utf8())
- print(file.get_16())
- print(file.get_32())
+ var header = GRF.Header.from_file(file)
+ print(inst_to_dict(header))
+
+
+func _process(_delta: float) -> void:
+ if login_server:
+ login_server.listen()
+
+ if character_server:
+ character_server.listen()
+
+ if map_server:
+ map_server.listen()
diff --git a/packets/character_selection_success_packet.gd b/packets/character_selection_success_packet.gd
index f483d9e..b43b4b5 100644
--- a/packets/character_selection_success_packet.gd
+++ b/packets/character_selection_success_packet.gd
@@ -2,7 +2,8 @@ class_name CharacterSelectionSuccessPacket
extends Packet
-static var header := 0x0ac5
+const HEADER := 0x0ac5
+const BYTE_LENGTH := 0
## Byte Type: u32
@@ -38,16 +39,10 @@ func get_map_server_ip():
static func from_bytes(bytes: PackedByteArray):
var packet = CharacterSelectionSuccessPacket.new()
- packet.character_id = bytes.decode_u32(0)
- packet.map_name = bytes.slice(4, 4 + 16).get_string_from_utf8()
- packet.map_server_ip = bytes.slice(20, 20 + 4)
- packet.map_server_port = bytes.decode_u16(24)
- packet.unknown = bytes.slice(26)
+ packet.character_id = bytes.decode_u32(2)
+ packet.map_name = bytes.slice(6, 6 + 16).get_string_from_utf8()
+ packet.map_server_ip = bytes.slice(22, 22 + 4)
+ packet.map_server_port = bytes.decode_u16(26)
+ packet.unknown = bytes.slice(28)
return packet
-
-static func from_bytes_via_peer(peer: StreamPeer):
- var _header = peer.get_data(2)
- var remaining_bytes = peer.get_data(peer.get_available_bytes())
-
- return from_bytes(remaining_bytes[1])
diff --git a/packets/character_server_login_packet.gd b/packets/character_server_login_packet.gd
index 0e3116f..a2d4f7d 100644
--- a/packets/character_server_login_packet.gd
+++ b/packets/character_server_login_packet.gd
@@ -2,7 +2,8 @@ class_name CharacterServerLoginPacket
extends Packet
-static var header := 0x0065
+const HEADER := 0x0065
+const BYTE_LENGTH := 0
## Byte Type: u32
diff --git a/packets/character_server_login_success_packet.gd b/packets/character_server_login_success_packet.gd
index 800e218..bfe6c45 100644
--- a/packets/character_server_login_success_packet.gd
+++ b/packets/character_server_login_success_packet.gd
@@ -2,6 +2,10 @@ class_name CharacterServerLoginSuccessPacket
extends Packet
+const HEADER := 0x082d
+const BYTE_LENGTH := 0
+
+
## Byte Length: 2
var unknown: int
@@ -27,18 +31,12 @@ var unused: PackedByteArray
static func from_bytes(bytes: PackedByteArray):
var packet = CharacterServerLoginSuccessPacket.new()
- packet.unknown = bytes.decode_u16(0)
- packet.normal_slot_count = bytes.decode_u8(2)
- packet.vip_slot_count = bytes.decode_u8(3)
- packet.billing_slot_count = bytes.decode_u8(4)
- packet.producible_slot_count = bytes.decode_u8(5)
- packet.valid_slot = bytes.decode_u8(6)
- packet.unused = bytes.slice(7, 7 + 20)
+ packet.unknown = bytes.decode_u16(6)
+ packet.normal_slot_count = bytes.decode_u8(8)
+ packet.vip_slot_count = bytes.decode_u8(9)
+ packet.billing_slot_count = bytes.decode_u8(10)
+ packet.producible_slot_count = bytes.decode_u8(11)
+ packet.valid_slot = bytes.decode_u8(12)
+ packet.unused = bytes.slice(13, 13 + 20)
return packet
-
-static func from_bytes_via_peer(peer: StreamPeer):
- var _header = peer.get_data(6)
- var remaining_bytes = peer.get_data(peer.get_available_bytes())
-
- return from_bytes(remaining_bytes[1])
diff --git a/packets/couple_status_packet.gd b/packets/couple_status_packet.gd
new file mode 100644
index 0000000..9f41174
--- /dev/null
+++ b/packets/couple_status_packet.gd
@@ -0,0 +1,29 @@
+class_name CoupleStatusPacket
+extends Packet
+
+
+const HEADER := 0x0141
+const BYTE_LENGTH := 14
+
+
+## Byte Type: u32
+## Byte Length: 4
+var status_type: int
+
+## Byte Type: i32
+## Byte Length: 4
+var default_status: int
+
+## Byte Type: i32
+## Byte Length: 4
+var plus_status: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var packet = CoupleStatusPacket.new()
+
+ packet.status_type = bytes.decode_u32(2)
+ packet.default_status = bytes.decode_s32(6)
+ packet.plus_status = bytes.decode_s32(10)
+
+ return packet
diff --git a/packets/login_server_login_packet.gd b/packets/login_server_login_packet.gd
index 5b4c1f3..f7217fe 100644
--- a/packets/login_server_login_packet.gd
+++ b/packets/login_server_login_packet.gd
@@ -2,7 +2,8 @@ class_name LoginServerLoginPacket
extends Packet
-static var header := 0x064
+const HEADER := 0x064
+const BYTE_LENGTH := 0
## Byte Type: u32
diff --git a/packets/login_server_login_success_packet.gd b/packets/login_server_login_success_packet.gd
index fd7dbf1..1f95bae 100644
--- a/packets/login_server_login_success_packet.gd
+++ b/packets/login_server_login_success_packet.gd
@@ -2,9 +2,14 @@ class_name LoginServerLoginSuccessPacket
extends Packet
-static var header := 0x0ac4
+const HEADER := 0x0ac4
+const BYTE_LENGTH := 0
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
## Byte Type: u32
## Byte Length: 4
var login_id1: int
@@ -41,19 +46,14 @@ var character_server_information: Array
static func from_bytes(bytes: PackedByteArray):
var packet = LoginServerLoginSuccessPacket.new()
- packet.login_id1 = bytes.decode_u32(0)
- packet.account_id = bytes.decode_u32(4)
- packet.login_id2 = bytes.decode_u32(8)
- packet.ip_address = bytes.slice(12, 16)
- packet.last_login = bytes.slice(16, 16 + 26)
- packet.gender = bytes[42]
- packet.auth_token = bytes.slice(43, 43 + 17).get_string_from_utf8()
- packet.character_server_information = CharacterServerInformation.array_from_bytes(bytes.slice(60))
+ packet.packet_length = bytes.decode_u16(2)
+ packet.login_id1 = bytes.decode_u32(4)
+ packet.account_id = bytes.decode_u32(8)
+ packet.login_id2 = bytes.decode_u32(12)
+ packet.ip_address = bytes.slice(16, 20)
+ packet.last_login = bytes.slice(20, 20 + 26)
+ packet.gender = bytes[46]
+ packet.auth_token = bytes.slice(47, 47 + 17).get_string_from_utf8()
+ packet.character_server_information = CharacterServerInformation.array_from_bytes(bytes.slice(64))
return packet
-
-static func from_bytes_via_peer(peer: StreamPeer):
- var _header = peer.get_data(4) # 2 = header, 2 = packet_size
- var remaining_bytes = peer.get_data(peer.get_available_bytes())
-
- return from_bytes(remaining_bytes[1])
diff --git a/packets/map_server_login_packet.gd b/packets/map_server_login_packet.gd
index 89d0108..726cdff 100644
--- a/packets/map_server_login_packet.gd
+++ b/packets/map_server_login_packet.gd
@@ -2,7 +2,8 @@ class_name MapServerLoginPacket
extends Packet
-static var header := 0x0436
+const HEADER := 0x0436
+const BYTE_LENGTH := 0
## Byte Type: u32
diff --git a/packets/map_server_login_success_packet.gd b/packets/map_server_login_success_packet.gd
index 9eecc65..1791a85 100644
--- a/packets/map_server_login_success_packet.gd
+++ b/packets/map_server_login_success_packet.gd
@@ -2,7 +2,8 @@ class_name MapServerLoginSuccessPacket
extends Packet
-static var header := 0x02eb
+const HEADER := 0x02eb
+const BYTE_LENGTH := 0
## Byte Type: u32
@@ -33,16 +34,9 @@ func get_position():
static func from_bytes(bytes: PackedByteArray):
var packet = MapServerLoginSuccessPacket.new()
- packet.client_tick = bytes.decode_u32(0)
- packet.position = bytes.slice(4, 4 + 3)
- packet.ignored = bytes.slice(7, 7 + 2)
- packet.font = bytes.decode_u32(9)
+ packet.client_tick = bytes.decode_u32(2)
+ packet.position = bytes.slice(6, 6 + 3)
+ packet.ignored = bytes.slice(9, 9 + 2)
+ packet.font = bytes.decode_u32(11)
return packet
-
-
-static func from_bytes_via_peer(peer: StreamPeer):
- var _header = peer.get_data(2)
- var remaining_bytes = peer.get_data(peer.get_available_bytes())
-
- return from_bytes(remaining_bytes[1])
diff --git a/packets/new_mail_status_packet.gd b/packets/new_mail_status_packet.gd
new file mode 100644
index 0000000..4e87ed5
--- /dev/null
+++ b/packets/new_mail_status_packet.gd
@@ -0,0 +1,19 @@
+class_name NewMailStatusPacket
+extends Packet
+
+
+const HEADER := 0x09e7
+const BYTE_LENGTH := 3
+
+
+## Byte Type: u8
+## Byte Length: 1
+var new_available: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var packet = NewMailStatusPacket.new()
+
+ packet.new_available = bytes.decode_u8(2)
+
+ return packet
diff --git a/packets/packet.gd b/packets/packet.gd
index 9f82782..33db0b1 100644
--- a/packets/packet.gd
+++ b/packets/packet.gd
@@ -15,7 +15,7 @@ func get_byte_length() -> int:
## [param packet_length] is only needed when the packet has a variable length.
func get_header(packet_length: int = 0) -> PackedByteArray:
var bytes = PackedByteArray([0,0])
- bytes.encode_u16(0, self.header)
+ bytes.encode_u16(0, self.HEADER)
if packet_length > 0:
bytes.resize(4)
diff --git a/packets/parameter_change_packet.gd b/packets/parameter_change_packet.gd
new file mode 100644
index 0000000..138b4f5
--- /dev/null
+++ b/packets/parameter_change_packet.gd
@@ -0,0 +1,24 @@
+class_name ParameterChangePacket
+extends Packet
+
+
+const HEADER := 0x00b0
+const BYTE_LENGTH := 8
+
+
+## Byte Type: u16
+## Byte Length: 2
+var parameter_id: int
+
+## Byte Type: i32
+## Byte Length: 4
+var count: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var packet = ParameterChangePacket.new()
+
+ packet.parameter_id = bytes.decode_u16(2)
+ packet.count = bytes.decode_s32(4)
+
+ return packet
diff --git a/packets/quest.gd b/packets/quest.gd
new file mode 100644
index 0000000..347f5d1
--- /dev/null
+++ b/packets/quest.gd
@@ -0,0 +1,54 @@
+class_name Quest
+extends PacketChunk
+
+
+## Byte Type: u32
+## Byte Length: 4
+var quest_id: int
+
+## Byte Type: u8
+## Byte Length: 1
+var active: int
+
+## Byte Type: u32
+## Byte Length: 4
+var remaining_time: int
+
+## Byte Type: u32
+## Byte Length: 4
+var expire_time: int
+
+## Byte Type: u16
+## Byte Length: 2
+var objective_count: int
+
+var objective_details: Array
+
+
+func get_byte_length():
+ return "??"
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var quest = Quest.new()
+
+ quest.quest_id = bytes.slice(0, 4)
+ quest.active = bytes.decode_u16(4)
+ quest.remaining_time = bytes.slice(6, 6 + 20).get_string_from_utf8()
+ quest.expire_time = bytes.decode_u16(26)
+ quest.objective_count = bytes.decode_u16(28)
+ quest.objective_details = bytes.slice(32)
+
+ return quest
+
+
+static func array_from_bytes(bytes: PackedByteArray) -> Array:
+ var array = []
+
+ var offset = 0
+ while offset < bytes.size():
+ var chunk = from_bytes(bytes.slice(offset))
+ array.append(chunk)
+ offset += chunk.byte_length
+
+ return array
diff --git a/packets/quest_details.gd b/packets/quest_details.gd
new file mode 100644
index 0000000..eaf8d2e
--- /dev/null
+++ b/packets/quest_details.gd
@@ -0,0 +1,65 @@
+class_name QuestDetails
+extends PacketChunk
+
+
+## Byte Type: u32
+## Byte Length: 4
+var hunt_identification: int
+
+## Byte Type: u32
+## Byte Length: 4
+var objective_type: int
+
+## Byte Type: u32
+## Byte Length: 4
+var mob_id: int
+
+## Byte Type: u16
+## Byte Length: 2
+var minimum_level: int
+
+## Byte Type: u16
+## Byte Length: 2
+var maximum_level: int
+
+## Byte Type: u16
+## Byte Length: 2
+var kill_count: int
+
+## Byte Type: u16
+## Byte Length: 2
+var total_count: int
+
+## Byte Type: u8
+## Byte Length: 24
+var mob_name: String
+
+
+func get_byte_length():
+ return 44
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var details = QuestDetails.new()
+
+ details.server_ip = bytes.slice(0, 4)
+ details.server_port = bytes.decode_u16(4)
+ details.server_name = bytes.slice(6, 6 + 20).get_string_from_utf8()
+ details.user_count = bytes.decode_u16(26)
+ details.server_type = bytes.decode_u16(28)
+ details.display_new = bytes.decode_u16(30)
+ details.unknown = bytes.slice(32)
+
+ return details
+
+
+static func array_from_bytes(bytes: PackedByteArray) -> Array:
+ var array = []
+
+ var offset = 0
+ while offset < bytes.size():
+ var chunk = from_bytes(bytes.slice(offset))
+ array.append(chunk)
+ offset += chunk.byte_length
+
+ return array
diff --git a/packets/quest_list_packet.gd b/packets/quest_list_packet.gd
new file mode 100644
index 0000000..bf78f08
--- /dev/null
+++ b/packets/quest_list_packet.gd
@@ -0,0 +1,26 @@
+class_name QuestListPacket
+extends Packet
+
+
+const HEADER := 0x09f8
+const BYTE_LENGTH := 0
+
+
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
+## Byte Type: u32
+## Byte Length: 4
+var quest_count: int
+
+var quests: Array
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var packet = QuestListPacket.new()
+
+ packet.packet_length = bytes.decode_u16(2)
+ packet.quest_count = bytes.decode_u32(4)
+
+ return packet
diff --git a/packets/request_character_list_packet.gd b/packets/request_character_list_packet.gd
index e347abd..e2c761d 100644
--- a/packets/request_character_list_packet.gd
+++ b/packets/request_character_list_packet.gd
@@ -2,7 +2,8 @@ class_name RequestCharacterListPacket
extends Packet
-static var header := 0x09a1
+const HEADER := 0x09a1
+const BYTE_LENGTH := 0
func to_bytes():
diff --git a/packets/request_character_list_success_packet.gd b/packets/request_character_list_success_packet.gd
index 431e8ca..f85decc 100644
--- a/packets/request_character_list_success_packet.gd
+++ b/packets/request_character_list_success_packet.gd
@@ -2,19 +2,21 @@ class_name RequestCharacterListSuccessPacket
extends Packet
+const HEADER := 0x0b72
+const BYTE_LENGTH := 0
+
+
+## Byte Type: u16
+## Byte Length: 2
+var packet_length: int
+
var character_information: Array
static func from_bytes(bytes: PackedByteArray):
var packet = RequestCharacterListSuccessPacket.new()
- packet.character_information = CharacterInformation.array_from_bytes(bytes)
+ packet.packet_length = bytes.decode_u16(2)
+ packet.character_information = CharacterInformation.array_from_bytes(bytes.slice(4))
return packet
-
-
-static func from_bytes_via_peer(peer: StreamPeer):
- var _header = peer.get_data(4) # 2 = header, 2 = length
- var remaining_bytes = peer.get_data(peer.get_available_bytes())
-
- return from_bytes(remaining_bytes[1])
diff --git a/packets/select_character_packet.gd b/packets/select_character_packet.gd
index 18843cc..692183f 100644
--- a/packets/select_character_packet.gd
+++ b/packets/select_character_packet.gd
@@ -2,7 +2,8 @@ class_name SelectCharacterPacket
extends Packet
-static var header := 0x0066
+const HEADER := 0x0066
+const BYTE_LENGTH := 0
## Byte Type: u8
diff --git a/packets/update_attack_range_packet.gd b/packets/update_attack_range_packet.gd
new file mode 100644
index 0000000..1ace166
--- /dev/null
+++ b/packets/update_attack_range_packet.gd
@@ -0,0 +1,19 @@
+class_name UpdateAttackRangePacket
+extends Packet
+
+
+const HEADER := 0x013a
+const BYTE_LENGTH := 4
+
+
+## Byte Type: i16
+## Byte Length: 2
+var current_attack_range: int
+
+
+static func from_bytes(bytes: PackedByteArray):
+ var packet = UpdateAttackRangePacket.new()
+
+ packet.current_attack_range = bytes.decode_s16(2)
+
+ return packet