library ConflictDirectCostDLL; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils, System.Classes, REST.JSON, Windows, uHCDateTime in '..\..\shared\pascal\uHCDateTime.pas', uHCDefines in '..\..\shared\pascal\uHCDefines.pas', uHCGlobals in '..\..\shared\pascal\uHCGlobals.pas', uHCTypeDefs in '..\..\shared\pascal\uHCTypeDefs.pas', uHCAnnexDefs in '..\..\shared\pascal\uHCAnnexDefs.pas', uConflictDirectCostTypeDefs in 'uConflictDirectCostTypeDefs.pas', TGPSvcDiscoverUDP in 'TGPSvcDiscoverUDP.pas'; {$R *.res} const DLLVERN = 1; DLLVERINTN = 21; version = 1; // ALE 20150820 TMMFConflictDirectCost structure version var dt_scen_start: THCDateTimeRec; PAllDeadUnits: PHCDeadListItem; PBusyDLL: Pointer; ConflictDirectCost: TMMFConflictDirectCost; MulticastServer: TTGPServiceDiscoveryUDPServer; { *** Return DLL internal version, i.e. revision 5 of my DLL *** } function DLLVer(): word; export; cdecl; begin result := DLLVERN; end; { *** Return DLL interface version, i.e. revision 1 of my HCE interface spec *** } function DLLVerInt(): word; export; cdecl; begin result := DLLVERINTN; end; { *** Return DLL description, 255 characters max *** } function DLLDesc(): PAnsiChar; export; cdecl; begin result := 'DLL to send direct cost in lives and dollars to local network viewers, by Tony Eischens'; end; { *** Free DLL *** } procedure DLLFree(); export; cdecl; begin // Do any cleanup here, this is the end ConflictDirectCost.Free; MulticastServer.Active := False; // Application.ProcessMessages; MulticastServer.Free; // Application.ProcessMessages; end; { *** Init DLL *** } procedure DLLInit(hwndHC: HWND; pathHC: PAnsiChar; verHC: PAnsiChar; verSaveGame: LongWord; funcRefs: PHCDLL_FUNC_REF; PGEClosing: Pointer; PDLLBusy: Pointer; verInterface: LongWord); export; cdecl; begin PBusyDLL := PDLLBusy; ConflictDirectCost := TMMFConflictDirectCost.Create; MulticastServer := TTGPServiceDiscoveryUDPServer.Create(nil); MulticastServer.Group := 'HCConflictDirectCost'; MulticastServer.GroupAddress := '224.0.0.1'; MulticastServer.Active := True; end; { procedure ScenLoad(strHarpPath: PAnsiChar; intScenNum: SmallInt; strScenFPath: PAnsiChar; intBSNum: ShortInt; strBSFName: PAnsiChar; intSide: byte; intGameTimeIn: Long; intGameTimeLeftIn: Long; dt_scen_start_in: PHCDateTimeRec); export; cdecl; } procedure ScenLoad(strHarpPath: PAnsiChar; intScenNum: smallint; strScenFPath: PAnsiChar; intBSNum: shortint; strBSFName: PAnsiChar; intSide: byte; intGameTimeIn: Long; intGameTimeLeftIn: Long; AnnexDataIn: PHCAnnexes_disk; DatabaseVersionDBIn: PHCDATABASE_VERSION; ScenDataIn: PHCSCENARIO_DATA; ScenSaveDataIn: PHCSCENARIO_SAVE_DATA) export; cdecl; var lLLI: PHCLINEAGE_LIST_ITEM; lLineageStr: String; lRow: NativeInt; begin byte(PBusyDLL^) := CTRUE; // ALE 20130816 don't process other events in GE dt_scen_start := ScenDataIn^.dt_scen_start; byte(PBusyDLL^) := CFALSE; end; function GetCostHuman(pAnnex: word; pCount: short): UInt64; begin result := 0; case pAnnex of 2112: result := pCount * 100; 2128: result := pCount * 100; 2129: result := pCount * 100; 2132: result := pCount * 100; 2134: result := pCount * 100; 2136: result := pCount * 100; 2141: result := pCount * 100; 2142: result := pCount * 100; 2143: result := pCount * 100; 2144: result := pCount * 100; 2147: result := pCount * 100; 2150: result := pCount * 100; 2151: result := pCount * 100; 2153: result := pCount * 100; 2155: result := pCount * 100; 2158: result := pCount * 100; 2163: result := pCount * 100; 2167: result := pCount * 100; 2174: result := pCount * 100; 2186: result := pCount * 100; 2223: result := pCount * 100; 2263: result := pCount * 100; 2361: result := pCount * 100; 2366: result := pCount * 100; 2367: result := pCount * 100; 2383: result := pCount * 100; 2385: result := pCount * 100; 2395: result := pCount * 100; 2452: result := pCount * 100; 2465: result := pCount * 100; 2471: result := pCount * 100; 2473: result := pCount * 100; 2476: result := pCount * 100; 2502: result := pCount * 100; 2507: result := pCount * 100; 2509: result := pCount * 100; 2597: result := pCount * 100; 2611: result := pCount * 100; 2619: result := pCount * 100; 2678: result := pCount * 100; 2684: result := pCount * 100; 2698: result := pCount * 100; 2859: result := pCount * 100; 2860: result := pCount * 100; 2861: result := pCount * 100; 2869: result := pCount * 100; 2948: result := pCount * 100; 2949: result := pCount * 100; 3018: result := pCount * 100; 10259: result := pCount * 1; 10261: result := pCount * 2; 10262: result := pCount * 2; 10263: result := pCount * 1; 10266: result := pCount * 3; 10271: result := pCount * 3; 10277: result := pCount * 4; 10278: result := pCount * 4; 10282: result := pCount * 5; 10284: result := pCount * 5; 10285: result := pCount * 2; 10286: result := pCount * 2; 10288: result := pCount * 3; 10293: result := pCount * 3; 10294: result := pCount * 4; 10304: result := pCount * 4; 10305: result := pCount * 10; 10308: result := pCount * 10; 10309: result := pCount * 1; 10315: result := pCount * 1; 10317: result := pCount * 2; 10340: result := pCount * 2; 10347: result := pCount * 2; 10376: result := pCount * 2; 10406: result := pCount * 2; 10408: result := pCount * 2; 10409: result := pCount * 1; 10418: result := pCount * 1; 10432: result := pCount * 1; 10435: result := pCount * 1; 10436: result := pCount * 1; 10445: result := pCount * 1; 10459: result := pCount * 1; 10461: result := pCount * 1; 10466: result := pCount * 1; 10469: result := pCount * 1; 10475: result := pCount * 1; 10534: result := pCount * 1; 10600: result := pCount * 1; 10709: result := pCount * 1; 10712: result := pCount * 1; 10714: result := pCount * 1; 10715: result := pCount * 1; 10818: result := pCount * 1; 10819: result := pCount * 1; 10832: result := pCount * 1; 10841: result := pCount * 1; 10895: result := pCount * 1; 10896: result := pCount * 1; 10960: result := pCount * 1; end; end; function GetCostMonetary(pAnnex: word; pCount: short): UInt64; begin result := 0; case pAnnex of 2112: result := pCount * 100000000; 2128: result := pCount * 100000000; 2129: result := pCount * 100000000; 2132: result := pCount * 100000000; 2134: result := pCount * 100000000; 2136: result := pCount * 100000000; 2141: result := pCount * 100000000; 2142: result := pCount * 100000000; 2143: result := pCount * 100000000; 2144: result := pCount * 100000000; 2147: result := pCount * 100000000; 2150: result := pCount * 100000000; 2151: result := pCount * 100000000; 2153: result := pCount * 100000000; 2155: result := pCount * 100000000; 2158: result := pCount * 100000000; 2163: result := pCount * 100000000; 2167: result := pCount * 100000000; 2174: result := pCount * 100000000; 2186: result := pCount * 100000000; 2223: result := pCount * 100000000; 2263: result := pCount * 100000000; 2361: result := pCount * 100000000; 2366: result := pCount * 100000000; 2367: result := pCount * 100000000; 2383: result := pCount * 100000000; 2385: result := pCount * 100000000; 2395: result := pCount * 100000000; 2452: result := pCount * 100000000; 2465: result := pCount * 100000000; 2471: result := pCount * 100000000; 2473: result := pCount * 100000000; 2476: result := pCount * 100000000; 2502: result := pCount * 100000000; 2507: result := pCount * 100000000; 2509: result := pCount * 100000000; 2597: result := pCount * 100000000; 2611: result := pCount * 100000000; 2619: result := pCount * 100000000; 2678: result := pCount * 100000000; 2684: result := pCount * 100000000; 2698: result := pCount * 100000000; 2859: result := pCount * 100000000; 2860: result := pCount * 100000000; 2861: result := pCount * 100000000; 2869: result := pCount * 100000000; 2948: result := pCount * 100000000; 2949: result := pCount * 100000000; 3018: result := pCount * 100000000; 10259: result := pCount * 15000000; 10261: result := pCount * 15000000; 10262: result := pCount * 15000000; 10263: result := pCount * 15000000; 10266: result := pCount * 15000000; 10271: result := pCount * 15000000; 10277: result := pCount * 15000000; 10278: result := pCount * 15000000; 10282: result := pCount * 15000000; 10284: result := pCount * 15000000; 10285: result := pCount * 15000000; 10286: result := pCount * 15000000; 10288: result := pCount * 15000000; 10293: result := pCount * 15000000; 10294: result := pCount * 15000000; 10304: result := pCount * 15000000; 10305: result := pCount * 15000000; 10308: result := pCount * 15000000; 10309: result := pCount * 15000000; 10315: result := pCount * 15000000; 10317: result := pCount * 15000000; 10340: result := pCount * 15000000; 10347: result := pCount * 15000000; 10376: result := pCount * 15000000; 10406: result := pCount * 15000000; 10408: result := pCount * 15000000; 10409: result := pCount * 15000000; 10418: result := pCount * 15000000; 10432: result := pCount * 15000000; 10435: result := pCount * 15000000; 10436: result := pCount * 15000000; 10445: result := pCount * 15000000; 10459: result := pCount * 15000000; 10461: result := pCount * 15000000; 10466: result := pCount * 15000000; 10469: result := pCount * 15000000; 10475: result := pCount * 15000000; 10534: result := pCount * 15000000; 10600: result := pCount * 15000000; 10709: result := pCount * 15000000; 10712: result := pCount * 15000000; 10714: result := pCount * 15000000; 10715: result := pCount * 15000000; 10818: result := pCount * 15000000; 10819: result := pCount * 15000000; 10832: result := pCount * 15000000; 10841: result := pCount * 15000000; 10895: result := pCount * 15000000; 10896: result := pCount * 15000000; 10960: result := pCount * 15000000; end; end; procedure GameTime(GameTime: Long; GameTimeLeft: Long); export; cdecl; var intType, intSide: Integer; strLine: String; DeadUnitPtr: PHCDeadListItem; stlOut: TStringList; begin byte(PBusyDLL^) := CTRUE; // ALE 20130816 don't process other events in GE if MulticastServer.Active then begin ConflictDirectCost.version := version; CopyMemory(@(ConflictDirectCost.gamestartdatetime), @dt_scen_start, SizeOf(THCDateTimeRec)); ConflictDirectCost.GameTime := GameTime; ConflictDirectCost.GameTimeLeft := GameTimeLeft; // ALE 20150712 store remaining time DeadUnitPtr := PAllDeadUnits; // ALE 20150713 Initialize the array to zeros so we don't get false counts for intType := 0 to 9 do begin for intSide := 0 to SIDES - 1 do begin ConflictDirectCost.Fkillcounts[intType, intSide] := 0; end; end; // ALE 20150713 Tally up the individual dead units by type and side while (DeadUnitPtr <> nil) do begin Inc(ConflictDirectCost.Fkillcounts[DeadUnitPtr^.typeindex, DeadUnitPtr^.side], DeadUnitPtr^.count); DeadUnitPtr := DeadUnitPtr^.next; end; stlOut := TStringList.Create; // ALE 20150713 now report on it for intType := 0 to 9 do begin strLine := 'Type: ' + IntToStr(intType) + ', '; for intSide := 0 to SIDES - 1 do begin strLine := strLine + 'Side: ' + IntToStr(intSide) + ', Count=' + IntToStr(ConflictDirectCost.killcounts[intType, intSide]) + ' '; end; stlOut.Add(strLine); end; // ALE 20171204 tally up costs DeadUnitPtr := PAllDeadUnits; for intSide := 0 to SIDES - 1 do begin ConflictDirectCost.Fhumancost[intSide] := 0; ConflictDirectCost.Fmonetarycost[intSide] := 0; end; while (DeadUnitPtr <> nil) do begin Inc(ConflictDirectCost.Fhumancost[DeadUnitPtr^.side], GetCostHuman(DeadUnitPtr^.Annex, DeadUnitPtr^.count)); Inc(ConflictDirectCost.Fmonetarycost[DeadUnitPtr^.side], GetCostMonetary(DeadUnitPtr^.Annex, DeadUnitPtr^.count)); DeadUnitPtr := DeadUnitPtr^.next; end; // TThread.Queue(); MulticastServer.Send(TJson.ObjectToJsonString(ConflictDirectCost)); // stlOut.SaveToFile('C:\Games\HC\ConflictDirectCostDLL.txt'); stlOut.Free; end; byte(PBusyDLL^) := CFALSE; // ALE 20130816 don't process other events in GE end; procedure AllDeadUnitsPtr(AllDeadUnitsPtr: PHCDeadListItem); export; cdecl; begin PAllDeadUnits := AllDeadUnitsPtr; end; exports DLLVer, DLLVerInt, DLLDesc, DLLFree, DLLInit, ScenLoad, GameTime, AllDeadUnitsPtr; end.