Compare commits
10 Commits
7328d877b9
...
70541c0b47
| Author | SHA1 | Date | |
|---|---|---|---|
| 70541c0b47 | |||
| 285d36a097 | |||
| f551b85a73 | |||
| 1a5c27bb0c | |||
| fd0efa31ed | |||
| 604f798766 | |||
| 45a1c684fc | |||
| 918bd11bc6 | |||
| 0f4993c19d | |||
| 4031fb0c92 |
135
.dockerignore
Normal file
135
.dockerignore
Normal file
@@ -0,0 +1,135 @@
|
||||
# -------------------------------
|
||||
# Системные и скрытые каталоги
|
||||
# -------------------------------
|
||||
.git/
|
||||
.gitea/
|
||||
.hg/
|
||||
.svn/
|
||||
.gitignore
|
||||
.dockerignore
|
||||
.gitattributes
|
||||
|
||||
# -------------------------------
|
||||
# Виртуальные окружения, кэш и зависимости
|
||||
# -------------------------------
|
||||
# Python
|
||||
.venv/
|
||||
venv/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.egg-info/
|
||||
*.eggs/
|
||||
*.pytest_cache/
|
||||
.mypy_cache/
|
||||
.cache/
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-error.log*
|
||||
.pnp/
|
||||
.pnp.js
|
||||
|
||||
# Ruby
|
||||
.bundle/
|
||||
vendor/bundle/
|
||||
|
||||
# Java / JVM
|
||||
target/
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Go
|
||||
bin/
|
||||
*.exe
|
||||
|
||||
# -------------------------------
|
||||
# IDE и редакторы
|
||||
# -------------------------------
|
||||
.idea/
|
||||
.vscode/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.iml
|
||||
|
||||
# -------------------------------
|
||||
# Логи и временные файлы
|
||||
# -------------------------------
|
||||
*.log
|
||||
*.logs
|
||||
*.log.*
|
||||
*.logs.*
|
||||
Logs/
|
||||
Log/
|
||||
dist/
|
||||
build/
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
*.temp
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# -------------------------------
|
||||
# Конфиденциальные файлы и настройки
|
||||
# -------------------------------
|
||||
.env
|
||||
env/
|
||||
*.session
|
||||
*.key
|
||||
*.pem
|
||||
*.crt
|
||||
*.p12
|
||||
*.jks
|
||||
credentials/
|
||||
secrets/
|
||||
|
||||
# -------------------------------
|
||||
# Документация, тесты и примеры
|
||||
# -------------------------------
|
||||
docs/
|
||||
examples/
|
||||
tests/
|
||||
test/
|
||||
*.test
|
||||
*.tests
|
||||
README.md
|
||||
LICENSE
|
||||
|
||||
# -------------------------------
|
||||
# Базы данных и кэш
|
||||
# -------------------------------
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
*.sqlite-shm
|
||||
*.sqlite-wal
|
||||
*.dump
|
||||
*.sql
|
||||
*.bak
|
||||
*.backup
|
||||
|
||||
# -------------------------------
|
||||
# Сборка и артефакты
|
||||
# -------------------------------
|
||||
*.o
|
||||
*.obj
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.exe
|
||||
*.out
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.egg
|
||||
*.wheel
|
||||
*.pyc
|
||||
dist/
|
||||
build/
|
||||
coverage/
|
||||
.coverage.*
|
||||
43
.gitea/workflows/ci.yaml
Normal file
43
.gitea/workflows/ci.yaml
Normal file
@@ -0,0 +1,43 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r backend/requirements.txt
|
||||
|
||||
- name: Lint backend
|
||||
run: |
|
||||
pip install flake8
|
||||
flake8 backend
|
||||
|
||||
frontend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Check frontend files
|
||||
run: |
|
||||
test -f frontend/templates/index.html
|
||||
test -f frontend/css/style.css
|
||||
test -f frontend/js/main.js
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [2025] [freya]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
0
backend/__init__.py
Normal file
0
backend/__init__.py
Normal file
14
backend/config.py
Normal file
14
backend/config.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from os import getenv
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
class Config:
|
||||
"""
|
||||
Конфигурация FastAPI приложения.
|
||||
Все значения берутся из .env или имеют дефолтные.
|
||||
"""
|
||||
HOST: str = getenv("HOST", "0.0.0.0")
|
||||
PORT: int = int(getenv("PORT", "80"))
|
||||
DEBUG: bool = getenv("DEBUG", "False").lower() in ("1", "true", "yes")
|
||||
0
backend/routes/__init__.py
Normal file
0
backend/routes/__init__.py
Normal file
0
backend/services/__init__.py
Normal file
0
backend/services/__init__.py
Normal file
0
backend/utils/__init__.py
Normal file
0
backend/utils/__init__.py
Normal file
38
backend/utils/crypto.py
Normal file
38
backend/utils/crypto.py
Normal file
@@ -0,0 +1,38 @@
|
||||
def encrypt_bytes(key: int, bs: bytes) -> bytes:
|
||||
"""
|
||||
Простое шифрование XOR + модификация ключа.
|
||||
|
||||
Аргументы:
|
||||
- key: int - начальный ключ
|
||||
- bs: bytes - данные для шифрования
|
||||
|
||||
Возвращает:
|
||||
- bytes: зашифрованные данные
|
||||
"""
|
||||
result: bytearray = bytearray()
|
||||
for b in bs:
|
||||
k: int = (key >> 8) & 0xFF
|
||||
enc: int = b ^ k
|
||||
result.append(enc)
|
||||
key = (enc & key) | 0x482D
|
||||
return bytes(result)
|
||||
|
||||
|
||||
def decrypt_bytes(key: int, bs: bytes) -> bytes:
|
||||
"""
|
||||
Обратное преобразование к EncryptBytes.
|
||||
|
||||
Аргументы:
|
||||
- key: int - начальный ключ
|
||||
- bs: bytes - данные для расшифровки
|
||||
|
||||
Возвращает:
|
||||
- bytes: расшифрованные данные
|
||||
"""
|
||||
result: bytearray = bytearray()
|
||||
for b in bs:
|
||||
k: int = (key >> 8) & 0xFF
|
||||
dec: int = b ^ k
|
||||
result.append(dec)
|
||||
key = (b & key) | 0x482D
|
||||
return bytes(result)
|
||||
48
backend/utils/encoding.py
Normal file
48
backend/utils/encoding.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from typing import Dict
|
||||
|
||||
# Таблица Base64-подобного варианта
|
||||
VariantBase64Table: str = (
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
)
|
||||
VariantBase64Dict: Dict[int, str] = {
|
||||
i: VariantBase64Table[i] for i in range(len(VariantBase64Table))
|
||||
}
|
||||
VariantBase64ReverseDict: Dict[str, int] = {
|
||||
VariantBase64Table[i]: i for i in range(len(VariantBase64Table))
|
||||
}
|
||||
|
||||
|
||||
def variant_base64_encode(bs: bytes) -> bytes:
|
||||
"""
|
||||
Пользовательский Base64 encode (малые блоки, little-endian).
|
||||
|
||||
Аргументы:
|
||||
- bs: bytes - исходные данные
|
||||
|
||||
Возвращает:
|
||||
- bytes: закодированные данные
|
||||
"""
|
||||
result: bytearray = bytearray()
|
||||
blocks_count, left_bytes = divmod(len(bs), 3)
|
||||
|
||||
# Полные блоки по 3 байта
|
||||
for i in range(blocks_count):
|
||||
b: bytes = bs[3*i:3*i+3]
|
||||
coding_int: int = int.from_bytes(b, "little")
|
||||
block: str = "".join(
|
||||
VariantBase64Dict[(coding_int >> shift) & 0x3F]
|
||||
for shift in (0, 6, 12, 18)
|
||||
)
|
||||
result.extend(block.encode("ascii"))
|
||||
|
||||
# Обработка оставшихся байт
|
||||
if left_bytes:
|
||||
b: bytes = bs[-left_bytes:]
|
||||
coding_int: int = int.from_bytes(b, "little")
|
||||
block: str = "".join(
|
||||
VariantBase64Dict[(coding_int >> shift) & 0x3F]
|
||||
for shift in range(0, left_bytes * 8 + 1, 6)
|
||||
)
|
||||
result.extend(block.encode("ascii"))
|
||||
|
||||
return bytes(result)
|
||||
BIN
frontend/assets/fonts/LCDSolid1.13-Regular.otf
Normal file
BIN
frontend/assets/fonts/LCDSolid1.13-Regular.otf
Normal file
Binary file not shown.
114
frontend/css/style.css
Normal file
114
frontend/css/style.css
Normal file
@@ -0,0 +1,114 @@
|
||||
/* Подключение кастомного шрифта */
|
||||
@font-face {
|
||||
font-family: 'LCD';
|
||||
src: url('/static/assets/fonts/LCDSolid1.13-Regular.otf') format('opentype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: radial-gradient(circle at top, #1a1a1a, #000000);
|
||||
font-family: 'LCD', sans-serif;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: rgba(20, 20, 20, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 35px;
|
||||
width: 420px;
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 0 20px rgba(188, 190, 190, 0.2),
|
||||
0 0 40px rgba(182, 182, 182, 0.1);
|
||||
animation: fadeIn 0.8s ease;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
font-size: 15px;
|
||||
letter-spacing: 1px;
|
||||
color: #dfdfdf;
|
||||
text-shadow: 0 0 10px #a8aaaa60;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 10px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 18px;
|
||||
background: #0f0f0f;
|
||||
border: 1px solid #222;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
transition: 0.25s;
|
||||
font-size: 10px;
|
||||
font-family: 'LCD', sans-serif;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
border-color: #a5a3a3bd;
|
||||
box-shadow: 0 0 4px #9c9c9c;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, #eb9341, #f8500d);
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 15px;
|
||||
cursor: pointer;
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
transition: 0.25s;
|
||||
box-shadow: 0 0 15px rgba(255, 102, 0, 0.459);
|
||||
font-family: 'LCD', sans-serif;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 0 17px rgba(255, 123, 0, 0.836);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(15px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 12px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
font-family: 'LCD', Arial;
|
||||
opacity: 0.7;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
footer:hover { opacity: 1; }
|
||||
|
||||
footer a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
transition: 0.25s ease;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #ddddddd8;
|
||||
text-decoration: underline;
|
||||
}
|
||||
38
frontend/templates/index.html
Normal file
38
frontend/templates/index.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Moba Script Generator</title>
|
||||
<link rel="icon" type="image/x-icon" href="/static/assets/icons/favicon.ico">
|
||||
|
||||
<!-- Подключение CSS -->
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
|
||||
<!-- Подключение JS -->
|
||||
<script src="/static/js/main.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h2>MobaXterm Script Creator</h2>
|
||||
|
||||
<form id="licenseForm">
|
||||
<label>NAME:</label>
|
||||
<input name="name" placeholder="Введите имя" required>
|
||||
|
||||
<label>VERSION:</label>
|
||||
<input name="version" placeholder="Введите версию" required>
|
||||
|
||||
<button type="submit">Сгенерировать</button>
|
||||
</form>
|
||||
|
||||
<div id="status"></div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
Автор:
|
||||
<a href="https://t.me/prokiller006" target="_blank">icysanta</a>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user