From 12ce4ff2d26a721ac3465397f8b1c6f9a0b45457 Mon Sep 17 00:00:00 2001 From: Ritabrata Das Date: Wed, 29 Jan 2025 00:33:09 +0530 Subject: Add smoke on death and low health --- README.md | 5 +++-- lib/YSplayer.py | 6 +++++- lib/YSundead.py | 9 +++++++++ proxy.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 lib/YSundead.py diff --git a/README.md b/README.md index d74a3c0..f56b57f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ ## **Features** - Intercepts and parses network packets to monitor gameplay. -- Detects and logs suspicious activities, like unauthorized modifications. +- Adds features like G Limiter and Smoke Emission on Death. +- All features are server side, vanilla client can join - Easy configuration via `config.py`. --- @@ -56,7 +57,7 @@ PROXY_PORT = 9000 # Port where the proxy listens 2. Fix on ground re supply which triggers the cheat detection. 3. Negative g-values are wrong interpeted 4. Add more documentation. -5. Add black smoke emission on death +~~5. Add black smoke emission on death~~ Implemented in latest commit 6. Add radar features 7. Add Plugin API --- diff --git a/lib/YSplayer.py b/lib/YSplayer.py index c71f12e..53c9092 100644 --- a/lib/YSplayer.py +++ b/lib/YSplayer.py @@ -1,6 +1,7 @@ class Player: def __init__(self,username, playerId, x, y, z, throttle, aam, agm, - gunAmmo, rktAmmo, fuel, ipAddr, life, vx, vy, vz, gValue): + gunAmmo, rktAmmo, fuel, ipAddr, life, vx, vy, vz, gValue, + streamWriterObject=None, warningSent=False, smokedAdded=False): self.username = username self.ip = ipAddr self.playerId = playerId @@ -18,6 +19,9 @@ class Player: self.vy = vy self.vz = vz self.gValue = gValue + self.streamWriterObject = streamWriterObject + self.warningSent = warningSent + self.smokeAdded = smokedAdded def __str__(self): return f"Username: {self.username}, IP: {self.ip}, " \ diff --git a/lib/YSundead.py b/lib/YSundead.py new file mode 100644 index 0000000..2b68ed6 --- /dev/null +++ b/lib/YSundead.py @@ -0,0 +1,9 @@ +# Black smoke, 50 fuel, no load extra +# Comptaible with every type of plane +# just before their death +# +from struct import pack + +def undeadPatch(id:int, data:bytes): + buffer = data[0:8] + pack("I", id) + data[12:] + return buffer diff --git a/proxy.py b/proxy.py index 83690c2..75433ed 100644 --- a/proxy.py +++ b/proxy.py @@ -4,9 +4,10 @@ Lisenced under GPLv3 """ import asyncio -from struct import unpack +from os import write +from struct import unpack, pack from lib.parseFlightData import parseFlightData -from lib import YSchat, YSplayer, YSendFlight +from lib import YSchat, YSplayer, YSendFlight, YSundead import logging from logging import critical, warn, info, debug from config import * @@ -62,16 +63,34 @@ async def handle_client(client_reader, client_writer): # Check if health increased if player.life == -1: player.life = playerData[21] - # TODO : Remove in production - elif player.life == 0: - debug(data) + 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 abs(player.gValue) > G_LIM and player.gValue < 23: # TODO : Add limiter to read from a json file + + if player.life < 5: + 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(b'"\x00\x00\x00$\x00\x00\x00*\x03\x01\x00\x0c\x00\xc8\x00\x14\x00 \x00\x08!!\x00\x08!"\x00\x08!\x00\x00\xb8\x0b\xc8\x00\x14\x00') + await writer.drain() + targetWriter.write(YSundead.undeadState) + await targetWriter.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) @@ -79,6 +98,7 @@ async def handle_client(client_reader, client_writer): await writer.drain() break + # parsed_data = parseFlightData(data) # tRemote, playerId, x, y, z, *_ = parsed_data # gunAmmo, rktAmmo, aam, agm, *_ = parsed_data[16:] @@ -93,21 +113,30 @@ async def handle_client(client_reader, client_writer): info("Connection Request") username = (b''.join(unpack("II16cI", data)[2:16])).decode('ascii').strip('\x00') playerObject = YSplayer.Player(username, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ipAddr, - -1, -1, -1, -1, 0) + -1, -1, -1, -1, 0, client_writer) CONNECTED_PLAYERS.append(playerObject) elif packet_type == 12: # End Flight for player in CONNECTED_PLAYERS: if player.ip == ipAddr: player.playerId = 0 player.life = -1 + player.warningSent = False debug("Health resseted to -1") break - + elif packet_type == 36: # Weapon config + # here we patch the packet to have smoke forcefully + for player in CONNECTED_PLAYERS: + if player.ip == ipAddr: + targetPlayer = player + break + data = YSundead.undeadPatch(targetPlayer.playerId, data) + writer.write(data) + await writer.drain() """ - elif packet_type == 32: # Aircraft list transmission end - print("Aircraft list transmission end") - welcomeMsg = YSchat.message("Welcome to YSFlight Proxy!") - writer.write(welcomeMsg) + elif packet_type == 32: # Char message + # will be used for commands + msg = YSchat.message("Pong!") + writer.write(msg) await writer.drain() """ @@ -117,6 +146,15 @@ async def handle_client(client_reader, client_writer): length, packet_type = unpack("