Skip to content

Commit 6b921a8

Browse files
committed
fix problem with client having wrong route for getfile
1 parent 2b9f49b commit 6b921a8

File tree

3 files changed

+108
-106
lines changed

3 files changed

+108
-106
lines changed

Definitions/Web/Client.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static async Task<IEnumerable<DtoObjectEntry>> GetObjectListAsync(HttpCli
2929
=> await ClientHelpers.SendRequestAsync(
3030
client,
3131
ApiVersion + RoutesV2.Objects + $"/{id}/file",
32-
() => client.GetAsync(RoutesV2.Objects + $"/{id}/file"),
32+
() => client.GetAsync(ApiVersion + RoutesV2.Objects + $"/{id}/file"),
3333
ClientHelpers.ReadBinaryContentAsync,
3434
logger) ?? default;
3535

Gui/ViewModels/DatTypes/SCV5ViewModel.cs

Lines changed: 98 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.Linq;
1616
using System.Reactive;
1717
using System.Reactive.Linq;
18+
using System.Threading.Tasks;
1819

1920
namespace OpenLoco.Gui.ViewModels
2021
{
@@ -54,107 +55,7 @@ public SCV5ViewModel(FileSystemItem currentFile, ObjectEditorModel model)
5455
: base(currentFile, model)
5556
{
5657
Load();
57-
58-
DownloadMissingObjectsToGameObjDataCommand = ReactiveCommand.CreateFromTask<GameObjDataFolder, Unit>(async targetFolder =>
59-
{
60-
var folder = model.Settings.GetGameObjDataFolder(targetFolder);
61-
if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
62-
{
63-
logger.Error($"The specified [{targetFolder}] ObjData directory is invalid: \"{folder}\"");
64-
return default;
65-
}
66-
67-
LastGameObjDataFolder = targetFolder;
68-
69-
if (CurrentS5File == null)
70-
{
71-
logger.Error("Current S5File is null");
72-
return default;
73-
}
74-
75-
if (model.ObjectServiceClient == null)
76-
{
77-
logger.Error("The object service client is null");
78-
return default;
79-
}
80-
81-
var gameFolderIndex = ObjectIndex.LoadOrCreateIndex(folder, logger);
82-
83-
if (model.ObjectIndexOnline == null)
84-
{
85-
// need to download the index, ie call /objects/list
86-
logger.Info("Online index doesn't exist - downloading now");
87-
88-
model.ObjectIndexOnline = new ObjectIndex((await Model.ObjectServiceClient.GetObjectListAsync())
89-
.Select(x => new ObjectIndexEntry(x.DisplayName, null, x.Id, x.DatChecksum, null, x.ObjectType, x.ObjectSource, x.CreatedDate, x.ModifiedDate, x.VehicleType)));
90-
91-
logger.Info("Index downloaded");
92-
// technically should check if the index is downloaded and valid now
93-
}
94-
95-
foreach (var obj in CurrentS5File.RequiredObjects)
96-
{
97-
if (gameFolderIndex.Objects.Contains(x => x.DisplayName == obj.Name && x.DatChecksum == obj.Checksum))
98-
{
99-
continue;
100-
}
101-
102-
// obj is missing - we need to download
103-
logger.Info($"Scenario {currentFile.DisplayName} has missing {obj.ObjectType} \"{obj.Name}\" with checksum {obj.Checksum}");
104-
105-
var onlineObj = model.ObjectIndexOnline
106-
.Objects
107-
.FirstOrDefault(x => x.DisplayName == obj.Name && x.DatChecksum == obj.Checksum); // ideally would be SingleOrDefault but unfortunately DAT is not unique
108-
109-
if (onlineObj == null)
110-
{
111-
logger.Error("Couldn't find a matching object in the online index");
112-
continue;
113-
}
114-
115-
if (onlineObj.ObjectSource is ObjectSource.LocomotionSteam or ObjectSource.LocomotionGoG)
116-
{
117-
logger.Warning("This is a vanilla object. Cannot download from Object Service - your base game installation may be corrupt");
118-
continue;
119-
}
120-
121-
if (!UniqueObjectId.TryParse(onlineObj.FileName, out var id))
122-
{
123-
// couldn't get the id from the name, which is set into Filename. see FolderTreeViewModel::LoadOnlineDirectoryAsync() for more details
124-
logger.Error("Couldn't get object id from its filename");
125-
continue;
126-
}
127-
128-
// download actual file
129-
var downloadedObjBytes = await model.ObjectServiceClient.GetObjectFileAsync(id);
130-
131-
if (downloadedObjBytes == null)
132-
{
133-
logger.Error("Downloaded bytes was null");
134-
continue;
135-
}
136-
137-
// write file to the selected directory
138-
var filename = $"{Path.Combine(folder, onlineObj.DisplayName ?? onlineObj.FileName)}-{onlineObj.Id}.dat";
139-
140-
if (File.Exists(filename))
141-
{
142-
logger.Warning($"{filename} already exists - will NOT overwrite it");
143-
continue;
144-
}
145-
146-
logger.Info($"Writing file to {filename}");
147-
148-
await File.WriteAllBytesAsync(filename, downloadedObjBytes);
149-
}
150-
151-
return default;
152-
});
153-
}
154-
155-
void DownloadMissingObjectsToGameFolder(GameObjDataFolder targetFolder)
156-
{
157-
58+
DownloadMissingObjectsToGameObjDataCommand = ReactiveCommand.CreateFromTask<GameObjDataFolder>(DownloadMissingObjects);
15859
}
15960

16061
public override void Load()
@@ -190,6 +91,102 @@ public override void Load()
19091
}
19192
}
19293

94+
async Task DownloadMissingObjects(GameObjDataFolder targetFolder)
95+
{
96+
var folder = Model.Settings.GetGameObjDataFolder(targetFolder);
97+
98+
if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder))
99+
{
100+
logger.Error($"The specified [{targetFolder}] ObjData directory is invalid: \"{folder}\"");
101+
return;
102+
}
103+
104+
LastGameObjDataFolder = targetFolder;
105+
106+
if (CurrentS5File == null)
107+
{
108+
logger.Error("Current S5File is null");
109+
return;
110+
}
111+
112+
if (Model.ObjectServiceClient == null)
113+
{
114+
logger.Error("The object service client is null");
115+
return;
116+
}
117+
118+
var gameFolderIndex = ObjectIndex.LoadOrCreateIndex(folder, logger);
119+
120+
if (Model.ObjectIndexOnline == null)
121+
{
122+
// need to download the index, ie call /objects/list
123+
logger.Info("Online index doesn't exist - downloading now");
124+
125+
Model.ObjectIndexOnline = new ObjectIndex((await Model.ObjectServiceClient.GetObjectListAsync())
126+
.Select(x => new ObjectIndexEntry(x.DisplayName, null, x.Id, x.DatChecksum, null, x.ObjectType, x.ObjectSource, x.CreatedDate, x.ModifiedDate, x.VehicleType)));
127+
128+
logger.Info("Index downloaded");
129+
// technically should check if the index is downloaded and valid now
130+
}
131+
132+
foreach (var obj in CurrentS5File.RequiredObjects)
133+
{
134+
if (OriginalObjectFiles.GetFileSource(obj.Name, obj.Checksum) is ObjectSource.LocomotionSteam or ObjectSource.LocomotionGoG)
135+
{
136+
continue;
137+
}
138+
139+
if (gameFolderIndex.Objects.Contains(x => x.DisplayName == obj.Name && x.DatChecksum == obj.Checksum))
140+
{
141+
continue;
142+
}
143+
144+
// obj is missing - we need to download
145+
logger.Info($"Scenario {CurrentFile.DisplayName} has missing {obj.ObjectType} \"{obj.Name}\" with checksum {obj.Checksum}");
146+
147+
var onlineObj = Model.ObjectIndexOnline
148+
.Objects
149+
.FirstOrDefault(x => x.DisplayName == obj.Name && x.DatChecksum == obj.Checksum); // ideally would be SingleOrDefault but unfortunately DAT is not unique
150+
151+
if (onlineObj == null)
152+
{
153+
logger.Error("Couldn't find a matching object in the online index");
154+
continue;
155+
}
156+
157+
if (onlineObj.Id == null)
158+
{
159+
logger.Error("Downloaded object had no Id - this is a problem with the server");
160+
continue;
161+
}
162+
163+
// download actual file
164+
var downloadedObjBytes = await Model.ObjectServiceClient.GetObjectFileAsync(onlineObj.Id.Value);
165+
166+
if (downloadedObjBytes == null)
167+
{
168+
logger.Error("Downloaded bytes was null");
169+
continue;
170+
}
171+
172+
// write file to the selected directory
173+
var filename = $"{onlineObj.DisplayName ?? onlineObj.FileName}-{onlineObj.Id}.dat";
174+
filename = Path.Combine(folder, filename);
175+
176+
if (File.Exists(filename))
177+
{
178+
logger.Warning($"{filename} already exists - will NOT overwrite it");
179+
continue;
180+
}
181+
182+
logger.Info($"Writing file to {filename}");
183+
184+
await File.WriteAllBytesAsync(filename, downloadedObjBytes);
185+
}
186+
187+
return;
188+
}
189+
193190
void DrawMap()
194191
{
195192
Map = new WriteableBitmap(new Avalonia.PixelSize(384, 384), new Avalonia.Vector(92, 92), Avalonia.Platform.PixelFormat.Rgba8888);

ObjectService/RouteHandlers/TableHandlers/ObjectRouteHandler.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,19 +387,24 @@ static IResult ReturnFile(TblObject? obj, ServerFolderManager sfm, ILogger<Objec
387387
}
388388

389389
var dat = obj.DatObjects.First();
390-
if (!sfm.ObjectIndex.TryFind((dat.DatName, dat.DatChecksum), out var index))
390+
if (!sfm.ObjectIndex.TryFind((dat.DatName, dat.DatChecksum), out var entry) || entry == null)
391391
{
392392
logger.LogDebug("Object {datFile} didn't exist in the object index", dat);
393393
return Results.NotFound();
394394
}
395395

396-
const string contentType = "application/octet-stream";
396+
if (string.IsNullOrEmpty(entry.FileName))
397+
{
398+
logger.LogWarning("Object {datFile} has a null filename - suggest re-indexing the current folder", dat);
399+
return Results.NotFound();
400+
}
397401

398-
var path = Path.Combine(sfm.ObjectsFolder, index!.FileName);
402+
var path = Path.Combine(sfm.ObjectsFolder, entry.FileName);
403+
const string contentType = "application/octet-stream";
399404

400405
if (!File.Exists(path))
401406
{
402-
logger.LogDebug("Object {datFile} existed in the object index but not on disk. ExpectedPath=\"{path}\"", dat, path);
407+
logger.LogWarning("Object {datFile} existed in the object index but not on disk. ExpectedPath=\"{path}\"", dat, path);
403408
}
404409

405410
return Results.File(path, contentType, Path.GetFileName(path));

0 commit comments

Comments
 (0)