diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2024-12-22 18:38:11 +0100 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2024-12-22 18:38:11 +0100 |
commit | 7b3f386449aeab124d84d2aff4c273e646e68763 (patch) | |
tree | 9d24a7de247d190edcd8e315fc3e45ab8a4a8d34 | |
parent | f4e07d090cded56ebab54363f1b47f1ea45c8682 (diff) |
-rw-r--r-- | byte_stream.gd | 3 | ||||
-rw-r--r-- | client.gd | 11 | ||||
-rw-r--r-- | extensions/rust/.gdignore | 0 | ||||
-rw-r--r-- | extractor/action_format.gd | 2 | ||||
-rw-r--r-- | extractor/gat_format.gd | 8 | ||||
-rw-r--r-- | extractor/gnd_format.gd | 294 | ||||
-rw-r--r-- | extractor/rsw_format.gd | 519 | ||||
-rw-r--r-- | packets/map_server/moving_entity_appeared_packet.gd | 181 | ||||
-rw-r--r-- | ui/login.tscn | 2 |
9 files changed, 1012 insertions, 8 deletions
diff --git a/byte_stream.gd b/byte_stream.gd index 2ef85d2..219e977 100644 --- a/byte_stream.gd +++ b/byte_stream.gd @@ -97,3 +97,6 @@ func decode_float() -> float: func get_string_from_utf8(length: int) -> String: return get_buffer(length).bytes.get_string_from_utf8() + +func get_string_from_ascii(length: int) -> String: + return get_buffer(length).bytes.get_string_from_ascii() @@ -26,3 +26,14 @@ func _ready() -> void: FileAccess.get_file_as_bytes("res://client_data/data/int_land02.gat") ) ) + GNDFormat.from_bytes( + ByteStream.from_bytes( + FileAccess.get_file_as_bytes("res://client_data/data/int_land02.gnd") + ) + ) + RSWFormat.from_bytes( + ByteStream.from_bytes( + #FileAccess.get_file_as_bytes("res://client_data/data/int_land02.rsw") + FileAccess.get_file_as_bytes("res://client_data/data/pay_dun00.rsw") + ) + ) diff --git a/extensions/rust/.gdignore b/extensions/rust/.gdignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/extensions/rust/.gdignore diff --git a/extractor/action_format.gd b/extractor/action_format.gd index 97f6771..d61c590 100644 --- a/extractor/action_format.gd +++ b/extractor/action_format.gd @@ -49,7 +49,7 @@ func get_byte_length() -> int: static func from_bytes(bytes: ByteStream) -> ActionFormat: var action_format = ActionFormat.new() - bytes.seek(2) + bytes.advance(action_format.signature.length()) @warning_ignore("shadowed_variable") var version = Version.new() diff --git a/extractor/gat_format.gd b/extractor/gat_format.gd index 213972a..712657b 100644 --- a/extractor/gat_format.gd +++ b/extractor/gat_format.gd @@ -45,22 +45,22 @@ static func from_bytes(bytes: ByteStream) -> GATFormat: class Tile: ## Byte Type: f32 [br] ## Byte Length: 4 [br] - ## Orignal Coordinates_ (0, 0) + ## Orignal Coordinates: (0, 0) var bottom_left_altitude: int ## Byte Type: f32 [br] ## Byte Length: 4 [br] - ## Orignal Coordinates_ (1, 0) + ## Orignal Coordinates: (1, 0) var bottom_right_altitude: int ## Byte Type: f32 [br] ## Byte Length: 4 [br] - ## Orignal Coordinates_ (0, 1) + ## Orignal Coordinates: (0, 1) var top_left_altitude: int ## Byte Type: f32 [br] ## Byte Length: 4 [br] - ## Orignal Coordinates_ (1, 1) + ## Orignal Coordinates: (1, 1) var top_right_altitude: int ## Byte Type: u32 ?[br] diff --git a/extractor/gnd_format.gd b/extractor/gnd_format.gd new file mode 100644 index 0000000..f13956e --- /dev/null +++ b/extractor/gnd_format.gd @@ -0,0 +1,294 @@ +class_name GNDFormat + + +## Byte Length: 4 [br] +## GRAT +var signature: String = "GRGN" + +## Byte Type: u8 [br] +## Byte Length: 2 +var version: Version + +## Byte Type: i32 [br] +## Byte Length: 4 +var width: int + +## Byte Type: i32 [br] +## Byte Length: 4 +var height: int + +## Byte Type: f32 [br] +## Byte Length: 4 [br] +## Always 10. +var scale: float + +## Byte Type: i32 [br] +## Byte Length: 4 +var texture_count: int + +## Byte Type: i32 [br] +## Byte Length: 4 +## Always 80. +var texture_path_length: int + +## Byte Length: [member texture_count] * [member texture_path_length] [br] +var texture_paths: Array + +## Byte Type: i32 [br] +## Byte Length: 4 +var light_map_slice_count: int + +## Byte Type: i32 [br] +## Byte Length: 4 +var light_map_width: int + +## Byte Type: i32 [br] +## Byte Length: 4 +var light_map_slice_height: int + +## Byte Type: i32 [br] +## Byte Length: 4 +var light_map_cells_per_grid: int + +## Length: [member light_map_slice_count] +var light_map_slices: Array + +## Byte Type: i32 [br] +## Byte Length: 4 +var surface_count: int + +## Length: [member surface_count] +var surfaces: Array[Surface] + +## Length: [member width] * [member height] +var ground_mesh_cubes: Array[GroundMeshCube] + + +static func from_bytes(bytes: ByteStream) -> GNDFormat: + var gnd_format = GNDFormat.new() + + bytes.advance(gnd_format.signature.length()) + + @warning_ignore("shadowed_variable") + var version = Version.new() + version.major = bytes.decode_u8() + version.minor = bytes.decode_u8() + gnd_format.version = version + + if version.minor > 7: + print(version) + return gnd_format + + gnd_format.width = bytes.decode_s32() + gnd_format.height = bytes.decode_s32() + gnd_format.scale = bytes.decode_float() + gnd_format.texture_count = bytes.decode_s32() + gnd_format.texture_path_length = bytes.decode_s32() + + gnd_format.texture_paths = [] + for _n in gnd_format.texture_count: + gnd_format.texture_paths.append( + bytes.get_string_from_ascii(gnd_format.texture_path_length) + ) + + gnd_format.light_map_slice_count = bytes.decode_s32() + gnd_format.light_map_width = bytes.decode_s32() + gnd_format.light_map_slice_height = bytes.decode_s32() + gnd_format.light_map_cells_per_grid = bytes.decode_s32() + + #gnd_format.light_map_slices = [] + #for _n in gnd_format.light_map_slice_count: + #gnd_format.light_map_slices.append(LightMapSlice.from_bytes(bytes)) + bytes.advance( + gnd_format.light_map_slice_count * + gnd_format.light_map_width * + gnd_format.light_map_slice_height * + 4 + ) + + gnd_format.surface_count = bytes.decode_s32() + + gnd_format.surfaces = [] as Array[Surface] + for _n in gnd_format.surface_count: + gnd_format.surfaces.append(Surface.from_bytes(bytes)) + + gnd_format.ground_mesh_cubes = [] as Array[GroundMeshCube] + for _n in (gnd_format.width * gnd_format.height): + gnd_format.ground_mesh_cubes.append(GroundMeshCube.from_bytes(bytes)) + + #print(inst_to_dict(gnd_format)) + return gnd_format + + +class LightMapSlice: + ## Byte Type: i32 [br] + ## Byte Length: 4 + var pixel_format: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var width: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var height: int + + ## Byte Length: [member width] * [member height] + var shadow_map_pixels: ByteStream + + ## Byte Length: [member width] * [member height] + var light_map_pixels: ByteStream + + + static func from_bytes(bytes: ByteStream) -> LightMapSlice: + var slice = LightMapSlice.new() + + slice.pixel_format = bytes.decode_s32() + slice.width = bytes.decode_s32() + slice.height = bytes.decode_s32() + slice.shadow_map_pixels = bytes.get_buffer(slice.width * slice.height) + slice.light_map_pixels = bytes.get_buffer(slice.width * slice.height) + + #print(inst_to_dict(slice)) + return slice + + +class Surface: + ## Byte Type: f32 [br] + ## Byte Length: 4 + var u_bottom_left: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var u_bottom_right: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var u_top_left: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var u_top_right: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var v_bottom_left: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var v_bottom_right: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var v_top_left: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var v_top_right: float + + ## Byte Type: i16 [br] + ## Byte Length: 2 + var texture_index: int + + ## Byte Type: i16 [br] + ## Byte Length: 2 + var light_map_index: int + + ## Byte Type: u8 [br] + ## Byte Length: 1 + var vertex_color_blue: int + + ## Byte Type: u8 [br] + ## Byte Length: 1 + var vertex_color_green: int + + ## Byte Type: u8 [br] + ## Byte Length: 1 + var vertex_color_red: int + + ## Byte Type: u8 [br] + ## Byte Length: 1 + var vertex_color_alpha: int + + + func get_uvs() -> Dictionary: # Dictionary[Vector2, Vector2] + return { + Vector2(0, 0): Vector2(u_top_left, v_top_left), + Vector2(1, 0): Vector2(u_top_right, v_top_right), + Vector2(0, 1): Vector2(u_bottom_left, v_bottom_left), + Vector2(1, 1): Vector2(u_bottom_right, v_bottom_right), + } + + + static func from_bytes(bytes: ByteStream) -> Surface: + var surface = Surface.new() + + surface.u_bottom_left = bytes.decode_float() + surface.u_bottom_right = bytes.decode_float() + surface.u_top_left = bytes.decode_float() + surface.u_top_right = bytes.decode_float() + surface.v_bottom_left = bytes.decode_float() + surface.v_bottom_right = bytes.decode_float() + surface.v_top_left = bytes.decode_float() + surface.v_top_right = bytes.decode_float() + surface.texture_index = bytes.decode_s16() + surface.light_map_index = bytes.decode_s16() + surface.vertex_color_blue = bytes.decode_u8() + surface.vertex_color_green = bytes.decode_u8() + surface.vertex_color_red = bytes.decode_u8() + surface.vertex_color_alpha = bytes.decode_u8() + + #print(inst_to_dict(surface)) + return surface + + +class GroundMeshCube: + ## Byte Type: f32 [br] + ## Byte Length: 4 + ## upper left? + var bottom_left_height: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + ## upper right? + var bottom_right_height: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + ## lower left? + var top_left_height: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + ## lower right? + var top_right_height: float + + ## Byte Type: i32 [br] + ## Byte Length: 4 + ## top surface index? + var upwards_facing_surface_index: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + ## front surface index? + var northern_wall_surface_index: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + ## right surface index? + var eastern_wall_surface_index: int + + + static func from_bytes(bytes: ByteStream) -> GroundMeshCube: + var mesh = GroundMeshCube.new() + + mesh.bottom_left_height = bytes.decode_float() + mesh.bottom_right_height = bytes.decode_float() + mesh.top_left_height = bytes.decode_float() + mesh.top_right_height = bytes.decode_float() + mesh.upwards_facing_surface_index = bytes.decode_s32() + mesh.northern_wall_surface_index = bytes.decode_s32() + mesh.eastern_wall_surface_index = bytes.decode_s32() + + #print(inst_to_dict(mesh)) + return mesh diff --git a/extractor/rsw_format.gd b/extractor/rsw_format.gd new file mode 100644 index 0000000..18874e2 --- /dev/null +++ b/extractor/rsw_format.gd @@ -0,0 +1,519 @@ +class_name RSWFormat + + +## Byte Length: 4 [br] +## GRAT +var signature: String = "GRSW" + +## Byte Type: u8 [br] +## Byte Length: 2 +var version: Version + +## Byte Type: u8, u32 [br] +## Byte Length: 1, 4 +## Versions: [2.2, 2.5] +var build_number: int + +## Byte Type: u8 [br] +## Byte Length: 1 +## Versions: [2.5] +var unknown_render_flag: int + +## Byte Type: u8 [br] +## Byte Length: 40 +var ini_file: String + +## Byte Type: u8 [br] +## Byte Length: 40 +var gnd_file: String + +## Byte Type: u8 [br] +## Byte Length: 40 +var gat_file: String + +## Byte Type: u8 [br] +## Byte Length: 40 +## Versions: [1.4] +var source_file: String + +var water_configuration: WaterConfiguration +var lighting_parameters: LightingParameters + +## Byte Type: u32 [br] +## Byte Length: 4 +var map_resource_count: int + +## Length: [member map_resource_count] +var map_resources: Array[MapResource] + +var quad_tree + + +static func from_bytes(bytes: ByteStream) -> RSWFormat: + var rsw_format = RSWFormat.new() + + bytes.advance(rsw_format.signature.length()) + + @warning_ignore("shadowed_variable") + var version = Version.new() + version.major = bytes.decode_u8() + version.minor = bytes.decode_u8() + rsw_format.version = version + + if version.major < 2: + print(version) + return rsw_format + + if version.major >= 2 and version.minor >= 5: + rsw_format.build_number = bytes.decode_u32() + rsw_format.unknown_render_flag = bytes.decode_u8() + elif version.major >= 2 and version.minor >= 2: + rsw_format.build_number = bytes.decode_u8() + + rsw_format.ini_file = bytes.get_string_from_utf8(40) + rsw_format.gnd_file = bytes.get_string_from_utf8(40) + rsw_format.gat_file = bytes.get_string_from_utf8(40) + rsw_format.source_file = bytes.get_string_from_utf8(40) + + if version.major >= 2 and version.minor <= 5: + rsw_format.water_configuration = WaterConfiguration.from_bytes(bytes) + + rsw_format.lighting_parameters = LightingParameters.from_bytes(bytes) + + bytes.advance(16) # map boundaries - bounding box # TODO + + rsw_format.map_resource_count = bytes.decode_u32() + rsw_format.map_resources = [] as Array[MapResource] + for _n in rsw_format.map_resource_count: + var resource_type = bytes.decode_u32() + var resource: MapResource + + if resource_type == MapResourceType.Animated3DModel: + resource = Animated3DModel.from_bytes(bytes) + elif resource_type == MapResourceType.DynamicLightSource: + resource = DynamicLightSource.from_bytes(bytes) + elif resource_type == MapResourceType.SpatialAudioSource: + resource = SpatialAudioSource.from_bytes(bytes) + elif resource_type == MapResourceType.ParticleEffectEmitter: + resource = ParticleEffectEmitter.from_bytes(bytes) + + rsw_format.map_resources.append(resource) + + # TODO: quadtree + + #print(inst_to_dict(rsw_format)) + return rsw_format + + +class WaterConfiguration: + ## Byte Type: f32 [br] + ## Byte Length: 4 + var water_level: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var water_type: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var wave_height: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var wave_speed: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var wave_pitch: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var water_animation_speed: int + + + static func from_bytes(bytes: ByteStream) -> WaterConfiguration: + var config = WaterConfiguration.new() + + config.water_level = bytes.decode_float() + config.water_type = bytes.decode_u32() + config.wave_height = bytes.decode_float() + config.wave_speed = bytes.decode_float() + config.wave_pitch = bytes.decode_float() + config.water_animation_speed = bytes.decode_u32() + + return config + + +class LightingParameters: + ## Byte Type: i32 [br] + ## Byte Length: 4 + var longitude: int + + ## Byte Type: i32 [br] + ## Byte Length: 4 + var latitude: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_r: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_g: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_b: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var ambient_color_r: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var ambient_color_g: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var ambient_color_b: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + ## Shadow Map Alpha + var intensity: int + + + func get_diffuse_color() -> Color: + return Color(diffuse_color_r, diffuse_color_g, diffuse_color_b) + + + func get_ambient_color() -> Color: + return Color(ambient_color_r, ambient_color_g, ambient_color_b) + + + static func from_bytes(bytes: ByteStream) -> LightingParameters: + var params = LightingParameters.new() + + params.longitude = bytes.decode_s32() + params.latitude = bytes.decode_s32() + params.diffuse_color_r = bytes.decode_float() + params.diffuse_color_g = bytes.decode_float() + params.diffuse_color_b = bytes.decode_float() + params.ambient_color_r = bytes.decode_float() + params.ambient_color_g = bytes.decode_float() + params.ambient_color_b = bytes.decode_float() + params.intensity = bytes.decode_float() + + return params + + +class MapResource: + pass + +enum MapResourceType { + Animated3DModel = 1, + DynamicLightSource = 2, + SpatialAudioSource = 3, + ParticleEffectEmitter = 4, +} + +enum ModelAnimationType { + None = 0, + Looping = 2, +} + +enum ParticlePresetEffect { + None = -1, + Hit_1 = 1, + Hit_2 = 2, + Hit_3 = 3, + Torch = 47, + TunaParty = 1097, +} + + +class Animated3DModel extends MapResource: + ## Byte Type: u8 [br] + ## Byte Length: 40 + var name: String + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var animation_type: ModelAnimationType + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var animation_speed_percent: float + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var collision_flags: int + + ## Byte Type: u8 [br] + ## Byte Length: 80 + var model_file: String + + ## Byte Type: u8 [br] + ## Byte Length: 80 + var root_node_name: String + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_z: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var rotation_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var rotation_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var rotation_z: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var scale_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var scale_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var scale_z: float + + + func get_position() -> Vector3: + return Vector3(position_x, position_y, position_z) + + + func get_rotation() -> Vector3: + return Vector3(rotation_x, rotation_y, rotation_z) + + + func get_scale() -> Vector3: + return Vector3(scale_x, scale_y, scale_z) + + + static func from_bytes(bytes: ByteStream) -> Animated3DModel: + var resource = Animated3DModel.new() + + resource.name = bytes.get_string_from_ascii(40) + resource.animation_type = bytes.decode_u32() + resource.animation_speed_percent = bytes.decode_float() + resource.collision_flags = bytes.decode_u32() + resource.model_file = bytes.get_string_from_ascii(80) + resource.root_node_name = bytes.get_string_from_utf8(80) + resource.position_x = bytes.decode_float() + resource.position_y = bytes.decode_float() + resource.position_z = bytes.decode_float() + resource.rotation_x = bytes.decode_float() + resource.rotation_y = bytes.decode_float() + resource.rotation_z = bytes.decode_float() + resource.scale_x = bytes.decode_float() + resource.scale_y = bytes.decode_float() + resource.scale_z = bytes.decode_float() + + #print(inst_to_dict(resource)) + return resource + + +class DynamicLightSource extends MapResource: + ## Byte Type: u8 [br] + ## Byte Length: 80 + var name: String + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_z: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_r: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_g: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var diffuse_color_b: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var light_range: float + + + func get_position() -> Vector3: + return Vector3(position_x, position_y, position_z) + + + func get_diffuse_color() -> Color: + return Color(diffuse_color_r, diffuse_color_g, diffuse_color_b) + + + static func from_bytes(bytes: ByteStream) -> DynamicLightSource: + var resource = DynamicLightSource.new() + + resource.name = bytes.get_string_from_ascii(80) + resource.position_x = bytes.decode_float() + resource.position_y = bytes.decode_float() + resource.position_z = bytes.decode_float() + resource.diffuse_color_r = bytes.decode_float() + resource.diffuse_color_g = bytes.decode_float() + resource.diffuse_color_b = bytes.decode_float() + resource.light_range = bytes.decode_float() + + #print(inst_to_dict(resource)) + return resource + + +class SpatialAudioSource extends MapResource: + ## Byte Type: u8 [br] + ## Byte Length: 80 + var name: String + + ## Byte Type: u8 [br] + ## Byte Length: 80 + var audio_file: String + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_z: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var volume_gain: float + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var width: int + + ## Byte Type: u32 [br] + ## Byte Length: 4 + var height: int + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var audio_range: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var duration: float + + + func get_position() -> Vector3: + return Vector3(position_x, position_y, position_z) + + + func get_size() -> Vector2: + return Vector2(width, height) + + + static func from_bytes(bytes: ByteStream) -> SpatialAudioSource: + var resource = SpatialAudioSource.new() + + resource.name = bytes.get_string_from_ascii(80) + resource.audio_file = bytes.get_string_from_ascii(80) + resource.position_x = bytes.decode_float() + resource.position_y = bytes.decode_float() + resource.position_z = bytes.decode_float() + resource.volume_gain = bytes.decode_float() + resource.width = bytes.decode_u32() + resource.height = bytes.decode_u32() + resource.audio_range = bytes.decode_float() + resource.duration = bytes.decode_float() + + return resource + + +class ParticleEffectEmitter extends MapResource: + ## Byte Type: u8 [br] + ## Byte Length: 80 + var name: String + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_x: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_y: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var position_z: float + + @warning_ignore("enum_variable_without_default") + ## Byte Type: u32 [br] + ## Byte Length: 4 + var preset_effect: ParticlePresetEffect + + ## Byte Type: f32 [br] + ## Byte Length: 4 [br] + ## in frames; 60 means 1 second + var emission_delay: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var launch_parameter_a: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var launch_parameter_b: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var launch_parameter_c: float + + ## Byte Type: f32 [br] + ## Byte Length: 4 + var launch_parameter_d: float + + + func get_position() -> Vector3: + return Vector3(position_x, position_y, position_z) + + + static func from_bytes(bytes: ByteStream) -> ParticleEffectEmitter: + var resource = ParticleEffectEmitter.new() + + resource.name = bytes.get_string_from_ascii(80) + resource.position_x = bytes.decode_float() + resource.position_y = bytes.decode_float() + resource.position_z = bytes.decode_float() + resource.preset_effect = bytes.decode_u32() + resource.emission_delay = bytes.decode_float() + resource.launch_parameter_a = bytes.decode_float() + resource.launch_parameter_b = bytes.decode_float() + resource.launch_parameter_c = bytes.decode_float() + resource.launch_parameter_d = bytes.decode_float() + + return resource diff --git a/packets/map_server/moving_entity_appeared_packet.gd b/packets/map_server/moving_entity_appeared_packet.gd index 50afaf5..4ff9a9e 100644 --- a/packets/map_server/moving_entity_appeared_packet.gd +++ b/packets/map_server/moving_entity_appeared_packet.gd @@ -21,12 +21,187 @@ var object_type: int ## Byte Length: 4 var entity_id: int -# TODO +## Byte Type: u32 +## Byte Length: 4 +var group_id: int +## Byte Type: u16 +## Byte Length: 2 +var movement_speed: int + +## Byte Type: u16 +## Byte Length: 2 +var body_state: int + +## Byte Type: u16 +## Byte Length: 2 +var health_state: int + +## Byte Type: u32 +## Byte Length: 4 +var effect_state: int + +## Byte Type: u16 +## Byte Length: 2 +var job: int + +## Byte Type: u16 +## Byte Length: 2 +var head: int + +## Byte Type: u32 +## Byte Length: 4 +var weapon: int + +## Byte Type: u32 +## Byte Length: 4 +var shield: int + +## Byte Type: u16 +## Byte Length: 2 +var accessory: int + +## Byte Type: u32 +## Byte Length: 4 +var move_start_time: int + +## Byte Type: u16 +## Byte Length: 2 +var accessory2: int + +## Byte Type: u16 +## Byte Length: 2 +var accessory3: int + +## Byte Type: u16 +## Byte Length: 2 +var head_palette: int + +## Byte Type: u16 +## Byte Length: 2 +var body_palette: int + +## Byte Type: u16 +## Byte Length: 2 +var head_direction: int + +## Byte Type: u16 +## Byte Length: 2 +var robe: int -static func from_bytes(bytes: PackedByteArray) -> MovingEntityAppearedPacket: +## Byte Type: u32 +## Byte Length: 4 +var guild_id: int + +## Byte Type: u16 +## Byte Length: 2 +var emblem_version: int + +## Byte Type: u16 +## Byte Length: 2 +var honor: int + +## Byte Type: u32 +## Byte Length: 4 +var virtue: int + +## Byte Type: u8 +## Byte Length: 1 +var is_pk_mode_on: bool + +## Byte Type: u8 +## Byte Length: 1 +var gender: Constants.Gender + +## Byte Type: u8 +## Byte Length: 6 +var position: PackedByteArray + +## Byte Type: u8 +## Byte Length: 1 +var size_x: int + +## Byte Type: u8 +## Byte Length: 1 +var size_y: int + +## Byte Type: u16 +## Byte Length: 2 +var c_level: int + +## Byte Type: u16 +## Byte Length: 2 +var font: int + +## Byte Type: i32 +## Byte Length: 4 +var maximum_health_points: int + +## Byte Type: i32 +## Byte Length: 4 +var health_points: int + +## Byte Type: u8 +## Byte Length: 1 +var is_boss: bool + +## Byte Type: u16 +## Byte Length: 2 +var body: int + +## Byte Length: 24 +var name: String + + +func get_size() -> Vector2: + return Vector2( + size_x, + size_y + ) + + +static func from_bytes(pbytes: PackedByteArray) -> MovingEntityAppearedPacket: + var bytes := ByteStream.from_bytes(pbytes) + var packet = MovingEntityAppearedPacket.new() - packet.packet_length = bytes.decode_u16(2) + bytes.advance(2) # skip header + + packet.packet_length = bytes.decode_u16() + packet.object_type = bytes.decode_u8() + packet.entity_id = bytes.decode_u32() + packet.group_id = bytes.decode_u32() + packet.movement_speed = bytes.decode_u16() + packet.body_state = bytes.decode_u16() + packet.health_state = bytes.decode_u16() + packet.effect_state = bytes.decode_u32() + packet.job = bytes.decode_u16() + packet.head = bytes.decode_u16() + packet.weapon = bytes.decode_u32() + packet.shield = bytes.decode_u32() + packet.accessory = bytes.decode_u16() + packet.move_start_time = bytes.decode_u32() + packet.accessory2 = bytes.decode_u16() + packet.accessory3 = bytes.decode_u16() + packet.head_palette = bytes.decode_u16() + packet.body_palette = bytes.decode_u16() + packet.head_direction = bytes.decode_u16() + packet.robe = bytes.decode_u16() + packet.guild_id = bytes.decode_u32() + packet.emblem_version = bytes.decode_u16() + packet.honor = bytes.decode_u16() + packet.virtue = bytes.decode_u32() + packet.is_pk_mode_on = bytes.decode_u8() + packet.gender = bytes.decode_u8() + packet.position = bytes.get_buffer(6).bytes + packet.size_x = bytes.decode_u8() + packet.size_y = bytes.decode_u8() + packet.c_level = bytes.decode_u16() + packet.font = bytes.decode_u16() + packet.maximum_health_points = bytes.decode_s32() + packet.health_points = bytes.decode_s32() + packet.is_boss = bytes.decode_u8() + packet.body = bytes.decode_u16() + packet.name = bytes.get_string_from_utf8(24) return packet diff --git a/ui/login.tscn b/ui/login.tscn index c38df26..66bdd70 100644 --- a/ui/login.tscn +++ b/ui/login.tscn @@ -66,6 +66,8 @@ custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "ragnarok" placeholder_text = "Password" +secret = true +secret_character = "ยง" [node name="Login" type="Button" parent="Login/PanelContainer/MarginContainer/VBoxContainer"] layout_mode = 2 |