Skip to content
This repository was archived by the owner on Aug 21, 2024. It is now read-only.

Commit da0b628

Browse files
committed
Multiple fixes in mod processing.
* fixed loading submod when both child and parent are unpacked * implemented json config merging by same name
1 parent 87f6c42 commit da0b628

File tree

5 files changed

+176
-25
lines changed

5 files changed

+176
-25
lines changed

filesystem.pas

Lines changed: 122 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ TModConfig = class (TBaseConfig)
184184

185185
property Disabled:Boolean read FDisabled write FDisabled;
186186
property ID: TModId read FID write SetID;
187-
//realtive (to mod root) mod path
188187
property Path: String read FPath write SetPath;
189188
procedure MayBeSetDefaultFSConfig;
190189

@@ -294,9 +293,12 @@ TFSManager = class (TComponent, IResourceLoader)
294293

295294
procedure OnFileFound(FileIterator: TFileIterator);
296295
procedure OnDirectoryFound(FileIterator: TFileIterator);
296+
procedure OnTopLevelDirectoryFound(FileIterator: TFileIterator);
297+
297298
procedure OnArchiveFound(FileIterator: TFileIterator);
298299

299300
procedure ScanDir(const RelDir: string; ARootPath: TStrings);
301+
procedure ScanContentDir(const RelDir: string; ARootPath: TStrings);
300302

301303
procedure ScanMap(MapPath: string; ARootPath: TStrings);
302304

@@ -336,6 +338,7 @@ TFSManager = class (TComponent, IResourceLoader)
336338
procedure Load(AProgress: IProgressCallback);
337339

338340
procedure LoadResource(AResource: IResource; AResType: TResourceType; AName: string);
341+
procedure LoadResourceCombined(AResource: IResource; AResType: TResourceType; AName: string);
339342

340343
function TryLoadResource(AResource: IResource; AResType: TResourceType; AName: string): boolean;
341344

@@ -349,6 +352,10 @@ TFSManager = class (TComponent, IResourceLoader)
349352
property DataPath: TStringListUTF8 read FDataPath;
350353
end;
351354

355+
EResourceNotFound = class (Exception)
356+
357+
end;
358+
352359

353360
implementation
354361
uses
@@ -602,7 +609,7 @@ procedure TModConfig.MayBeSetDefaultFSConfig;
602609
cur_path := Filesystem.Add;
603610
cur_path.Identifier := '';
604611

605-
item := cur_path.Items.Add;
612+
item := cur_path.Items.Add;
606613
item.&Type := 'dir';
607614
item.Path := MOD_ROOT;
608615
end;
@@ -734,7 +741,7 @@ procedure TFSManager.ProcessModConfig(AParentModID: AnsiString;
734741
try
735742
mod_config := TModConfig.Create;
736743
mod_config.ID := AModID;
737-
mod_config.Path := ExtractFileNameOnly(ExcludeTrailingBackslash(ExtractFilePath(mod_path)));
744+
mod_config.Path := ExtractFilePath(mod_path);
738745
destreamer.JSONStreamToObject(stm, mod_config,'');
739746
mod_config.MayBeSetDefaultFSConfig;
740747

@@ -775,7 +782,30 @@ procedure TFSManager.OnDirectoryFound(FileIterator: TFileIterator);
775782
srch.OnDirectoryFound:=@OnDirectoryFound;
776783
try
777784
p := IncludeTrailingPathDelimiter(FileIterator.FileName);
778-
srch.Search(p);
785+
srch.Search(p, '', False);
786+
finally
787+
srch.Free;
788+
end;
789+
end;
790+
791+
procedure TFSManager.OnTopLevelDirectoryFound(FileIterator: TFileIterator);
792+
var
793+
srch: TFileSearcher;
794+
p, tld_name: string;
795+
begin
796+
srch := TFileSearcher.Create;
797+
srch.OnFileFound := @OnFileFound;
798+
srch.OnDirectoryFound:=@OnDirectoryFound;
799+
try
800+
p := IncludeTrailingPathDelimiter(FileIterator.FileName);
801+
802+
tld_name := ExtractFileNameOnly(ExcludeTrailingPathDelimiter(FileIterator.FileName));
803+
804+
if UpperCase(tld_name) <> 'MODS' then
805+
begin
806+
DebugLn('TLD :', p);
807+
srch.Search(p, '', False);
808+
end;
779809
finally
780810
srch.Free;
781811
end;
@@ -993,10 +1023,62 @@ procedure TFSManager.LoadResource(AResource: IResource; AResType: TResourceType;
9931023
begin
9941024
if not TryLoadResource(AResource, AResType, AName) then
9951025
begin
996-
raise Exception.Create('Resource not found: '+AName);
1026+
raise EResourceNotFound.Create('Resource not found: '+AName);
9971027
end;
9981028
end;
9991029

1030+
procedure TFSManager.LoadResourceCombined(AResource: IResource;
1031+
AResType: TResourceType; AName: string);
1032+
var
1033+
it : TResIDToLocationMap.TIterator;
1034+
1035+
last_location: TResLocation;
1036+
order: Integer;
1037+
begin
1038+
AName := NormalizeResourceName(AName);
1039+
it := SelectResource(AResType, AName);
1040+
if not Assigned(it) then
1041+
begin
1042+
raise EResourceNotFound.Create('Resource not found: '+AName);
1043+
end;
1044+
1045+
last_location := it.Value;
1046+
order := it.Key.ModOrder;
1047+
1048+
case last_location.lt of
1049+
TLocationType.InLod: last_location.lod.LoadResource(AResource,last_location.FileHeader);
1050+
TLocationType.InFile: LoadFileResource(AResource,last_location.path);
1051+
TLocationType.InArchive: LoadArchiveResource(AResource, last_location.archive, last_location.entry);
1052+
end;
1053+
1054+
while it.Next do
1055+
begin
1056+
if (it.Key.VFSPath = AName) and (it.Key.Typ = AResType) then
1057+
begin
1058+
last_location := it.Value;
1059+
1060+
if not (order < it.Key.ModOrder) then
1061+
begin
1062+
raise Exception.CreateFmt('[Internal error] wrong order %d for %s', [it.Key.ModOrder, AName]);
1063+
end;
1064+
1065+
case last_location.lt of
1066+
TLocationType.InLod: last_location.lod.LoadResource(AResource,last_location.FileHeader) ;
1067+
TLocationType.InFile: LoadFileResource(AResource,last_location.path);
1068+
TLocationType.InArchive: LoadArchiveResource(AResource, last_location.archive, last_location.entry);
1069+
end;
1070+
1071+
order := it.Key.ModOrder;
1072+
end
1073+
else
1074+
begin
1075+
Break;
1076+
end;
1077+
end;
1078+
1079+
FreeAndNil(it);
1080+
end;
1081+
10001082
function TFSManager.TryLoadResource(AResource: IResource; AResType: TResourceType; AName: string): boolean;
10011083
var
10021084
it : TResIDToLocationMap.TIterator;
@@ -1132,15 +1214,9 @@ procedure TFSManager.ScanMods;
11321214
FCurrentLoadOrder:=load_order;
11331215
mod_paths.Clear;
11341216

1135-
for APath in mod_roots do
1136-
begin
1137-
mod_paths.Append( IncludeTrailingPathDelimiter(APath) + AMod.Path);
1138-
end;
1217+
mod_paths.Append(AMod.Path);
11391218

1140-
for APath in mod_roots do
1141-
begin
1142-
ProcessFSConfig(FModMap.Data[mod_idx].Filesystem,mod_paths);
1143-
end;
1219+
ProcessFSConfig(FModMap.Data[mod_idx].Filesystem,mod_paths);
11441220
end;
11451221
end;
11461222

@@ -1297,12 +1373,14 @@ procedure TFSManager.OnFileFound(FileIterator: TFileIterator);
12971373
file_name := ExtractFileNameOnly(FileIterator.FileName);
12981374

12991375
res_id.Typ := res_typ;
1300-
res_id.VFSPath := SetDirSeparators(UpperCase(FCurrentVFSPath+ExtractFilePath(rel_path)+file_name));//
1376+
res_id.VFSPath := SetDirSeparators(UpperCase(FCurrentVFSPath+ExtractFilePath(rel_path)+file_name));
13011377
res_id.ModOrder:=FCurrentLoadOrder;
13021378

13031379
res_loc.SetFile(FileIterator.FileName);
13041380

13051381
FResMap.Insert(res_id,res_loc);
1382+
1383+
DebugLn(rel_path, ' => ' , res_id.VFSPath, ' => ', FileIterator.FileName);
13061384
end;
13071385

13081386
procedure TFSManager.OnLodItemFound(Alod: TLod; constref AItem: TLodItem);
@@ -1327,7 +1405,7 @@ procedure TFSManager.OnLodItemFound(Alod: TLod; constref AItem: TLodItem);
13271405
exit;
13281406

13291407
res_id.Typ := res_typ;
1330-
res_id.VFSPath := FCurrentVFSPath+file_name;//
1408+
res_id.VFSPath := FCurrentVFSPath+file_name;
13311409
res_id.ModOrder:=FCurrentLoadOrder;
13321410

13331411
res_loc.SetLod(Alod, AItem);
@@ -1395,12 +1473,13 @@ procedure TFSManager.ProcessConfigItem(APath: TFilesystemConfigPath; ARootPath:
13951473
ScanLod(rel_path,ARootPath);
13961474
end;
13971475
'dir':begin
1398-
if item.Path = MOD_ROOT then
1476+
if UpperCase(rel_path) = UpperCase(MOD_ROOT) then
13991477
begin
14001478
ScanArchive(item, rel_path, ARootPath);
1401-
ScanDir(rel_path,ARootPath);
1479+
ScanContentDir(rel_path,ARootPath);
14021480
end
1403-
else begin
1481+
else if UpperCase(item.Path) <> 'MODS' then
1482+
begin
14041483
ScanDir(rel_path,ARootPath);
14051484
end;
14061485
end;
@@ -1431,12 +1510,35 @@ procedure TFSManager.ScanDir(const RelDir: string; ARootPath: TStrings);
14311510
begin
14321511
srch := TFileSearcher.Create;
14331512
srch.OnFileFound := @OnFileFound;
1434-
//srch.OnDirectoryFound:=@OnDirectoryFound;
1513+
srch.OnDirectoryFound:=@OnDirectoryFound;
1514+
try
1515+
FCurrentRelPath := RelDir;
1516+
FCurrentRootPath := root_path;
1517+
p := IncludeTrailingPathDelimiter(MakeFullPath(root_path,RelDir));
1518+
srch.Search(p, '', False);
1519+
finally
1520+
srch.Free;
1521+
end;
1522+
end;
1523+
end;
1524+
1525+
procedure TFSManager.ScanContentDir(const RelDir: string; ARootPath: TStrings);
1526+
var
1527+
srch: TFileSearcher;
1528+
p: string;
1529+
root_path: String;
1530+
begin
1531+
for root_path in ARootPath do
1532+
begin
1533+
DebugLn('ScanContentDir: ', root_path, ' ', RelDir);
1534+
srch := TFileSearcher.Create;
1535+
//srch.OnFileFound := @OnFileFound;
1536+
srch.OnDirectoryFound:=@OnTopLevelDirectoryFound;
14351537
try
14361538
FCurrentRelPath := RelDir;
14371539
FCurrentRootPath := root_path;
14381540
p := IncludeTrailingPathDelimiter(MakeFullPath(root_path,RelDir));
1439-
srch.Search(p);
1541+
srch.Search(p, '', False);
14401542
finally
14411543
srch.Free;
14421544
end;

filesystem_base.pas

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ interface
4545
*)
4646
procedure LoadResource(AResource: IResource; AResType: TResourceType; AName: string);
4747

48+
procedure LoadResourceCombined(AResource: IResource; AResType: TResourceType; AName: string);
49+
4850
function ExistsResource(AResType: TResourceType; AName: string): boolean;
4951

5052
function TryLoadResource(AResource: IResource; AResType: TResourceType; AName: string):boolean;
@@ -67,8 +69,8 @@ TBaseResource = class abstract (TObject, IResource)
6769

6870
procedure LoadFromStream(AFileName: AnsiString; AStream: TStream); virtual; abstract;
6971

70-
procedure Load(ALoader: IResourceLoader);
71-
function TryLoad(ALoader: IResourceLoader): Boolean;
72+
procedure Load(ALoader: IResourceLoader); virtual;
73+
function TryLoad(ALoader: IResourceLoader): Boolean; virtual;
7274
end;
7375

7476
{ TFSConsumer }

lists_manager.pas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,9 +2393,9 @@ procedure TListsManager.LoadResourceTypes;
23932393

23942394
procedure TListsManager.LoadTextDataConfig;
23952395
var
2396-
config: TJsonResource;
2396+
config: TJsonCombinedResource;
23972397
begin
2398-
config := TJsonResource.Create(TEXT_DATA_CONFIG);
2398+
config := TJsonCombinedResource.Create(TEXT_DATA_CONFIG);
23992399
try
24002400
config.Load(ResourceLoader);
24012401
config.DestreamTo(FTextDataConfig, 'textData');

vcmi_json.pas

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ TJsonResource = class (TBaseResource, IResource)
139139
procedure DestreamTo(AObject: TObject; AFieldName: string = '');
140140
end;
141141

142+
143+
{ TJsonCombinedResource }
144+
145+
TJsonCombinedResource = class (TJsonResource)
146+
public
147+
procedure LoadFromStream(AFileName: AnsiString; AStream: TStream); override;
148+
procedure Load(ALoader: IResourceLoader); override;
149+
function TryLoad(ALoader: IResourceLoader): Boolean; override;
150+
end;
151+
142152
TJsonObjectList = specialize TFPGObjectList<TJSONObject>;
143153

144154

@@ -357,6 +367,40 @@ function LoadHeroSex(ASrc: TJSONData): THeroSex;
357367

358368
end;
359369

370+
{ TJsonCombinedResource }
371+
372+
procedure TJsonCombinedResource.LoadFromStream(AFileName: AnsiString; AStream: TStream);
373+
var
374+
current: TJSONObject;
375+
begin
376+
if not Assigned(FRoot) then
377+
begin
378+
FRoot := CreateJSONObject([]);
379+
end;
380+
381+
current := destreamer.JSONStreamToJSONObject(AStream,'');
382+
try
383+
MergeJson(current, Root);
384+
finally
385+
current.Free;
386+
end;
387+
end;
388+
389+
procedure TJsonCombinedResource.Load(ALoader: IResourceLoader);
390+
begin
391+
ALoader.LoadResourceCombined(Self, Typ, Path);
392+
end;
393+
394+
function TJsonCombinedResource.TryLoad(ALoader: IResourceLoader): Boolean;
395+
begin
396+
Result:= ALoader.ExistsResource(Self.Typ, Self.Path);
397+
398+
if Result then
399+
begin
400+
Load(ALoader);
401+
end;
402+
end;
403+
360404
{ TVCMIJsonArray }
361405

362406
function TVCMIJsonArray.Clone: TJSONData;

vcmieditor.lpi

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@
815815
</Other>
816816
</CompilerOptions>
817817
<Debugging>
818-
<Exceptions Count="3">
818+
<Exceptions Count="4">
819819
<Item1>
820820
<Name Value="EAbort"/>
821821
</Item1>
@@ -825,6 +825,9 @@
825825
<Item3>
826826
<Name Value="EFOpenError"/>
827827
</Item3>
828+
<Item4>
829+
<Name Value="EResourceNotFound"/>
830+
</Item4>
828831
</Exceptions>
829832
</Debugging>
830833
</CONFIG>

0 commit comments

Comments
 (0)