diff options
| author | Stefan Boberg <[email protected]> | 2023-06-16 17:02:23 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-06-16 17:02:23 +0200 |
| commit | 86418ed57c677ffc8ce314acfcf9b9f1eab3586b (patch) | |
| tree | d197ea40f2e8255338c806a27e82ae289a33bf68 /src/zenserver | |
| parent | added ZenServerInstance::SpawnServerAndWait (#334) (diff) | |
| download | zen-86418ed57c677ffc8ce314acfcf9b9f1eab3586b.tar.xz zen-86418ed57c677ffc8ce314acfcf9b9f1eab3586b.zip | |
file share support (#328)
this change adds a serve command to the zen CLI. This can be used to establish links to a set of files which may be served to clients via the project store interface:
```cmd> zen serve Lyra/WindowsClient d:\temp_share\StagedBuilds\WindowsClient```
with the appropriate changes in UE you may then start an instance of the runtime and have it load all files via the remote file connection:
```
Lyra\Binaries\LyraClient.exe ../../../Lyra/Lyra.uproject -pak -basedir=D:\temp_share\StagedBuilds\WindowsClient/Lyra/Binaries/Win64 -Mount=Lyra/WindowsClient
```
Diffstat (limited to 'src/zenserver')
| -rw-r--r-- | src/zenserver/projectstore/httpprojectstore.cpp | 39 | ||||
| -rw-r--r-- | src/zenserver/projectstore/projectstore.cpp | 33 | ||||
| -rw-r--r-- | src/zenserver/projectstore/projectstore.h | 13 |
3 files changed, 47 insertions, 38 deletions
diff --git a/src/zenserver/projectstore/httpprojectstore.cpp b/src/zenserver/projectstore/httpprojectstore.cpp index b0efb6bec..185f2783d 100644 --- a/src/zenserver/projectstore/httpprojectstore.cpp +++ b/src/zenserver/projectstore/httpprojectstore.cpp @@ -758,14 +758,23 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects, if (!legacy::TryLoadCbPackage(Package, Payload, &UniqueBuffer::Alloc, &Resolver)) { - std::filesystem::path BadPackagePath = - Oplog.TempPath() / "bad_packages"sv / fmt::format("session{}_request{}"sv, HttpReq.SessionId(), HttpReq.RequestId()); + if (CbObject Core = LoadCompactBinaryObject(Payload)) + { + Package.SetObject(Core); + } + else + { + std::filesystem::path BadPackagePath = Oplog.TempPath() / "bad_packages"sv / + fmt::format("session{}_request{}"sv, HttpReq.SessionId(), HttpReq.RequestId()); - ZEN_WARN("Received malformed package! Saving payload to '{}'", BadPackagePath); + ZEN_WARN("Received malformed package! Saving payload to '{}'", BadPackagePath); - WriteFile(BadPackagePath, Payload); + WriteFile(BadPackagePath, Payload); - return HttpReq.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid package"); + return HttpReq.WriteResponse(HttpResponseCode::BadRequest, + HttpContentType::kText, + u8"request body must be a compact binary object or package in legacy format"); + } } if (!IsValid) @@ -1056,20 +1065,20 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects, return HttpReq.WriteResponse(HttpResponseCode::InsufficientStorage); } - IoBuffer Payload = HttpReq.ReadPayload(); - CbObject Params = LoadCompactBinaryObject(Payload); - std::string_view Id = Params["id"sv].AsString(); - std::string_view Root = Params["root"sv].AsString(); - std::string_view EngineRoot = Params["engine"sv].AsString(); - std::string_view ProjectRoot = Params["project"sv].AsString(); - std::string_view ProjectFilePath = Params["projectfile"sv].AsString(); + IoBuffer Payload = HttpReq.ReadPayload(); + CbObject Params = LoadCompactBinaryObject(Payload); + std::string_view Root = Params["root"sv].AsString(); // Workspace root (i.e `D:/UE5/`) + std::string_view EngineRoot = Params["engine"sv].AsString(); // Engine root (i.e `D:/UE5/Engine`) + std::string_view ProjectRoot = + Params["project"sv].AsString(); // Project root directory (i.e `D:/UE5/Samples/Games/Lyra`) + std::string_view ProjectFilePath = + Params["projectfile"sv].AsString(); // Project file path (i.e `D:/UE5/Samples/Games/Lyra/Lyra.uproject`) const std::filesystem::path BasePath = m_ProjectStore->BasePath() / ProjectId; m_ProjectStore->NewProject(BasePath, ProjectId, Root, EngineRoot, ProjectRoot, ProjectFilePath); - ZEN_INFO("established project - {} (id: '{}', roots: '{}', '{}', '{}', '{}'{})", + ZEN_INFO("established project (id: '{}', roots: '{}', '{}', '{}', '{}'{})", ProjectId, - Id, Root, EngineRoot, ProjectRoot, @@ -1496,4 +1505,4 @@ HttpProjectService::HandleStatsRequest(HttpServerRequest& HttpReq) return HttpReq.WriteResponse(HttpResponseCode::OK, Cbo.Save()); } -} // namespace zen
\ No newline at end of file +} // namespace zen diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp index 6ca43af0e..184376c39 100644 --- a/src/zenserver/projectstore/projectstore.cpp +++ b/src/zenserver/projectstore/projectstore.cpp @@ -574,8 +574,7 @@ ProjectStore::Oplog::ReplayLog() { return; } - m_Storage->ReplayLog( - [&](CbObject Op, const OplogEntry& OpEntry) { RegisterOplogEntry(OplogLock, GetMapping(Op), OpEntry, kUpdateReplay); }); + m_Storage->ReplayLog([&](CbObject Op, const OplogEntry& OpEntry) { RegisterOplogEntry(OplogLock, GetMapping(Op), OpEntry); }); } IoBuffer @@ -774,21 +773,20 @@ ProjectStore::Oplog::AddFileMapping(const RwLock::ExclusiveLockScope&, std::string_view ServerPath, std::string_view ClientPath) { + FileMapEntry Entry; + if (Hash != IoHash::Zero) { m_ChunkMap.insert_or_assign(FileId, Hash); } + else + { + Entry.ServerPath = ServerPath; + } - FileMapEntry Entry; - Entry.ServerPath = ServerPath; Entry.ClientPath = ClientPath; m_FileMap[FileId] = std::move(Entry); - - if (Hash != IoHash::Zero) - { - m_ChunkMap.insert_or_assign(FileId, Hash); - } } void @@ -858,8 +856,7 @@ ProjectStore::Oplog::GetMapping(CbObject Core) Oid Id = FileObj["id"sv].AsObjectId(); IoHash Hash = FileObj["data"sv].AsBinaryAttachment(); - Result.Files.emplace_back( - OplogEntryMapping::FileMapping{OplogEntryMapping::Mapping{Id, Hash}, std::string(ServerPath), std::string(ClientPath)}); + Result.Files.emplace_back(OplogEntryMapping::FileMapping{Id, Hash, std::string(ServerPath), std::string(ClientPath)}); ZEN_DEBUG("file {} -> {}, ServerPath: {}, ClientPath: {}", Id, Hash, ServerPath, ClientPath); } @@ -881,13 +878,10 @@ ProjectStore::Oplog::GetMapping(CbObject Core) uint32_t ProjectStore::Oplog::RegisterOplogEntry(RwLock::ExclusiveLockScope& OplogLock, const OplogEntryMapping& OpMapping, - const OplogEntry& OpEntry, - UpdateType TypeOfUpdate) + const OplogEntry& OpEntry) { ZEN_TRACE_CPU("ProjectStore::Oplog::RegisterOplogEntry"); - ZEN_UNUSED(TypeOfUpdate); - // For now we're assuming the update is all in-memory so we can hold an exclusive lock without causing // too many problems. Longer term we'll probably want to ensure we can do concurrent updates however @@ -986,7 +980,7 @@ ProjectStore::Oplog::AppendNewOplogEntry(CbObject Core) const OplogEntry OpEntry = m_Storage->AppendOp(Buffer, OpCoreHash, KeyHash); RwLock::ExclusiveLockScope OplogLock(m_OplogLock); - const uint32_t EntryId = RegisterOplogEntry(OplogLock, Mapping, OpEntry, kUpdateNewEntry); + const uint32_t EntryId = RegisterOplogEntry(OplogLock, Mapping, OpEntry); return EntryId; } @@ -1904,7 +1898,7 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin Response.BeginObject(); Response << "id"sv << Id; Response << "clientpath"sv << ClientPath; - if (!FilterClient) + if (!FilterClient && !ServerPath.empty()) { Response << "serverpath"sv << ServerPath; } @@ -2519,6 +2513,11 @@ ProjectStore::Rpc(HttpServerRequest& HttpReq, return true; } + else if (Field.GetName() == "serverpath"sv) + { + // omit this field as it's not relevant if there is a hash + return true; + } return false; }); diff --git a/src/zenserver/projectstore/projectstore.h b/src/zenserver/projectstore/projectstore.h index 8b5369e98..c9816ec55 100644 --- a/src/zenserver/projectstore/projectstore.h +++ b/src/zenserver/projectstore/projectstore.h @@ -166,11 +166,15 @@ public: Oid Id; IoHash Hash; }; - struct FileMapping : public Mapping + + struct FileMapping { - std::string ServerPath; + Oid Id; + IoHash Hash; // This is either zero or a cid + std::string ServerPath; // If Hash is valid then this should be empty std::string ClientPath; }; + std::vector<Mapping> Chunks; std::vector<Mapping> Meta; std::vector<FileMapping> Files; @@ -184,10 +188,7 @@ public: * * Returns the oplog LSN assigned to the new entry, or kInvalidOp if the entry is rejected */ - uint32_t RegisterOplogEntry(RwLock::ExclusiveLockScope& OplogLock, - const OplogEntryMapping& OpMapping, - const OplogEntry& OpEntry, - UpdateType TypeOfUpdate); + uint32_t RegisterOplogEntry(RwLock::ExclusiveLockScope& OplogLock, const OplogEntryMapping& OpMapping, const OplogEntry& OpEntry); void AddFileMapping(const RwLock::ExclusiveLockScope& OplogLock, Oid FileId, |