aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRitabrata Das <[email protected]>2025-02-14 06:10:58 +0530
committerGitHub <[email protected]>2025-02-14 06:10:58 +0530
commit1e37498c1f99c1bea1452ff21e6c549bd301d420 (patch)
tree7fa4cb6775ec87cf5fba63ad41dc7f53c0c65253
parent7fb77e2f0f715713950878f4369d420481ab5170 (diff)
parent7e74ceff2b7d32c934fa2e42fefaee45cfab4ff9 (diff)
Merge pull request #4 from Skipper-is/plugin_manager
Updated plugin manager and plugins
-rw-r--r--lib/Aircraft.py4
-rw-r--r--lib/YSchat.py6
-rw-r--r--lib/plugin_manager.py14
-rw-r--r--plugins/smoke_on_damage/Plugin.py48
-rw-r--r--plugins/smoke_on_damage/__init__.py2
-rw-r--r--proxy.py25
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
diff --git a/proxy.py b/proxy.py
index 5d3e02a..82fe90b 100644
--- a/proxy.py
+++ b/proxy.py
@@ -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))