Compare commits
2 Commits
console-on
...
main
Author | SHA1 | Date | |
---|---|---|---|
a37f162b21 | |||
5ba816715e |
4
.idea/vcs.xml
generated
4
.idea/vcs.xml
generated
@ -1,4 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings" defaultProject="true" />
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
289
main.py
289
main.py
@ -1,15 +1,20 @@
|
||||
from pathlib import Path
|
||||
|
||||
import threading
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, filedialog, scrolledtext
|
||||
import queue
|
||||
import requests
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Generator, Self
|
||||
|
||||
|
||||
DISCORD_WEBHOOK_URL = "HOOOOOOOOOOOOOOOOK"
|
||||
LOG_FILE_PATH = Path(r"E:\RSI\StarCitizen\LIVE\Game.log")
|
||||
# Default values
|
||||
DEFAULT_DISCORD_WEBHOOK_URL = "HOOOOOOOOOOOOOOOOK"
|
||||
DEFAULT_LOG_FILE_PATH = Path(r"E:\RSI\StarCitizen\LIVE\Game.log")
|
||||
DEBUG = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Line:
|
||||
line: str
|
||||
@ -44,15 +49,20 @@ class App:
|
||||
discord_webhook_url: str,
|
||||
do_backread: bool = False,
|
||||
do_mock_discord: bool = False,
|
||||
hide_npc_kills: bool = False,
|
||||
kill_callback=None,
|
||||
):
|
||||
self.log_file_path = log_file_path
|
||||
self.do_backread: bool = do_backread
|
||||
self.do_mock_discord: bool = do_mock_discord
|
||||
self.discord_webhook_url: str = discord_webhook_url
|
||||
self.nickname: str | None = None
|
||||
self.kill_callback = kill_callback
|
||||
self.hide_npc_kills = hide_npc_kills
|
||||
self.running = True
|
||||
|
||||
if not (discord_webhook_url.startswith("https://") or do_mock_discord):
|
||||
msg = f'{discord_webhook_url} не вебхук, так то'
|
||||
msg = f"{discord_webhook_url} не вебхук, так то"
|
||||
print(msg)
|
||||
raise RuntimeError(msg)
|
||||
|
||||
@ -71,6 +81,9 @@ class App:
|
||||
|
||||
def process_lines(self) -> None:
|
||||
for line in self.monitor_log_file():
|
||||
if not self.running:
|
||||
break
|
||||
|
||||
process_important_realtime_events = self.do_backread or line.is_realtime
|
||||
|
||||
if "<AccountLoginCharacterStatus_Character>" in line.line:
|
||||
@ -82,23 +95,27 @@ class App:
|
||||
and process_important_realtime_events
|
||||
):
|
||||
kill = Kill.from_line(line.line)
|
||||
# if self.nickname in (kill.killer, kill.victim):
|
||||
# Skip processing if this is an NPC kill and hide_npc_kills is enabled
|
||||
if self.hide_npc_kills and "_NPC_" in kill.victim:
|
||||
continue
|
||||
self.send_kill(kill)
|
||||
|
||||
def send_kill(self, kill: Kill) -> None:
|
||||
if kill.victim == kill.killer:
|
||||
msg = f"**{kill.victim}** РКН"
|
||||
|
||||
msg = f"🤦 **{kill.victim}** РКН"
|
||||
else:
|
||||
msg = f"**{kill.victim}** killed by **{kill.killer}**"
|
||||
msg = f"💀 **{kill.victim}** killed by 🔫 **{kill.killer}**"
|
||||
|
||||
self.send(msg)
|
||||
|
||||
# Call the callback if provided
|
||||
if self.kill_callback:
|
||||
self.kill_callback(kill, msg)
|
||||
|
||||
def send(self, message: str) -> None:
|
||||
try:
|
||||
if self.do_mock_discord:
|
||||
print("Sending message to discord", message)
|
||||
|
||||
else:
|
||||
requests.post(self.discord_webhook_url, json={"content": message})
|
||||
|
||||
@ -107,31 +124,251 @@ class App:
|
||||
|
||||
def monitor_log_file(self) -> Generator[Line, None, None]:
|
||||
is_realtime = False
|
||||
with self.log_file_path.open("r", encoding="utf-8") as file:
|
||||
while True:
|
||||
current_position = file.tell()
|
||||
line = file.readline()
|
||||
try:
|
||||
with self.log_file_path.open("r", encoding="utf-8") as file:
|
||||
while self.running:
|
||||
current_position = file.tell()
|
||||
line = file.readline()
|
||||
|
||||
if not line:
|
||||
is_realtime = True
|
||||
time.sleep(5)
|
||||
file.seek(current_position)
|
||||
if DEBUG is True:
|
||||
return
|
||||
if not line:
|
||||
is_realtime = True
|
||||
time.sleep(5)
|
||||
file.seek(current_position)
|
||||
if DEBUG is True:
|
||||
return
|
||||
|
||||
line = line.removesuffix("\n")
|
||||
yield Line(line, is_realtime)
|
||||
line = line.removesuffix("\n")
|
||||
yield Line(line, is_realtime)
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Log file not found: {self.log_file_path}")
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error monitoring log file: {e}")
|
||||
return
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
|
||||
class DeathLogGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("Star Citizen Death Log Monitor")
|
||||
self.root.geometry("800x600")
|
||||
self.root.minsize(600, 400)
|
||||
|
||||
self.log_path = tk.StringVar(value=str(DEFAULT_LOG_FILE_PATH))
|
||||
self.webhook_url = tk.StringVar(value=DEFAULT_DISCORD_WEBHOOK_URL)
|
||||
self.do_backread = tk.BooleanVar(value=False)
|
||||
self.do_mock_discord = tk.BooleanVar(value=False)
|
||||
self.hide_npc_kills = tk.BooleanVar(value=True)
|
||||
|
||||
self.app = None
|
||||
self.monitor_thread = None
|
||||
self.kill_queue = queue.Queue()
|
||||
self.recent_kills: list[str] = []
|
||||
self.max_kills_to_display = 100
|
||||
|
||||
self.create_widgets()
|
||||
self.update_kill_display()
|
||||
|
||||
def create_widgets(self):
|
||||
# Create main frame
|
||||
main_frame = ttk.Frame(self.root, padding="10")
|
||||
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# Configuration section
|
||||
config_frame = ttk.LabelFrame(main_frame, text="Configuration", padding="10")
|
||||
config_frame.pack(fill=tk.X, pady=5)
|
||||
|
||||
# Log file path
|
||||
ttk.Label(config_frame, text="Log File Path:").grid(
|
||||
row=0, column=0, sticky=tk.W, pady=2
|
||||
)
|
||||
ttk.Entry(config_frame, textvariable=self.log_path, width=50).grid(
|
||||
row=0, column=1, sticky=tk.W + tk.E, pady=2, padx=5
|
||||
)
|
||||
ttk.Button(config_frame, text="Browse", command=self.browse_log_file).grid(
|
||||
row=0, column=2, pady=2
|
||||
)
|
||||
|
||||
# Discord webhook URL
|
||||
ttk.Label(config_frame, text="Discord Webhook URL:").grid(
|
||||
row=1, column=0, sticky=tk.W, pady=2
|
||||
)
|
||||
ttk.Entry(config_frame, textvariable=self.webhook_url, width=50).grid(
|
||||
row=1, column=1, sticky=tk.W + tk.E, pady=2, padx=5
|
||||
)
|
||||
|
||||
# Checkboxes
|
||||
ttk.Checkbutton(
|
||||
config_frame, text="Process existing log entries", variable=self.do_backread
|
||||
).grid(row=2, column=0, columnspan=2, sticky=tk.W, pady=2)
|
||||
ttk.Checkbutton(
|
||||
config_frame,
|
||||
text="Mock Discord (don't send actual messages)",
|
||||
variable=self.do_mock_discord,
|
||||
).grid(row=3, column=0, columnspan=2, sticky=tk.W, pady=2)
|
||||
ttk.Checkbutton(
|
||||
config_frame,
|
||||
text="Hide NPC kills (_NPC_ in name)",
|
||||
variable=self.hide_npc_kills,
|
||||
).grid(row=4, column=0, columnspan=2, sticky=tk.W, pady=2)
|
||||
|
||||
# Control buttons
|
||||
control_frame = ttk.Frame(main_frame)
|
||||
control_frame.pack(fill=tk.X, pady=5)
|
||||
|
||||
self.start_button = ttk.Button(
|
||||
control_frame, text="Start Monitoring", command=self.start_monitoring
|
||||
)
|
||||
self.start_button.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
self.stop_button = ttk.Button(
|
||||
control_frame,
|
||||
text="Stop Monitoring",
|
||||
command=self.stop_monitoring,
|
||||
state=tk.DISABLED,
|
||||
)
|
||||
self.stop_button.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
# Status indicator
|
||||
self.status_var = tk.StringVar(value="Not monitoring")
|
||||
status_frame = ttk.Frame(main_frame)
|
||||
status_frame.pack(fill=tk.X, pady=5)
|
||||
ttk.Label(status_frame, text="Status:").pack(side=tk.LEFT)
|
||||
self.status_label = ttk.Label(
|
||||
status_frame, textvariable=self.status_var, foreground="red"
|
||||
)
|
||||
self.status_label.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
# Kill events display
|
||||
kills_frame = ttk.LabelFrame(
|
||||
main_frame, text="Recent Kill Events", padding="10"
|
||||
)
|
||||
kills_frame.pack(fill=tk.BOTH, expand=True, pady=5)
|
||||
|
||||
self.kill_display = scrolledtext.ScrolledText(
|
||||
kills_frame, wrap=tk.WORD, height=10
|
||||
)
|
||||
self.kill_display.pack(fill=tk.BOTH, expand=True)
|
||||
self.kill_display.config(state=tk.DISABLED)
|
||||
|
||||
def browse_log_file(self):
|
||||
filename = filedialog.askopenfilename(
|
||||
title="Select Star Citizen Log File",
|
||||
filetypes=[("Log Files", "*.log"), ("All Files", "*.*")],
|
||||
)
|
||||
if filename:
|
||||
self.log_path.set(filename)
|
||||
|
||||
def start_monitoring(self):
|
||||
if self.monitor_thread and self.monitor_thread.is_alive():
|
||||
return
|
||||
|
||||
try:
|
||||
log_path = Path(self.log_path.get())
|
||||
webhook_url = self.webhook_url.get()
|
||||
|
||||
self.app = App(
|
||||
log_file_path=log_path,
|
||||
discord_webhook_url=webhook_url,
|
||||
do_backread=self.do_backread.get(),
|
||||
do_mock_discord=self.do_mock_discord.get(),
|
||||
hide_npc_kills=self.hide_npc_kills.get(),
|
||||
kill_callback=self.on_kill,
|
||||
)
|
||||
|
||||
self.monitor_thread = threading.Thread(
|
||||
target=self.app.process_lines, daemon=True
|
||||
)
|
||||
self.monitor_thread.start()
|
||||
|
||||
self.status_var.set("Monitoring active")
|
||||
self.status_label.config(foreground="green")
|
||||
self.start_button.config(state=tk.DISABLED)
|
||||
self.stop_button.config(state=tk.NORMAL)
|
||||
|
||||
except Exception as e:
|
||||
self.status_var.set(f"Error: {str(e)}")
|
||||
self.status_label.config(foreground="red")
|
||||
|
||||
def stop_monitoring(self):
|
||||
if self.app:
|
||||
self.app.stop()
|
||||
|
||||
if self.monitor_thread:
|
||||
self.monitor_thread.join(timeout=1.0)
|
||||
|
||||
self.status_var.set("Monitoring stopped")
|
||||
self.status_label.config(foreground="red")
|
||||
self.start_button.config(state=tk.NORMAL)
|
||||
self.stop_button.config(state=tk.DISABLED)
|
||||
|
||||
def on_kill(self, kill: Kill, message: str):
|
||||
# No need to filter here as it's already filtered in the App class
|
||||
self.kill_queue.put((kill, message))
|
||||
|
||||
def update_kill_display(self):
|
||||
while not self.kill_queue.empty():
|
||||
try:
|
||||
kill, message = self.kill_queue.get_nowait()
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
# Simplified message with only nicknames and emojis
|
||||
if kill.victim == kill.killer:
|
||||
formatted_message = f"[{timestamp}] 🤦 {kill.victim} (self-kill)\n"
|
||||
else:
|
||||
formatted_message = (
|
||||
f"[{timestamp}] 💀 {kill.victim} killed by 🔫 {kill.killer}\n"
|
||||
)
|
||||
|
||||
self.recent_kills.append(formatted_message)
|
||||
if len(self.recent_kills) > self.max_kills_to_display:
|
||||
self.recent_kills.pop(0)
|
||||
|
||||
self.kill_display.config(state=tk.NORMAL)
|
||||
self.kill_display.delete(1.0, tk.END)
|
||||
for msg in self.recent_kills:
|
||||
self.kill_display.insert(tk.END, msg)
|
||||
self.kill_display.config(state=tk.DISABLED)
|
||||
self.kill_display.see(tk.END)
|
||||
except queue.Empty:
|
||||
break
|
||||
|
||||
self.root.after(100, self.update_kill_display)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
if DEBUG is True:
|
||||
app = App(Path("./Game.log"), DISCORD_WEBHOOK_URL, do_mock_discord=True, do_backread=True)
|
||||
# Check if we should run in GUI mode or CLI mode
|
||||
import sys
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "--cli":
|
||||
# CLI mode
|
||||
if DEBUG is True:
|
||||
app = App(
|
||||
Path("./Game.log"),
|
||||
DEFAULT_DISCORD_WEBHOOK_URL,
|
||||
do_mock_discord=True,
|
||||
do_backread=True,
|
||||
hide_npc_kills=False,
|
||||
)
|
||||
|
||||
else:
|
||||
app = App(
|
||||
DEFAULT_LOG_FILE_PATH,
|
||||
DEFAULT_DISCORD_WEBHOOK_URL,
|
||||
hide_npc_kills=False,
|
||||
)
|
||||
app.process_lines()
|
||||
|
||||
else:
|
||||
app = App(LOG_FILE_PATH, DISCORD_WEBHOOK_URL)
|
||||
|
||||
app.process_lines()
|
||||
# GUI mode
|
||||
root = tk.Tk()
|
||||
app = DeathLogGUI(root)
|
||||
root.mainloop()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nMonitoring stopped")
|
||||
|
@ -4,5 +4,6 @@ version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"pyinstaller>=6.13.0",
|
||||
"requests>=2.32.3",
|
||||
]
|
||||
|
104
uv.lock
generated
104
uv.lock
generated
@ -2,6 +2,15 @@ version = 1
|
||||
revision = 1
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/de/a8/7145824cf0b9e3c28046520480f207df47e927df83aa9555fb47f8505922/altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406", size = 48418 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/3f/3bc3f1d83f6e4a7fcb834d3720544ca597590425be5ba9db032b2bf322a2/altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff", size = 21212 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.4.26"
|
||||
@ -42,6 +51,86 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macholib"
|
||||
version = "1.16.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "altgraph" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/95/ee/af1a3842bdd5902ce133bd246eb7ffd4375c38642aeb5dc0ae3a0329dfa2/macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30", size = 59309 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/5d/c059c180c84f7962db0aeae7c3b9303ed1d73d76f2bfbc32bc231c8be314/macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c", size = 38094 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pefile"
|
||||
version = "2023.2.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/78/c5/3b3c62223f72e2360737fd2a57c30e5b2adecd85e70276879609a7403334/pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc", size = 74854 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/55/26/d0ad8b448476d0a1e8d3ea5622dc77b916db84c6aa3cb1e1c0965af948fc/pefile-2023.2.7-py3-none-any.whl", hash = "sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6", size = 71791 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller"
|
||||
version = "6.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "altgraph" },
|
||||
{ name = "macholib", marker = "sys_platform == 'darwin'" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pefile", marker = "sys_platform == 'win32'" },
|
||||
{ name = "pyinstaller-hooks-contrib" },
|
||||
{ name = "pywin32-ctypes", marker = "sys_platform == 'win32'" },
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/b1/2949fe6d3874e961898ca5cfc1bf2cf13bdeea488b302e74a745bc28c8ba/pyinstaller-6.13.0.tar.gz", hash = "sha256:38911feec2c5e215e5159a7e66fdb12400168bd116143b54a8a7a37f08733456", size = 4276427 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/02/d1a347d35b1b627da1e148159e617576555619ac3bb8bbd5fed661fc7bb5/pyinstaller-6.13.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:aa404f0b02cd57948098055e76ee190b8e65ccf7a2a3f048e5000f668317069f", size = 1001923 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/80/6da39f7aeac65c9ca5afad0fac37887d75fdfd480178a7077c9d30b0704c/pyinstaller-6.13.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:92efcf2f09e78f07b568c5cb7ed48c9940f5dad627af4b49bede6320fab2a06e", size = 718135 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/2c/d21d31f780a489609e7bf6385c0f7635238dc98b37cba8645b53322b7450/pyinstaller-6.13.0-py3-none-manylinux2014_i686.whl", hash = "sha256:9f82f113c463f012faa0e323d952ca30a6f922685d9636e754bd3a256c7ed200", size = 728543 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/20/e6ca87bbed6c0163533195707f820f05e10b8da1223fc6972cfe3c3c50c7/pyinstaller-6.13.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:db0e7945ebe276f604eb7c36e536479556ab32853412095e19172a5ec8fca1c5", size = 726868 },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/d5/53b19285f8817ab6c4b07c570208d62606bab0e5a049d50c93710a1d9dc6/pyinstaller-6.13.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:92fe7337c5aa08d42b38d7a79614492cb571489f2cb0a8f91dc9ef9ccbe01ed3", size = 725037 },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/5b/08e0b305ba71e6d7cb247e27d714da7536895b0283132d74d249bf662366/pyinstaller-6.13.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:bc09795f5954135dd4486c1535650958c8218acb954f43860e4b05fb515a21c0", size = 721027 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/9c/d8d0a7120103471be8dbe1c5419542aa794b9b9ec2ef628b542f9e6f9ef0/pyinstaller-6.13.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:589937548d34978c568cfdc39f31cf386f45202bc27fdb8facb989c79dfb4c02", size = 723443 },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/c7/8a9d81569dda2352068ecc6ee779d5feff6729569dd1b4ffd1236ecd38fe/pyinstaller-6.13.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b7260832f7501ba1d2ce1834d4cddc0f2b94315282bc89c59333433715015447", size = 719915 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/e6/cccadb02b90198c7ed4ffb8bc34d420efb72b996f47cbd4738067a602d65/pyinstaller-6.13.0-py3-none-win32.whl", hash = "sha256:80c568848529635aa7ca46d8d525f68486d53e03f68b7bb5eba2c88d742e302c", size = 1294997 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/06/15cbe0e25d1e73d5b981fa41ff0bb02b15e924e30b8c61256f4a28c4c837/pyinstaller-6.13.0-py3-none-win_amd64.whl", hash = "sha256:8d4296236b85aae570379488c2da833b28828b17c57c2cc21fccd7e3811fe372", size = 1352714 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/ef/74379298d46e7caa6aa7ceccc865106d3d4b15ac487ffdda2a35bfb6fe79/pyinstaller-6.13.0-py3-none-win_arm64.whl", hash = "sha256:d9f21d56ca2443aa6a1e255e7ad285c76453893a454105abe1b4d45e92bb9a20", size = 1293589 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller-hooks-contrib"
|
||||
version = "2025.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e3/94/dfc5c7903306211798f990e6794c2eb7b8685ac487b26979e9255790419c/pyinstaller_hooks_contrib-2025.4.tar.gz", hash = "sha256:5ce1afd1997b03e70f546207031cfdf2782030aabacc102190677059e2856446", size = 162628 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/e1/ed48c7074145898e5c5b0072e87be975c5bd6a1d0f08c27a1daa7064fca0/pyinstaller_hooks_contrib-2025.4-py3-none-any.whl", hash = "sha256:6c2d73269b4c484eb40051fc1acee0beb113c2cfb3b37437b8394faae6f0d072", size = 434451 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywin32-ctypes"
|
||||
version = "0.2.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.3"
|
||||
@ -62,11 +151,24 @@ name = "sc-death-log"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "pyinstaller" },
|
||||
{ name = "requests" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "requests", specifier = ">=2.32.3" }]
|
||||
requires-dist = [
|
||||
{ name = "pyinstaller", specifier = ">=6.13.0" },
|
||||
{ name = "requests", specifier = ">=2.32.3" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "80.8.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8d/d2/ec1acaaff45caed5c2dedb33b67055ba9d4e96b091094df90762e60135fe/setuptools-80.8.0.tar.gz", hash = "sha256:49f7af965996f26d43c8ae34539c8d99c5042fbff34302ea151eaa9c207cd257", size = 1319720 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/58/29/93c53c098d301132196c3238c312825324740851d77a8500a2462c0fd888/setuptools-80.8.0-py3-none-any.whl", hash = "sha256:95a60484590d24103af13b686121328cc2736bee85de8936383111e421b9edc0", size = 1201470 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
|
Loading…
x
Reference in New Issue
Block a user