Skip to content

Commit 1761725

Browse files
author
karel26
committed
ENHANCEMENTS:
- You can specify that bot commands work with specific DCS versions only now. CHANGES: - Changed the way extensions are started to avoid race conditions like with SRS. - SRS: wait on extension startup until the SRS server is up and accepting commands.
1 parent 9026b72 commit 1761725

File tree

12 files changed

+67
-31
lines changed

12 files changed

+67
-31
lines changed

core/extension.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ async def beforeMissionLoad(self, filename: str) -> tuple[str, bool]:
5858
return filename, False
5959

6060
async def startup(self) -> bool:
61-
# avoid race conditions
62-
if await asyncio.to_thread(self.is_running):
63-
return True
6461
self.running = True
65-
self.log.info(f" => {self.name} launched for \"{self.server.name}\".")
66-
return True
62+
if self.is_running():
63+
self.log.info(f" => {self.name} launched for \"{self.server.name}\".")
64+
return True
65+
else:
66+
self.log.warning(f" => {self.name} NOT launched for \"{self.server.name}\".")
67+
return False
6768

6869
def shutdown(self) -> bool:
6970
# avoid race conditions

core/plugin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from discord.app_commands.commands import CommandCallback, GroupT, P, T
1919
from discord.ext import commands, tasks
2020
from discord.utils import MISSING, _shorten
21-
from packaging import version
21+
from packaging.version import parse
2222
from pathlib import Path
2323
from typing import Type, Optional, TYPE_CHECKING, Union, Any, Dict, Callable, List
2424

@@ -352,7 +352,7 @@ async def _init_db(self) -> bool:
352352
# old variant, to be migrated
353353
if installed.startswith('v'):
354354
installed = installed[1:]
355-
while version.parse(installed) < version.parse(self.plugin_version):
355+
while parse(installed) < parse(self.plugin_version):
356356
updates_file = f'./plugins/{self.plugin_name}/db/update_v{installed}.sql'
357357
if os.path.exists(updates_file):
358358
with open(updates_file, mode='r') as updates_sql:

core/utils/discord.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from discord.ui import Button, View, Select, Item, Modal, TextInput
1818
from enum import Enum, auto
1919
from fuzzywuzzy import fuzz
20+
from packaging.version import parse, Version
2021
from psycopg.rows import dict_row
2122
from typing import Optional, cast, Union, TYPE_CHECKING, Iterable, Any, Callable
2223

@@ -43,6 +44,7 @@
4344
"app_has_not_role",
4445
"app_has_roles",
4546
"app_has_not_roles",
47+
"app_has_dcs_version",
4648
"cmd_has_roles",
4749
"get_role_ids",
4850
"format_embed",
@@ -553,6 +555,16 @@ def predicate(interaction: Interaction) -> bool:
553555
return app_commands.check(predicate)
554556

555557

558+
def app_has_dcs_version(version: str):
559+
def predicate(interaction: Interaction) -> bool:
560+
if parse(interaction.client.node.dcs_version) < Version(version):
561+
raise app_commands.AppCommandError(
562+
_("You need at least DCS version {} to use this command!").format(version))
563+
return True
564+
565+
return app_commands.check(predicate)
566+
567+
556568
def format_embed(data: dict, **kwargs) -> discord.Embed:
557569
"""
558570
:param data: A dictionary containing the data for formatting the embed.

extensions/lardoon/extension.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def _get_tacview_dir(self) -> str:
6464
async def startup(self) -> bool:
6565
global process, servers, tacview_dirs, lock
6666

67-
await super().startup()
6867
if 'Tacview' not in self.server.options['plugins']:
6968
self.log.warning('Lardoon needs Tacview to be enabled in your server!')
7069
return False
@@ -100,7 +99,7 @@ def run_subprocess():
10099
if tacview_dir not in tacview_dirs:
101100
tacview_dirs[tacview_dir] = set()
102101
tacview_dirs[tacview_dir].add(self.server.name)
103-
return self.is_running()
102+
return await super().startup()
104103

105104
def terminate(self) -> bool:
106105
global process

extensions/lotatc/extension.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,13 @@ def is_installed(self) -> bool:
192192
return True
193193

194194
async def startup(self) -> bool:
195-
await super().startup()
196195
path = os.path.join(self.home, 'stats.json')
197196
if os.path.exists(path):
198197
self.process_stats_file(path)
199198
self.observer = Observer()
200199
self.observer.schedule(self, path=self.home)
201200
self.observer.start()
202-
return True
201+
return await super().startup()
203202

204203
def stop_observer(self):
205204
if self.observer:

extensions/olympus/extension.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,6 @@ async def prepare(self) -> bool:
215215
return False
216216

217217
async def startup(self) -> bool:
218-
await super().startup()
219218

220219
def log_output(proc: subprocess.Popen):
221220
for line in iter(proc.stdout.readline, b''):
@@ -255,9 +254,11 @@ def run_subprocess():
255254
# Give the Olympus server 10s to start
256255
for _ in range(0, 10):
257256
if self.is_running():
258-
return True
257+
break
259258
await asyncio.sleep(1)
260-
return False
259+
else:
260+
return False
261+
return await super().startup()
261262

262263
def is_running(self) -> bool:
263264
return self.process is not None and self.process.is_running()

extensions/ovgme/extension.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ def __init__(self, server: Server, config: dict):
1414
self.modules: dict[str, list[str]] = {}
1515

1616
async def startup(self) -> bool:
17-
await super().startup()
1817
filename = await self.server.get_current_mission_file()
1918
try:
2019
mission = await asyncio.to_thread(MizFile, filename)
2120
self.modules[self.server.name] = mission.requiredModules
2221
except UnsupportedMizFileException:
2322
self.log.warning(f"Can't read requiredModules from Mission {filename}, unsupported format.")
24-
return True
23+
return await super().startup()
2524

2625
def shutdown(self) -> bool:
2726
self.modules.pop(self.server.name, None)

extensions/sneaker/extension.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ def _run_subprocess(self, config: str):
9999
async def startup(self) -> bool:
100100
global process, servers, lock
101101

102-
await super().startup()
103102
if 'Tacview' not in self.server.options['plugins']:
104103
self.log.warning('Sneaker needs Tacview to be enabled in your server!')
105104
return False
@@ -117,7 +116,7 @@ async def startup(self) -> bool:
117116
process = psutil.Process(p.pid)
118117
atexit.register(self.terminate)
119118
servers.add(self.server.name)
120-
return True
119+
return await super().startup()
121120
except Exception as ex:
122121
self.log.error(f"Error during launch of {self.config['cmd']}: {str(ex)}")
123122
return False

extensions/srs/extension.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -213,21 +213,21 @@ async def prepare(self) -> bool:
213213
return await super().prepare()
214214

215215
async def startup(self) -> bool:
216-
await super().startup()
217216
if self.config.get('autostart', True):
218217
self.log.debug(f"Launching SRS server with: \"{self.get_exe_path()}\" -cfg=\"{self.config['config']}\"")
219-
if sys.platform == 'win32' and self.config.get('minimized', True):
220-
import win32process
221-
import win32con
222-
223-
info = subprocess.STARTUPINFO()
224-
info.dwFlags |= win32process.STARTF_USESHOWWINDOW
225-
info.wShowWindow = win32con.SW_SHOWMINNOACTIVE
226-
else:
227-
info = None
228-
out = subprocess.DEVNULL if not self.config.get('debug', False) else None
229218

230219
def run_subprocess():
220+
if sys.platform == 'win32' and self.config.get('minimized', True):
221+
import win32process
222+
import win32con
223+
224+
info = subprocess.STARTUPINFO()
225+
info.dwFlags |= win32process.STARTF_USESHOWWINDOW
226+
info.wShowWindow = win32con.SW_SHOWMINNOACTIVE
227+
else:
228+
info = None
229+
out = subprocess.DEVNULL if not self.config.get('debug', False) else None
230+
231231
return subprocess.Popen([
232232
self.get_exe_path(),
233233
f"-cfg={os.path.expandvars(self.config['config'])}"
@@ -241,7 +241,14 @@ def run_subprocess():
241241
except psutil.NoSuchProcess:
242242
self.log.error(f"Error during launch of {self.get_exe_path()}!")
243243
return False
244-
return await asyncio.to_thread(self.is_running)
244+
# Give SRS 10s to start
245+
for _ in range(0, 10):
246+
if self.is_running():
247+
break
248+
await asyncio.sleep(1)
249+
else:
250+
return False
251+
return await super().startup()
245252

246253
def shutdown(self) -> bool:
247254
if self.config.get('autostart', True) and not self.config.get('no_shutdown', False):
@@ -336,6 +343,8 @@ def is_running(self) -> bool:
336343
if not self.process:
337344
self.process = utils.find_process('SR-Server.exe', self.server.instance.name)
338345
running = self.process is not None and self.process.is_running()
346+
if not running:
347+
self.log.debug("SRS: is NOT running (process)")
339348
else:
340349
try:
341350
server_ip = self.locals['Server Settings'].get('SERVER_IP', '127.0.0.1')
@@ -347,6 +356,8 @@ def is_running(self) -> bool:
347356
f"It does not contain a valid IP-address!")
348357
server_ip = '127.0.0.1'
349358
running = utils.is_open(server_ip, self.locals['Server Settings'].get('SERVER_PORT', 5002))
359+
if not running:
360+
self.log.debug("SRS: is NOT running (port)")
350361
# start the observer, if we were started to a running SRS server
351362
if running and not self.observer:
352363
self.start_observer()

plugins/slotblocking/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ DEFAULT: # Default section - true for all your servers.
4444
threshold: 0.1 # 10% threshold until slots are blocked
4545
activation_threshold: 10 # do not balance, if the number of players is below this threshold
4646
message: You need to take a slot of the opposite coalition to keep the balance!
47+
messages:
48+
credits_taken: '{deposit} credits taken for using a reserved module.' # Possible variables: deposit, old_points, new_points
49+
payback: 'You have been given {deposit} credits back.' # Possible variables: deposit, old_points, new_points
4750
DCS.release_server:
4851
restricted: # in this example we restrict by credit points
4952
- group_name: Rookie # this tag has to be in the group name of the respective units (best is to prepend it)

0 commit comments

Comments
 (0)