diff options
| author | Ritabrata Das <[email protected]> | 2025-02-14 06:10:58 +0530 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-02-14 06:10:58 +0530 |
| commit | 1e37498c1f99c1bea1452ff21e6c549bd301d420 (patch) | |
| tree | 7fa4cb6775ec87cf5fba63ad41dc7f53c0c65253 | |
| parent | 7fb77e2f0f715713950878f4369d420481ab5170 (diff) | |
| parent | 7e74ceff2b7d32c934fa2e42fefaee45cfab4ff9 (diff) | |
Merge pull request #4 from Skipper-is/plugin_manager
Updated plugin manager and plugins
| -rw-r--r-- | lib/Aircraft.py | 4 | ||||
| -rw-r--r-- | lib/YSchat.py | 6 | ||||
| -rw-r--r-- | lib/plugin_manager.py | 14 | ||||
| -rw-r--r-- | plugins/smoke_on_damage/Plugin.py | 48 | ||||
| -rw-r--r-- | plugins/smoke_on_damage/__init__.py | 2 | ||||
| -rw-r--r-- | proxy.py | 25 |
6 files changed, 73 insertions, 26 deletions
diff --git a/lib/Aircraft.py b/lib/Aircraft.py index dd2bbed..5e6e24d 100644 --- a/lib/Aircraft.py +++ b/lib/Aircraft.py @@ -76,7 +76,11 @@ class Aircraft: if packet.player_id != self.id: return None + if self.life == -1: + self.life=packet.life + self.prev_life = self.life + self.life = packet.life self.set_position(packet.position) self.set_attitude(packet.atti) diff --git a/lib/YSchat.py b/lib/YSchat.py index d3db201..980a11b 100644 --- a/lib/YSchat.py +++ b/lib/YSchat.py @@ -1,6 +1,5 @@ from struct import pack, unpack from lib.PacketManager.packets import FSNETCMD_TEXTMESSAGE -#Re-write this to wrap the FSNETCMD_TEXTMESSAGE class def send(buffer: bytes): """ @@ -18,7 +17,4 @@ def message(msg: str): """ Generate packets for sending messages """ - decode = "l" + str(len(msg) + 2) + "s" - msg_buffer = bytes(msg, 'utf-8') - buffer = pack(decode, 0, msg_buffer) - return reply(32, buffer) + return FSNETCMD_TEXTMESSAGE.encode(msg,True) diff --git a/lib/plugin_manager.py b/lib/plugin_manager.py index 113c47a..73c2ac1 100644 --- a/lib/plugin_manager.py +++ b/lib/plugin_manager.py @@ -14,6 +14,7 @@ class PluginManager: def load_plugins(self): for plugin in os.listdir(PLUGIN_DIR): + plugin_path = os.path.join(PLUGIN_DIR, plugin) if plugin.endswith('.py') and not plugin.startswith('__'): plugin_name = plugin[:-3] plugin_module = importlib.import_module(plugin_name) @@ -23,6 +24,15 @@ class PluginManager: self.register_plugin(plugin_instance) info(f"Loaded plugin {plugin_name}") self.plugins[plugin_name] = plugin_instance + elif os.path.isdir(plugin_path) and os.path.exists(os.path.join(plugin_path, '__init__.py')): + plugin_module = importlib.import_module(plugin) + if hasattr(plugin_module, 'Plugin'): + if plugin_module.ENABLED: + plugin_instance = plugin_module.Plugin() + self.register_plugin(plugin_instance) + info(f"Loaded plugin {plugin}") + self.plugins[plugin] = plugin_instance + def register_plugin(self, plugin): """Registers the plugin with the plugin manager""" @@ -42,5 +52,7 @@ class PluginManager: keep_orignal = True if hook_name in self.hooks: for callback in self.hooks[hook_name]: - keep_orignal = callback(data, *args, **kwargs) + keep = callback(data, *args, **kwargs) + if keep == False: + keep_orignal = False return keep_orignal diff --git a/plugins/smoke_on_damage/Plugin.py b/plugins/smoke_on_damage/Plugin.py new file mode 100644 index 0000000..e6c57e2 --- /dev/null +++ b/plugins/smoke_on_damage/Plugin.py @@ -0,0 +1,48 @@ +"""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 FSNETCMD_AIRCMD, FSNETCMD_AIRPLANESTATE, FSNETCMD_TEXTMESSAGE +from logging import debug +from config import SMOKE_LIFE, SMOKE_PLANE +ENABLED = True + +class Plugin: + def __init__(self): + self.plugin_manager = None + + def register(self, plugin_manager): + self.plugin_manager = plugin_manager + self.plugin_manager.register_hook('on_flight_data', self.on_flight_data) + self.plugin_manager.register_hook('on_weapon_config', self.on_weapon_config) + + def on_flight_data(self, data, player,message_to_client, message_to_server): + """After the initial incoming flight packet, check whether + the health is below the threshold, if so add smoke""" + if ENABLED and SMOKE_PLANE and player.aircraft.life<SMOKE_LIFE: + + #Add smoke to the plane + smoke_packet = FSNETCMD_AIRPLANESTATE(data).smoke() + #forward it on to the server + + message_to_server.append(smoke_packet) + + + + if not player.aircraft.damage_engine_warn_sent: + player.aircraft.damage_engine_warn_sent = True + #Warn the player + message = "Your engine has been damaged! You can't turn on your afterburner!" + message_to_client.append(FSNETCMD_TEXTMESSAGE.encode(message,True)) + + debug(f"Engine damage warning sent to {player.username}") + + message_to_client.append(FSNETCMD_AIRCMD.set_afterburner(player.aircraft.id, False, True)) + + return False + + def on_weapon_config(self, data, player, message_to_client, message_to_server): + if ENABLED: + player.aircraft.just_repaired = True + if player.aircraft.get_initial_config_value("AFTBURNR") == "TRUE": + message_to_client.append(FSNETCMD_AIRCMD.set_afterburner(player.aircraft.id, True, True)) + return True diff --git a/plugins/smoke_on_damage/__init__.py b/plugins/smoke_on_damage/__init__.py new file mode 100644 index 0000000..425d2ad --- /dev/null +++ b/plugins/smoke_on_damage/__init__.py @@ -0,0 +1,2 @@ +from .Plugin import Plugin +from .Plugin import ENABLED
\ No newline at end of file @@ -6,7 +6,7 @@ Lisenced under GPLv3 import asyncio from struct import unpack, pack from lib.parseFlightData import parseFlightData -from lib import YSchat, YSplayer, YSendFlight, YSundead, YSviaversion, Player, Aircraft +from lib import YSchat, YSviaversion, Player, Aircraft from lib.plugin_manager import PluginManager from lib.PacketManager.PacketManager import PacketManager from lib.PacketManager.packets import * @@ -132,39 +132,25 @@ async def handle_client(client_reader, client_writer): continue elif packet_type == "FSNETCMD_AIRPLANESTATE": - packet = player.aircraft.add_state(FSNETCMD_AIRPLANESTATE(packet)) #TODO: Do we want to convert all this to plugins? Probably not, but there is duplicated functionality + player.aircraft.add_state(FSNETCMD_AIRPLANESTATE(packet)) #TODO: Do we want to convert all this to plugins? Probably not, but there is duplicated functionality keep_message = plugin_manager.triggar_hook('on_flight_data', packet, player, message_to_client, message_to_server) if not keep_message: data = None - if player.aircraft.life == -1: #Uninitialised - player.aircraft.prev_life = player.aircraft.life - elif player.aircraft.prev_life < player.aircraft.life and player.aircraft.prev_life != -1 and not player.aircraft.just_repaired: cheatingMsg = YSchat.message(f"{HEALTH_HACK_MESSAGE} by {player.username}") warning(f"Health hack detected for {player.username}, Connected from {player.ip}") message_to_server.append(cheatingMsg) - elif player.aircraft.life < SMOKE_LIFE and SMOKE_PLANE: - # We patch the packet to have smoke forcefully - data = FSNETCMD_AIRPLANESTATE(data[4:]).smoke() - if not player.aircraft.damage_engine_warn_sent: - warningMsg = YSchat.message(f"Your engine has been damaged! You can't turn on afterburner") - debug(f"Sending warning to {player.username}") - message_to_client.append(warningMsg) - player.aircraft.damage_engine_warn_sent = True - message_to_client.append(FSNETCMD_AIRCMD.set_afterburner(player.aircraft.id, False, True)) - - player.aircraft.prev_life = player.aircraft.life player.aircraft.just_repaired = False elif packet_type == "FSNETCMD_UNJOIN": player.aircraft.reset() elif packet_type == "FSNETCMD_WEAPONCONFIG": - player.aircraft.just_repaired = True - if player.aircraft.get_initial_config_value("AFTBURNR") == "TRUE": message_to_client.append(player.aircraft.set_afterburner(True)) - debug("Aircraft repaired!") + keep_message = plugin_manager.triggar_hook('on_weapon_config', packet, player, message_to_client, message_to_server) + if not keep_message: + data = None elif packet_type == "FSNETCMD_TEXTMESSAGE": msg = FSNETCMD_TEXTMESSAGE(packet) @@ -173,7 +159,6 @@ async def handle_client(client_reader, client_writer): data = None finalMsg = (f"{player.username} : {msg.message}") - if DISCORD_ENABLED: # Make it non blocking! asyncio.create_task(discord_send_message(CHANNEL_ID, finalMsg)) |
