FlightControl-Master / MOOSE

Mission Object Oriented Scripting Environment (MOOSE) for lua mission scripting design in DCS World
http://flightcontrol-master.github.io/MOOSE/
GNU General Public License v3.0
290 stars 95 forks source link

BUG - GROUP:IsActive() causing error and crashing my script #1102

Closed shadowze closed 4 years ago

shadowze commented 5 years ago

local SamSet2 = SET_GROUP:New():FilterPrefixes(t_sam_check.prefix):FilterActive():FilterOnce() I have a function that iterates over a set the set is of SAM units that are currently active This is think is related to the bug I raised last year, with sets and trying to work out which units are active

Error in timer function: [string "D:\games\Develop_Moose_m.lua"]:31244: attempt to index a nil value

function GROUP:IsActive() self:F2( self.GroupName )

local DCSGroup = self:GetDCSObject() -- DCS#Group

if DCSGroup then

local GroupIsActive = DCSGroup:getUnit(1):isActive() -- this is line 31244 that errors
return GroupIsActive 

end

return nil end

131stGutts commented 5 years ago

Do you have the miz file with static Moose inside and steps for reproducing your issue?

shadowze commented 5 years ago

Sorry dude, my mission is a shitty mess, I think the issue is related to FilterActive() sometimes returnig units that are not active causing the issue (this bug took 40 mins or more to hit)

I have spawn templates which are used to spawn in units, sometimes i think filteractive messes up and the set grabs a unit that is not real causing the check to fail

Delta-99 commented 5 years ago

How are you iterating over the SET because that could be the issue instead. Rather than IsActive() filter I use the following which works fine and never an issue when units are not alive / active anymore. So you can always use something similar as a workaround if IsActive() is actually bugged.

RU_SAMGroups = SET_GROUP:New()
  :FilterPrefixes("RU SA")
  :FilterPrefixes("RU Rapier")
  :FilterPrefixes("RU Hawk")
  :FilterStart()

alarmStates = {}

RUSamSchedulerAlarmState, RUSamSchedulerAlarmStateId = SCHEDULER:New(nil,
  function ()
    RU_SAMGroups:ForEachGroup(
      function(tempGroup)
        if (tempGroup ~=nil) and (tempGroup:IsAlive()) then
          -- DO SOMETHING
        end
      end
    )
  end, {}, D99_Option_AlarmInitialCheckSeconds, D99_Option_AlarmCheckDurationSeconds, D99_Option_AlarmCheckDurationFactor
)

Similar thing for Units can be used: ForEachUnit()

shadowze commented 5 years ago

using :ForEachGroup( same as you are using :FilterOnce() different from your example Reason I am using IsActive() , is because I want to filter out the template units that would be in the set otherwise

This error is similar to the one I raised last year with units( in SET_UNIT:IsIncludeObject function) , which I ended up patching mysef with MUnit:GetDesc() ~= nil then do stuff

tempGroup ~=nil can still return objects that if you do GetDesc(), will return nil

shadowze commented 5 years ago

tried your work arround Delta, it causes same error

Delta-99 commented 5 years ago

Must still be something within the IsActive then on the filtering only. I was using FilterOnce at one point and that seemed to be fine too. I am NOT using IsActive on filtering though. How about this, remove the IsActive on the filtering and then use something like in the ForEachGroup. Doubt it will help but MAYBE!!!

if (tempGroup ~=nil) and (tempGroup:IsActive() and (tempGroup:IsAlive()) then

shadowze commented 5 years ago

I have tried a small edit to moose file to see if that catches the problem I removed filterActive at the outset , made no difference I think it is releasted possibly to FilterOnce()

shadowze commented 5 years ago

stuck if DCSGroup:GetDesc() ~= nil then

before the line in MOOSE that crashes out, it is possible in DCS for a group to NOT be nil ...... but when you try and query it eg GetDesc() or some other request for info it return nil then

Delta-99 commented 5 years ago

I think that means we need to backtrack and figure out what DCSGroup actually contains. Maybe the call to get the DCS Object really returns something else in some odd cases or another object or something that is NOT nil like an empty table or something.

131stGutts commented 5 years ago

Could you try to add in your code a trace like:

env.info("Category of my Group = " .. tempGround:GetCategory())

You'll be fix on the kind of object you received. That was the problem on #1101 perhaps it's the same for you.

shadowze commented 5 years ago

30 mins is as long as this script would work before shitting itself, been running 8 hours with out falling over so the catch I put in works

baluballa commented 5 years ago

Cannot reproduce error: Use GetUnit() with capital G in DCSGroup:getUnit(1):isActive() might get you going.

Follwing code works:


RU_SAMGroups = SET_GROUP:New()
  :FilterPrefixes("RU SA")
  :FilterPrefixes("RU Rapier")
  :FilterPrefixes("RU Hawk")
  :FilterStart()

alarmStates = {}
RU_SAMGroups:ForEachGroup(function (MooseGroup) 
  local DCSGroup = MooseGroup --Wrapper.Group#GROUP
  local GroupIsActive = DCSGroup:GetUnit(1):IsActive() -- getUnit(1):isActive() -- this is line 31244 that errors
  BASE:T({GroupIsActive})
  return GroupIsActive
end)```
shadowze commented 5 years ago

So the lines listed in the initial bug report are from moose.lua not my code

So how do I go about getting the fix into moose ? can you do this ? see current code from moose.lua below

--- Returns if the group is activated. -- @param #GROUP self -- @return #boolean true if group is activated. -- @return #nil The group is not existing or alive.
function GROUP:IsActive() self:F2( self.GroupName )

local DCSGroup = self:GetDCSObject() -- DCS#Group

if DCSGroup then

local GroupIsActive = DCSGroup:getUnit(1):isActive()
return GroupIsActive 

end

return nil end

shadowze commented 5 years ago

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaand silence, but still someone has set this to not a bug .. when it is

baluballa commented 5 years ago

So did using the Garbage collector helped?

shadowze commented 5 years ago

Tested this for a couple of weeks garbage collector is indeed hiding this bug in MOOSE, but the bug is still there in when using FilterActive() and FilterOnce() methods together and not using garbage collector

Will leave this open for now, because the bug is still there and also when others start experiencing this same error , they can find this "work around"

Code segment that runs for 20 mins fine on a VERY busy MP server, then craps itself

function check_SAM_ammo() local SamSet2 = SET_GROUP:New():FilterPrefixes(t_sam_check.prefix):FilterActive():FilterOnce() env.info("+++++++++ CHECK SAM AMMO HIT ++++++++++++++++++++++++++++++++++++++++++++++++++++++++")

SamSet2:ForEachGroup(
function( MooseGroup )
    if (MooseGroup ~=nil) and (MooseGroup:IsAlive()) then
        if MooseGroup:GetUnit( 1 ):GetAmmo() == nil then
            env.info("SAM unit out of ammo destroying")
            MooseGroup:Destroy()
        return
        end
    end
end)

end -- EOF

thebgpikester commented 4 years ago

Lots of discussion historically but even to date there isnt a working reproducible code and miz to demonstrate the issue first hand in its simplest form. The date of this is so old that recalling what has happened since (and I recall LOTS of discussion on SETS in Discord) makes this ticket too hard to work out a next step for other than asking for a simple miz. I suggest to cut down on the noise and get to this the best course of action will be to archive this and ask for a straight up report with the details so it can be reproduced at will Basiclaly what you were trying to achieve in code CAN be achieved, but I'v enever used FilterOnce() repeatedly in the way you do and I suggest not, if it keeps giving errors.