ndVpi 1.0.0b0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ndvpi-1.0.0b0/PKG-INFO +34 -0
- ndvpi-1.0.0b0/README.md +13 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/PKG-INFO +34 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/SOURCES.txt +23 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/dependency_links.txt +1 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/entry_points.txt +2 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/requires.txt +3 -0
- ndvpi-1.0.0b0/ndVpi.egg-info/top_level.txt +1 -0
- ndvpi-1.0.0b0/ndvpi/__init__.py +27 -0
- ndvpi-1.0.0b0/ndvpi/charm_enhance.py +136 -0
- ndvpi-1.0.0b0/ndvpi/cli.py +13 -0
- ndvpi-1.0.0b0/ndvpi/collquan_ext.py +111 -0
- ndvpi-1.0.0b0/ndvpi/critchers.py +184 -0
- ndvpi-1.0.0b0/ndvpi/diagnostics.py +75 -0
- ndvpi-1.0.0b0/ndvpi/history.py +58 -0
- ndvpi-1.0.0b0/ndvpi/menu.py +270 -0
- ndvpi-1.0.0b0/ndvpi/monitor.py +86 -0
- ndvpi-1.0.0b0/ndvpi/network_config.py +205 -0
- ndvpi-1.0.0b0/ndvpi/network_info.py +117 -0
- ndvpi-1.0.0b0/ndvpi/optimizer.py +113 -0
- ndvpi-1.0.0b0/ndvpi/polidium.py +69 -0
- ndvpi-1.0.0b0/ndvpi/version.py +1 -0
- ndvpi-1.0.0b0/ndvpi/wifi.py +126 -0
- ndvpi-1.0.0b0/pyproject.toml +35 -0
- ndvpi-1.0.0b0/setup.cfg +4 -0
ndvpi-1.0.0b0/PKG-INFO
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ndVpi
|
|
3
|
+
Version: 1.0.0b0
|
|
4
|
+
Summary: Фоновая оптимизация сети, сканер Wi-Fi и агрессивный сетевой бустер для Windows.
|
|
5
|
+
Author-email: CharmLxt <reception.mailspypi@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/ndVpi/
|
|
8
|
+
Keywords: wifi,network,latency,optimization,diagnostics,monitoring,charmpkk
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Topic :: System :: Networking
|
|
16
|
+
Classifier: Topic :: System :: Networking :: Monitoring
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Provides-Extra: charm
|
|
20
|
+
Requires-Dist: CharmPkk>=25.10.26b1; extra == "charm"
|
|
21
|
+
|
|
22
|
+
ndVpi. Версия 1.0.0b. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com).
|
|
23
|
+
|
|
24
|
+
Библиотека ndVpi — это мощный инструмент для диагностики, мониторинга и агрессивной оптимизации сети, созданный специально для энтузиастов и разработчиков. В бета-версии 1.0.0b произошло глобальное разделение оптимизатора на два независимых модуля: Polidium и Critchers, что позволяет гибко настраивать сеть под свои задачи.
|
|
25
|
+
|
|
26
|
+
Модуль Polidium отвечает за безопасную очистку и умную оптимизацию. Он очищает системный DNS-кэш и ARP-таблицы, устраняя ошибки маршрутизации, а также внедряет в оперативную память собственный TTL-кэш для DNS-запросов. Благодаря этому веб-страницы в браузерах начинают открываться быстрее, так как запросы к DNS-серверам перехватываются и выполняются мгновенно.
|
|
27
|
+
|
|
28
|
+
Модуль Critchers — это агрессивный сетевой бустер, который выполняет скрытую от глаз, но крайне полезную работу. Он очищает невидимый кэш оперативной памяти (Standby List), освобождая ресурсы для сетевых драйверов. С помощью правки реестра Windows (требуются права Администратора) он отключает алгоритмы задержки TCP (TcpAckFrequency, NetworkThrottlingIndex), что снижает пинг в играх и стримингах. Кроме того, Critchers отключает энергосбережение Wi-Fi адаптера, чтобы предотвратить микро-фризы, и временно приостанавливает фоновые процессы (например, OneDrive или обновления Windows), которые воруют трафик. Все изменения реестра бэкапятся, и их можно откатить одной командой restore.
|
|
29
|
+
|
|
30
|
+
В версии 1.0.0b также значительно расширены диагностика и мониторинг. Real-time монитор теперь отрисовывает графики пинга (спарклайны) прямо в консоли, отслеживает джиттер и потери пакетов. Диагностика проверяет доступность шлюза, скорость разрешения DNS и состояние адаптеров. Если у вас установлена библиотека CharmPkk, весь интерфейс (меню, таблицы диагностики и графики) автоматически окрашивается в красивые градиентные цвета и использует плавную перерисовку Live без мерцания. Без CharmPkk ndVpi работает автономно на чистом print.
|
|
31
|
+
|
|
32
|
+
Для установки используйте команду pip install ndVpi. Для интеграции с красивым интерфейсом CharmPkk используйте pip install "ndVpi[charm]". Обратите внимание, что функции Critchers (очистка RAM, твики реестра, сон Wi-Fi) работают только на Windows и требуют запуска консоли от имени Администратора.
|
|
33
|
+
|
|
34
|
+
Связь с автором: reception.mailspypi@gmail.com.
|
ndvpi-1.0.0b0/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ndVpi. Версия 1.0.0b. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com).
|
|
2
|
+
|
|
3
|
+
Библиотека ndVpi — это мощный инструмент для диагностики, мониторинга и агрессивной оптимизации сети, созданный специально для энтузиастов и разработчиков. В бета-версии 1.0.0b произошло глобальное разделение оптимизатора на два независимых модуля: Polidium и Critchers, что позволяет гибко настраивать сеть под свои задачи.
|
|
4
|
+
|
|
5
|
+
Модуль Polidium отвечает за безопасную очистку и умную оптимизацию. Он очищает системный DNS-кэш и ARP-таблицы, устраняя ошибки маршрутизации, а также внедряет в оперативную память собственный TTL-кэш для DNS-запросов. Благодаря этому веб-страницы в браузерах начинают открываться быстрее, так как запросы к DNS-серверам перехватываются и выполняются мгновенно.
|
|
6
|
+
|
|
7
|
+
Модуль Critchers — это агрессивный сетевой бустер, который выполняет скрытую от глаз, но крайне полезную работу. Он очищает невидимый кэш оперативной памяти (Standby List), освобождая ресурсы для сетевых драйверов. С помощью правки реестра Windows (требуются права Администратора) он отключает алгоритмы задержки TCP (TcpAckFrequency, NetworkThrottlingIndex), что снижает пинг в играх и стримингах. Кроме того, Critchers отключает энергосбережение Wi-Fi адаптера, чтобы предотвратить микро-фризы, и временно приостанавливает фоновые процессы (например, OneDrive или обновления Windows), которые воруют трафик. Все изменения реестра бэкапятся, и их можно откатить одной командой restore.
|
|
8
|
+
|
|
9
|
+
В версии 1.0.0b также значительно расширены диагностика и мониторинг. Real-time монитор теперь отрисовывает графики пинга (спарклайны) прямо в консоли, отслеживает джиттер и потери пакетов. Диагностика проверяет доступность шлюза, скорость разрешения DNS и состояние адаптеров. Если у вас установлена библиотека CharmPkk, весь интерфейс (меню, таблицы диагностики и графики) автоматически окрашивается в красивые градиентные цвета и использует плавную перерисовку Live без мерцания. Без CharmPkk ndVpi работает автономно на чистом print.
|
|
10
|
+
|
|
11
|
+
Для установки используйте команду pip install ndVpi. Для интеграции с красивым интерфейсом CharmPkk используйте pip install "ndVpi[charm]". Обратите внимание, что функции Critchers (очистка RAM, твики реестра, сон Wi-Fi) работают только на Windows и требуют запуска консоли от имени Администратора.
|
|
12
|
+
|
|
13
|
+
Связь с автором: reception.mailspypi@gmail.com.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ndVpi
|
|
3
|
+
Version: 1.0.0b0
|
|
4
|
+
Summary: Фоновая оптимизация сети, сканер Wi-Fi и агрессивный сетевой бустер для Windows.
|
|
5
|
+
Author-email: CharmLxt <reception.mailspypi@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://pypi.org/project/ndVpi/
|
|
8
|
+
Keywords: wifi,network,latency,optimization,diagnostics,monitoring,charmpkk
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Topic :: System :: Networking
|
|
16
|
+
Classifier: Topic :: System :: Networking :: Monitoring
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Provides-Extra: charm
|
|
20
|
+
Requires-Dist: CharmPkk>=25.10.26b1; extra == "charm"
|
|
21
|
+
|
|
22
|
+
ndVpi. Версия 1.0.0b. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com).
|
|
23
|
+
|
|
24
|
+
Библиотека ndVpi — это мощный инструмент для диагностики, мониторинга и агрессивной оптимизации сети, созданный специально для энтузиастов и разработчиков. В бета-версии 1.0.0b произошло глобальное разделение оптимизатора на два независимых модуля: Polidium и Critchers, что позволяет гибко настраивать сеть под свои задачи.
|
|
25
|
+
|
|
26
|
+
Модуль Polidium отвечает за безопасную очистку и умную оптимизацию. Он очищает системный DNS-кэш и ARP-таблицы, устраняя ошибки маршрутизации, а также внедряет в оперативную память собственный TTL-кэш для DNS-запросов. Благодаря этому веб-страницы в браузерах начинают открываться быстрее, так как запросы к DNS-серверам перехватываются и выполняются мгновенно.
|
|
27
|
+
|
|
28
|
+
Модуль Critchers — это агрессивный сетевой бустер, который выполняет скрытую от глаз, но крайне полезную работу. Он очищает невидимый кэш оперативной памяти (Standby List), освобождая ресурсы для сетевых драйверов. С помощью правки реестра Windows (требуются права Администратора) он отключает алгоритмы задержки TCP (TcpAckFrequency, NetworkThrottlingIndex), что снижает пинг в играх и стримингах. Кроме того, Critchers отключает энергосбережение Wi-Fi адаптера, чтобы предотвратить микро-фризы, и временно приостанавливает фоновые процессы (например, OneDrive или обновления Windows), которые воруют трафик. Все изменения реестра бэкапятся, и их можно откатить одной командой restore.
|
|
29
|
+
|
|
30
|
+
В версии 1.0.0b также значительно расширены диагностика и мониторинг. Real-time монитор теперь отрисовывает графики пинга (спарклайны) прямо в консоли, отслеживает джиттер и потери пакетов. Диагностика проверяет доступность шлюза, скорость разрешения DNS и состояние адаптеров. Если у вас установлена библиотека CharmPkk, весь интерфейс (меню, таблицы диагностики и графики) автоматически окрашивается в красивые градиентные цвета и использует плавную перерисовку Live без мерцания. Без CharmPkk ndVpi работает автономно на чистом print.
|
|
31
|
+
|
|
32
|
+
Для установки используйте команду pip install ndVpi. Для интеграции с красивым интерфейсом CharmPkk используйте pip install "ndVpi[charm]". Обратите внимание, что функции Critchers (очистка RAM, твики реестра, сон Wi-Fi) работают только на Windows и требуют запуска консоли от имени Администратора.
|
|
33
|
+
|
|
34
|
+
Связь с автором: reception.mailspypi@gmail.com.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
ndVpi.egg-info/PKG-INFO
|
|
4
|
+
ndVpi.egg-info/SOURCES.txt
|
|
5
|
+
ndVpi.egg-info/dependency_links.txt
|
|
6
|
+
ndVpi.egg-info/entry_points.txt
|
|
7
|
+
ndVpi.egg-info/requires.txt
|
|
8
|
+
ndVpi.egg-info/top_level.txt
|
|
9
|
+
ndvpi/__init__.py
|
|
10
|
+
ndvpi/charm_enhance.py
|
|
11
|
+
ndvpi/cli.py
|
|
12
|
+
ndvpi/collquan_ext.py
|
|
13
|
+
ndvpi/critchers.py
|
|
14
|
+
ndvpi/diagnostics.py
|
|
15
|
+
ndvpi/history.py
|
|
16
|
+
ndvpi/menu.py
|
|
17
|
+
ndvpi/monitor.py
|
|
18
|
+
ndvpi/network_config.py
|
|
19
|
+
ndvpi/network_info.py
|
|
20
|
+
ndvpi/optimizer.py
|
|
21
|
+
ndvpi/polidium.py
|
|
22
|
+
ndvpi/version.py
|
|
23
|
+
ndvpi/wifi.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ndvpi
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""ndVpi — фоновая оптимизация сети и сканер Wi-Fi."""
|
|
2
|
+
from .version import __version__
|
|
3
|
+
from .wifi import WiFiScanner
|
|
4
|
+
from .network_info import NetworkInfo
|
|
5
|
+
from .polidium import Polidium
|
|
6
|
+
from .critchers import Critchers
|
|
7
|
+
from .network_config import NetworkConfig
|
|
8
|
+
from .monitor import NetworkMonitor
|
|
9
|
+
from .diagnostics import NetworkDiagnostics
|
|
10
|
+
from .history import SessionHistory
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"__version__",
|
|
14
|
+
"WiFiScanner",
|
|
15
|
+
"NetworkInfo",
|
|
16
|
+
"Polidium",
|
|
17
|
+
"Critchers",
|
|
18
|
+
"NetworkConfig",
|
|
19
|
+
"NetworkMonitor",
|
|
20
|
+
"NetworkDiagnostics",
|
|
21
|
+
"SessionHistory",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from . import collquan_ext # noqa: F401
|
|
26
|
+
except Exception:
|
|
27
|
+
pass
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Мягкая интеграция с CharmPkk: красиво, если есть; обычно, если нет."""
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
_charm = None
|
|
5
|
+
_c = None
|
|
6
|
+
_available = False
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from charmpkk import console as _c
|
|
10
|
+
_charm = __import__("charmpkk")
|
|
11
|
+
_available = True
|
|
12
|
+
except Exception:
|
|
13
|
+
_available = False
|
|
14
|
+
|
|
15
|
+
def has_charm(): return _available
|
|
16
|
+
def console(): return _c
|
|
17
|
+
def theme(name="tokyo_night"): return _c.get_theme(name) if _available else None
|
|
18
|
+
|
|
19
|
+
def _fg(color):
|
|
20
|
+
if not _available or not color: return None
|
|
21
|
+
if isinstance(color, str) and color.startswith("#"): return _c.fg_hex(color)
|
|
22
|
+
return color
|
|
23
|
+
|
|
24
|
+
def print_msg(text, color=None, style=None):
|
|
25
|
+
print(_c.colorize(text, fg=_fg(color), style=style)) if _available else print(text)
|
|
26
|
+
|
|
27
|
+
def banner(title, subtitle=None, color="#7aa2ff"):
|
|
28
|
+
if _available: return _c.banner(title, subtitle, fg=_fg(color))
|
|
29
|
+
return f"\n=== {title} ===\n{subtitle}\n" if subtitle else f"\n=== {title} ===\n"
|
|
30
|
+
|
|
31
|
+
def box(content, title=None, color="#7aa2ff"):
|
|
32
|
+
if _available: return _c.box(content, title=title, border_fg=_fg(color))
|
|
33
|
+
lines = content if isinstance(content, list) else [content]
|
|
34
|
+
return "\n".join([f"--- {title} ---" if title else "-"*20] + [str(l) for l in lines] + ["-"*20])
|
|
35
|
+
|
|
36
|
+
def table(headers, rows, header_color="#7aa2ff"):
|
|
37
|
+
if _available: return _c.Table(headers=headers, rows=rows, header_fg=_fg(header_color)).render()
|
|
38
|
+
all_rows = [list(headers)] + [list(r) for r in rows]
|
|
39
|
+
n_cols = len(headers)
|
|
40
|
+
widths = [max(len(str(r[i])) if i < len(r) else 0 for r in all_rows) for i in range(n_cols)]
|
|
41
|
+
lines = []
|
|
42
|
+
for i, row in enumerate(all_rows):
|
|
43
|
+
cells = [str(row[j]) if j < len(row) else "" for j in range(n_cols)]
|
|
44
|
+
lines.append(" | ".join(c.ljust(widths[j]) for j, c in enumerate(cells)))
|
|
45
|
+
if i == 0: lines.append("-+-".join("-" * w for w in widths))
|
|
46
|
+
return "\n".join(lines)
|
|
47
|
+
|
|
48
|
+
def sparkline(values, fg="#7aa2ff"):
|
|
49
|
+
if _available: return _c.sparkline(values, fg=_fg(fg))
|
|
50
|
+
return "".join("▁▂▃▄▅▆▇█"[int(v/max(values or [1])*(7))] for v in values)
|
|
51
|
+
|
|
52
|
+
def key_value(data, key_color="#8b93a7"):
|
|
53
|
+
if _available: return _c.key_value(data, key_fg=_fg(key_color))
|
|
54
|
+
max_k = max((len(str(k)) for k in data), default=0)
|
|
55
|
+
return "\n".join(f" {str(k).ljust(max_k)}: {v}" for k, v in data.items())
|
|
56
|
+
|
|
57
|
+
def info(msg): print(_c.info(msg)) if _available else print(f"[i] {msg}")
|
|
58
|
+
def success(msg): print(_c.success(msg)) if _available else print(f"[+] {msg}")
|
|
59
|
+
def warning(msg): print(_c.warning(msg)) if _available else print(f"[!] {msg}")
|
|
60
|
+
def error(msg): print(_c.error(msg)) if _available else print(f"[x] {msg}")
|
|
61
|
+
|
|
62
|
+
def render_info(msg): return _c.info(msg) if _available else f"[i] {msg}"
|
|
63
|
+
def render_success(msg): return _c.success(msg) if _available else f"[+] {msg}"
|
|
64
|
+
def render_warning(msg): return _c.warning(msg) if _available else f"[!] {msg}"
|
|
65
|
+
def render_error(msg): return _c.error(msg) if _available else f"[x] {msg}"
|
|
66
|
+
|
|
67
|
+
def ask(prompt, default=None):
|
|
68
|
+
if _available: return _c.ask(prompt, default=default)
|
|
69
|
+
hint = f" [{default}]" if default is not None else ""
|
|
70
|
+
try: return input(f"? {prompt}{hint}: ").strip() or default
|
|
71
|
+
except (EOFError, KeyboardInterrupt): return default
|
|
72
|
+
|
|
73
|
+
def confirm(prompt, default=False):
|
|
74
|
+
if _available: return _c.confirm(prompt, default=default)
|
|
75
|
+
d = "Y/n" if default else "y/N"
|
|
76
|
+
try: v = input(f"? {prompt} ({d}): ").strip().lower()
|
|
77
|
+
except (EOFError, KeyboardInterrupt): return default
|
|
78
|
+
return v.startswith("y") if v else default
|
|
79
|
+
|
|
80
|
+
def select(title, options, color="#7aa2ff"):
|
|
81
|
+
if not options: return None
|
|
82
|
+
if _available: return _c.select(title, options, fg_cursor=_fg(color), fg_title=_fg(color))
|
|
83
|
+
print(title)
|
|
84
|
+
for i, opt in enumerate(options, 1): print(f" {i}. {opt}")
|
|
85
|
+
try:
|
|
86
|
+
idx = int(input("> ").strip()) - 1
|
|
87
|
+
if 0 <= idx < len(options): return options[idx]
|
|
88
|
+
except Exception: return None
|
|
89
|
+
|
|
90
|
+
class _NullProgress:
|
|
91
|
+
def __enter__(self): return self
|
|
92
|
+
def __exit__(self, *exc): print()
|
|
93
|
+
def update(self, current): sys.stdout.write(f"\r {current}%"); sys.stdout.flush()
|
|
94
|
+
def finish(self, msg=None): print(msg) if msg else None
|
|
95
|
+
|
|
96
|
+
def progress(total=100, label="", color="#7aa2ff"):
|
|
97
|
+
return _c.FancyProgressBar(total=total, label=label, fg=_fg(color)) if _available else _NullProgress()
|
|
98
|
+
|
|
99
|
+
class _NullSpinner:
|
|
100
|
+
def __enter__(self): return self
|
|
101
|
+
def __exit__(self, *exc): pass
|
|
102
|
+
def stop(self, final=None): print(final) if final else None
|
|
103
|
+
|
|
104
|
+
def spinner(text="Loading", color="#7aa2ff"):
|
|
105
|
+
if _available: return _c.Spinner(text, fg=_fg(color))
|
|
106
|
+
print(text + "...")
|
|
107
|
+
return _NullSpinner()
|
|
108
|
+
|
|
109
|
+
class LiveDashboard:
|
|
110
|
+
def __init__(self):
|
|
111
|
+
self._live = None
|
|
112
|
+
self._running = False
|
|
113
|
+
self._last_lines = 0
|
|
114
|
+
def __enter__(self):
|
|
115
|
+
if _available: self._live = _c.Live(); self._live.__enter__()
|
|
116
|
+
self._running = True
|
|
117
|
+
return self
|
|
118
|
+
def update(self, content):
|
|
119
|
+
if not self._running: return
|
|
120
|
+
if _available and self._live: self._live.update(content)
|
|
121
|
+
else:
|
|
122
|
+
lines = content.split("\n")
|
|
123
|
+
if self._last_lines > 0: sys.stdout.write(f"\033[{self._last_lines}A")
|
|
124
|
+
max_lines = max(self._last_lines, len(lines))
|
|
125
|
+
for i in range(max_lines):
|
|
126
|
+
sys.stdout.write("\033[2K")
|
|
127
|
+
if i < len(lines): sys.stdout.write(lines[i])
|
|
128
|
+
sys.stdout.write("\n")
|
|
129
|
+
if max_lines > len(lines): sys.stdout.write(f"\033[{max_lines - len(lines)}A")
|
|
130
|
+
self._last_lines = len(lines)
|
|
131
|
+
sys.stdout.flush()
|
|
132
|
+
def __exit__(self, *exc):
|
|
133
|
+
self._running = False
|
|
134
|
+
if _available and self._live: self._live.__exit__(*exc)
|
|
135
|
+
else: sys.stdout.write("\n")
|
|
136
|
+
return False
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""Интеграция ndVpi с Collquan (CharmPkk)."""
|
|
2
|
+
try:
|
|
3
|
+
from charmpkk.terminals import CollquanShell
|
|
4
|
+
except Exception:
|
|
5
|
+
CollquanShell = None
|
|
6
|
+
|
|
7
|
+
from .wifi import WiFiScanner
|
|
8
|
+
from .network_info import NetworkInfo
|
|
9
|
+
from .polidium import Polidium
|
|
10
|
+
from .critchers import Critchers
|
|
11
|
+
from .network_config import NetworkConfig, _is_admin
|
|
12
|
+
|
|
13
|
+
_polidium = Polidium()
|
|
14
|
+
_critchers = Critchers()
|
|
15
|
+
_config = NetworkConfig()
|
|
16
|
+
|
|
17
|
+
def _cmd_scan(args):
|
|
18
|
+
data = WiFiScanner().current_network()
|
|
19
|
+
if not data: print("Нет данных о Wi-Fi."); return
|
|
20
|
+
for k, v in data.items(): print(f"{k}: {v}")
|
|
21
|
+
|
|
22
|
+
def _cmd_info(args):
|
|
23
|
+
info = NetworkInfo()
|
|
24
|
+
print(f"IP: {info.local_ip()}")
|
|
25
|
+
print(f"Шлюз: {info.gateway()}")
|
|
26
|
+
print(f"DNS: {', '.join(info.dns_servers()) or '—'}")
|
|
27
|
+
print(f"Ping: {info.ping() or '—'} ms")
|
|
28
|
+
|
|
29
|
+
def _cmd_poli(args):
|
|
30
|
+
if args and args[0] == "dns":
|
|
31
|
+
_polidium.flush_dns()
|
|
32
|
+
print("[+] DNS кэш очищен")
|
|
33
|
+
elif args and args[0] == "arp":
|
|
34
|
+
_polidium.flush_arp()
|
|
35
|
+
print("[+] ARP кэш очищен")
|
|
36
|
+
else:
|
|
37
|
+
_polidium.flush_dns()
|
|
38
|
+
_polidium.flush_arp()
|
|
39
|
+
print("[+] Polidium: кэши очищены")
|
|
40
|
+
|
|
41
|
+
def _cmd_crit(args):
|
|
42
|
+
if args and args[0] == "ram":
|
|
43
|
+
ok, msg = _critchers.clean_standby_list()
|
|
44
|
+
print(f"[{'x' if not ok else '+'}] {msg}")
|
|
45
|
+
elif args and args[0] == "tcp":
|
|
46
|
+
ok, msg = _critchers.apply_tcp_tweaks()
|
|
47
|
+
print(f"[{'x' if not ok else '+'}] {msg}")
|
|
48
|
+
elif args and args[0] == "restore":
|
|
49
|
+
ok, msg = _critchers.restore()
|
|
50
|
+
print(f"[{'x' if not ok else '+'}] {msg}")
|
|
51
|
+
else:
|
|
52
|
+
print("Использование: ndcrit <ram|tcp|restore>")
|
|
53
|
+
|
|
54
|
+
def _cmd_dns(args):
|
|
55
|
+
if not args or args[0] == "show":
|
|
56
|
+
servers = _config.get_dns()
|
|
57
|
+
print("DNS:", ", ".join(servers) if servers else "автоматически")
|
|
58
|
+
return
|
|
59
|
+
if args[0] == "set":
|
|
60
|
+
if len(args) < 2: print("Использование: nddns set <ip1> [ip2]..."); return
|
|
61
|
+
ok, msg = _config.set_dns(args[1:])
|
|
62
|
+
print(("[+] " if ok else "[x] ") + msg)
|
|
63
|
+
return
|
|
64
|
+
if args[0] == "reset":
|
|
65
|
+
ok, msg = _config.reset_dns()
|
|
66
|
+
print(("[+] " if ok else "[x] ") + msg)
|
|
67
|
+
return
|
|
68
|
+
print("Использование: nddns [show|set <ip>...|reset]")
|
|
69
|
+
|
|
70
|
+
def _cmd_pass(args):
|
|
71
|
+
if len(args) < 2: print("Использование: ndpass <ssid> <new_password>"); return
|
|
72
|
+
ssid, pwd = args[0], args[1]
|
|
73
|
+
print(f"[!] Внимание: смена пароля для '{ssid}' может разорвать соединение.")
|
|
74
|
+
if input("Продолжить? [y/N] ").strip().lower() != "y":
|
|
75
|
+
print("Отменено."); return
|
|
76
|
+
ok, msg = _config.change_wifi_password(ssid, pwd)
|
|
77
|
+
print(("[+] " if ok else "[x] ") + msg)
|
|
78
|
+
|
|
79
|
+
def _cmd_adapters(args):
|
|
80
|
+
if not args or args[0] == "list":
|
|
81
|
+
for a in _config.list_adapters(): print(f" {a.get('name', '?'):<30} {a}")
|
|
82
|
+
return
|
|
83
|
+
if args[0] in ("enable", "disable") and len(args) >= 2:
|
|
84
|
+
ok, msg = _config.set_adapter_state(args[1], enabled=(args[0] == "enable"))
|
|
85
|
+
print(("[+] " if ok else "[x] ") + msg)
|
|
86
|
+
return
|
|
87
|
+
print("Использование: ndadapters [list|enable|disable <name>]")
|
|
88
|
+
|
|
89
|
+
def _cmd_mtu(args):
|
|
90
|
+
if not args: print("Использование: ndmtu <interface> [new_mtu]"); return
|
|
91
|
+
iface = args[0]
|
|
92
|
+
if len(args) == 1:
|
|
93
|
+
mtu = _config.get_mtu(iface)
|
|
94
|
+
print(f"MTU {iface} = {mtu if mtu is not None else '—'}")
|
|
95
|
+
return
|
|
96
|
+
ok, msg = _config.set_mtu(iface, args[1])
|
|
97
|
+
print(("[+] " if ok else "[x] ") + msg)
|
|
98
|
+
|
|
99
|
+
def _cmd_admin(args):
|
|
100
|
+
print("Администратор:", "да" if _is_admin() else "нет")
|
|
101
|
+
|
|
102
|
+
if CollquanShell is not None:
|
|
103
|
+
CollquanShell.register("ndscan", "Сканировать Wi-Fi")(_cmd_scan)
|
|
104
|
+
CollquanShell.register("ndinfo", "Информация о сети")(_cmd_info)
|
|
105
|
+
CollquanShell.register("ndpoli", "Polidium: очистка DNS/ARP")(_cmd_poli)
|
|
106
|
+
CollquanShell.register("ndcrit", "Critchers: RAM/TCP буст")(_cmd_crit)
|
|
107
|
+
CollquanShell.register("nddns", "DNS: show/set/reset")(_cmd_dns)
|
|
108
|
+
CollquanShell.register("ndpass", "Сменить пароль Wi-Fi: <ssid> <pass>")(_cmd_pass)
|
|
109
|
+
CollquanShell.register("ndadapters", "Адаптеры: list/enable/disable")(_cmd_adapters)
|
|
110
|
+
CollquanShell.register("ndmtu", "MTU: <iface> [new_mtu]")(_cmd_mtu)
|
|
111
|
+
CollquanShell.register("ndadmin", "Проверить права администратора")(_cmd_admin)
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""Critchers: Агрессивный сетевой бустер и очистка ресурсов (Без psutil)."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
import ctypes
|
|
6
|
+
import platform
|
|
7
|
+
import subprocess
|
|
8
|
+
import atexit
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
BACKUP_FILE = Path.home() / ".ndvpi" / "critchers_backup.json"
|
|
12
|
+
|
|
13
|
+
def _is_windows():
|
|
14
|
+
return platform.system() == "Windows"
|
|
15
|
+
|
|
16
|
+
def _is_admin():
|
|
17
|
+
if not _is_windows(): return False
|
|
18
|
+
try:
|
|
19
|
+
return ctypes.windll.shell32.IsUserAnAdmin() != 0
|
|
20
|
+
except Exception:
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
def _get_pids(process_name):
|
|
24
|
+
try:
|
|
25
|
+
cmd = f'tasklist /FI "IMAGENAME eq {process_name}" /FO CSV /NH'
|
|
26
|
+
out = subprocess.run(cmd, shell=True, capture_output=True, text=True, encoding="cp866").stdout
|
|
27
|
+
pids = []
|
|
28
|
+
for line in out.splitlines():
|
|
29
|
+
if process_name.lower() in line.lower():
|
|
30
|
+
parts = line.split('","')
|
|
31
|
+
if len(parts) > 1:
|
|
32
|
+
try: pids.append(int(parts[1]))
|
|
33
|
+
except ValueError: pass
|
|
34
|
+
return pids
|
|
35
|
+
except Exception:
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
def _suspend_process(pid):
|
|
39
|
+
try:
|
|
40
|
+
PROCESS_SUSPEND_RESUME = 0x0800
|
|
41
|
+
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_SUSPEND_RESUME, False, pid)
|
|
42
|
+
if handle:
|
|
43
|
+
ctypes.windll.ntdll.NtSuspendProcess(handle)
|
|
44
|
+
ctypes.windll.kernel32.CloseHandle(handle)
|
|
45
|
+
return True
|
|
46
|
+
except Exception:
|
|
47
|
+
pass
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def _resume_process(pid):
|
|
51
|
+
try:
|
|
52
|
+
PROCESS_SUSPEND_RESUME = 0x0800
|
|
53
|
+
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_SUSPEND_RESUME, False, pid)
|
|
54
|
+
if handle:
|
|
55
|
+
ctypes.windll.ntdll.NtResumeProcess(handle)
|
|
56
|
+
ctypes.windll.kernel32.CloseHandle(handle)
|
|
57
|
+
return True
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
class Critchers:
|
|
63
|
+
def __init__(self):
|
|
64
|
+
self.backup_data = {}
|
|
65
|
+
self.suspended_pids = []
|
|
66
|
+
atexit.register(self.resume_background_downloads)
|
|
67
|
+
|
|
68
|
+
if BACKUP_FILE.exists():
|
|
69
|
+
try:
|
|
70
|
+
self.backup_data = json.loads(BACKUP_FILE.read_text("utf-8"))
|
|
71
|
+
except Exception:
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
def _save_backup(self):
|
|
75
|
+
BACKUP_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
BACKUP_FILE.write_text(json.dumps(self.backup_data, indent=2), "utf-8")
|
|
77
|
+
|
|
78
|
+
def clean_standby_list(self):
|
|
79
|
+
if not _is_windows() or not _is_admin():
|
|
80
|
+
return False, "Требуются права администратора Windows"
|
|
81
|
+
try:
|
|
82
|
+
ctypes.windll.ntdll.NtSetSystemInformation(-1073744922, ctypes.byref(ctypes.c_int(4)), 4)
|
|
83
|
+
return True, "RAM Standby List очищен"
|
|
84
|
+
except Exception as e:
|
|
85
|
+
return False, f"Ошибка RAM: {e}"
|
|
86
|
+
|
|
87
|
+
def apply_tcp_tweaks(self, dry_run=False):
|
|
88
|
+
if not _is_windows(): return False, "Только для Windows"
|
|
89
|
+
import winreg
|
|
90
|
+
tweaks = {
|
|
91
|
+
r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters": {
|
|
92
|
+
"NetworkThrottlingIndex": 0xffffffff,
|
|
93
|
+
"TcpAckFrequency": 1,
|
|
94
|
+
"TCPNoDelay": 1,
|
|
95
|
+
"TcpDelAckTicks": 0
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if dry_run:
|
|
99
|
+
return True, "DRY-RUN: Будет изменен реестр (TCP Acknowledgment, Throttling)"
|
|
100
|
+
if not _is_admin():
|
|
101
|
+
return False, "Требуются права администратора"
|
|
102
|
+
for path, values in tweaks.items():
|
|
103
|
+
try:
|
|
104
|
+
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path, 0, winreg.KEY_ALL_ACCESS)
|
|
105
|
+
for name, val in values.items():
|
|
106
|
+
try:
|
|
107
|
+
orig_val, _ = winreg.QueryValueEx(key, name)
|
|
108
|
+
self.backup_data[f"{path}\\{name}"] = orig_val
|
|
109
|
+
except FileNotFoundError:
|
|
110
|
+
self.backup_data[f"{path}\\{name}"] = None
|
|
111
|
+
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, val)
|
|
112
|
+
winreg.CloseKey(key)
|
|
113
|
+
except Exception as e:
|
|
114
|
+
return False, f"Ошибка реестра: {e}"
|
|
115
|
+
self._save_backup()
|
|
116
|
+
return True, "Твики TCP успешно применены"
|
|
117
|
+
|
|
118
|
+
def disable_wifi_power_saving(self, dry_run=False):
|
|
119
|
+
if not _is_windows(): return False, "Только для Windows"
|
|
120
|
+
if dry_run: return True, "DRY-RUN: Отключение энергосбережения Wi-Fi адаптера"
|
|
121
|
+
if not _is_admin(): return False, "Требуются права администратора"
|
|
122
|
+
ps_cmd = (
|
|
123
|
+
'Get-NetAdapter | Where-Object {$_.PhysicalMediaType -match "Native 802.11"} '
|
|
124
|
+
'| Disable-NetAdapterPowerManagement -ErrorAction SilentlyContinue'
|
|
125
|
+
)
|
|
126
|
+
try:
|
|
127
|
+
subprocess.run(["powershell", "-NoProfile", "-Command", ps_cmd], capture_output=True)
|
|
128
|
+
return True, "Энергосбережение Wi-Fi отключено"
|
|
129
|
+
except Exception as e:
|
|
130
|
+
return False, f"Ошибка: {e}"
|
|
131
|
+
|
|
132
|
+
def pause_background_downloads(self):
|
|
133
|
+
if not _is_windows() or not _is_admin():
|
|
134
|
+
return False, "Требуются права администратора"
|
|
135
|
+
targets = ["OneDrive.exe", "wuauclt.exe", "SysMain.exe"]
|
|
136
|
+
paused = []
|
|
137
|
+
for proc_name in targets:
|
|
138
|
+
pids = _get_pids(proc_name)
|
|
139
|
+
for pid in pids:
|
|
140
|
+
if _suspend_process(pid):
|
|
141
|
+
self.suspended_pids.append(pid)
|
|
142
|
+
paused.append(f"{proc_name} (PID: {pid})")
|
|
143
|
+
if paused:
|
|
144
|
+
return True, f"Приостановлены процессы: {', '.join(paused)}"
|
|
145
|
+
return True, "Фоновые качалки не найдены (или уже спят)"
|
|
146
|
+
|
|
147
|
+
def resume_background_downloads(self):
|
|
148
|
+
if not self.suspended_pids: return
|
|
149
|
+
resumed = []
|
|
150
|
+
for pid in self.suspended_pids:
|
|
151
|
+
if _resume_process(pid):
|
|
152
|
+
resumed.append(str(pid))
|
|
153
|
+
self.suspended_pids = []
|
|
154
|
+
if resumed:
|
|
155
|
+
print(f"[Critchers] Возобновлены процессы: {', '.join(resumed)}")
|
|
156
|
+
|
|
157
|
+
def restore(self):
|
|
158
|
+
if not _is_windows() or not _is_admin():
|
|
159
|
+
return False, "Требуются права администратора"
|
|
160
|
+
import winreg
|
|
161
|
+
restored = 0
|
|
162
|
+
for full_key, orig_val in self.backup_data.items():
|
|
163
|
+
path, name = full_key.rsplit("\\", 1)
|
|
164
|
+
try:
|
|
165
|
+
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path, 0, winreg.KEY_ALL_ACCESS)
|
|
166
|
+
if orig_val is None:
|
|
167
|
+
try: winreg.DeleteValue(key, name)
|
|
168
|
+
except FileNotFoundError: pass
|
|
169
|
+
else:
|
|
170
|
+
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, orig_val)
|
|
171
|
+
winreg.CloseKey(key)
|
|
172
|
+
restored += 1
|
|
173
|
+
except Exception:
|
|
174
|
+
pass
|
|
175
|
+
self.backup_data = {}
|
|
176
|
+
if BACKUP_FILE.exists():
|
|
177
|
+
BACKUP_FILE.unlink()
|
|
178
|
+
ps_cmd = (
|
|
179
|
+
'Get-NetAdapter | Where-Object {$_.PhysicalMediaType -match "Native 802.11"} '
|
|
180
|
+
'| Enable-NetAdapterPowerManagement -ErrorAction SilentlyContinue'
|
|
181
|
+
)
|
|
182
|
+
subprocess.run(["powershell", "-NoProfile", "-Command", ps_cmd], capture_output=True)
|
|
183
|
+
self.resume_background_downloads()
|
|
184
|
+
return True, f"Восстановлено настроек: {restored}. Wi-Fi питание и процессы возвращены."
|