diff options
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | lib/YSplayer.py | 6 | ||||
| -rw-r--r-- | lib/YSundead.py | 9 | ||||
| -rw-r--r-- | proxy.py | 62 |
4 files changed, 67 insertions, 15 deletions
@@ -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 @@ -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("<I I", data[:8]) debug("S2C" + str(packet_type)) debug(data) + if packet_type == 36: + for player in CONNECTED_PLAYERS: + if player.ip == ipAddr: + targetWriter = player.streamWriterObject + id = player.playerId + break + data = YSundead.undeadPatch(id, data) + targetWriter.write(data) + await targetWriter.drain() # Forward the packet to the other endpoint writer.write(data) |
