summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/PacketManager/packets/FSNETCMD_LIST.py70
-rw-r--r--lib/PacketManager/packets/__init__.py4
-rw-r--r--plugins/custom_aircraft_list/Plugin.py42
-rw-r--r--plugins/custom_aircraft_list/__init__.py2
-rw-r--r--plugins/custom_aircraft_list/custom_list.json14
-rw-r--r--proxy.py10
6 files changed, 140 insertions, 2 deletions
diff --git a/lib/PacketManager/packets/FSNETCMD_LIST.py b/lib/PacketManager/packets/FSNETCMD_LIST.py
new file mode 100644
index 0000000..d6cb83c
--- /dev/null
+++ b/lib/PacketManager/packets/FSNETCMD_LIST.py
@@ -0,0 +1,70 @@
+from struct import unpack, pack
+class FSNETCMD_LIST: #44
+ def __init__(self, buffer:bytes, should_decode:bool=True):
+ self.buffer = buffer
+ self.list_type = None
+ self.num_of_items = 0
+ self.list = []
+ if should_decode:
+ self.decode()
+
+ def decode(self):
+ packet_type = unpack('I', self.buffer[:4])[0]
+ self.list_type = unpack('B', self.buffer[4:5])[0]
+ self.num_of_items = unpack('B', self.buffer[5:6])[0]
+ #Then there is a spacer.
+ _ = unpack('BB', self.buffer[6:8])
+ self.list = self.buffer[8:].split(b'\x00')[:-1]
+
+ @staticmethod
+ def encode(list_type:int=1, list_buffer:bytes=b'', num_of_items:int=0, with_size:bool=False):
+ #Max length of the packet is 1024 bytes.
+ # 8+1 bytes for the header, leaving 1015 bytes for the list.
+ buffer = pack('IBBBB', 44, list_type, num_of_items, 0, 0)
+ buffer += list_buffer
+ if with_size:
+ return pack("I", len(buffer)) + buffer
+ return buffer
+
+
+class List_Constructor:
+ """Takes a list of aircraft, and constructes a list of FSNETCMD_LIST packets for sending.
+ If sending custom lists to clients, the client FSNETCMD_LIST reply must be blocked from the server
+ and the server FSNETCMD_LIST command must also be blocked.
+ """
+ def __init__(self, aircraftList:list, with_size:bool=True):
+ self.aircraftList = aircraftList
+ self.packet_list = []
+ self.num_of_packets = 0
+ self.with_size = with_size
+ self.construct_packets()
+
+ def construct_packets(self):
+ packet = b''
+ packet_length = 0
+ for aircraft in self.aircraftList:
+ aircraft = aircraft.replace(' ', '_')
+ aircraft = aircraft.encode() + b'\x00'
+ if self.check_fit(packet, aircraft) and packet_length<32:
+ packet += aircraft
+ packet_length += 1
+ else:
+ packet = FSNETCMD_LIST.encode(1,packet, packet_length,self.with_size)
+ self.packet_list.append(packet)
+ packet = b''
+ packet += aircraft
+ self.num_of_packets += 1
+ packet_length = 1
+ #Append whatever is left over.
+ if len(packet) > 0:
+ packet = FSNETCMD_LIST.encode(1,packet, packet_length,self.with_size)
+ self.packet_list.append(packet)
+ self.num_of_packets += 1
+
+ def check_fit(self, packet, aircraft):
+ if len(packet) + len(aircraft) + 1 > 1015:
+ return False
+ return True
+
+ def get_packets(self):
+ return self.packet_list
diff --git a/lib/PacketManager/packets/__init__.py b/lib/PacketManager/packets/__init__.py
index 250be0d..1139ab5 100644
--- a/lib/PacketManager/packets/__init__.py
+++ b/lib/PacketManager/packets/__init__.py
@@ -41,7 +41,7 @@ from .FSNETCMD_WEAPONCONFIG import FSNETCMD_WEAPONCONFIG
#from .FSNETCMD_CTRLSHOWUSERNAME import FSNETCMD_CTRLSHOWUSERNAME
#from .FSNETCMD_CONFIRMEXISTENCE import FSNETCMD_CONFIRMEXISTENCE
#from .FSNETCMD_CONFIGSTRING import FSNETCMD_CONFIGSTRING
-#from .FSNETCMD_LIST import FSNETCMD_LIST
+from .FSNETCMD_LIST import FSNETCMD_LIST, List_Constructor
#from .FSNETCMD_GNDCMD import FSNETCMD_GNDCMD
#from .FSNETCMD_REPORTSCORE import FSNETCMD_REPORTSCORE
#from .FSNETCMD_SERVER_FORCE_JOIN import FSNETCMD_SERVER_FORCE_JOIN
@@ -64,4 +64,4 @@ __all__ = ["FSNETCMD_LOGON", "FSNETCMD_LOGOFF", "FSNETCMD_ERROR",
"FSNETCMD_MISSILELAUNCH", "FSNETCMD_GETDAMAGE",
"FSNETCMD_WEAPONCONFIG", "FSNETCMD_AIRCMD",
"FSNETCMD_TEXTMESSAGE", "FSNETCMD_ENVIRONMENT",
- "FSNETCMD_SKYCOLOR", "FSNETCMD_FOGCOLOR"]
+ "FSNETCMD_SKYCOLOR", "FSNETCMD_FOGCOLOR", "FSNETCMD_LIST", "List_Constructor"]
diff --git a/plugins/custom_aircraft_list/Plugin.py b/plugins/custom_aircraft_list/Plugin.py
new file mode 100644
index 0000000..0fc1bd0
--- /dev/null
+++ b/plugins/custom_aircraft_list/Plugin.py
@@ -0,0 +1,42 @@
+"""TThis plugin will cause the aircraft to emit smoke if it's health is below a certain threshold.
+It is also an example of a plugin as a folder/module.
+This can be used as a basis for more complex plugins that may need multiple files."""
+from lib.PacketManager.packets import List_Constructor
+from json import load
+from struct import pack
+from logging import error
+ENABLED = False
+custom_list_file = "plugins\\custom_aircraft_list\\custom_list.json"
+
+class Plugin:
+ def __init__(self):
+ self.plugin_manager = None
+ self.aircraft_list = []
+
+ def register(self, plugin_manager):
+ self.plugin_manager = plugin_manager
+ with open(custom_list_file, 'r', encoding='utf-8') as f:
+ json_file = load(f)
+ if isinstance(json_file,list):
+ self.aircraft_list = json_file
+ else:
+ error(f"Invalid JSON file {custom_list_file}. Must be a list of aircraft.")
+ self.plugin_manager.register_hook('on_list', self.on_list)
+ self.plugin_manager.register_hook('on_list_server', self.on_list_server)
+
+ def on_list(self, packet, player, message_to_client, message_to_server):
+ if ENABLED:
+ return False
+
+ def on_list_server(self, packet, player, message_to_client, message_to_server):
+ if ENABLED:
+ #Send the packet straight back to the server, and prevent it being passed to the client.
+ packet = pack("I",len(packet)) + packet
+ message_to_server.append(packet)
+ if not hasattr(player, 'custom_packet_sent'):
+ player.custom_packet_sent=True
+ #Send the custom list packets.
+ lc = List_Constructor(self.aircraft_list).get_packets()
+ for packet in lc:
+ message_to_client.append(packet)
+ return False
diff --git a/plugins/custom_aircraft_list/__init__.py b/plugins/custom_aircraft_list/__init__.py
new file mode 100644
index 0000000..425d2ad
--- /dev/null
+++ b/plugins/custom_aircraft_list/__init__.py
@@ -0,0 +1,2 @@
+from .Plugin import Plugin
+from .Plugin import ENABLED \ No newline at end of file
diff --git a/plugins/custom_aircraft_list/custom_list.json b/plugins/custom_aircraft_list/custom_list.json
new file mode 100644
index 0000000..987350d
--- /dev/null
+++ b/plugins/custom_aircraft_list/custom_list.json
@@ -0,0 +1,14 @@
+[
+ "AIRBUS300",
+ "AIRBUS320",
+ "B737",
+ "B747",
+ "B767",
+ "B777",
+ "CONCORDE",
+ "DIAMOND_ECLIPSE",
+ "PIPER_ARCHER(WASHIN-AIR_MARKING)",
+ "T-400",
+ "U-125",
+ "U-125A"
+]
diff --git a/proxy.py b/proxy.py
index e419123..46bcfa7 100644
--- a/proxy.py
+++ b/proxy.py
@@ -82,6 +82,7 @@ async def handle_client(client_reader, client_writer):
try:
#Test if there are any unsent messages to the client or
# server from other processes.
+ keep_message = True # Reset this before each loop.
if len(message_to_client) > 0:
client_writer.write(message_to_client.pop(0))
await client_writer.drain()
@@ -162,6 +163,10 @@ async def handle_client(client_reader, client_writer):
if DISCORD_ENABLED:
# Make it non blocking!
asyncio.create_task(discord_send_message(CHANNEL_ID, finalMsg))
+ elif packet_type == "FSNETCMD_LIST":
+ keep_message = plugin_manager.triggar_hook('on_list', packet, player, message_to_client, message_to_server)
+ if not keep_message:
+ data = None
except Exception as e:
warning(f"Error parsing flight data: {e}", exc_info=True)
@@ -196,6 +201,11 @@ async def handle_client(client_reader, client_writer):
if not keep_message:
data = None
+ elif packet_type == "FSNETCMD_LIST":
+ keep_message = plugin_manager.triggar_hook('on_list_server', packet, player, message_to_client, message_to_server)
+ if not keep_message:
+ data = None
+
# Forward the packet to the other endpoint if the data packet still exists.
if data:
writer.write(data)