mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-08 13:53:45 +00:00
feat(dashboard): UGC lists paged with totals, prefix search and sorting; car and rocket assemblies
IUgcLookup::ListUgc pages either kind with the UGC search's matching, a state and a sort, and counts the matches (MySQL and SQLite share the SQL). The UGC server records each model's bricks and triangles (new ugc columns) so models can be sorted by size. Cars and rockets are listed as assemblies, one per combination of modules, with their build type, module names and how many builds use them; filters for type, state, module and owner. Each assembly's builds (with where they are) are paged, and a build's assembly can be looked up for links. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -222,6 +222,7 @@ public:
|
||||
|
||||
// IUgcLookup
|
||||
std::vector<UgcEntry> SearchUgc(const UgcSearch& search, const uint32_t limit) override;
|
||||
std::pair<std::vector<UgcEntry>, uint64_t> ListUgc(const eUgcKind kind, const UgcListQuery& query) override;
|
||||
std::vector<UgcEntry> GetUgcEntries(const std::vector<LWOOBJID>& ids) override;
|
||||
std::vector<UgcPlacement> GetUgcPlacements(const std::vector<LWOOBJID>& ugcIds) override;
|
||||
std::vector<UgcMail> GetUgcMail(const std::vector<LWOOBJID>& subkeys, const LOT modelItemLot) override;
|
||||
@@ -427,6 +428,7 @@ public:
|
||||
void SetUgcIconSettings(const std::string_view target, const std::string_view params) override;
|
||||
void DeleteUgcIconSettings(const std::string_view target) override;
|
||||
void SetUgcModelProcessed(const LWOOBJID id, const eProcessState state, const uint32_t attempts, const std::string_view error, const bool bakeAo) override;
|
||||
void SetUgcModelStats(const LWOOBJID id, const uint32_t bricks, const uint32_t triangles) override;
|
||||
std::optional<IUgc::ProcessInfo> GetUgcProcessInfo(const LWOOBJID id) override;
|
||||
uint64_t ResetUgcModelProcessing(const std::optional<LWOOBJID> id, const bool failedOnly) override;
|
||||
std::vector<IUgc::ProcessInfo> GetUgcProcessList(const std::optional<eProcessState> state, const std::string_view search, const uint32_t offset, const uint32_t limit) override;
|
||||
|
||||
@@ -177,3 +177,7 @@ void MySQLDatabase::ExpediteUgcModel(const LWOOBJID id) {
|
||||
void MySQLDatabase::ExpediteUgcModels(const LWOOBJID characterId) {
|
||||
ExecuteUpdate("UPDATE ugc SET process_after = 0 WHERE character_id = ? AND is_optimized = 0 AND process_after > 0;", characterId);
|
||||
}
|
||||
|
||||
void MySQLDatabase::SetUgcModelStats(const LWOOBJID id, const uint32_t bricks, const uint32_t triangles) {
|
||||
ExecuteUpdate("UPDATE ugc SET brick_count = ?, triangle_count = ? WHERE id = ?;", bricks, triangles, id);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ namespace {
|
||||
entry.state = static_cast<IUgc::eProcessState>(result->getInt("is_optimized"));
|
||||
entry.error = std::string(result->getString("process_error").c_str());
|
||||
entry.detail = std::string(result->getString("detail").c_str());
|
||||
entry.attempts = static_cast<uint32_t>(result->getInt("process_attempts"));
|
||||
entry.processedAt = result->getInt64("processed_at");
|
||||
entry.processAfter = result->getInt64("process_after");
|
||||
entry.bakeAo = result->getInt("bake_ao") != 0;
|
||||
entry.bricks = static_cast<uint32_t>(result->getInt64("brick_count"));
|
||||
entry.triangles = static_cast<uint32_t>(result->getInt64("triangle_count"));
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
@@ -75,3 +81,26 @@ std::vector<IUgcLookup::UgcMail> MySQLDatabase::GetUgcMail(const std::vector<LWO
|
||||
}
|
||||
return mail;
|
||||
}
|
||||
|
||||
std::pair<std::vector<IUgcLookup::UgcEntry>, uint64_t> MySQLDatabase::ListUgc(const eUgcKind kind, const UgcListQuery& query) {
|
||||
const bool modular = kind == eUgcKind::MODULAR;
|
||||
const std::string pattern = "%" + query.search.text + "%";
|
||||
const bool searching = UgcLookupSql::Searching(query.search);
|
||||
const auto where = (searching ? UgcLookupSql::Where(query.search, modular) : std::string("WHERE 1=1 ")) + UgcLookupSql::ListFilter(query, modular);
|
||||
std::vector<UgcEntry> entries;
|
||||
uint64_t total = 0;
|
||||
const auto page = UgcLookupSql::Select(modular) + where + UgcLookupSql::ListOrder(query, modular) + "LIMIT ? OFFSET ?;";
|
||||
const auto count = "SELECT COUNT(*) AS n " + UgcLookupSql::From(modular) + where + ";";
|
||||
if (searching) {
|
||||
auto result = ExecuteSelect(page, pattern, pattern, pattern, pattern, pattern, pattern, query.limit, query.offset);
|
||||
while (result->next()) entries.push_back(ReadEntry(result, kind));
|
||||
auto counted = ExecuteSelect(count, pattern, pattern, pattern, pattern, pattern, pattern);
|
||||
if (counted->next()) total = static_cast<uint64_t>(counted->getInt64("n"));
|
||||
} else {
|
||||
auto result = ExecuteSelect(page, query.limit, query.offset);
|
||||
while (result->next()) entries.push_back(ReadEntry(result, kind));
|
||||
auto counted = ExecuteSelect(count);
|
||||
if (counted->next()) total = static_cast<uint64_t>(counted->getInt64("n"));
|
||||
}
|
||||
return { entries, total };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user