From 2dce709db1604552d85b4b0d50fe5344013d59e1 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 3 Oct 2024 14:02:14 +0200 Subject: [PATCH] Some fixes --- Moose Development/Moose/Functional/Sead.lua | 31 ++++++----- Moose Development/Moose/Ops/Awacs.lua | 22 +++++++- Moose Development/Moose/Sound/SRS.lua | 62 +++++++++++++-------- 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/Moose Development/Moose/Functional/Sead.lua b/Moose Development/Moose/Functional/Sead.lua index 314c9422f..ac89dddb4 100644 --- a/Moose Development/Moose/Functional/Sead.lua +++ b/Moose Development/Moose/Functional/Sead.lua @@ -155,7 +155,7 @@ function SEAD:New( SEADGroupPrefixes, Padding ) self:AddTransition("*", "ManageEvasion", "*") self:AddTransition("*", "CalculateHitZone", "*") - self:I("*** SEAD - Started Version 0.4.7") + self:I("*** SEAD - Started Version 0.4.8") return self end @@ -463,21 +463,24 @@ end -- @return #SEAD self function SEAD:HandleEventShot( EventData ) self:T( { EventData.id } ) - local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT - local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP - local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE - local SEADUnit = EventData.IniDCSUnit - local SEADUnitName = EventData.IniDCSUnitName - local SEADWeapon = EventData.Weapon -- Identify the weapon fired - local SEADWeaponName = EventData.WeaponName -- return weapon type - - local WeaponWrapper = WEAPON:New(EventData.Weapon) -- Wrapper.Weapon#WEAPON - --local SEADWeaponSpeed = WeaponWrapper:GetSpeed() -- mps - self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName) - --self:T({ SEADWeapon }) - + local SEADWeapon = EventData.Weapon -- Identify the weapon fired + local SEADWeaponName = EventData.WeaponName or "None" -- return weapon type + if self:_CheckHarms(SEADWeaponName) then + local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT + + if not SEADPlane then return self end -- case IniUnit is empty + + local SEADGroup = EventData.IniGroup -- Wrapper.Group#GROUP + local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE + local SEADUnit = EventData.IniDCSUnit + local SEADUnitName = EventData.IniDCSUnitName + + local WeaponWrapper = WEAPON:New(EventData.Weapon) -- Wrapper.Weapon#WEAPON + + self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName) + self:T( '*** SEAD - Weapon Match' ) if self.WeaponTrack == true then WeaponWrapper:SetFuncTrack(function(weapon) env.info(string.format("*** Weapon Speed: %d m/s",weapon:GetSpeed() or -1)) end) diff --git a/Moose Development/Moose/Ops/Awacs.lua b/Moose Development/Moose/Ops/Awacs.lua index 3b048ada3..e04a1060d 100644 --- a/Moose Development/Moose/Ops/Awacs.lua +++ b/Moose Development/Moose/Ops/Awacs.lua @@ -122,6 +122,7 @@ do -- @field #number TacticalModulation -- @field #number TacticalInterval -- @field Core.Set#SET_GROUP DetectionSet +-- @field #number MaxMissionRange -- @extends Core.Fsm#FSM @@ -508,7 +509,7 @@ do -- @field #AWACS AWACS = { ClassName = "AWACS", -- #string - version = "0.2.65", -- #string + version = "0.2.66", -- #string lid = "", -- #string coalition = coalition.side.BLUE, -- #number coalitiontxt = "blue", -- #string @@ -605,6 +606,7 @@ AWACS = { TacticalModulation = radio.modulation.AM, TacticalInterval = 120, DetectionSet = nil, + MaxMissionRange = 125, } --- @@ -1572,6 +1574,15 @@ function AWACS:SetLocale(Locale) return self end +--- [User] Set the max mission range flights can be away from their home base. +-- @param #AWACS self +-- @param #number NM Distance in nautical miles +-- @return #AWACS self +function AWACS:SetMaxMissionRange(NM) + self.MaxMissionRange = NM or 125 + return self +end + --- [User] Add additional frequency and modulation for AWACS SRS output. -- @param #AWACS self -- @param #number Frequency The frequency to add, e.g. 132.5 @@ -2228,6 +2239,7 @@ function AWACS:_StartEscorts(Shiftchange) local escort = AUFTRAG:NewESCORT(group, {x= -100*((i + (i%2))/2), y=0, z=(100 + 100*((i + (i%2))/2))*(-1)^i},45,{"Air"}) escort:SetRequiredAssets(1) escort:SetTime(nil,timeonstation) + escort:SetMissionRange(self.MaxMissionRange) self.AirWing:AddMission(escort) self.CatchAllMissions[#self.CatchAllMissions+1] = escort @@ -5739,7 +5751,7 @@ function AWACS:_AssignPilotToTarget(Pilots,Targets) local intercept = AUFTRAG:NewINTERCEPT(Target.Target) intercept:SetWeaponExpend(AI.Task.WeaponExpend.ALL) intercept:SetWeaponType(ENUMS.WeaponFlag.Auto) - + intercept:SetMissionRange(self.MaxMissionRange) -- TODO -- now this is going to be interesting... -- Check if the target left the "hot" area or is dead already @@ -5787,6 +5799,7 @@ function AWACS:_AssignPilotToTarget(Pilots,Targets) AnchorSpeed = UTILS.KnotsToAltKIAS(AnchorSpeed,Angels) local Anchor = self.AnchorStacks:ReadByPointer(Pilot.AnchorStackNo) -- #AWACS.AnchorData local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels,AnchorSpeed,Anchor.StationZoneCoordinate,0,15,{}) + capauftrag:SetMissionRange(self.MaxMissionRange) capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60))) Pilot.FlightGroup:AddMission(capauftrag) @@ -5904,6 +5917,7 @@ function AWACS:onafterStart(From, Event, To) -- set up the AWACS and let it orbit local AwacsAW = self.AirWing -- Ops.Airwing#AIRWING local mission = AUFTRAG:NewORBIT_RACETRACK(self.OrbitZone:GetCoordinate(),self.AwacsAngels*1000,self.Speed,self.Heading,self.Leg) + mission:SetMissionRange(self.MaxMissionRange) local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600 mission:SetTime(nil,timeonstation) self.CatchAllMissions[#self.CatchAllMissions+1] = mission @@ -6477,6 +6491,7 @@ function AWACS:onafterAssignedAnchor(From, Event, To, GID, Anchor, AnchorStackNo if auftragtype == AUFTRAG.Type.ALERT5 then -- all correct local capauftrag = AUFTRAG:NewCAP(Anchor.StationZone,Angels*1000,AnchorSpeed,Anchor.StationZone:GetCoordinate(),0,15,{}) + capauftrag:SetMissionRange(self.MaxMissionRange) capauftrag:SetTime(nil,((self.CAPTimeOnStation*3600)+(15*60))) capauftrag:AddAsset(managedgroup.FlightGroup) self.CatchAllMissions[#self.CatchAllMissions+1] = capauftrag @@ -6840,7 +6855,8 @@ function AWACS:onafterAwacsShiftChange(From,Event,To) self.CatchAllMissions[#self.CatchAllMissions+1] = mission local timeonstation = (self.AwacsTimeOnStation + self.ShiftChangeTime) * 3600 mission:SetTime(nil,timeonstation) - + mission:SetMissionRange(self.MaxMissionRange) + AwacsAW:AddMission(mission) self.AwacsMissionReplacement = mission diff --git a/Moose Development/Moose/Sound/SRS.lua b/Moose Development/Moose/Sound/SRS.lua index 3f621d594..461c80aae 100644 --- a/Moose Development/Moose/Sound/SRS.lua +++ b/Moose Development/Moose/Sound/SRS.lua @@ -52,6 +52,7 @@ -- @field #table poptions Provider options. Each element is a data structure of type `MSRS.ProvierOptions`. -- @field #string provider Provider of TTS (win, gcloud, azure, amazon). -- @field #string backend Backend used as interface to SRS (MSRS.Backend.SRSEXE or MSRS.Backend.GRPC). +-- @field #boolean UsePowerShell Use PowerShell to execute the command and not cmd.exe -- @extends Core.Base#BASE --- *It is a very sad thing that nowadays there is so little useless information.* - Oscar Wilde @@ -256,11 +257,12 @@ MSRS = { ConfigFilePath = "Config\\", ConfigLoaded = false, poptions = {}, + UsePowerShell = false, } --- MSRS class version. -- @field #string version -MSRS.version="0.3.0" +MSRS.version="0.3.2" --- Voices -- @type MSRS.Voices @@ -588,7 +590,7 @@ function MSRS:SetBackendSRSEXE() end --- Set the default backend. --- @param #MSRS self +-- @param #string Backend function MSRS.SetDefaultBackend(Backend) MSRS.backend=Backend or MSRS.Backend.SRSEXE end @@ -1375,20 +1377,25 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp modus=modus:gsub("1", "FM") -- Command. + local pwsh = string.format('Start-Process -WindowStyle Hidden -WorkingDirectory \"%s\" -FilePath \"%s\" -ArgumentList \'-f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"', path, exe, freqs, modus, coal, port, label,volume ) + local command=string.format('"%s\\%s" -f "%s" -m "%s" -c %s -p %s -n "%s" -v "%.1f"', path, exe, freqs, modus, coal, port, label,volume) -- Set voice or gender/culture. - if voice then + if voice and self.UsePowerShell ~= true then -- Use a specific voice (no need for gender and/or culture. command=command..string.format(" --voice=\"%s\"", tostring(voice)) + pwsh=pwsh..string.format(" --voice=\"%s\"", tostring(voice)) else -- Add gender. if gender and gender~="female" then command=command..string.format(" -g %s", tostring(gender)) + pwsh=pwsh..string.format(" -g %s", tostring(gender)) end -- Add culture. if culture and culture~="en-GB" then command=command..string.format(" -l %s", tostring(culture)) + pwsh=pwsh..string.format(" -l %s", tostring(culture)) end end @@ -1396,12 +1403,14 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp if coordinate then local lat,lon,alt=self:_GetLatLongAlt(coordinate) command=command..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt) + pwsh=pwsh..string.format(" -L %.4f -O %.4f -A %d", lat, lon, alt) end -- Set provider options if self.provider==MSRS.Provider.GOOGLE then local pops=self:GetProviderOptions() command=command..string.format(' --ssml -G "%s"', pops.credentials) + pwsh=pwsh..string.format(' --ssml -G "%s"', pops.credentials) elseif self.provider==MSRS.Provider.WINDOWS then -- Nothing to do. else @@ -1415,8 +1424,12 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp -- Debug output. self:T("MSRS command from _GetCommand="..command) - - return command + + if self.UsePowerShell == true then + return pwsh + else + return command + end end --- Execute SRS command to play sound using the `DCS-SR-ExternalAudio.exe`. @@ -1424,7 +1437,7 @@ end -- @param #string command Command to executer -- @return #number Return value of os.execute() command. function MSRS:_ExecCommand(command) - self:F( {command=command} ) + self:T2( {command=command} ) -- Skip this function if _GetCommand was not able to find the executable if string.find(command, "CommandNotFound") then return 0 end @@ -1432,7 +1445,13 @@ function MSRS:_ExecCommand(command) local batContent = command.." && exit" -- Create a tmp file. local filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".bat" - + + if self.UsePowerShell == true then + filename=os.getenv('TMP').."\\MSRS-"..MSRS.uuid()..".ps1" + batContent = command .. "\'" + self:I({batContent=batContent}) + end + local script=io.open(filename, "w+") script:write(batContent) script:close() @@ -1441,7 +1460,7 @@ function MSRS:_ExecCommand(command) self:T("MSRS batch content: "..batContent) local res=nil - if true then + if self.UsePowerShell ~= true then -- Create a tmp file. local filenvbs = os.getenv('TMP') .. "\\MSRS-"..MSRS.uuid()..".vbs" @@ -1469,23 +1488,20 @@ function MSRS:_ExecCommand(command) timer.scheduleFunction(os.remove, filenvbs, timer.getTime()+1) self:T("MSRS vbs and batch file removed") - elseif false then - - -- Create a tmp file. - local filenvbs = os.getenv('TMP') .. "\\MSRS-"..MSRS.uuid()..".vbs" - - -- VBS script - local script = io.open(filenvbs, "w+") - script:write(string.format('Set oShell = CreateObject ("Wscript.Shell")\n')) - script:write(string.format('Dim strArgs\n')) - script:write(string.format('strArgs = "cmd /c %s"\n', filename)) - script:write(string.format('oShell.Run strArgs, 0, false')) - script:close() - - local runvbs=string.format('cscript.exe //Nologo //B "%s"', filenvbs) + elseif self.UsePowerShell == true then + local pwsh = string.format('powershell.exe -ExecutionPolicy Unrestricted -WindowStyle Hidden -Command "%s"',filename) + --env.info("[MSRS] TextToSpeech Command :\n" .. pwsh.."\n") + + if string.len(pwsh) > 255 then + self:E("[MSRS] - pwsh string too long") + end + -- Play file in 0.01 seconds - res=os.execute(runvbs) + res=os.execute(pwsh) + + -- Remove file in 1 second. + timer.scheduleFunction(os.remove, filename, timer.getTime()+1) else -- Play command.