diff options
| -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}") |
