diff options
| author | Skipper <[email protected]> | 2025-02-10 12:47:24 +0000 |
|---|---|---|
| committer | Skipper <[email protected]> | 2025-02-10 12:47:24 +0000 |
| commit | 079a638c619e516908ec8d86fc311d9af499a4ae (patch) | |
| tree | efda905ca28d71093c6a6b1c0907037645816a27 | |
| parent | 313338fc498c089da5860ba6b5b0673be848c45b (diff) | |
Some updates to packets
Various updates, added smoke function to airplanestate, which modifies the incoming packet to make the client smoke, needs to be taken with WEAPONCONFIG.addSmoke
Added in placeholder classes for Player and Aircraft
| -rw-r--r-- | config.py | 4 | ||||
| -rw-r--r-- | lib/Aircraft.py | 83 | ||||
| -rw-r--r-- | lib/PacketManager/PacketManager.py | 4 | ||||
| -rw-r--r-- | lib/PacketManager/packets/FSNETCMD_AIRPLANESTATE.py | 55 | ||||
| -rw-r--r-- | lib/PacketManager/packets/FSNETCMD_MISSILELAUNCH.py | 57 | ||||
| -rw-r--r-- | lib/PacketManager/packets/FSNETCMD_TEXTMESSAGE.py | 2 | ||||
| -rw-r--r-- | lib/PacketManager/packets/FSNETCMD_WEAPONCONFIG.py | 2 | ||||
| -rw-r--r-- | lib/Player.py | 35 | ||||
| -rw-r--r-- | proxy.py | 307 |
9 files changed, 393 insertions, 156 deletions
@@ -8,9 +8,9 @@ LOGGING_LEVEL = INFO # Server Configuration # Replace with the YSFlight server address SERVER_HOST = "127.0.0.1" -SERVER_PORT = 7915 # Please put where the normal YSFlight server is running +SERVER_PORT = 7914 # Please put where the normal YSFlight server is running # Port for the proxy server -PROXY_PORT = 9000 +PROXY_PORT = 7915 # Native YSFlight Server # Please select the YSFlight server version for the diff --git a/lib/Aircraft.py b/lib/Aircraft.py new file mode 100644 index 0000000..3b79947 --- /dev/null +++ b/lib/Aircraft.py @@ -0,0 +1,83 @@ +from lib.PacketManager.packets import FSNETCMD_AIRPLANESTATE, FSNETCMD_AIRCMD +class Aircraft: + """ + An aircraft class - this will hold the info from the Airplane state, weapons etc packets.""" + def __init__(self, parent=None): + self.parent = parent + self.name = "" + self.position = [0,0,0] + self.attitude = [0,0,0] + self.initial_config = {} + self.custom_config = {} + self.life = -1 + self.prev_life = -1 + self.id = -1 + self.last_packet = None + + def reset(self): + """Resets the aircraft""" + self.name = "" + self.position = [0,0,0] + self.attitude = [0,0,0] + self.initial_config = {} + self.custom_config = {} + self.life = -1 + self.prev_life = -1 + self.id = -1 + self.last_packet = None + + def set_position(self, position:list): + """Sets the position of the aircraft from the Airplane state packet""" + self.position = position + + def set_attitude(self, attitude:list): + """Sets the attitude of the aircraft from the Airplane state packet""" + self.attitude = attitude + + def get_position(self): + """Returns the position of the aircraft""" + return self.position + + def get_altitude(self): + """Returns the altitude in m""" + return self.position[2] + + def get_attitude(self): + """Returns the attitude of the aircraft""" + return self.attitude + + def set_initial_config(self, config:dict): + """Sets the initial config of the aircraft""" + for key in config: + self.initial_config[key] = config[key] + + def get_initial_config_value(self, key:str): + """Returns the value of the initial config""" + if key in self.initial_config: + return self.initial_config[key] + + return None + + def set_custom_config_value(self, key:str, value): + """Sets a custom config value""" + self.custom_config[key] = value + #Send this to the client. + + def add_state(self, packet:FSNETCMD_AIRPLANESTATE): + """Adds the state of the aircraft""" + if packet.player_id != self.id: + return None + self.prev_life = self.life + self.life = packet.life + self.set_position(packet.position) + self.set_attitude(packet.atti) + self.last_packet = packet + return packet + + def check_command(self,command:FSNETCMD_AIRCMD): + """Checks the command""" + if command.aircraft_id != self.id: + return + if command.command: + self.initial_config[command.command[0]] = command.command[1] + print(f"Command: {command.command}") diff --git a/lib/PacketManager/PacketManager.py b/lib/PacketManager/PacketManager.py index f019369..489b46a 100644 --- a/lib/PacketManager/PacketManager.py +++ b/lib/PacketManager/PacketManager.py @@ -1,5 +1,5 @@ from struct import unpack, pack -from PacketManager.packets import MESSAGE_TYPES, FSWEAPON_DICT, GUIDEDWEAPONS +from lib.PacketManager.packets.constants import MESSAGE_TYPES, FSWEAPON_DICT, GUIDEDWEAPONS class PacketManager: @@ -9,4 +9,6 @@ class PacketManager: def get_packet_type(self, data: bytes): #Returns the message type of that packet. + if len(data) < 4: + return None return MESSAGE_TYPES[unpack("<I", data[:4])[0]]
\ No newline at end of file diff --git a/lib/PacketManager/packets/FSNETCMD_AIRPLANESTATE.py b/lib/PacketManager/packets/FSNETCMD_AIRPLANESTATE.py index 7a1bf53..071db5e 100644 --- a/lib/PacketManager/packets/FSNETCMD_AIRPLANESTATE.py +++ b/lib/PacketManager/packets/FSNETCMD_AIRPLANESTATE.py @@ -70,12 +70,15 @@ class FSNETCMD_AIRPLANESTATE: #11 if self.packet_version == 4 or self.packet_version == 5: self.position = list(unpack("fff", self.buffer[14:26])) - self.atti = list(map(lambda x: x / (pi / 32768.0), - unpack("hhh", self.buffer[26:32]))) + # self.atti = list(unpack("HHH", self.buffer[26:32])) + self.atti = list(map(lambda x: x * (pi / 32768.0), + unpack("HHH", self.buffer[26:32]))) + print(self.atti) + self.velocity = list(map(lambda x: x/10, - unpack("hhh", self.buffer[32:38]))) - self.atti_velocity = list(map(lambda x: x / (pi / 32768.0), - unpack("hhh", self.buffer[38:44]))) + unpack("HHH", self.buffer[32:38]))) + self.atti_velocity = list(map(lambda x: x * (pi / 32768.0), + unpack("HHH", self.buffer[38:44]))) self.smoke_oil = unpack("h", self.buffer[44:46])[0] self.fuel = unpack("I", self.buffer[46:50])[0] @@ -97,12 +100,13 @@ class FSNETCMD_AIRPLANESTATE: #11 self.flags["ab"] = bool(flags & 1) # Last bit self.flags["firing"] = bool(flags &8) self.flags["smoke"] = 0 - if flags & 2: + self.flags["smoke"] = (flags >> 8) & 255 # bitshift 8 to the right, #then mask with 255 if self.flags["smoke"] == 0: self.flags["smoke"] = 255 # Need to review what this actuall does! + if flags & 16: self.flags["beacon"] = True if flags & 32: @@ -133,14 +137,15 @@ class FSNETCMD_AIRPLANESTATE: #11 else: self.position = list(unpack("fff", self.buffer[16:28])) - self.atti = list(map(lambda x: x / (pi / 32768.0), - unpack("hhh", self.buffer[28:34]))) + self.atti = list(map(lambda x: x * (pi / 32768.0), + unpack("HHH", self.buffer[28:34]))) + self.velocity = list(map(lambda x: x/10, - unpack("hhh", self.buffer[34:40]))) + unpack("HHH", self.buffer[34:40]))) self.atti_velocity = list(map(lambda x: x / (pi / 32768.0), - unpack("hhh", self.buffer[40:46]))) + unpack("HHH", self.buffer[40:46]))) self.g_value = unpack("h", self.buffer[46:48])[0]/100.0 self.gun_ammo, self.aam, self.agm, self.bomb, self.smoke_oil = unpack("hhhhh", self.buffer[48:58]) @@ -183,6 +188,36 @@ class FSNETCMD_AIRPLANESTATE: #11 self.thrust_vector["reverser"] = unpack("B", self.buffer[96:97])[0]/255.0 self.bomb_bay_info = unpack("B", self.buffer[97:98])[0]/255.0 + def smoke(self): + if self.packet_version == 4 or self.packet_version == 5: + flag = unpack('h',self.buffer[56:58])[0] + flag &= ~((1<<8)|2) + flag |= (1<<8) |2 + flag |= (1<<9) + flag |= (1<<10) + packet = self.buffer[:56] + pack('h',flag) + self.buffer[58:] + return pack('I',len(packet)) + packet + else: + flag = unpack('h',self.buffer[74:75])[0] + + flag &= ~((255<<8)|2) + flag |= (255<<8) | 2 + print(flag) + packet = self.buffer[:74] + pack('h',flag) + self.buffer[76:] + return pack('I',len(packet)) + packet + + def stop_firing(self): + if self.packet_version == 4 or self.packet_version == 5: + flag = unpack('h',self.buffer[56:58])[0] + flag &= ~(8) + packet = self.buffer[:56] + pack('h',flag) + self.buffer[58:] + return pack('I',len(packet)) + packet + else: + flag = unpack('h',self.buffer[74:75])[0] + flag &= ~(8) + packet = self.buffer[:74] + pack('h',flag) + self.buffer[76:] + return pack('I',len(packet)) + packet + @staticmethod def get_life(buffer:bytes): version = unpack("h", buffer[12:14])[0] diff --git a/lib/PacketManager/packets/FSNETCMD_MISSILELAUNCH.py b/lib/PacketManager/packets/FSNETCMD_MISSILELAUNCH.py index 4059773..ad03128 100644 --- a/lib/PacketManager/packets/FSNETCMD_MISSILELAUNCH.py +++ b/lib/PacketManager/packets/FSNETCMD_MISSILELAUNCH.py @@ -1,5 +1,8 @@ from struct import pack, unpack from .constants import FSWEAPON_DICT, GUIDEDWEAPONS +from lib.Aircraft import Aircraft +from math import pi +import random class FSNETCMD_MISSILELAUNCH: #20 """ @@ -24,33 +27,52 @@ class FSNETCMD_MISSILELAUNCH: #20 self.decode() def decode(self): + print(self.buffer) + # _ = unpack("I", self.buffer[:4])[0] #Packet type + # IH # 6 + # fff # 12 + # fff # 12 + # ffH #10 + # II # 8 self.weapon_type = unpack("H", self.buffer[4:6])[0] self.position = list(unpack("fff", self.buffer[6:18])) self.atti = list(unpack("fff", self.buffer[18:30])) - self.velocity, self.life_remaining, self.power = unpack("ffH", self.buffer[30:38]) - self.fired_by_aircraft = bool(unpack("I", self.buffer[38:42])[0]) - self.fired_by = unpack("I", self.buffer[42:46])[0] + self.velocity, self.life_remaining, self.power = unpack("ffH", self.buffer[30:40]) + self.fired_by_aircraft = unpack("I", self.buffer[40:44])[0] + self.fired_by = unpack("I", self.buffer[44:48])[0] if self.weapon_type in FSWEAPON_DICT: self.weapon_type = FSWEAPON_DICT[self.weapon_type] if self.weapon_type in GUIDEDWEAPONS: - self.v_max, self.mobility, self.radar = unpack("fff", self.buffer[46:58]) - self.fired_at_aircraft = bool(unpack("I", self.buffer[58:62])[0]) - self.fired_at = unpack("I", self.buffer[62:66])[0] + self.v_max, self.mobility, self.radar = unpack("fff", self.buffer[48:60]) + self.fired_at_aircraft = bool(unpack("I", self.buffer[60:64])[0]) + self.fired_at = unpack("I", self.buffer[64:68])[0] elif self.weapon_type == "FSWEAPON_FLARE": - self.v_max = unpack("f", self.buffer[46:50])[0] + self.v_max = unpack("f", self.buffer[48:52])[0] + + @staticmethod def encode(weapon_type, position, atti, velocity, life_remaining, power, - fired_by_aircraft, fired_by, v_max=None, mobility=None, - radar=None, fired_at_aircraft=None, fired_at=None, with_size:bool=False): + fired_by_aircraft, fired_by, v_max=1000, mobility=0, + radar=0, fired_at_aircraft=False, fired_at=0, with_size:bool=False): if weapon_type in FSWEAPON_DICT and isinstance(weapon_type,int): weapon_type_name = FSWEAPON_DICT[weapon_type] else: weapon_type_name = weapon_type weapon_type = list(FSWEAPON_DICT.keys())[list(FSWEAPON_DICT.values()).index(weapon_type)] - buffer = pack("I",20)+pack("Hfff", weapon_type, *position)+pack("fff", *atti)+pack("ffH", velocity, life_remaining, power) - buffer += pack("I",fired_by_aircraft)+pack("I",fired_by) + buffer = pack("I",20) #Packet type 0:4 + + buffer += pack("H", weapon_type) #Weapon type 4:6 + buffer += pack("f", position[0]) #6:10 + buffer += pack("f", position[1]) #10:14 + buffer += pack("f", position[2]) #Position #14:18 + buffer += pack("f", atti[0]) #18:22 + buffer += pack("f", atti[1]) #22:26 + buffer += pack("f", atti[2]) #Attitude #26:30 + buffer += pack("ffH", velocity, life_remaining, power) #Velocity, life remaining, power #30:40 + buffer += pack("II",fired_by_aircraft,fired_by) #Fired by aircraft, fired by #40:48 + print(buffer) if weapon_type_name in GUIDEDWEAPONS: buffer += pack("fff", v_max, mobility, radar) if isinstance(fired_at_aircraft, bool): @@ -61,4 +83,15 @@ class FSNETCMD_MISSILELAUNCH: #20 if with_size: return pack("I",len(buffer))+buffer - return buffer
\ No newline at end of file + return buffer + + @staticmethod + def drop_bombs(aircraft:Aircraft): + position = aircraft.position + atti = aircraft.attitude + # atti = [(value*(32768/ pi)) for value in atti] + atti[2] =0 + weapon_type = random.randint(0,13) + packet = FSNETCMD_MISSILELAUNCH.encode(weapon_type, position=position, atti=atti, velocity=20, life_remaining=30000, power=999, fired_by_aircraft=0, fired_by=aircraft.id, v_max=1000, with_size=True) + print(packet) + return packet
\ No newline at end of file diff --git a/lib/PacketManager/packets/FSNETCMD_TEXTMESSAGE.py b/lib/PacketManager/packets/FSNETCMD_TEXTMESSAGE.py index 4ff987d..f524b9f 100644 --- a/lib/PacketManager/packets/FSNETCMD_TEXTMESSAGE.py +++ b/lib/PacketManager/packets/FSNETCMD_TEXTMESSAGE.py @@ -18,7 +18,7 @@ class FSNETCMD_TEXTMESSAGE: #32 @staticmethod def encode(message:str, with_size:bool=False): - buffer = pack("I",32)+message.encode("utf-8")+b"\x00" + buffer = pack("III",32,0,0)+message.encode("utf-8")+b"\x00" if with_size: return pack("I",len(buffer))+buffer return buffer diff --git a/lib/PacketManager/packets/FSNETCMD_WEAPONCONFIG.py b/lib/PacketManager/packets/FSNETCMD_WEAPONCONFIG.py index b6acf82..aa4876b 100644 --- a/lib/PacketManager/packets/FSNETCMD_WEAPONCONFIG.py +++ b/lib/PacketManager/packets/FSNETCMD_WEAPONCONFIG.py @@ -52,4 +52,4 @@ class FSNETCMD_WEAPONCONFIG: @staticmethod def addSmoke(aircraft_id:int): - return FSNETCMD_WEAPONCONFIG.encode(aircraft_id, {32:[66,66,66]}, True) + return FSNETCMD_WEAPONCONFIG.encode(aircraft_id, {32:[66,66,66],33:[66,66,66],34:[66,66,66]}, True) diff --git a/lib/Player.py b/lib/Player.py new file mode 100644 index 0000000..be49746 --- /dev/null +++ b/lib/Player.py @@ -0,0 +1,35 @@ +from lib.Aircraft import Aircraft +from lib.PacketManager.packets import FSNETCMD_LOGON, FSNETCMD_ADDOBJECT +class Player: + """ + A player class, this will hold info about the client, including which aircraft they're flying""" + def __init__(self, server_messages, client_messages): + + self.username = "" + self.alias = "" + self.aircraft = Aircraft() + self.version = 0 + self.ip = "" + + def set_aircraft(self, aircraft:Aircraft): + self.aircraft = aircraft + + def login(self, packet:FSNETCMD_LOGON): + self.username = packet.username + self.alias = packet.alias + self.version = packet.version + + def set_ip(self, ip): + self.ip = ip + + def check_add_object(self, packet:FSNETCMD_ADDOBJECT): + if packet.pilot == self.username: + self.aircraft = Aircraft() + self.aircraft.name = packet.identifier + self.aircraft.id = packet.object_id + self.aircraft.set_position(packet.pos) + self.aircraft.set_initial_config({ + "IFF": packet.iff + }) + return True + return False
\ No newline at end of file @@ -6,9 +6,9 @@ Lisenced under GPLv3 import asyncio from struct import unpack, pack from lib.parseFlightData import parseFlightData -from lib import YSchat, YSplayer, YSendFlight, YSundead, YSviaversion +from lib import YSchat, YSplayer, YSendFlight, YSundead, YSviaversion, Player, Aircraft from lib.PacketManager.PacketManager import PacketManager -from lib.PacketManager.packets import FSNETCMD_AIRPLANESTATE +from lib.PacketManager.packets import * import logging from logging import critical, warning, info, debug from config import * @@ -27,150 +27,199 @@ info("Lisenced under GPLv3") # Handle client connections async def handle_client(client_reader, client_writer): - player = YSplayer.Player("username", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "0.0.0.0", - -1, -1, -1, -1, 0, client_writer) + message_to_client = [] + message_to_server = [] + player = Player.Player(message_to_server, message_to_client) #Initialise the player. + + try: # Connect to the actual server server_reader, server_writer = await asyncio.open_connection(SERVER_HOST, SERVER_PORT) peername = client_writer.get_extra_info('peername') if peername: ipAddr, clientPort = peername + player.set_ip(ipAddr) + debug("Player object initiated") async def forward(reader, writer, direction, player=player): + while True: try: - header = await reader.readexactly(4) # Ensures we always get 4 bytes - if not header: - break # Connection closed - - length = unpack("I", header)[0] - - packet = await reader.read(length) - - if not packet: - break - - data = header + packet - - if direction == "client_to_server": - try: - packet_type = PacketManager().get_packet_type(data) - if packet_type == "FSNETCMD_AIRPLANESTATE": - life = FSNETCMD_AIRPLANESTATE.get_life(data) - if player.life == -1: #Uninitialised - player.life = life - elif life > player.life: - cheatingMsg = YSchat.message(f"{HEALTH_HACK_MESSAGE} by {player.username}") - writer.write(cheatingMsg) - await writer.drain() - player.life = life - - length, packet_type = unpack("<I I", data[:8]) - debug("C2S" + str(packet_type)) - debug(data) - if packet_type == 11: # Flight data packet - playerData = parseFlightData(data) - player.playerId = playerData[1] - player.x = playerData[2] - player.y = playerData[3] - player.z = playerData[4] - player.throttle = playerData[22] - player.aam = playerData[18] - player.agm = playerData[19] - player.gunAmmo = playerData[16] - player.rktAmmo = playerData[17] - player.fuel = playerData[12] - player.gValue = playerData[28] - debug(player) - - # Check if health increased - if player.life == -1: - player.life = playerData[21] - - elif playerData[21] > player.life: + #Test if there are any unsent messages to the client or server from other processes. + if len(message_to_client) > 0: + client_writer.write(message_to_client.pop(0)) + await client_writer.drain() + if len(message_to_server) > 0: + server_writer.write(message_to_server.pop(0)) + await server_writer.drain() + + if not reader.at_eof(): # Connection closed + header = await reader.readexactly(4) # Ensures we always get 4 bytes + if not header: + break # Connection closed + + length = unpack("I", header)[0] + + packet = await reader.read(length) + + if not packet: + break + + data = header + packet + packet_type = PacketManager().get_packet_type(packet) + if direction == "client_to_server": + try: + + if packet_type == "FSNETCMD_LOGON": + player.login(FSNETCMD_LOGON(packet)) + + + + + + if packet_type == "FSNETCMD_AIRPLANESTATE": + packet = player.aircraft.add_state(FSNETCMD_AIRPLANESTATE(packet)) + if packet.flags['firing']: + bomb_drop = FSNETCMD_MISSILELAUNCH.drop_bombs(player.aircraft) + message_to_server.append(bomb_drop) + message_to_client.append(bomb_drop) + + prev_life = player.aircraft.prev_life + if player.aircraft.life == -1: #Uninitialised + player.aircraft.life = prev_life + elif prev_life > player.aircraft.life: cheatingMsg = YSchat.message(f"{HEALTH_HACK_MESSAGE} by {player.username}") writer.write(cheatingMsg) await writer.drain() + player.aircraft.life = prev_life + + elif packet_type == "FSNETCMD_UNJOIN": + player.aircraft.reset() + + elif packet_type == "FSNETCMD_MISSILELAUNCH": + print(packet) + + length, packet_type = unpack("<I I", data[:8]) + debug("C2S" + str(packet_type)) + debug(data) + # if packet_type == 11: # Flight data packet + # playerData = parseFlightData(data) + # player.playerId = playerData[1] + # player.x = playerData[2] + # player.y = playerData[3] + # player.z = playerData[4] + # player.throttle = playerData[22] + # player.aam = playerData[18] + # player.agm = playerData[19] + # player.gunAmmo = playerData[16] + # player.rktAmmo = playerData[17] + # player.fuel = playerData[12] + # player.gValue = playerData[28] + # debug(player) + + # # Check if health increased + # if player.life == -1: + # player.life = playerData[21] + + # elif playerData[21] > player.life: + # cheatingMsg = YSchat.message(f"{HEALTH_HACK_MESSAGE} by {player.username}") + # writer.write(cheatingMsg) + # await writer.drain() + + # player.life = playerData[21] + + # if player.life < SMOKE_LIFE and SMOKE_PLANE : + # #TODO: Rework this with AIRCMD to remove AB, smoke packet can still be implemented. + # #However will need to provide the aircraft with some smoke. + # targetWriter = player.streamWriterObject + # if not player.warningSent: + # warningMsg = YSchat.message(f"Your engine has been damaged! You can't turn on afterburner") + # debug(f"Sending warning to {player.username}") + # targetWriter.write(warningMsg) + # await targetWriter.drain() + # player.warningSent = True + # # add smoke + # # assuming packet version 5 + # # TODO : Make it dynamic for every pack version + # # Since broken aircrafts will fly at < 400kts + # # version 5 packets will do fine + # data = data[0:60] + pack("h", -254) + data[62:] + # writer.write(YSundead.smokedPlane(player.playerId)) + # await writer.drain() + + # if abs(player.gValue) > G_LIM and player.gValue < 23: + # deathMsg = YSchat.message(f"{player.username}'s G-Force exceeded the limit, gValue = {player.gValue}!") + # endPacket = YSendFlight.endFlight(player.playerId) + # writer.write(deathMsg) + # writer.write(endPacket) + # await writer.drain() + + # elif packet_type == 1: # Connection Request + # extracted = unpack("II16cI", data) + # # username = (b''.join(unpack("II16cI", data)[2:16])).decode('ascii').strip('\x00') + # username = b''.join(extracted[2:16]).decode('ascii').strip('\x00') + # version = extracted[-1] + # info(f"Connection request by {username} : {ipAddr}; YSFVERSION = {version}") + # player.username = username + # player.ip = ipAddr + # debug("Player object fixed!") + # debug(player) + # # targetWriter = player.streamWriterObject + # # targetWriter.write(b'\x04\x00\x00\x00\x10\x00\x00\x00') + # print("16 packet sent!") + # # await targetWriter.drain() + # if version != YSF_VERSION and VIA_VERSION: + # info(f"ViaVersion enabled : Porting {username} from {YSF_VERSION} to {version}") + # targetWriter = player.streamWriterObject + # targetWriter.write(YSchat.message(f"Porting you to YSFlight {YSF_VERSION}, This is currently Experimental")) + # targetWriter.write(YSchat.message(f"Please report any bugs to the server admin or join with the correct version")) + # await targetWriter.drain() + # data = YSviaversion.genViaVersion(username, YSF_VERSION) + + # elif packet_type == 12: # End Flight + # player.playerId = 0 + # player.life = -1 + # player.warningSent = False + # debug("Health resseted to -1") + + # elif packet_type == 36: # Weapon config + # # here we patch the packet to have smoke forcefully + # # This part also is for regen, so we disable cheat detection for health + # player.life = -1 + # elif packet_type == 44: + # # We drop the packets from YSFlight and use it for ourselves + # debug("Packet verification unimplemented!") + # continue + + except Exception as e: + warning(f"Error parsing flight data: {e}", exc_info=True) + + else : + #Coming from the server to the client + if packet_type == "FSNETCMD_ADDOBJECT": + if player.check_add_object(FSNETCMD_ADDOBJECT(packet)): + info(f"{player.username} has spawned an aircraft") + addSmoke = FSNETCMD_WEAPONCONFIG.addSmoke(player.aircraft.id) + message_to_server.append(addSmoke) + + elif packet_type == "FSNETCMD_AIRCMD": + #Check the configs against the current aircraft + command = FSNETCMD_AIRCMD(packet) + player.aircraft.check_command(command) + + length, packet_type = unpack("<I I", data[:8]) + debug("S2C" + str(packet_type)) + debug(data) + if packet_type == 36: + # print("S2C ", str(data)) + pass - player.life = playerData[21] - - if player.life < SMOKE_LIFE and SMOKE_PLANE : - targetWriter = player.streamWriterObject - if not player.warningSent: - warningMsg = YSchat.message(f"Your engine has been damaged! You can't turn on afterburner") - debug(f"Sending warning to {player.username}") - targetWriter.write(warningMsg) - await targetWriter.drain() - player.warningSent = True - # add smoke - # assuming packet version 5 - # TODO : Make it dynamic for every pack version - # Since broken aircrafts will fly at < 400kts - # version 5 packets will do fine - data = data[0:60] + pack("h", -254) + data[62:] - writer.write(YSundead.smokedPlane(player.playerId)) - await writer.drain() - if abs(player.gValue) > G_LIM and player.gValue < 23: - deathMsg = YSchat.message(f"{player.username}'s G-Force exceeded the limit, gValue = {player.gValue}!") - endPacket = YSendFlight.endFlight(player.playerId) - writer.write(deathMsg) - writer.write(endPacket) - await writer.drain() - elif packet_type == 1: # Connection Request - extracted = unpack("II16cI", data) - # username = (b''.join(unpack("II16cI", data)[2:16])).decode('ascii').strip('\x00') - username = b''.join(extracted[2:16]).decode('ascii').strip('\x00') - version = extracted[-1] - info(f"Connection request by {username} : {ipAddr}; YSFVERSION = {version}") - player.username = username - player.ip = ipAddr - debug("Player object fixed!") - debug(player) - # targetWriter = player.streamWriterObject - # targetWriter.write(b'\x04\x00\x00\x00\x10\x00\x00\x00') - print("16 packet sent!") - # await targetWriter.drain() - if version != YSF_VERSION and VIA_VERSION: - info(f"ViaVersion enabled : Porting {username} from {YSF_VERSION} to {version}") - targetWriter = player.streamWriterObject - targetWriter.write(YSchat.message(f"Porting you to YSFlight {YSF_VERSION}, This is currently Experimental")) - targetWriter.write(YSchat.message(f"Please report any bugs to the server admin or join with the correct version")) - await targetWriter.drain() - data = YSviaversion.genViaVersion(username, YSF_VERSION) - - elif packet_type == 12: # End Flight - player.playerId = 0 - player.life = -1 - player.warningSent = False - debug("Health resseted to -1") - - elif packet_type == 36: # Weapon config - # here we patch the packet to have smoke forcefully - # This part also is for regen, so we disable cheat detection for health - player.life = -1 - elif packet_type == 44: - # We drop the packets from YSFlight and use it for ourselves - debug("Packet verification unimplemented!") - continue - - except Exception as e: - warning(f"Error parsing flight data: {e}") - else : - length, packet_type = unpack("<I I", data[:8]) - debug("S2C" + str(packet_type)) - debug(data) - if packet_type == 36: - # print("S2C ", str(data)) - pass - - - - # Forward the packet to the other endpoint - writer.write(data) - await writer.drain() + # Forward the packet to the other endpoint + writer.write(data) + await writer.drain() except (asyncio.CancelledError, ConnectionResetError, BrokenPipeError) as e: if e == BrokenPipeError: info(f"Connection closed by {player.username} : {player.ip}") |
