changed the system to make use of JSON files

This commit is contained in:
David Pierron
2020-10-18 18:23:31 +02:00
parent 373924a959
commit ed92e9afb9
25 changed files with 7305 additions and 417 deletions

View File

@@ -1,10 +1,2 @@
from .base_plugin import BasePlugin
from .veaf_plugin import VeafPlugin
from .jtacautolase_plugin import JtacAutolasePlugin
from .liberation_plugin import LiberationPlugin
INSTALLED_PLUGINS={
"VeafPlugin": VeafPlugin(),
"JtacAutolasePlugin": JtacAutolasePlugin(),
"LiberationPlugin": LiberationPlugin(),
}
from .luaplugin import LuaPlugin
from .manager import LuaPluginManager

View File

@@ -1,48 +0,0 @@
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
class BasePlugin():
nameInUI:str = "Base plugin"
nameInSettings:str = "plugin.base"
enabledDefaultValue:bool = False
def __init__(self):
self.uiWidget: QCheckBox = None
self.enabled = self.enabledDefaultValue
self.settings = None
def setupUI(self, settingsWindow, row:int):
self.settings = settingsWindow.game.settings
self.uiWidget = QCheckBox()
self.uiWidget.setChecked(self.isEnabled())
self.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
settingsWindow.pluginsGroupLayout.addWidget(QLabel(self.nameInUI), row, 0)
settingsWindow.pluginsGroupLayout.addWidget(self.uiWidget, row, 1, Qt.AlignRight)
def setSettings(self, settings):
self.settings = settings
if not self.nameInSettings in self.settings.plugins:
self.settings.plugins[self.nameInSettings] = self.enabledDefaultValue
def applySetting(self, settingsWindow):
self.settings.plugins[self.nameInSettings] = self.uiWidget.isChecked()
self.enabled = self.settings.plugins[self.nameInSettings]
def injectScripts(self, operation):
self.settings = operation.game.settings
return self.isEnabled()
def injectConfiguration(self, operation):
self.settings = operation.game.settings
return self.isEnabled()
def isEnabled(self) -> bool:
if not self.settings:
return False
self.setSettings(self.settings) # create the necessary settings keys if needed
return self.settings != None and self.settings.plugins[self.nameInSettings]

View File

@@ -1,95 +0,0 @@
from dcs.triggers import TriggerStart
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
from .base_plugin import BasePlugin
class JtacAutolasePlugin(BasePlugin):
nameInUI:str = "JTAC Autolase"
nameInSettings:str = "plugin.jtacAutolase"
enabledDefaultValue:bool = True
#Allow spawn option
nameInUI_useSmoke:str = "JTACs use smoke"
nameInSettings_useSmoke:str = "plugin.jtacAutolase.useSmoke"
enabledDefaultValue_useSmoke:bool = True
def setupUI(self, settingsWindow, row:int):
# call the base method to add the plugin selection checkbox
super().setupUI(settingsWindow, row)
if settingsWindow.pluginsOptionsPageLayout:
self.optionsGroup = QGroupBox(self.nameInUI)
optionsGroupLayout = QGridLayout();
optionsGroupLayout.setAlignment(Qt.AlignTop)
self.optionsGroup.setLayout(optionsGroupLayout)
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
# JTAC use smoke
if not self.nameInSettings_useSmoke in self.settings.plugins:
self.settings.plugins[self.nameInSettings_useSmoke] = True
self.uiWidget_useSmoke = QCheckBox()
self.uiWidget_useSmoke.setChecked(self.settings.plugins[self.nameInSettings_useSmoke])
self.uiWidget_useSmoke.toggled.connect(lambda: self.applySetting(settingsWindow))
optionsGroupLayout.addWidget(QLabel(self.nameInUI_useSmoke), 0, 0)
optionsGroupLayout.addWidget(self.uiWidget_useSmoke, 0, 1, Qt.AlignRight)
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def enableOptionsGroup(self):
pluginEnabled = self.uiWidget.isChecked()
self.optionsGroup.setEnabled(pluginEnabled)
def setSettings(self, settings):
# call the base method
super().setSettings(settings)
if not self.nameInSettings_useSmoke in self.settings.plugins:
self.settings.plugins[self.nameInSettings_useSmoke] = self.enabledDefaultValue_useSmoke
def applySetting(self, settingsWindow):
# call the base method to apply the plugin selection checkbox value
super().applySetting(settingsWindow)
# save the "use smoke" option
self.settings.plugins[self.nameInSettings_useSmoke] = self.uiWidget_useSmoke.isChecked()
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def injectScripts(self, operation):
if super().injectScripts(operation):
operation.injectPluginScript("jtacautolase", "JTACAutoLase.lua", "jtacautolase")
def injectConfiguration(self, operation):
if super().injectConfiguration(operation):
# add a configuration for JTACAutoLase and start lasing for all JTACs
smoke = "local smoke = false"
if self.isUseSmoke():
smoke = "local smoke = true"
lua = smoke + """
-- setting and starting JTACs
env.info("DCSLiberation|: setting and starting JTACs")
for _, jtac in pairs(dcsLiberation.JTACs) do
if dcsLiberation.JTACAutoLase then
dcsLiberation.JTACAutoLase(jtac.dcsUnit, jtac.code, smoke, 'vehicle')
end
end
"""
operation.injectLuaTrigger(lua, "Setting and starting JTACs")
def isUseSmoke(self) -> bool:
if not self.settings:
return False
self.setSettings(self.settings) # create the necessary settings keys if needed
return self.settings.plugins[self.nameInSettings_useSmoke]

View File

@@ -1,23 +0,0 @@
from .base_plugin import BasePlugin
class LiberationPlugin(BasePlugin):
nameInUI:str = "Liberation script"
nameInSettings:str = "plugin.liberation"
enabledDefaultValue:bool = True
def setupUI(self, settingsWindow, row:int):
# Don't setup any UI, this plugin is mandatory
pass
def injectScripts(self, operation):
if super().injectScripts(operation):
operation.injectPluginScript("base", "mist_4_3_74.lua", "mist")
operation.injectPluginScript("base", "json.lua", "json")
operation.injectPluginScript("base", "dcs_liberation.lua", "liberation")
def injectConfiguration(self, operation):
if super().injectConfiguration(operation):
pass
def isEnabled(self) -> bool:
return True # mandatory plugin

199
plugin/luaplugin.py Normal file
View File

@@ -0,0 +1,199 @@
from typing import List
from pathlib import Path
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
import json
class LuaPluginWorkOrder():
def __init__(self, parent, filename:str, mnemonic:str, disable:bool):
self.filename = filename
self.mnemonic = mnemonic
self.disable = disable
self.parent = parent
def work(self, mnemonic:str, operation):
if self.disable:
operation.bypassPluginScript(self.parent.mnemonic, self.mnemonic)
else:
operation.injectPluginScript(self.parent.mnemonic, self.filename, self.mnemonic)
class LuaPluginSpecificOption():
def __init__(self, parent, mnemonic:str, nameInUI:str, defaultValue:bool):
self.mnemonic = mnemonic
self.nameInUI = nameInUI
self.defaultValue = defaultValue
self.parent = parent
class LuaPlugin():
NAME_IN_SETTINGS_BASE:str = "plugins."
def __init__(self, jsonFilename:str):
self.mnemonic:str = None
self.skipUI:bool = False
self.nameInUI:str = None
self.nameInSettings:str = None
self.defaultValue:bool = False
self.specificOptions = []
self.scriptsWorkOrders: List[LuaPluginWorkOrder] = None
self.configurationWorkOrders: List[LuaPluginWorkOrder] = None
self.initFromJson(jsonFilename)
self.enabled = self.defaultValue
self.settings = None
def initFromJson(self, jsonFilename:str):
jsonFile:Path = Path(jsonFilename)
if jsonFile.exists():
jsonData = json.loads(jsonFile.read_text())
self.mnemonic = jsonData.get("mnemonic")
self.skipUI = jsonData.get("skipUI", False)
self.nameInUI = jsonData.get("nameInUI")
self.nameInSettings = LuaPlugin.NAME_IN_SETTINGS_BASE + self.mnemonic
self.defaultValue = jsonData.get("defaultValue", False)
self.specificOptions = []
for jsonSpecificOption in jsonData.get("specificOptions"):
mnemonic = jsonSpecificOption.get("mnemonic")
nameInUI = jsonSpecificOption.get("nameInUI", mnemonic)
defaultValue = jsonSpecificOption.get("defaultValue")
self.specificOptions.append(LuaPluginSpecificOption(self, mnemonic, nameInUI, defaultValue))
self.scriptsWorkOrders = []
for jsonWorkOrder in jsonData.get("scriptsWorkOrders"):
file = jsonWorkOrder.get("file")
mnemonic = jsonWorkOrder.get("mnemonic")
disable = jsonWorkOrder.get("disable", False)
self.scriptsWorkOrders.append(LuaPluginWorkOrder(self, file, mnemonic, disable))
self.configurationWorkOrders = []
for jsonWorkOrder in jsonData.get("configurationWorkOrders"):
file = jsonWorkOrder.get("file")
mnemonic = jsonWorkOrder.get("mnemonic")
disable = jsonWorkOrder.get("disable", False)
self.configurationWorkOrders.append(LuaPluginWorkOrder(self, file, mnemonic, disable))
def setupUI(self, settingsWindow, row:int):
# set the game settings
self.settings = settingsWindow.game.settings
if not self.skipUI:
# create the plugin choice checkbox interface
self.uiWidget: QCheckBox = QCheckBox()
self.uiWidget.setChecked(self.isEnabled())
self.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
settingsWindow.pluginsGroupLayout.addWidget(QLabel(self.nameInUI), row, 0)
settingsWindow.pluginsGroupLayout.addWidget(self.uiWidget, row, 1, Qt.AlignRight)
# if needed, create the plugin options special page
if settingsWindow.pluginsOptionsPageLayout and self.specificOptions != None:
self.optionsGroup: QGroupBox = QGroupBox(self.nameInUI)
optionsGroupLayout = QGridLayout();
optionsGroupLayout.setAlignment(Qt.AlignTop)
self.optionsGroup.setLayout(optionsGroupLayout)
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
# browse each option in the specific options list
row = 0
for specificOption in self.specificOptions:
nameInSettings = self.nameInSettings + specificOption.mnemonic
if not nameInSettings in self.settings.plugins:
self.settings.plugins[nameInSettings] = specificOption.defaultValue
specificOption.uiWidget = QCheckBox()
specificOption.uiWidget.setChecked(self.settings.plugins[nameInSettings])
#specificOption.uiWidget.setEnabled(False)
specificOption.uiWidget.toggled.connect(lambda: self.applySetting(settingsWindow))
optionsGroupLayout.addWidget(QLabel(specificOption.nameInUI), row, 0)
optionsGroupLayout.addWidget(specificOption.uiWidget, row, 1, Qt.AlignRight)
row += 1
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def enableOptionsGroup(self):
if self.optionsGroup:
self.optionsGroup.setEnabled(self.isEnabled())
def setSettings(self, settings):
self.settings = settings
# ensure the setting exist
if not self.nameInSettings in self.settings.plugins:
self.settings.plugins[self.nameInSettings] = self.defaultValue
# do the same for each option in the specific options list
for specificOption in self.specificOptions:
nameInSettings = self.nameInSettings + "." + specificOption.mnemonic
if not nameInSettings in self.settings.plugins:
self.settings.plugins[nameInSettings] = specificOption.defaultValue
def applySetting(self, settingsWindow):
# apply the main setting
self.settings.plugins[self.nameInSettings] = self.uiWidget.isChecked()
self.enabled = self.settings.plugins[self.nameInSettings]
# do the same for each option in the specific options list
for specificOption in self.specificOptions:
nameInSettings = self.nameInSettings + specificOption.mnemonic
self.settings.plugins[nameInSettings] = specificOption.uiWidget.isChecked()
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def injectScripts(self, operation):
# set the game settings
self.settings = operation.game.settings
# execute the work order
if self.scriptsWorkOrders != None:
for workOrder in self.scriptsWorkOrders:
workOrder.work(self.mnemonic, operation)
# serves for subclasses
return self.isEnabled()
def injectConfiguration(self, operation):
# set the game settings
self.settings = operation.game.settings
# inject the plugin options
if len(self.specificOptions) > 0:
defineAllOptions = ""
for specificOption in self.specificOptions:
nameInSettings = self.nameInSettings + specificOption.mnemonic
value = "true" if self.settings.plugins[nameInSettings] else "false"
defineAllOptions += f" dcsLiberation.plugins.{self.mnemonic}.{specificOption.mnemonic} = {value} \n"
lua = f"-- {self.mnemonic} plugin configuration.\n"
lua += "\n"
lua += "if dcsLiberation then\n"
lua += " if not dcsLiberation.plugins then \n"
lua += " dcsLiberation.plugins = {}\n"
lua += " end\n"
lua += f" dcsLiberation.plugins.{self.mnemonic} = {{}}\n"
lua += defineAllOptions
lua += "end"
operation.injectLuaTrigger(lua, f"{self.mnemonic} plugin configuration")
# execute the work order
if self.configurationWorkOrders != None:
for workOrder in self.configurationWorkOrders:
workOrder.work(self.mnemonic, operation)
# serves for subclasses
return self.isEnabled()
def isEnabled(self) -> bool:
if not self.settings:
return False
self.setSettings(self.settings) # create the necessary settings keys if needed
return self.settings != None and self.settings.plugins[self.nameInSettings]
def hasUI(self) -> bool:
return not self.skipUI

43
plugin/manager.py Normal file
View File

@@ -0,0 +1,43 @@
from .luaplugin import LuaPlugin
from typing import List
import glob
from pathlib import Path
import json
import logging
class LuaPluginManager():
PLUGINS_RESOURCE_PATH = Path("resources/plugins")
PLUGINS_LIST_FILENAME = "plugins.json"
PLUGINS_JSON_FILENAME = "plugin.json"
__plugins = None
def __init__(self):
if not LuaPluginManager.__plugins:
LuaPluginManager.__plugins= []
jsonFile:Path = Path(LuaPluginManager.PLUGINS_RESOURCE_PATH, LuaPluginManager.PLUGINS_LIST_FILENAME)
if jsonFile.exists():
logging.info(f"Reading plugins list from {jsonFile}")
jsonData = json.loads(jsonFile.read_text())
for plugin in jsonData:
jsonPluginFolder = Path(LuaPluginManager.PLUGINS_RESOURCE_PATH, plugin)
jsonPluginFile = Path(jsonPluginFolder, LuaPluginManager.PLUGINS_JSON_FILENAME)
if jsonPluginFile.exists():
logging.info(f"Reading plugin {plugin} from {jsonPluginFile}")
plugin = LuaPlugin(jsonPluginFile)
LuaPluginManager.__plugins.append(plugin)
else:
logging.error(f"Missing configuration file {jsonPluginFile} for plugin {plugin}")
else:
logging.error(f"Missing plugins list file {jsonFile}")
def getPlugins(self):
return LuaPluginManager.__plugins
def getPlugin(self, pluginName):
for plugin in LuaPluginManager.__plugins:
if plugin.mnemonic == pluginName:
return plugin
return None

View File

@@ -1,90 +0,0 @@
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
from .base_plugin import BasePlugin
class VeafPlugin(BasePlugin):
nameInUI:str = "VEAF framework"
nameInSettings:str = "plugin.veaf"
enabledDefaultValue:bool = False
#Allow spawn option
nameInUI_allowSpawn:str = "Allow units spawn via markers and CTLD (not implemented yet)"
nameInSettings_allowSpawn:str = "plugin.veaf.allowSpawn"
def setupUI(self, settingsWindow, row:int):
# call the base method to add the plugin selection checkbox
super().setupUI(settingsWindow, row)
if settingsWindow.pluginsOptionsPageLayout:
self.optionsGroup = QGroupBox(self.nameInUI)
optionsGroupLayout = QGridLayout();
optionsGroupLayout.setAlignment(Qt.AlignTop)
self.optionsGroup.setLayout(optionsGroupLayout)
settingsWindow.pluginsOptionsPageLayout.addWidget(self.optionsGroup)
# allow spawn of objects
if not self.nameInSettings_allowSpawn in self.settings.plugins:
self.settings.plugins[self.nameInSettings_allowSpawn] = True
self.uiWidget_allowSpawn = QCheckBox()
self.uiWidget_allowSpawn.setChecked(self.settings.plugins[self.nameInSettings_allowSpawn])
self.uiWidget_allowSpawn.setEnabled(False)
self.uiWidget_allowSpawn.toggled.connect(lambda: self.applySetting(settingsWindow))
optionsGroupLayout.addWidget(QLabel(self.nameInUI_allowSpawn), 0, 0)
optionsGroupLayout.addWidget(self.uiWidget_allowSpawn, 0, 1, Qt.AlignRight)
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def enableOptionsGroup(self):
pluginEnabled = self.uiWidget.isChecked()
self.optionsGroup.setEnabled(pluginEnabled)
def applySetting(self, settingsWindow):
# call the base method to apply the plugin selection checkbox value
super().applySetting(settingsWindow)
# save the "allow spawn" option
self.settings.plugins[self.nameInSettings_allowSpawn] = self.uiWidget_allowSpawn.isChecked()
# disable or enable the UI in the plugins special page
self.enableOptionsGroup()
def injectScripts(self, operation):
if super().injectScripts(operation):
# bypass JTACAutoLase
operation.bypassPluginScript("veaf", "jtacautolase")
# inject the required scripts
operation.injectPluginScript("veaf", "src\\scripts\\mist.lua", "mist")
operation.injectPluginScript("veaf", "src\\scripts\\Moose.lua", "moose")
operation.injectPluginScript("veaf", "src\\scripts\\CTLD.lua", "ctld")
#operation.injectPluginScript("veaf", "src\\scripts\\NIOD.lua", "niod")
operation.injectPluginScript("veaf", "src\\scripts\\WeatherMark.lua", "weathermark")
operation.injectPluginScript("veaf", "src\\scripts\\veaf.lua", "veaf")
operation.injectPluginScript("veaf", "src\\scripts\\dcsUnits.lua", "dcsunits")
operation.injectPluginScript("veaf", "src\\scripts\\veafAssets.lua", "veafassets")
operation.injectPluginScript("veaf", "src\\scripts\\veafCarrierOperations.lua", "veafcarrieroperations")
operation.injectPluginScript("veaf", "src\\scripts\\veafCasMission.lua", "veafcasmission")
operation.injectPluginScript("veaf", "src\\scripts\\veafCombatMission.lua", "veafcombatmission")
operation.injectPluginScript("veaf", "src\\scripts\\veafCombatZone.lua", "veafcombatzone")
operation.injectPluginScript("veaf", "src\\scripts\\veafGrass.lua", "veafgrass")
operation.injectPluginScript("veaf", "src\\scripts\\veafInterpreter.lua", "veafinterpreter")
operation.injectPluginScript("veaf", "src\\scripts\\veafMarkers.lua", "veafmarkers")
operation.injectPluginScript("veaf", "src\\scripts\\veafMove.lua", "veafmove")
operation.injectPluginScript("veaf", "src\\scripts\\veafNamedPoints.lua", "veafnamedpoints")
operation.injectPluginScript("veaf", "src\\scripts\\veafRadio.lua", "veafradio")
operation.injectPluginScript("veaf", "src\\scripts\\veafRemote.lua", "veafremote")
operation.injectPluginScript("veaf", "src\\scripts\\veafSecurity.lua", "veafsecurity")
operation.injectPluginScript("veaf", "src\\scripts\\veafShortcuts.lua", "veafshortcuts")
operation.injectPluginScript("veaf", "src\\scripts\\veafSpawn.lua", "veafspawn")
operation.injectPluginScript("veaf", "src\\scripts\\veafTransportMission.lua", "veaftransportmission")
operation.injectPluginScript("veaf", "src\\scripts\\veafUnits.lua", "veafunits")
def injectConfiguration(self, operation):
if super().injectConfiguration(operation):
operation.injectPluginScript("veaf", "src\\config\\missionConfig.lua", "veaf-config")