bmpbypass 0.1.0__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.
- bmpbypass-0.1.0/LICENSE +21 -0
- bmpbypass-0.1.0/PKG-INFO +91 -0
- bmpbypass-0.1.0/README.md +69 -0
- bmpbypass-0.1.0/pyproject.toml +43 -0
- bmpbypass-0.1.0/setup.cfg +4 -0
- bmpbypass-0.1.0/src/bmpbypass/__init__.py +1 -0
- bmpbypass-0.1.0/src/bmpbypass/__main__.py +275 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/PKG-INFO +91 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/SOURCES.txt +11 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/dependency_links.txt +1 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/entry_points.txt +2 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/requires.txt +1 -0
- bmpbypass-0.1.0/src/bmpbypass.egg-info/top_level.txt +1 -0
bmpbypass-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zokrazium
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bmpbypass-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bmpbypass
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: BeamMP Mod Manager Bypass Tool
|
|
5
|
+
Author: zokraz
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/zokrazium/bmpbypass#readme
|
|
8
|
+
Project-URL: Source, https://github.com/zokrazium/bmpbypass
|
|
9
|
+
Project-URL: Documentation, https://github.com/zokrazium/bmpbypass#readme
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Environment :: X11 Applications :: Qt
|
|
16
|
+
Classifier: Topic :: Games/Entertainment
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: PyQt6>=6.5
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# bmpbypass
|
|
24
|
+
|
|
25
|
+
Patch **BeamNG.drive** so BeamMP stops force-managing your client-side mods.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install bmpbypass
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Use (GUI)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bmpbypass
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
* Click **Patch Game**
|
|
44
|
+
* Launch the game
|
|
45
|
+
* Play
|
|
46
|
+
|
|
47
|
+
If it says **Restore Original**, it’s already patched.
|
|
48
|
+
|
|
49
|
+
> [!IMPORTANT]
|
|
50
|
+
> Close the game before patching or restoring.
|
|
51
|
+
|
|
52
|
+
> [!TIP]
|
|
53
|
+
> If something breaks, click **Restore Original**.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Use (Terminal)
|
|
58
|
+
|
|
59
|
+
Patch:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bmpbypass --nogui
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Restore:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bmpbypass --nogui --restore
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Manual Game Path (if needed)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bmpbypass --nogui --game-path "/path/to/BeamNG.drive"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> [!NOTE]
|
|
80
|
+
> Path must be the main `BeamNG.drive` folder.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## What It Does
|
|
85
|
+
|
|
86
|
+
* Finds the game (Steam)
|
|
87
|
+
* Backs up `modmanager.lua`
|
|
88
|
+
* Adds a small patch
|
|
89
|
+
|
|
90
|
+
> [!CAUTION]
|
|
91
|
+
> Game updates may undo the patch. Just run it again.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# bmpbypass
|
|
2
|
+
|
|
3
|
+
Patch **BeamNG.drive** so BeamMP stops force-managing your client-side mods.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install bmpbypass
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Use (GUI)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bmpbypass
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
* Click **Patch Game**
|
|
22
|
+
* Launch the game
|
|
23
|
+
* Play
|
|
24
|
+
|
|
25
|
+
If it says **Restore Original**, it’s already patched.
|
|
26
|
+
|
|
27
|
+
> [!IMPORTANT]
|
|
28
|
+
> Close the game before patching or restoring.
|
|
29
|
+
|
|
30
|
+
> [!TIP]
|
|
31
|
+
> If something breaks, click **Restore Original**.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Use (Terminal)
|
|
36
|
+
|
|
37
|
+
Patch:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bmpbypass --nogui
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Restore:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bmpbypass --nogui --restore
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Manual Game Path (if needed)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bmpbypass --nogui --game-path "/path/to/BeamNG.drive"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
> [!NOTE]
|
|
58
|
+
> Path must be the main `BeamNG.drive` folder.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## What It Does
|
|
63
|
+
|
|
64
|
+
* Finds the game (Steam)
|
|
65
|
+
* Backs up `modmanager.lua`
|
|
66
|
+
* Adds a small patch
|
|
67
|
+
|
|
68
|
+
> [!CAUTION]
|
|
69
|
+
> Game updates may undo the patch. Just run it again.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bmpbypass"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "BeamMP Mod Manager Bypass Tool"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "zokraz" }
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
dependencies = [
|
|
18
|
+
"PyQt6>=6.5"
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"License :: OSI Approved :: MIT License",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Environment :: X11 Applications :: Qt",
|
|
28
|
+
"Topic :: Games/Entertainment"
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/zokrazium/bmpbypass#readme"
|
|
33
|
+
Source = "https://github.com/zokrazium/bmpbypass"
|
|
34
|
+
Documentation = "https://github.com/zokrazium/bmpbypass#readme"
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
bmpbypass = "bmpbypass.__main__:main"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
package-dir = {"" = "src"}
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import shutil
|
|
4
|
+
import argparse
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from PyQt6.QtCore import Qt
|
|
8
|
+
from PyQt6.QtWidgets import (
|
|
9
|
+
QApplication,
|
|
10
|
+
QWidget,
|
|
11
|
+
QLabel,
|
|
12
|
+
QPushButton,
|
|
13
|
+
QMessageBox,
|
|
14
|
+
QVBoxLayout,
|
|
15
|
+
QLineEdit,
|
|
16
|
+
QFileDialog,
|
|
17
|
+
QHBoxLayout,
|
|
18
|
+
QMenuBar
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
PATCH_MARKER = '-- BEAMMP_BYPASS_PATCH'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ---------------- THEME ---------------- #
|
|
25
|
+
|
|
26
|
+
def apply_theme(app: QApplication):
|
|
27
|
+
app.setStyle("Fusion")
|
|
28
|
+
app.setPalette(app.style().standardPalette())
|
|
29
|
+
|
|
30
|
+
# ---------------- STEAM DETECTION ---------------- #
|
|
31
|
+
|
|
32
|
+
def find_steam_base():
|
|
33
|
+
if os.name == "nt":
|
|
34
|
+
program_files_x86 = os.environ.get("PROGRAMFILES(X86)")
|
|
35
|
+
if not program_files_x86:
|
|
36
|
+
raise FileNotFoundError("PROGRAMFILES(X86) not set")
|
|
37
|
+
vdf = os.path.join(program_files_x86, "Steam", "steamapps", "libraryfolders.vdf")
|
|
38
|
+
if os.path.isfile(vdf):
|
|
39
|
+
return vdf
|
|
40
|
+
raise FileNotFoundError("Steam not found.")
|
|
41
|
+
else:
|
|
42
|
+
home = os.path.expanduser("~")
|
|
43
|
+
paths = [
|
|
44
|
+
os.path.join(home, ".steam", "steam"),
|
|
45
|
+
os.path.join(home, ".local", "share", "Steam"),
|
|
46
|
+
]
|
|
47
|
+
for base in paths:
|
|
48
|
+
vdf = os.path.join(base, "steamapps", "libraryfolders.vdf")
|
|
49
|
+
if os.path.isfile(vdf):
|
|
50
|
+
return vdf
|
|
51
|
+
raise FileNotFoundError("Steam not found.")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def find_library_paths(vdf_path):
|
|
55
|
+
with open(vdf_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
56
|
+
content = f.read()
|
|
57
|
+
return [
|
|
58
|
+
os.path.normpath(p)
|
|
59
|
+
for p in re.findall(r'^\s*"path"\s*"([^"]+)"$', content, re.MULTILINE)
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def find_game_dir(appid=284160):
|
|
64
|
+
vdf = find_steam_base()
|
|
65
|
+
for lib in find_library_paths(vdf):
|
|
66
|
+
manifest = os.path.join(lib, 'steamapps', f'appmanifest_{appid}.acf')
|
|
67
|
+
if os.path.exists(manifest):
|
|
68
|
+
with open(manifest, 'r', encoding="utf-8", errors="ignore") as f:
|
|
69
|
+
content = f.read()
|
|
70
|
+
match = re.search(r'^\s*"installdir"\s*"([^"]+)"$', content, re.MULTILINE)
|
|
71
|
+
if match:
|
|
72
|
+
return os.path.join(lib, 'steamapps', 'common', match.group(1))
|
|
73
|
+
raise FileNotFoundError("BeamNG.drive not found")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_lua_path(game_dir):
|
|
77
|
+
return os.path.join(
|
|
78
|
+
game_dir,
|
|
79
|
+
'lua', 'ge', 'extensions', 'core', 'modmanager.lua'
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def is_already_patched(lua_path):
|
|
84
|
+
with open(lua_path, 'r', encoding="utf-8", errors="ignore") as f:
|
|
85
|
+
return PATCH_MARKER in f.read()
|
|
86
|
+
|
|
87
|
+
def create_backup(lua_path):
|
|
88
|
+
backup_path = f"{lua_path}.bak"
|
|
89
|
+
shutil.copy2(lua_path, backup_path)
|
|
90
|
+
return backup_path
|
|
91
|
+
|
|
92
|
+
def modify_lua_file(lua_path):
|
|
93
|
+
if is_already_patched(lua_path):
|
|
94
|
+
raise RuntimeError("Already patched.")
|
|
95
|
+
|
|
96
|
+
create_backup(lua_path)
|
|
97
|
+
|
|
98
|
+
with open(lua_path, 'r', encoding="utf-8", errors="ignore") as f:
|
|
99
|
+
lines = f.readlines()
|
|
100
|
+
|
|
101
|
+
insert = [
|
|
102
|
+
' -- BEAMMP_BYPASS_PATCH\n',
|
|
103
|
+
' for level = 2, 6 do\n',
|
|
104
|
+
' local info = debug.getinfo(level, "S")\n',
|
|
105
|
+
' if not info or not info.source then break end\n',
|
|
106
|
+
' if string.find(info.source, "MPModManager.lua", 1, true) then\n',
|
|
107
|
+
' return\n',
|
|
108
|
+
' end\n',
|
|
109
|
+
' end\n'
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
for i, line in enumerate(lines):
|
|
113
|
+
if line.strip().startswith('local function deactivateMod'):
|
|
114
|
+
lines = lines[:i + 1] + insert + lines[i + 1:]
|
|
115
|
+
with open(lua_path, 'w', encoding="utf-8") as f:
|
|
116
|
+
f.writelines(lines)
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
raise ValueError("deactivateMod not found")
|
|
120
|
+
|
|
121
|
+
def restore_from_backup(lua_path):
|
|
122
|
+
backup_path = f"{lua_path}.bak"
|
|
123
|
+
if not os.path.exists(backup_path):
|
|
124
|
+
raise FileNotFoundError("No backup found.")
|
|
125
|
+
shutil.copy2(backup_path, lua_path)
|
|
126
|
+
|
|
127
|
+
def run_operation(restore=False, custom_path=None):
|
|
128
|
+
game_dir = custom_path if custom_path else find_game_dir()
|
|
129
|
+
lua = get_lua_path(game_dir)
|
|
130
|
+
|
|
131
|
+
if not os.path.exists(lua):
|
|
132
|
+
raise FileNotFoundError("modmanager.lua not found")
|
|
133
|
+
|
|
134
|
+
if restore:
|
|
135
|
+
restore_from_backup(lua)
|
|
136
|
+
return "Restored original file."
|
|
137
|
+
else:
|
|
138
|
+
modify_lua_file(lua)
|
|
139
|
+
return "Game successfully patched."
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# ---------------- GUI ---------------- #
|
|
143
|
+
|
|
144
|
+
class ModLockWindow(QWidget):
|
|
145
|
+
def __init__(self):
|
|
146
|
+
super().__init__()
|
|
147
|
+
self.setWindowTitle("MP Bypasser")
|
|
148
|
+
self.setMinimumWidth(450)
|
|
149
|
+
|
|
150
|
+
self.app = QApplication.instance()
|
|
151
|
+
|
|
152
|
+
self.menu_bar = QMenuBar(self)
|
|
153
|
+
|
|
154
|
+
# File menu
|
|
155
|
+
file_menu = self.menu_bar.addMenu("File")
|
|
156
|
+
exit_action = file_menu.addAction("Exit")
|
|
157
|
+
exit_action.triggered.connect(self.close)
|
|
158
|
+
|
|
159
|
+
layout = QVBoxLayout()
|
|
160
|
+
layout.setMenuBar(self.menu_bar)
|
|
161
|
+
|
|
162
|
+
self.path_label = QLabel("BeamNG Path (optional):")
|
|
163
|
+
self.path_input = QLineEdit()
|
|
164
|
+
self.path_input.setPlaceholderText("Leave empty for auto-detect")
|
|
165
|
+
self.path_input.textChanged.connect(self.update_ui)
|
|
166
|
+
|
|
167
|
+
self.browse_button = QPushButton("Browse")
|
|
168
|
+
self.browse_button.clicked.connect(self.browse_folder)
|
|
169
|
+
|
|
170
|
+
path_layout = QHBoxLayout()
|
|
171
|
+
path_layout.addWidget(self.path_input)
|
|
172
|
+
path_layout.addWidget(self.browse_button)
|
|
173
|
+
|
|
174
|
+
self.badge = QLabel("")
|
|
175
|
+
self.badge.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
176
|
+
self.badge.setMinimumHeight(28)
|
|
177
|
+
|
|
178
|
+
self.primary_button = QPushButton()
|
|
179
|
+
self.primary_button.setMinimumHeight(42)
|
|
180
|
+
self.primary_button.clicked.connect(self.primary_clicked)
|
|
181
|
+
|
|
182
|
+
self.status_label = QLabel("")
|
|
183
|
+
self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
184
|
+
|
|
185
|
+
layout.addWidget(self.path_label)
|
|
186
|
+
layout.addLayout(path_layout)
|
|
187
|
+
layout.addWidget(self.badge)
|
|
188
|
+
layout.addWidget(self.primary_button)
|
|
189
|
+
layout.addWidget(self.status_label)
|
|
190
|
+
|
|
191
|
+
self.setLayout(layout)
|
|
192
|
+
self.update_ui()
|
|
193
|
+
|
|
194
|
+
def resolve_lua_path(self):
|
|
195
|
+
custom = self.path_input.text().strip() or None
|
|
196
|
+
game_dir = custom if custom else find_game_dir()
|
|
197
|
+
lua = get_lua_path(game_dir)
|
|
198
|
+
if not os.path.exists(lua):
|
|
199
|
+
raise FileNotFoundError
|
|
200
|
+
return lua
|
|
201
|
+
|
|
202
|
+
def update_ui(self):
|
|
203
|
+
try:
|
|
204
|
+
lua = self.resolve_lua_path()
|
|
205
|
+
|
|
206
|
+
if is_already_patched(lua):
|
|
207
|
+
self.primary_button.setText("Restore Original")
|
|
208
|
+
self.primary_button.setProperty("m", "r")
|
|
209
|
+
self.primary_button.setEnabled(True)
|
|
210
|
+
self.badge.setText("STATUS: PATCHED")
|
|
211
|
+
else:
|
|
212
|
+
self.primary_button.setText("Patch Game")
|
|
213
|
+
self.primary_button.setProperty("m", "p")
|
|
214
|
+
self.primary_button.setEnabled(True)
|
|
215
|
+
self.badge.setText("STATUS: CLEAN")
|
|
216
|
+
|
|
217
|
+
except Exception:
|
|
218
|
+
self.primary_button.setText("BeamNG Not Found")
|
|
219
|
+
self.primary_button.setEnabled(False)
|
|
220
|
+
self.badge.setText("STATUS: NOT FOUND")
|
|
221
|
+
|
|
222
|
+
def primary_clicked(self):
|
|
223
|
+
try:
|
|
224
|
+
custom = self.path_input.text().strip() or None
|
|
225
|
+
mode = self.primary_button.property("m")
|
|
226
|
+
msg = run_operation(restore=(mode == "r"), custom_path=custom)
|
|
227
|
+
self.status_label.setText(msg)
|
|
228
|
+
QMessageBox.information(self, "Result", msg)
|
|
229
|
+
self.update_ui()
|
|
230
|
+
except Exception as e:
|
|
231
|
+
QMessageBox.critical(self, "Error", str(e))
|
|
232
|
+
|
|
233
|
+
def browse_folder(self):
|
|
234
|
+
folder = QFileDialog.getExistingDirectory(self, "Select BeamNG.drive Folder")
|
|
235
|
+
if folder:
|
|
236
|
+
self.path_input.setText(folder)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def launch_gui():
|
|
240
|
+
app = QApplication(sys.argv)
|
|
241
|
+
app.setApplicationName("MP Bypasser")
|
|
242
|
+
app.setApplicationDisplayName("MP Bypasser")
|
|
243
|
+
|
|
244
|
+
apply_theme(app)
|
|
245
|
+
|
|
246
|
+
window = ModLockWindow()
|
|
247
|
+
window.show()
|
|
248
|
+
|
|
249
|
+
sys.exit(app.exec())
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def main():
|
|
253
|
+
parser = argparse.ArgumentParser(description="MP Bypasser")
|
|
254
|
+
parser.add_argument('--nogui', action='store_true')
|
|
255
|
+
parser.add_argument('--restore', action='store_true')
|
|
256
|
+
parser.add_argument('--game-path', type=str)
|
|
257
|
+
args = parser.parse_args()
|
|
258
|
+
|
|
259
|
+
if not args.nogui:
|
|
260
|
+
launch_gui()
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
try:
|
|
264
|
+
result = run_operation(
|
|
265
|
+
restore=args.restore,
|
|
266
|
+
custom_path=args.game_path
|
|
267
|
+
)
|
|
268
|
+
print(result)
|
|
269
|
+
except Exception as e:
|
|
270
|
+
print(f"Error: {e}")
|
|
271
|
+
sys.exit(1)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
main()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bmpbypass
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: BeamMP Mod Manager Bypass Tool
|
|
5
|
+
Author: zokraz
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/zokrazium/bmpbypass#readme
|
|
8
|
+
Project-URL: Source, https://github.com/zokrazium/bmpbypass
|
|
9
|
+
Project-URL: Documentation, https://github.com/zokrazium/bmpbypass#readme
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Environment :: X11 Applications :: Qt
|
|
16
|
+
Classifier: Topic :: Games/Entertainment
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: PyQt6>=6.5
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# bmpbypass
|
|
24
|
+
|
|
25
|
+
Patch **BeamNG.drive** so BeamMP stops force-managing your client-side mods.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install bmpbypass
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Use (GUI)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bmpbypass
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
* Click **Patch Game**
|
|
44
|
+
* Launch the game
|
|
45
|
+
* Play
|
|
46
|
+
|
|
47
|
+
If it says **Restore Original**, it’s already patched.
|
|
48
|
+
|
|
49
|
+
> [!IMPORTANT]
|
|
50
|
+
> Close the game before patching or restoring.
|
|
51
|
+
|
|
52
|
+
> [!TIP]
|
|
53
|
+
> If something breaks, click **Restore Original**.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Use (Terminal)
|
|
58
|
+
|
|
59
|
+
Patch:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bmpbypass --nogui
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Restore:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bmpbypass --nogui --restore
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Manual Game Path (if needed)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bmpbypass --nogui --game-path "/path/to/BeamNG.drive"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> [!NOTE]
|
|
80
|
+
> Path must be the main `BeamNG.drive` folder.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## What It Does
|
|
85
|
+
|
|
86
|
+
* Finds the game (Steam)
|
|
87
|
+
* Backs up `modmanager.lua`
|
|
88
|
+
* Adds a small patch
|
|
89
|
+
|
|
90
|
+
> [!CAUTION]
|
|
91
|
+
> Game updates may undo the patch. Just run it again.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/bmpbypass/__init__.py
|
|
5
|
+
src/bmpbypass/__main__.py
|
|
6
|
+
src/bmpbypass.egg-info/PKG-INFO
|
|
7
|
+
src/bmpbypass.egg-info/SOURCES.txt
|
|
8
|
+
src/bmpbypass.egg-info/dependency_links.txt
|
|
9
|
+
src/bmpbypass.egg-info/entry_points.txt
|
|
10
|
+
src/bmpbypass.egg-info/requires.txt
|
|
11
|
+
src/bmpbypass.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyQt6>=6.5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bmpbypass
|