Skip to content

Commit 42e4e53

Browse files
authored
Merge pull request #84 from agentsofthesystem/bug-fixes-several
Fix several bugs found in production
2 parents 85a172f + 43427f6 commit 42e4e53

9 files changed

+95
-20
lines changed

application/common/game_base.py

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ def __init__(self, defaults_dict: dict = {}) -> None:
2626
self._defaults = defaults_dict
2727
self._game_default_install_dir = None
2828

29+
# Whether or not users are alloed to add additional args.
30+
# Allowed by default. Game implementations will have to disable it.
31+
self._allow_user_args = True
32+
2933
if constants.SETTING_NAME_DEFAULT_PATH in self._defaults:
3034
self._game_default_install_dir = defaults_dict[
3135
constants.SETTING_NAME_DEFAULT_PATH

application/common/toolbox.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import inspect
33
import importlib.util
4+
import platform
45
import psutil
56
import sys
67

@@ -179,3 +180,11 @@ def update_game_state(game_data: dict, new_state: GameStates) -> True:
179180
update_success = False
180181

181182
return update_success
183+
184+
185+
@staticmethod
186+
def _correct_path(path_value):
187+
fixed_path = ""
188+
if platform.system() == "Windows":
189+
fixed_path = path_value.replace("/", "\\")
190+
return fixed_path

application/games/seven_dtd_game.py

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ def __init__(self, defaults_dict: dict = {}) -> None:
5353
)
5454
)
5555

56+
# The user may not add additional arguments for this game server.
57+
self._allow_user_args = False
58+
5659
def startup(self) -> None:
5760
# Run base class checks
5861
# Run base class checks

application/gui/widgets/add_argument_widget.py

+35-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from PyQt5.QtCore import Qt
1414

15+
from application.common import toolbox
1516
from application.common.constants import FileModes
1617
from application.common.decorators import timeit
1718
from application.gui.widgets.file_select_widget import FileSelectWidget
@@ -33,22 +34,24 @@ def __init__(self, client: Operator, parent: QWidget = None) -> None:
3334

3435
self._arg_name_edit: QLineEdit = None
3536
self._arg_value_edit: QWidget = None
36-
self._arg_required: QCheckBox = None
3737
self._arg_file_mode_edit: QComboBox = None
3838
self._arg_equals_edit: QCheckBox = None
3939
self._arg_quotes_edit: QCheckBox = None
4040

4141
self._submit_btn: QPushButton = QPushButton("Submit")
4242
self._reset_btn: QPushButton = QPushButton("Reset")
4343

44+
def closeEvent(self, event):
45+
if self._parent:
46+
self._parent.start_timer()
47+
4448
def init_ui(self, game_name: str):
4549
self._layout.setAlignment(Qt.AlignTop)
4650

4751
self._layout.addWidget(QLabel("Add Argument:"), 0, 0)
4852

4953
self._arg_name_edit = QLineEdit()
5054
self._arg_value_edit = QLineEdit()
51-
self._arg_required = QCheckBox()
5255
self._arg_file_mode_edit = QComboBox()
5356
self._arg_equals_edit = QCheckBox()
5457
self._arg_quotes_edit = QCheckBox()
@@ -64,9 +67,6 @@ def init_ui(self, game_name: str):
6467
self._layout.addWidget(QLabel("Argument Value: "), 2, 0)
6568
self._layout.addWidget(self._arg_value_edit, 2, 1)
6669

67-
self._layout.addWidget(QLabel("Required? "), 3, 0)
68-
self._layout.addWidget(self._arg_required, 3, 1)
69-
7070
self._layout.addWidget(QLabel("File Mode Select: "), 4, 0)
7171
self._layout.addWidget(self._arg_file_mode_edit, 4, 1)
7272

@@ -89,6 +89,19 @@ def init_ui(self, game_name: str):
8989

9090
self._initialized = True
9191

92+
self.clear()
93+
94+
def clear(self):
95+
self._arg_name_edit.setText("")
96+
97+
if isinstance(self._arg_value_edit, FileSelectWidget):
98+
self._arg_value_edit.get_line_edit().setText("")
99+
else:
100+
self._arg_value_edit.setText("")
101+
self._arg_file_mode_edit.setCurrentIndex(0)
102+
self._arg_equals_edit.setChecked(False)
103+
self._arg_quotes_edit.setChecked(False)
104+
92105
def update(self, game_name: str):
93106
self._game_name = game_name
94107

@@ -110,13 +123,16 @@ def _update_value_edit(self, file_mode_string: str) -> None:
110123
self.adjustSize()
111124

112125
def _submit_argument(self, game_name: str) -> None:
126+
# For error messages
127+
message = QMessageBox()
128+
113129
# Line edit
114130
arg_name = self._arg_name_edit.text()
115131

116132
# combo
117133
file_mode = self._arg_file_mode_edit.currentIndex()
118134

119-
arg_required = self._arg_required.isChecked()
135+
arg_required = False # User may never add a new required argument.
120136
arg_equals = self._arg_equals_edit.isChecked()
121137
arg_quotes = self._arg_quotes_edit.isChecked()
122138

@@ -126,6 +142,15 @@ def _submit_argument(self, game_name: str) -> None:
126142
file_mode == FileModes.FILE.value or file_mode == FileModes.DIRECTORY.value
127143
):
128144
arg_value = self._arg_value_edit.get_line_edit().text()
145+
arg_value = toolbox._correct_path(arg_value)
146+
147+
# Check if all args are empty.
148+
if arg_value == "" or arg_name == "":
149+
message.setText("Error: Cannot create an empty argument!")
150+
message.exec()
151+
self.clear()
152+
self._parent.start_timer()
153+
return
129154

130155
argument_id = self._client.game.create_argument(
131156
game_name,
@@ -138,11 +163,13 @@ def _submit_argument(self, game_name: str) -> None:
138163
use_quotes=arg_quotes,
139164
)
140165

141-
message = QMessageBox()
142166
if argument_id == -1:
143167
message.setText("New Arg: There was an error creating the argument.")
144168
else:
145-
message.setText("Success!")
169+
message.setText("Success! Please wait for user interface to update.")
146170
self.hide()
171+
self._parent._refresh_on_timer()
172+
self._parent.start_timer()
173+
self.clear()
147174

148175
message.exec()

application/gui/widgets/file_select_widget.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
)
88
from PyQt5.QtGui import QFont, QFontMetrics
99

10+
from application.common import toolbox
1011
from application.common.constants import FileModes
1112
from operator_client import Operator
1213

@@ -74,7 +75,7 @@ def handle_button(self) -> None:
7475
)
7576

7677
if path:
77-
self._path_line_edit.setText(path)
78+
self._path_line_edit.setText(toolbox._correct_path(path))
7879

7980
def _resize_to_content(self):
8081
text = self._path_line_edit.text()

application/gui/widgets/game_arguments_widget.py

+25-4
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,23 @@ class GameArgumentsWidget(QWidget):
2727
ARG_ACTION_COL = 3
2828

2929
def __init__(
30-
self, client: Operator, arg_data: dict, parent: QWidget, disable_cols: list = []
30+
self,
31+
client: Operator,
32+
arg_data: dict,
33+
parent: QWidget,
34+
disable_cols: list = [],
35+
built_in_args=None,
3136
) -> None:
3237
super(QWidget, self).__init__(parent)
3338

3439
self._parent = parent
3540
self._client = client
3641
self._layout = QVBoxLayout()
42+
# Args that the game has built in + args the user added.
3743
self._arg_data = arg_data
44+
# Args that the game has built in
45+
self._built_in_args = built_in_args
46+
# Args on this widget
3847
self._args_dict: dict = {}
3948
self._disable_cols = disable_cols
4049

@@ -131,9 +140,21 @@ def update_arguments_table(self, game_arguments=None):
131140
elif c == self.ARG_REQUIRED_COL:
132141
if "Required" in self._disable_cols:
133142
continue
134-
required_cb = QCheckBox()
135-
required_cb.setChecked(True if arg_required == 1 else False)
136-
self._table.setCellWidget(r, c, required_cb)
143+
# If provided built in args list... check if arg is in that list.
144+
if self._built_in_args:
145+
required_cb = QCheckBox()
146+
required_cb.setChecked(True if arg_required == 1 else False)
147+
self._table.setCellWidget(r, c, required_cb)
148+
149+
# disable the checkbox if the arg isn't in that place.
150+
if arg_name not in self._built_in_args:
151+
required_cb.setDisabled(True)
152+
153+
else:
154+
# otherwise... Just add a checkbox
155+
required_cb = QCheckBox()
156+
required_cb.setChecked(True if arg_required == 1 else False)
157+
self._table.setCellWidget(r, c, required_cb)
137158
elif c == self.ARG_ACTION_COL:
138159
if "Actions" in self._disable_cols:
139160
continue

application/gui/widgets/game_manager_widget.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323

2424

2525
class GameManagerWidget(QWidget):
26-
REFRESH_INTERVAL = 15 * constants.MILIS_PER_SECOND
26+
# The lower this number ,the faster it updates.
27+
REFRESH_INTERVAL = 6 * constants.MILIS_PER_SECOND
28+
# Update at this faster interval in certain situations.
2729
FAST_INTERVAL = 1 * constants.MILIS_PER_SECOND
2830

2931
def __init__(self, client: Operator, globals, parent: QWidget) -> None:
@@ -40,6 +42,8 @@ def __init__(self, client: Operator, globals, parent: QWidget) -> None:
4042
self._add_arguments_widget: AddArgumentWidget = globals._add_arguments_widget
4143
self._current_arg_widget: GameArgumentsWidget = None
4244

45+
self._add_arguments_widget._parent = self
46+
4347
# Primitives
4448
self._installed_supported_games: dict = {}
4549
self._modules_dict: dict = toolbox._find_conforming_modules(games)
@@ -136,7 +140,7 @@ def update_installed_games(
136140

137141
installed_supported_games = list(self._installed_supported_games.keys())
138142

139-
# Init routine uses this fucntion. Don't want to replace the widget the "first" time.
143+
# Init routine uses this function. Don't want to replace the widget the "first" time.
140144
if len(installed_supported_games) > 0:
141145
new_game_frame = self._build_game_frame(installed_supported_games[0])
142146

@@ -302,19 +306,24 @@ def _build_game_frame(self, game_name):
302306
game_frame_main_layout.addLayout(h_layout_all_game_info)
303307

304308
# Game Arguments
305-
306309
game_args_label = QLabel("Game Arguments:", game_frame)
307310
game_args_label.setStyleSheet("text-decoration: underline;")
311+
built_in_args = game_object._get_argument_list()
308312
game_args = self._client.game.get_argument_by_game_name(game_object._game_name)
309313
self._current_arg_widget = GameArgumentsWidget(
310-
self._client, game_args, game_frame
314+
self._client, game_args, game_frame, built_in_args=built_in_args
311315
)
312316

313317
game_frame_main_layout.addWidget(game_args_label)
314318
game_frame_main_layout.addWidget(self._current_arg_widget)
315319

316320
# Add argument button
317321
self._add_arg_btn = QPushButton("Add Argument")
322+
323+
# Disable this button if the game server doesn't allow user to add arguments.
324+
if not game_object._allow_user_args:
325+
self._add_arg_btn.setDisabled(True)
326+
318327
game_frame_main_layout.addWidget(self._add_arg_btn)
319328
self._add_arg_btn.clicked.connect(
320329
lambda: self._show_add_argument_widget(self._current_game_name)
@@ -398,6 +407,7 @@ def _show_add_argument_widget(self, game_name):
398407
self._add_arguments_widget.init_ui(game_name)
399408
else:
400409
self._add_arguments_widget.update(game_name)
410+
self.stop_timer()
401411
self._add_arguments_widget.show()
402412

403413
def _startup_game(self, game_name):

requirements.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
alembic
22
concurrent-log-handler
3-
debugpy
4-
flask
5-
Flask-SQLAlchemy
3+
flask==3.0.0
4+
Flask-SQLAlchemy==3.1.1
65
gunicorn
76
oauthlib
87
psutil

test-requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# TODO - Split requirements.txt file up.
22
black
33
coverage
4+
debugpy
45
flake8
56
pytest
67
pytest-mock

0 commit comments

Comments
 (0)