mirror of
https://github.com/AlienMajik/pwnagotchi_plugins.git
synced 2025-07-01 18:37:27 -04:00
Add files via upload
Below is an example of how you can describe the plugin’s purpose, functionality, and installation instructions in a README.md file on your GitHub repository. You can adjust the wording and formatting as you see fit: Age, Strength, and Network Points Plugin for Pwnagotchi Author: AlienMajik Version: 1.0.4 License: MIT Description This Pwnagotchi plugin extends your Pwnagotchi’s user interface and functionality by adding three key stats: Age (♥ Age): Tracks how many epochs your Pwnagotchi has lived. Strength (Str): Indicates how much your Pwnagotchi has "trained," increasing every 10 epochs by default. Network Points (★ Pts): Awards points based on the type of network handshakes your Pwnagotchi captures. Stronger encryptions yield more points, weaker encryptions yield fewer. The points are logged for your reference. Network Points Scoring: WPA3: +10 points WPA2: +5 points WEP/WPA: +2 points Open/Unknown: +1 point Each time points are awarded, an entry is appended to /root/network_points.log with the ESSID, encryption type, points gained, and the updated total. All stats (age, strength, network points) are saved to /root/age_strength.json, ensuring that your Pwnagotchi remembers these values across reboots. Features Persistent Stats: Age, Strength, and Points survive restarts. UI Integration: Displays stats directly on the Pwnagotchi screen. Logging: Keeps a dedicated log file of network-related point gains. Customizable: You can tweak increments and positions via config options.
This commit is contained in:
159
age.py
Normal file
159
age.py
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pwnagotchi
|
||||||
|
import pwnagotchi.plugins as plugins
|
||||||
|
import pwnagotchi.ui.faces as faces
|
||||||
|
import pwnagotchi.ui.fonts as fonts
|
||||||
|
from pwnagotchi.ui.components import LabeledValue
|
||||||
|
from pwnagotchi.ui.view import BLACK
|
||||||
|
|
||||||
|
class Age(plugins.Plugin):
|
||||||
|
__author__ = 'AlienMajik'
|
||||||
|
__version__ = '1.0.4'
|
||||||
|
__license__ = 'MIT'
|
||||||
|
__description__ = 'A plugin that adds age, strength, and network points stats with a dedicated log of point increments.'
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.epochs = 0
|
||||||
|
self.train_epochs = 0
|
||||||
|
self.network_points = 0 # Stat to track points from network encounters
|
||||||
|
self.data_path = '/root/age_strength.json'
|
||||||
|
self.log_path = '/root/network_points.log' # Dedicated log file
|
||||||
|
|
||||||
|
def on_loaded(self):
|
||||||
|
# Load stored data from file if available
|
||||||
|
self.load_data()
|
||||||
|
|
||||||
|
def on_ui_setup(self, ui):
|
||||||
|
ui.add_element('Age', LabeledValue(
|
||||||
|
color=BLACK,
|
||||||
|
label='♥ Age',
|
||||||
|
value=0,
|
||||||
|
position=(int(self.options["age_x_coord"]), int(self.options["age_y_coord"])),
|
||||||
|
label_font=fonts.Bold,
|
||||||
|
text_font=fonts.Medium
|
||||||
|
))
|
||||||
|
ui.add_element('Strength', LabeledValue(
|
||||||
|
color=BLACK,
|
||||||
|
label='Str',
|
||||||
|
value=0,
|
||||||
|
position=(int(self.options["str_x_coord"]), int(self.options["str_y_coord"])),
|
||||||
|
label_font=fonts.Bold,
|
||||||
|
text_font=fonts.Medium
|
||||||
|
))
|
||||||
|
# Using a simpler label instead of an emoji for points
|
||||||
|
points_x = int(self.options.get("points_x_coord", 10))
|
||||||
|
points_y = int(self.options.get("points_y_coord", 100))
|
||||||
|
ui.add_element('Points', LabeledValue(
|
||||||
|
color=BLACK,
|
||||||
|
label='★ Pts', # ASCII-friendly label
|
||||||
|
value=0,
|
||||||
|
position=(points_x, points_y),
|
||||||
|
label_font=fonts.Bold,
|
||||||
|
text_font=fonts.Medium
|
||||||
|
))
|
||||||
|
|
||||||
|
def on_unload(self, ui):
|
||||||
|
with ui._lock:
|
||||||
|
ui.remove_element('Age')
|
||||||
|
ui.remove_element('Strength')
|
||||||
|
ui.remove_element('Points')
|
||||||
|
# Save data on unload
|
||||||
|
self.save_data()
|
||||||
|
|
||||||
|
def on_ui_update(self, ui):
|
||||||
|
ui.set('Age', str(self.abrev_number(self.epochs)))
|
||||||
|
ui.set('Strength', str(self.abrev_number(self.train_epochs)))
|
||||||
|
ui.set('Points', str(self.abrev_number(self.network_points)))
|
||||||
|
|
||||||
|
def on_epoch(self, agent, epoch, epoch_data):
|
||||||
|
self.epochs += 1
|
||||||
|
# Example: Increase strength every 10 epochs
|
||||||
|
if self.epochs % 10 == 0:
|
||||||
|
self.train_epochs += 1
|
||||||
|
|
||||||
|
# Checkpoints
|
||||||
|
if self.epochs % 100 == 0:
|
||||||
|
self.age_checkpoint(agent)
|
||||||
|
if self.train_epochs != 0 and self.train_epochs % 10 == 0:
|
||||||
|
self.strength_checkpoint(agent)
|
||||||
|
|
||||||
|
# Save data each epoch
|
||||||
|
self.save_data()
|
||||||
|
|
||||||
|
def on_handshake(self, agent, filename, access_point, client):
|
||||||
|
# Determine encryption type and award points
|
||||||
|
enc = access_point.get('encryption', '').lower()
|
||||||
|
essid = access_point.get('essid', 'unknown')
|
||||||
|
old_points = self.network_points
|
||||||
|
|
||||||
|
if 'wpa3' in enc:
|
||||||
|
increment = 10
|
||||||
|
desc = "WPA3"
|
||||||
|
elif 'wpa2' in enc:
|
||||||
|
increment = 5
|
||||||
|
desc = "WPA2"
|
||||||
|
elif 'wep' in enc or 'wpa' in enc:
|
||||||
|
increment = 2
|
||||||
|
desc = "WEP/WPA"
|
||||||
|
else:
|
||||||
|
increment = 1
|
||||||
|
desc = "Open/Unknown"
|
||||||
|
|
||||||
|
self.network_points += increment
|
||||||
|
self.display_encounter(agent, f"{desc} network discovered! +{increment} pts")
|
||||||
|
|
||||||
|
# Log the event to a dedicated file
|
||||||
|
with open(self.log_path, 'a') as f:
|
||||||
|
f.write(f"ESSID: {essid}, ENC: {enc}, Points Gained: {increment}, Total Points: {self.network_points}\n")
|
||||||
|
|
||||||
|
self.save_data()
|
||||||
|
|
||||||
|
def abrev_number(self, num):
|
||||||
|
if num < 100000:
|
||||||
|
return str(num)
|
||||||
|
else:
|
||||||
|
magnitude = 0
|
||||||
|
while abs(num) >= 1000:
|
||||||
|
magnitude += 1
|
||||||
|
num /= 1000.0
|
||||||
|
abbr = ['', 'K', 'M', 'B', 'T', 'P'][magnitude]
|
||||||
|
return '{}{}'.format('{:.2f}'.format(num).rstrip('0').rstrip('.'), abbr)
|
||||||
|
|
||||||
|
def age_checkpoint(self, agent):
|
||||||
|
view = agent.view()
|
||||||
|
view.set('face', faces.HAPPY)
|
||||||
|
view.set('status', f"Living for them {self.abrev_number(self.epochs)} epochs!")
|
||||||
|
view.update(force=True)
|
||||||
|
|
||||||
|
def strength_checkpoint(self, agent):
|
||||||
|
view = agent.view()
|
||||||
|
view.set('face', faces.MOTIVATED)
|
||||||
|
view.set('status', f"Getting them Gains Sucka!\nThey Drew First {self.abrev_number(self.train_epochs)} Epochs!")
|
||||||
|
view.update(force=True)
|
||||||
|
|
||||||
|
def display_encounter(self, agent, message):
|
||||||
|
# A helper method to display a quick status update when points are awarded
|
||||||
|
view = agent.view()
|
||||||
|
view.set('face', faces.EXCITED)
|
||||||
|
view.set('status', message)
|
||||||
|
view.update(force=True)
|
||||||
|
|
||||||
|
def load_data(self):
|
||||||
|
if os.path.exists(self.data_path):
|
||||||
|
with open(self.data_path, 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
self.epochs = data.get('epochs_lived', 0)
|
||||||
|
self.train_epochs = data.get('epochs_trained', 0)
|
||||||
|
self.network_points = data.get('network_points', 0)
|
||||||
|
|
||||||
|
def save_data(self):
|
||||||
|
data = {
|
||||||
|
'epochs_lived': self.epochs,
|
||||||
|
'epochs_trained': self.train_epochs,
|
||||||
|
'network_points': self.network_points
|
||||||
|
}
|
||||||
|
with open(self.data_path, 'w') as f:
|
||||||
|
json.dump(data, f)
|
Reference in New Issue
Block a user