From 4a0842bea6b0a5db591fef8dfc9d9a8ac18d0995 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 29 Dec 2024 12:52:51 +0100 Subject: [PATCH 1/2] #STORAGE - Added persistence options --- Moose Development/Moose/Wrapper/Storage.lua | 154 +++++++++++++++++++- 1 file changed, 151 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua index 15cbf995d..4ed35c196 100644 --- a/Moose Development/Moose/Wrapper/Storage.lua +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -226,7 +226,7 @@ function STORAGE:NewFromStaticCargo(StaticCargoName) return self end ---- Create a new STORAGE object from an DCS static cargo object. +--- Create a new STORAGE object from a Wrapper.DynamicCargo#DYNAMICCARGO object. -- @param #STORAGE self -- @param #string DynamicCargoName Unit name of the dynamic cargo. -- @return #STORAGE self @@ -235,7 +235,7 @@ function STORAGE:NewFromDynamicCargo(DynamicCargoName) -- Inherit everything from BASE class. local self=BASE:Inherit(self, BASE:New()) -- #STORAGE - self.airbase=Unit.getByName(DynamicCargoName) + self.airbase=Unit.getByName(DynamicCargoName) or StaticObject.getByName(DynamicCargoName) if Airbase.getWarehouse then self.warehouse=Warehouse.getCargoAsWarehouse(self.airbase) @@ -499,7 +499,7 @@ function STORAGE:IsUnlimited(Type) end -- Debug info. - self:I(self.lid..string.format("Type=%s: unlimited=%s (N=%d n=%d)", tostring(Type), tostring(unlimited), N, n)) + self:T(self.lid..string.format("Type=%s: unlimited=%s (N=%d n=%d)", tostring(Type), tostring(unlimited), N, n)) end return unlimited @@ -595,6 +595,154 @@ function STORAGE:GetInventory(Item) return inventory.aircraft, inventory.liquids, inventory.weapon end +--- Save the contents of a STORAGE to files in CSV format. Filenames created are the Filename given amended by "_Liquids", "_Aircraft" and "_Weapons" followed by a ".csv". Requires io and lfs to be desanitized to be working. +-- @param #STORAGE self +-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems. +-- @param #string Filename The base name of the files. Existing files will be overwritten. +-- @return #STORAGE self +function STORAGE:SaveToFile(Path,Filename) + + if not io then + BASE:E("ERROR: io not desanitized. Can't save the files.") + return false + end + + -- Check default path. + if Path==nil and not lfs then + BASE:E("WARNING: lfs not desanitized. File will be saved in DCS installation root directory rather than your given path.") + end + + local ac, lq, wp = self:GetInventory() + local DataAircraft = "" + local DataLiquids = "" + local DataWeapons = "" + + if #lq > 0 then + DataLiquids = DataLiquids .."Liquids in Storage:\n" + for key,amount in pairs(lq) do + DataLiquids = DataLiquids..tostring(key).."="..tostring(amount).."\n" + end + --self:I(DataLiquids) + UTILS.SaveToFile(Path,Filename.."_Liquids.csv",DataLiquids) + end + + if UTILS.TableLength(ac) > 0 then + DataAircraft = DataAircraft .."Aircraft in Storage:\n" + for key,amount in pairs(ac) do + DataAircraft = DataAircraft..tostring(key).."="..tostring(amount).."\n" + end + --self:I(DataAircraft) + UTILS.SaveToFile(Path,Filename.."_Aircraft.csv",DataAircraft) + end + + if UTILS.TableLength(wp) > 0 then + DataWeapons = DataWeapons .."Weapons and Materiel in Storage:\n" + for key,amount in pairs(wp) do + DataWeapons = DataWeapons..tostring(key).."="..tostring(amount).."\n" + end + -- Gazelle table keys + for key,amount in pairs(ENUMS.Storage.weapons.Gazelle) do + amount = self:GetItemAmount(ENUMS.Storage.weapons.Gazelle[key]) + DataWeapons = DataWeapons.."ENUMS.Storage.weapons.Gazelle."..tostring(key).."="..tostring(amount).."\n" + end + -- CH47 + for key,amount in pairs(ENUMS.Storage.weapons.CH47) do + amount = self:GetItemAmount(ENUMS.Storage.weapons.CH47[key]) + DataWeapons = DataWeapons.."ENUMS.Storage.weapons.CH47."..tostring(key).."="..tostring(amount).."\n" + end + -- UH1H + for key,amount in pairs(ENUMS.Storage.weapons.UH1H) do + amount = self:GetItemAmount(ENUMS.Storage.weapons.UH1H[key]) + DataWeapons = DataWeapons.."ENUMS.Storage.weapons.UH1H."..tostring(key).."="..tostring(amount).."\n" + end + -- OH58D + for key,amount in pairs(ENUMS.Storage.weapons.OH58) do + amount = self:GetItemAmount(ENUMS.Storage.weapons.OH58[key]) + DataWeapons = DataWeapons.."ENUMS.Storage.weapons.OH58."..tostring(key).."="..tostring(amount).."\n" + end + -- AH64D + for key,amount in pairs(ENUMS.Storage.weapons.AH64D) do + amount = self:GetItemAmount(ENUMS.Storage.weapons.AH64D[key]) + DataWeapons = DataWeapons.."ENUMS.Storage.weapons.AH64D."..tostring(key).."="..tostring(amount).."\n" + end + --self:I(DataAircraft) + UTILS.SaveToFile(Path,Filename.."_Weapons.csv",DataWeapons) + end + + return self +end + +--- Load the contents of a STORAGE from files. Filenames searched for are the Filename given amended by "_Liquids", "_Aircraft" and "_Weapons" followed by a ".csv". Requires io and lfs to be desanitized to be working. +-- @param #STORAGE self +-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems. +-- @param #string Filename The name of the file. +-- @return #STORAGE self +function STORAGE:LoadFromFile(Path,Filename) + + if not io then + BASE:E("ERROR: io not desanitized. Can't read the files.") + return false + end + + -- Check default path. + if Path==nil and not lfs then + BASE:E("WARNING: lfs not desanitized. File will be read from DCS installation root directory rather than your give path.") + end + + --Liquids + if self:IsLimitedLiquids() then + local Ok,Liquids = UTILS.LoadFromFile(Path,Filename.."_Liquids.csv") + if Ok then + for _id,_line in pairs(Liquids) do + if string.find(_line,"Storage") == nil then + local tbl=UTILS.Split(_line,"=") + local lqno = tonumber(tbl[1]) + local lqam = tonumber(tbl[2]) + self:SetLiquid(lqno,lqam) + end + end + else + self:E("File for Liquids could not be found: "..tostring(Path).."\\"..tostring(Filename"_Liquids.csv")) + end + end + + --Aircraft + if self:IsLimitedAircraft() then + local Ok,Aircraft = UTILS.LoadFromFile(Path,Filename.."_Aircraft.csv") + if Ok then + for _id,_line in pairs(Aircraft) do + if string.find(_line,"Storage") == nil then + local tbl=UTILS.Split(_line,"=") + local acname = tbl[1] + local acnumber = tonumber(tbl[2]) + self:SetAmount(acname,acnumber) + end + end + else + self:E("File for Aircraft could not be found: "..tostring(Path).."\\"..tostring(Filename"_Aircraft.csv")) + end + end + + --Weapons + if self:IsLimitedWeapons()() then + local Ok,Weapons = UTILS.LoadFromFile(Path,Filename.."_Weapons.csv") + if Ok then + for _id,_line in pairs(Weapons) do + if string.find(_line,"Storage") == nil then + local tbl=UTILS.Split(_line,"=") + local wpname = tbl[1] + local wpnumber = tonumber(tbl[2]) + self:SetAmount(wpname,wpnumber) + end + end + else + self:E("File for Weapons could not be found: "..tostring(Path).."\\"..tostring(Filename"_Weapons.csv")) + end + end + + return self +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Private Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- From 0f7759d070cb2f4bf87fe3c16d9689b2fc3c73f0 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 29 Dec 2024 18:04:42 +0100 Subject: [PATCH 2/2] #STORAGE - Added StartAutoSave and StopAutoSave() --- Moose Development/Moose/Wrapper/Storage.lua | 58 +++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua index 4ed35c196..8cbc8a0ab 100644 --- a/Moose Development/Moose/Wrapper/Storage.lua +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -26,6 +26,7 @@ -- @field #string lid Class id string for output to DCS log file. -- @field DCS#Warehouse warehouse The DCS warehouse object. -- @field DCS#Airbase airbase The DCS airbase object. +-- @field Core.Timer#TIMER SaverTimer The TIMER for autosave. -- @extends Core.Base#BASE --- *The capitalist cannot store labour-power in warehouses after he has bought it, as he may do with the raw material.* -- Karl Marx @@ -173,14 +174,14 @@ STORAGE.Type = { --- STORAGE class version. -- @field #string version -STORAGE.version="0.0.3" +STORAGE.version="0.1.4" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO: A lot... --- TODO: Persistence +-- DONE: Persistence ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -266,6 +267,10 @@ end -- @return #STORAGE self function STORAGE:SetVerbosity(VerbosityLevel) self.verbose=VerbosityLevel or 0 + if self.verbose > 1 then + BASE:TraceOn() + BASE:TraceClass("STORAGE") + end return self end @@ -624,6 +629,9 @@ function STORAGE:SaveToFile(Path,Filename) end --self:I(DataLiquids) UTILS.SaveToFile(Path,Filename.."_Liquids.csv",DataLiquids) + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Saving Liquids to "..tostring(Path).."\\"..tostring(Filename).."_Liquids.csv") + end end if UTILS.TableLength(ac) > 0 then @@ -633,6 +641,9 @@ function STORAGE:SaveToFile(Path,Filename) end --self:I(DataAircraft) UTILS.SaveToFile(Path,Filename.."_Aircraft.csv",DataAircraft) + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Saving Aircraft to "..tostring(Path).."\\"..tostring(Filename).."_Aircraft.csv") + end end if UTILS.TableLength(wp) > 0 then @@ -666,7 +677,10 @@ function STORAGE:SaveToFile(Path,Filename) DataWeapons = DataWeapons.."ENUMS.Storage.weapons.AH64D."..tostring(key).."="..tostring(amount).."\n" end --self:I(DataAircraft) - UTILS.SaveToFile(Path,Filename.."_Weapons.csv",DataWeapons) + UTILS.SaveToFile(Path,Filename.."_Weapons.csv",DataWeapons) + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Saving Weapons to "..tostring(Path).."\\"..tostring(Filename).."_Weapons.csv") + end end return self @@ -693,6 +707,9 @@ function STORAGE:LoadFromFile(Path,Filename) if self:IsLimitedLiquids() then local Ok,Liquids = UTILS.LoadFromFile(Path,Filename.."_Liquids.csv") if Ok then + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Loading Liquids from "..tostring(Path).."\\"..tostring(Filename).."_Liquids.csv") + end for _id,_line in pairs(Liquids) do if string.find(_line,"Storage") == nil then local tbl=UTILS.Split(_line,"=") @@ -710,6 +727,9 @@ function STORAGE:LoadFromFile(Path,Filename) if self:IsLimitedAircraft() then local Ok,Aircraft = UTILS.LoadFromFile(Path,Filename.."_Aircraft.csv") if Ok then + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Loading Aircraft from "..tostring(Path).."\\"..tostring(Filename).."_Aircraft.csv") + end for _id,_line in pairs(Aircraft) do if string.find(_line,"Storage") == nil then local tbl=UTILS.Split(_line,"=") @@ -727,6 +747,9 @@ function STORAGE:LoadFromFile(Path,Filename) if self:IsLimitedWeapons()() then local Ok,Weapons = UTILS.LoadFromFile(Path,Filename.."_Weapons.csv") if Ok then + if self.verbose and self.verbose > 0 then + self:I(self.lid.."Loading _eapons from "..tostring(Path).."\\"..tostring(Filename).."_Weapons.csv") + end for _id,_line in pairs(Weapons) do if string.find(_line,"Storage") == nil then local tbl=UTILS.Split(_line,"=") @@ -743,6 +766,35 @@ function STORAGE:LoadFromFile(Path,Filename) return self end +--- Start a STORAGE autosave process. +-- @param #STORAGE self +-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems. +-- @param #string Filename The name of the file. +-- @param #number Interval The interval, start after this many seconds and repeat every interval seconds. Defaults to 300. +-- @param #boolean LoadOnce If LoadOnce is true or nil, we try to load saved storage first. +-- @return #STORAGE self +function STORAGE:StartAutoSave(Path,Filename,Interval,LoadOnce) + if LoadOnce ~= false then + self:LoadFromFile(Path,Filename) + end + local interval = Interval or 300 + self.SaverTimer = TIMER:New(STORAGE.SaveToFile,self,Path,Filename) + self.SaverTimer:Start(interval,interval) + return self +end + +--- Stop a running STORAGE autosave process. +-- @param #STORAGE self +-- @return #STORAGE self +function STORAGE:StopAutoSave() + if self.SaverTimer and self.SaverTimer:IsRunning() then + self.SaverTimer:Stop() + self.SaverTimer = nil + end + return self +end + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Private Functions -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------