Skip to content

Commit a684f41

Browse files
author
karel26
committed
BUGFIX:
- Tacview: configuration could end up with empty ports (reworked the whole config part)
1 parent 786412f commit a684f41

File tree

10 files changed

+69
-44
lines changed

10 files changed

+69
-44
lines changed

README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,25 @@ DCSServerBot supports some of them already and can add a bit of quality of life.
136136
## Installation
137137

138138
### Prerequisites
139-
You need to have [Python](https://www.python.org/downloads/) 3.9 or higher and [PostgreSQL](https://www.postgresql.org/download/) installed. Please make sure that you tick
140-
"Add python.exe to PATH" during your Python installation.<br>
139+
You need the following software to run DCSServerBot:
140+
141+
#### a) Python
142+
You need to have [Python](https://www.python.org/downloads/) 3.9 or higher and installed. Please make sure that you tick "Add python.exe to PATH"
143+
during your Python installation.<br>
141144
> [!NOTE]
142145
> Keep in mind, that Python 3.13 is still very new and can have bugs. I would recommend using the latest Python 3.12 for
143146
> now.
144147
148+
#### b) PostgreSQL
149+
DCSServerBot needs a database to store information in. I decided to use [PostgreSQL](https://www.postgresql.org/download/), as it has a great performance
150+
and stability and allows secure remote access, which is needed for [Multi-Node](./MULTINODE.md) installations.
151+
> [!NOTE]
152+
> If you install PostgreSQL on Linux, please make sure that you install the postgresXX-contrib package also.
153+
154+
> [!IMPORTANT]
155+
> If using PostgreSQL remotely over unsecured networks, it is recommended to have SSL enabled.
156+
157+
#### c) Git (optional)
145158
If you want to use instant autoupdate from the master branch, you have to install [Git for Windows](https://git-scm.com/download/win) and make sure
146159
the ```git```-command is in your PATH.
147160

@@ -176,6 +189,7 @@ The bot needs a unique Token per installation. This one can be obtained at http:
176189
If you do not want to use Discord, or if you maybe are not allowed to do so due to limitations of your Country, etc.
177190
you can now install DCSServerBot without the need to use Discord. Just select the respective option during the
178191
installation, and you will install a variant that works without.
192+
179193
> [!NOTE]
180194
> Please keep in mind that DCSServerBot was originally made for Discord and that there are some functionalities that
181195
> can only work, if you use it, like static graphs, greenieboards, and others.<br>
@@ -189,15 +203,7 @@ it somewhere on your PC that is running the DCS server(s) and give it write perm
189203
> [!CAUTION]
190204
> Make sure that the bots installation directory can only be seen by yourself and is not exposed to anybody
191205
> outside via www etc. as it contains sensitive data. Do NEVER expose any of the DCSServerBot ports to the
192-
> outside world.
193-
194-
### Database
195-
DCSServerBot uses PostgreSQL to store all information that needs to be persistent. This consists of, but is not limited
196-
to: players, mission information, statistics. DCSServerBot needs a fast database to do this. Install the latest
197-
available PostgreSQL version from the above-mentioned website.<br>
198-
199-
> [!IMPORTANT]
200-
> If using PostgreSQL remotely over unsecured networks, it is recommended to have SSL enabled.
206+
> outside world also.
201207
202208
### DCSServerBot Installation (Discord)
203209
Run the provided `install.cmd` script or just `run.cmd`.<br>

core/data/impl/serverimpl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def _load_extension(self, name: str) -> Optional[Extension]:
478478
async def init_extensions(self) -> list[str]:
479479
async with self.lock:
480480
extensions = DEFAULT_EXTENSIONS | self.locals.get('extensions', {})
481-
for extension in extensions:
481+
for extension in extensions.keys():
482482
try:
483483
ext: Extension = self.extensions.get(extension)
484484
if not ext:

core/utils/discord.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,19 +1249,19 @@ async def get_command(bot: DCSServerBot, *, name: str,
12491249

12501250

12511251
class ConfigModal(Modal):
1252-
def __init__(self, title: str, config: dict, default: Optional[dict] = None, ephemeral: Optional[bool] = False):
1252+
def __init__(self, title: str, config: dict, old_values: Optional[dict] = None, ephemeral: Optional[bool] = False):
12531253
super().__init__(title=title)
12541254
self.ephemeral = ephemeral
12551255
self.value = None
12561256
self.config = config
1257-
if not default:
1258-
default = {}
1257+
if not old_values:
1258+
old_values = {}
12591259
for k, v in self.config.items():
12601260
self.add_item(TextInput(custom_id=k,
12611261
label=v.get('label'),
12621262
style=discord.TextStyle(v.get('style', 1)),
12631263
placeholder=v.get('placeholder'),
1264-
default=str(default.get(k)) if default.get(k) is not None else "",
1264+
default=str(old_values.get(k)) if old_values.get(k) is not None else v.get('default', ''),
12651265
required=v.get('required', False),
12661266
min_length=v.get('min_length'),
12671267
max_length=v.get('max_length')))
@@ -1270,6 +1270,8 @@ def __init__(self, title: str, config: dict, default: Optional[dict] = None, eph
12701270
def unmap(value: str, t: str = None) -> Any:
12711271
if not t or t == str:
12721272
return value
1273+
elif not value:
1274+
return None
12731275
elif t == int:
12741276
return int(value)
12751277
elif t == float:
@@ -1286,7 +1288,7 @@ async def on_submit(self, interaction: discord.Interaction) -> None:
12861288
# noinspection PyUnresolvedReferences
12871289
await interaction.response.defer(ephemeral=self.ephemeral)
12881290
self.value = {
1289-
v.custom_id: self.unmap(v.value, self.config[v.custom_id].get('type')) if v.value else v.default
1291+
v.custom_id: self.unmap(v.value, self.config[v.custom_id].get('type'))
12901292
for v in self.children
12911293
}
12921294
self.stop()

extensions/lotatc/extension.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class LotAtc(Extension, FileSystemEventHandler):
4141
"type": int,
4242
"label": _("LotAtc Port"),
4343
"placeholder": _("Unique port number for LotAtc"),
44-
"required": True
44+
"required": True,
45+
"default": 10310
4546
}
4647
}
4748

extensions/realweather/README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ If you want to use real-time weather in your missions, you can do that by using
33
Download the release zip and unzip it to a directory of your choice on your system running your DCS servers and the
44
DCSServerBot.
55

6+
> [!IMPORTANT]
7+
> DCSServerBot only supports DCS Real Weather Updater versions from 1.9.0 upwards.
8+
69
## Configuration
710
The configuration for RealWeather goes into your nodes.yaml. There are 2 versions available at the moment, v1.x.x and
811
v2.x.x. Both differ in their configuration, which is why I added 2 examples in here:
@@ -52,6 +55,8 @@ MyNode:
5255
visibility-minimum: 300
5356
visibility-maximum: 2000
5457
```
58+
> [!NOTE]
59+
> You can find a list of supported parameters in the config.json provided by DCS-real-weather.
5560
5661
### Version 2.x
5762
```yaml
@@ -114,19 +119,20 @@ MyNode:
114119
enable: true
115120
system-time: true
116121
offset: '0h5m'
122+
date:
123+
enable: true
124+
system-date: true
125+
offset: "0"
117126
```
118-
You can find a list of supported parameters in the config.json (v1.x) or config.toml (v2.x) provided by DCS-real-weather.
119-
120-
121-
> [!IMPORTANT]
122-
> DCSServerBot only supports DCS Real Weather Updater versions from 1.9.0 upwards.
127+
> [!NOTE]
128+
> You can find a list of supported parameters in the config.toml provided by DCS-real-weather.
123129
124130
> [!TIP]
125131
> If you want to set a custom ICAO code (URMM in this case) per mission, you can name your mission like so:<br>
126132
> `MyFancyMission_ICAO_URMM_whatsoever.miz`
127133

128134
> [!NOTE]
129-
> You can use any parameter that Real Weather describes in their discord. I only write a toml from whatever
135+
> You can use any parameter that Real Weather describes in their discord. I only write a json/toml from whatever
130136
> you put in the extension configuration to pass that through to Real Weather. That said, it is ALWAYS a good
131137
> idea to look at what they added or changed, as I can not keep up with every 3rd party app I support with the
132138
> bot.

extensions/srs/extension.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,22 @@ class SRS(Extension, FileSystemEventHandler):
4444
"type": int,
4545
"label": _("SRS Port"),
4646
"placeholder": _("Unique port number for SRS"),
47-
"required": True
47+
"required": True,
48+
"default": 5002
4849
},
4950
"blue_password": {
5051
"type": str,
5152
"label": _("Blue Password"),
5253
"placeholder": _("Password for blue GCI, . for none"),
53-
"required": True
54+
"required": True,
55+
"default": "blue"
5456
},
5557
"red_password": {
5658
"type": str,
5759
"label": _("Red Password"),
5860
"placeholder": _("Password for red GCI, . for none"),
59-
"required": True
61+
"required": True,
62+
"default": "red"
6063
}
6164
}
6265

extensions/tacview/extension.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,33 @@ class Tacview(Extension):
3434
"type": int,
3535
"label": _("Tacview Port"),
3636
"placeholder": _("Unique port number for Tacview"),
37-
"required": True
37+
"required": True,
38+
"default": 42674
3839
},
3940
"tacviewRealTimeTelemetryPassword": {
4041
"type": str,
4142
"label": _("Tacview Password"),
4243
"placeholder": _("Password for Tacview, . for none"),
44+
"default": ""
4345
},
4446
"tacviewRemoteControlPort": {
4547
"type": int,
4648
"label": _("Remote Control Port"),
47-
"placeholder": _("Unique port number for remote control")
49+
"placeholder": _("Unique port number for remote control"),
50+
"default": 42675
4851
},
4952
"tacviewRemoteControlPassword": {
5053
"type": str,
5154
"label": _("Remote Control Password"),
5255
"placeholder": _("Password for remote control, . for none"),
56+
"default": ""
5357
},
5458
"tacviewPlaybackDelay": {
5559
"type": int,
5660
"label": _("Playback Delay"),
5761
"placeholder": _("Playback delay time"),
58-
"required": True
62+
"required": True,
63+
"default": 0
5964
}
6065
}
6166

plugins/lotatc/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ async def _configure(self, interaction: discord.Interaction,
111111
config = server.instance.locals.get('extensions', {}).get('LotAtc', {})
112112
modal = utils.ConfigModal(title=_("LotAtc Configuration"),
113113
config=LotAtcExt.CONFIG_DICT,
114-
default=config)
114+
old_values=config)
115115
# noinspection PyUnresolvedReferences
116116
await interaction.response.send_modal(modal)
117117
if await modal.wait():

plugins/srs/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ async def _configure(self, interaction: discord.Interaction,
8686
config = server.instance.locals.get('extensions', {}).get('SRS', {})
8787
modal = utils.ConfigModal(title=_("SRS Configuration"),
8888
config=SRSExt.CONFIG_DICT,
89-
default=config)
89+
old_values=config)
9090
# noinspection PyUnresolvedReferences
9191
await interaction.response.send_modal(modal)
9292
if await modal.wait():

plugins/tacview/commands.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,10 @@ async def _configure(self, interaction: discord.Interaction, *,
1818
server: Server,
1919
enabled: bool = None,
2020
autoupdate: bool = None) -> Optional[dict]:
21-
config = server.instance.locals.get('extensions', {}).get('Tacview', {
22-
"tacviewRealTimeTelemetryPort": "42674",
23-
"tacviewRealTimeTelemetryPassword": "",
24-
"tacviewRemoteControlEnabled": "42675",
25-
"tacviewRemoteControlPassword": "",
26-
"tacviewPlaybackDelay": "0"
27-
})
21+
config = server.instance.locals.get('extensions', {}).get('Tacview', {})
2822
modal = utils.ConfigModal(title=_("Tacview Configuration"),
2923
config=TacviewExt.CONFIG_DICT,
30-
default=config)
24+
old_values=config)
3125
# noinspection PyUnresolvedReferences
3226
await interaction.response.send_modal(modal)
3327
if await modal.wait():
@@ -38,16 +32,24 @@ async def _configure(self, interaction: discord.Interaction, *,
3832
tacviewRemoteControlPassword = modal.value.get('tacviewRemoteControlPassword')
3933
if tacviewRemoteControlPassword == '.':
4034
tacviewRemoteControlPassword = ""
41-
return {
35+
ret = {
4236
"enabled": enabled or config.get('enabled', True),
4337
"autoupdate": autoupdate or config.get('autoupdate', False),
4438
"tacviewRealTimeTelemetryPort": modal.value.get('tacviewRealTimeTelemetryPort'),
4539
"tacviewRealTimeTelemetryPassword": tacviewRealTimeTelemetryPassword,
46-
"tacviewRemoteControlEnabled": True if modal.value.get('tacviewRemoteControlPort') else False,
47-
"tacviewRemoteControlPort": modal.value.get('tacviewRemoteControlPort'),
48-
"tacviewRemoteControlPassword": tacviewRemoteControlPassword,
4940
"tacviewPlaybackDelay": int(modal.value.get('tacviewPlaybackDelay')),
5041
}
42+
if modal.value.get('tacviewRemoteControlPort'):
43+
ret |= {
44+
"tacviewRemoteControlEnabled": True,
45+
"tacviewRemoteControlPort": modal.value.get('tacviewRemoteControlPort'),
46+
"tacviewRemoteControlPassword": tacviewRemoteControlPassword
47+
}
48+
else:
49+
ret |= {
50+
"tacviewRemoteControlEnabled": False
51+
}
52+
return ret
5153

5254
@tacview.command(description=_('Configure Tacview'))
5355
@app_commands.guild_only()

0 commit comments

Comments
 (0)