aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-06-16 17:02:23 +0200
committerGitHub <[email protected]>2023-06-16 17:02:23 +0200
commit86418ed57c677ffc8ce314acfcf9b9f1eab3586b (patch)
treed197ea40f2e8255338c806a27e82ae289a33bf68 /src/zenserver
parentadded ZenServerInstance::SpawnServerAndWait (#334) (diff)
downloadzen-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.cpp39
-rw-r--r--src/zenserver/projectstore/projectstore.cpp33
-rw-r--r--src/zenserver/projectstore/projectstore.h13
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,