Skip to content

Commit 8e9f5a4

Browse files
committed
Merge branch 'development'
2 parents 5fb434c + b66b4af commit 8e9f5a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1739
-275
lines changed

core/data/impl/nodeimpl.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -506,19 +506,27 @@ async def upgrade_pending(self) -> bool:
506506
self.log.debug('- No update found for DCSServerBot.')
507507
return rc
508508

509-
async def upgrade(self):
509+
async def _upgrade(self, conn: psycopg.AsyncConnection):
510510
# We do not want to run an upgrade, if we are on a cloud drive, so just restart in this case
511511
if not self.master and self.locals.get('cloud_drive', True):
512512
await self.restart()
513-
return
514513
elif await self.upgrade_pending():
515514
if self.master:
516-
async with self.cpool.connection() as conn:
517-
async with conn.transaction():
518-
await conn.execute("""
519-
UPDATE cluster SET update_pending = TRUE WHERE guild_id = %s
520-
""", (self.guild_id, ))
515+
await conn.execute("""
516+
UPDATE cluster SET update_pending = TRUE WHERE guild_id = %s
517+
""", (self.guild_id, ))
521518
await self.shutdown(UPDATE)
519+
elif self.master:
520+
await conn.execute("""
521+
UPDATE cluster
522+
SET update_pending = FALSE, version = %s
523+
WHERE guild_id = %s
524+
""", (__version__, self.guild_id))
525+
526+
async def upgrade(self):
527+
async with self.cpool.connection() as conn:
528+
async with conn.transaction():
529+
await self._upgrade(conn)
522530

523531
async def get_dcs_branch_and_version(self) -> tuple[str, str]:
524532
if not self.dcs_branch or not self.dcs_version:
@@ -858,8 +866,18 @@ async def check_nodes():
858866
if update_pending:
859867
return await handle_upgrade(master)
860868
elif parse(version) > parse(__version__):
861-
await self.upgrade()
862-
return False
869+
# avoid update loops if we are the master
870+
if master == self.name:
871+
self.master = True
872+
self.log.warning("We are the master, but the cluster seems to have a newer version.\n"
873+
"Rolling back the cluser version to my version.")
874+
await self._upgrade(conn)
875+
elif parse(version) < parse(__version__):
876+
if master != self.name:
877+
raise FatalException(f"This node uses DCSServerBot version {__version__} "
878+
f"where the master uses version {version}!")
879+
self.master = True
880+
await self._upgrade(conn)
863881

864882
# I am the master
865883
if master == self.name:
@@ -885,6 +903,9 @@ async def check_nodes():
885903
current_stats = self.cpool.get_stats()
886904
self.log.warning(f"Pool stats: {repr(current_stats)}")
887905
raise
906+
except FatalException as ex:
907+
self.log.critical(ex)
908+
exit(SHUTDOWN)
888909
except Exception as ex:
889910
self.log.exception(ex)
890911
raise

core/data/impl/serverimpl.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from core.data.dataobject import DataObjectFactory
2424
from core.data.const import Status, Channel, Coalition
2525
from core.extension import Extension, InstallException, UninstallException
26-
from core.mizfile import MizFile, UnsupportedMizFileException
26+
from core.mizfile import MizFile
2727
from core.data.node import UploadStatus
2828
from core.utils.performance import performance_log
2929
from dataclasses import dataclass, field
@@ -159,8 +159,7 @@ def options(self) -> dict:
159159
def set_instance(self, instance: Instance):
160160
self._instance = instance
161161
self.locals |= self.instance.locals
162-
if self.name != 'n/a':
163-
self.prepare()
162+
self.prepare()
164163

165164
def start_observer(self):
166165
if not self.observer:
@@ -945,7 +944,7 @@ async def replaceMission(self, mission_id: int, path: str) -> list[str]:
945944

946945
async def loadMission(self, mission: Union[int, str], modify_mission: Optional[bool] = True,
947946
use_orig: Optional[bool] = True) -> bool:
948-
start_index = int(self.settings['listStartIndex'])
947+
start_index = int(self.settings.get('listStartIndex', 1))
949948
mission_list = self.settings['missionList']
950949
# check if we re-load the running mission
951950
if ((isinstance(mission, int) and mission == start_index) or

core/data/proxy/serverproxy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ async def rename(self, new_name: str, update_settings: bool = False) -> None:
222222
}, node=self.node.name, timeout=timeout)
223223
self.name = new_name
224224

225-
async def render_extensions(self) -> list:
225+
async def render_extensions(self) -> list[dict]:
226226
if not self._extensions:
227227
timeout = 60 if not self.node.slow_system else 120
228228
data = await self.bus.send_to_node_sync({

core/data/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ async def prepare_extensions(self):
424424
async def persist_settings(self):
425425
raise NotImplementedError()
426426

427-
async def render_extensions(self) -> list:
427+
async def render_extensions(self) -> list[dict]:
428428
raise NotImplementedError()
429429

430430
async def is_running(self) -> bool:

core/extension.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ def __init__(self, server: Server, config: dict):
4242
self.config: dict = config
4343
self.server: Server = server
4444
self.running = False
45+
self.locals: dict = {}
4546
if not self.enabled or not self.is_installed():
4647
return
47-
self.locals: dict = self.load_config()
48+
self.locals = self.load_config()
4849
if self.__class__.__name__ not in Extension.started_schedulers:
4950
schedule = getattr(self, 'schedule', None)
5051
if schedule:

core/utils/discord.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,13 +1594,16 @@ def __init__(self, server: Server, message: discord.Message, pattern: list[str])
15941594
self.server = server
15951595

15961596
@staticmethod
1597-
async def get_server(message: discord.Message) -> Optional[Server]:
1597+
async def get_server(message: discord.Message, channel_id: Optional[int] = None) -> Optional[Server]:
15981598
from services.bot import BotService
15991599
from services.servicebus import ServiceBus
16001600

16011601
bot = ServiceRegistry.get(BotService).bot
16021602
server = bot.get_server(message, admin_only=True)
1603-
if not server and message.channel.id == bot.locals.get('channels', {}).get('admin'):
1603+
if not channel_id:
1604+
channel_id = bot.locals.get('channels', {}).get('admin')
1605+
1606+
if not server and message.channel.id == channel_id:
16041607
bus = ServiceRegistry.get(ServiceBus)
16051608
ctx = await bot.get_context(message)
16061609
server = await utils.server_selection(bus, ctx, title=_("To which server do you want to upload?"))

extensions/lotatc/extension.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,21 +167,21 @@ def version(self) -> str:
167167
return utils.get_windows_version(os.path.join(self.home, r'bin', 'lotatc.dll'))
168168

169169
async def render(self, param: Optional[dict] = None) -> dict:
170-
if self.locals:
171-
host = self.config.get('host', self.node.public_ip)
172-
value = f"{host}:{self.locals.get('port', 10310)}"
173-
show_passwords = self.config.get('show_passwords', True)
174-
blue = self.locals.get('blue_password', '')
175-
red = self.locals.get('red_password', '')
176-
if show_passwords and (blue or red):
177-
value += f"\n🔹 Pass: {blue}\n🔸 Pass: {red}"
178-
return {
179-
"name": "LotAtc",
180-
"version": self.version,
181-
"value": value
182-
}
183-
else:
184-
return {}
170+
if not self.locals:
171+
raise NotImplementedError()
172+
173+
host = self.config.get('host', self.node.public_ip)
174+
value = f"{host}:{self.locals.get('port', 10310)}"
175+
show_passwords = self.config.get('show_passwords', True)
176+
blue = self.locals.get('blue_password', '')
177+
red = self.locals.get('red_password', '')
178+
if show_passwords and (blue or red):
179+
value += f"\n🔹 Pass: {blue}\n🔸 Pass: {red}"
180+
return {
181+
"name": "LotAtc",
182+
"version": self.version,
183+
"value": value
184+
}
185185

186186
def is_installed(self) -> bool:
187187
if not super().is_installed():
@@ -267,6 +267,7 @@ async def install(self):
267267
major_version, _ = self.get_inst_version()
268268
from_path = os.path.join(self.get_inst_path(), 'server', major_version)
269269
shutil.copytree(from_path, self.server.instance.home, dirs_exist_ok=True)
270+
self.locals = self.load_config()
270271
self.log.info(f" => {self.name} {self.version} installed into instance {self.server.instance.name}.")
271272

272273
async def uninstall(self):

extensions/modmanager/extension.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ def shutdown(self) -> bool:
2828

2929
async def render(self, param: Optional[dict] = None) -> dict:
3030
mods = self.modules.get(self.server.name)
31-
if mods:
32-
return {
33-
"name": "Required Mods",
34-
"value": '\n'.join([f"- {mod}" for mod in mods])
35-
}
36-
else:
31+
if not mods:
3732
raise NotImplementedError()
33+
34+
return {
35+
"name": "Required Mods",
36+
"value": '\n'.join([f"- {mod}" for mod in mods])
37+
}

extensions/olympus/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ DCS_MERCS:
1111
- name: DCSOlympus
1212
version: latest
1313
source: SavedGames
14+
# uncomment for auto-update:
15+
# repo: https://github.com/Pax1601/DCSOlympus
1416
```
1517
To use the DCS Olympus client, you need [Node.js](https://nodejs.org/download/release/latest-v20.x/) installed.
1618
Click on the link, download and install it. Remember the installation location, as you need to provide it in the

extensions/olympus/extension.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ async def prepare_olympus_json(self) -> bool:
207207
if extension:
208208
self.locals['audio'] = {
209209
"SRSPort": extension.config.get('port', extension.locals['Server Settings']['SERVER_PORT'])
210-
} | self.config.get('audio', {})
210+
} | self.config.get('audio', {
211+
"WSPort": 4000
212+
})
211213
with open(self.config_path, mode='w', encoding='utf-8') as cfg:
212214
json.dump(self.locals, cfg, indent=2)
213215
return True

0 commit comments

Comments
 (0)