diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenserver/frontend/frontend.cpp | 3 | ||||
| -rw-r--r-- | src/zenserver/frontend/html.zip | bin | 116429 -> 119799 bytes | |||
| -rw-r--r-- | src/zenserver/frontend/html/compactbinary.js | 2 | ||||
| -rw-r--r-- | src/zenserver/frontend/html/index.html | 6 | ||||
| -rw-r--r-- | src/zenserver/frontend/html/zen.css | 31 | ||||
| -rw-r--r-- | src/zenserver/frontend/html/zen.js | 278 | ||||
| -rw-r--r-- | src/zenserver/projectstore/projectstore.cpp | 5 |
7 files changed, 221 insertions, 104 deletions
diff --git a/src/zenserver/frontend/frontend.cpp b/src/zenserver/frontend/frontend.cpp index 7ce19363a..31d9e1c94 100644 --- a/src/zenserver/frontend/frontend.cpp +++ b/src/zenserver/frontend/frontend.cpp @@ -133,7 +133,8 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request) // The given content directory overrides any zip-fs discovered in the binary if (!m_Directory.empty()) { - FileContents File = ReadFile(m_Directory / Uri); + auto FullPath = m_Directory / std::filesystem::path(Uri).make_preferred(); + FileContents File = ReadFile(FullPath); if (!File.ErrorCode) { diff --git a/src/zenserver/frontend/html.zip b/src/zenserver/frontend/html.zip Binary files differindex 0edf64c95..cda479fc8 100644 --- a/src/zenserver/frontend/html.zip +++ b/src/zenserver/frontend/html.zip diff --git a/src/zenserver/frontend/html/compactbinary.js b/src/zenserver/frontend/html/compactbinary.js index c648e6052..1247e556d 100644 --- a/src/zenserver/frontend/html/compactbinary.js +++ b/src/zenserver/frontend/html/compactbinary.js @@ -1,3 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + "use strict"; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/zenserver/frontend/html/index.html b/src/zenserver/frontend/html/index.html index 300b8c62e..fad4bf902 100644 --- a/src/zenserver/frontend/html/index.html +++ b/src/zenserver/frontend/html/index.html @@ -2,6 +2,12 @@ <!DOCTYPE html> <html> <head> + <script> + if (window.location.pathname == "/dashboard") + { + window.location.pathname = "/dashboard/"; + } + </script> <link rel="shortcut icon" href="favicon.ico"> <link rel="stylesheet" type="text/css" href="zen.css" /> <script src="compactbinary.js"></script> diff --git a/src/zenserver/frontend/html/zen.css b/src/zenserver/frontend/html/zen.css index 885c58fc4..a725ffb79 100644 --- a/src/zenserver/frontend/html/zen.css +++ b/src/zenserver/frontend/html/zen.css @@ -1,3 +1,5 @@ +/* Copyright Epic Games, Inc. All Rights Reserved. */ + /* page --------------------------------------------------------------------- */ :root { @@ -59,6 +61,10 @@ pre { /* sector ------------------------------------------------------------------- */ +h1, h2, h3 { + white-space: nowrap; +} + h1 { font-size: 1.5em; width: 100%; @@ -91,7 +97,6 @@ h3 { .zen_table { display: grid; - grid-template-columns: max-content repeat(calc(var(--zen_columns) - 1), 1fr); border: 1px solid var(--theme_g2); border-left-style: none; margin-bottom: 1.2em; @@ -110,6 +115,10 @@ h3 { background-color: var(--theme_p3); } +.zen_table > div:hover { + background-color: var(--theme_p4); +} + .zen_table > hidden { visibility: hidden; display: none; @@ -295,11 +304,25 @@ h3 { padding: 1.0em 2em 2em 2em; width: 100%; border-top: 1px solid var(--theme_g0); + display: flex; +} + +#error > div:nth-child(1) { + font-size: 2.5em; + font-weight: bolder; + font-family: serif; + transform: rotate(-13deg); + color: var(--theme_p0); } -#error > pre:nth-child(2) { - font-size: 0.8em; - color: var(--theme_g1); +#error > div:nth-child(2) { + margin-left: 2em; +} + +#error > div:nth-child(2) > pre:nth-child(2) { + margin-top: 0.5em; + font-size: 0.8em; + color: var(--theme_g1); } /* stats -------------------------------------------------------------------- */ diff --git a/src/zenserver/frontend/html/zen.js b/src/zenserver/frontend/html/zen.js index df71cac7b..4d3895d1f 100644 --- a/src/zenserver/frontend/html/zen.js +++ b/src/zenserver/frontend/html/zen.js @@ -1,3 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + "use strict"; //////////////////////////////////////////////////////////////////////////////// @@ -85,9 +87,9 @@ class ComponentDom extends ComponentBase return this; } - css_var(key, value) + style(key, value) { - this._element.style.setProperty("--" + key, value); + this._element.style[key] = value; return this; } @@ -192,21 +194,38 @@ class TableRow extends Component //////////////////////////////////////////////////////////////////////////////// class Table extends Component { - constructor(parent, column_names, index_base=0) + static Flag_EvenSpacing = 1 << 0; + static Flag_PackRight = 1 << 1; + static Flag_BiasLeft = 1 << 2; + static Flag_FitLeft = 1 << 3; + + constructor(parent, column_names, flags=Table.Flag_EvenSpacing, index_base=0) { var root = parent.tag().classify("zen_table"); super(root); - this._index = index_base; + var column_style; + if (flags & Table.Flag_FitLeft) column_style = "max-content"; + else if (flags & Table.Flag_BiasLeft) column_style = "2fr"; + else column_style = "1fr"; + for (var i = 1; i < column_names.length; ++i) + { + const style = (flags & Table.Flag_PackRight) ? " auto" : " 1fr"; + column_style += style; + } + if (index_base >= 0) + { column_names = ["#", ...column_names]; + column_style = "max-content " + column_style; + } - this._num_columns = column_names.length; - root.css_var("zen_columns", this._num_columns); + root.style("gridTemplateColumns", column_style); - this._num_columns = column_names.length; this._add_row(column_names, false); + this._index = index_base; + this._num_columns = column_names.length; this._rows = []; } @@ -251,7 +270,7 @@ class Table extends Component add_row(...args) { - var row = this._add_row(...args); + var row = this._add_row(args); this._rows.push(row); return row; } @@ -272,13 +291,13 @@ class PropTable extends Table { constructor(parent) { - super(parent, ["prop", "value"], -1); + super(parent, ["prop", "value"], Table.Flag_FitLeft, -1); this.classify("zen_proptable"); } add_property(key, value) { - return this.add_row([key, value]); + return this.add_row(key, value); } add_object(object, friendly=false, prec=2) @@ -580,6 +599,14 @@ class ZenPage extends Page zen_store.tag().id("go_home").on_click(() => window.location.search = ""); root.tag("img").attr("src", "favicon.ico").id("ue_logo"); + + /* + _________ _______ __ + \____ /___ ___ / ___// |__ ___ ______ ____ + / __/ __ \ / \ \___ \\_ __// \\_ \/ __ \ + / \ __// | \/ \| | ( - )| |\/\ __/ + /______/\___/\__|__/\______/|__| \___/ |__| \___| + */ } set_title(...args) @@ -654,16 +681,63 @@ class Entry extends ZenPage for (const dep_name in tree) { const dep_section = sub_section.add_section(dep_name); - const table = new Table(dep_section, ["id", "name"]); + const table = new Table(dep_section, ["id", "name"], Table.Flag_FitLeft); for (const dep_id of tree[dep_name]) { const cell_values = [dep_id.toString(16)]; - const row = table.add_row(cell_values); + const row = table.add_row(...cell_values); row.get_cell(0).on_click(() => void(0)); } } } + // data + { + const sub_section = section.add_section("data"); + const table = new Table(sub_section, ["name", "actions"], Table.Flag_PackRight); + for (const field_name of ["packagedata", "bulkdata"]) + { + var pkg_data = entry.find(field_name); + if (pkg_data == undefined) + continue; + + for (const item of pkg_data.as_array()) + { + var io_hash; + var file_name; + for (const field of item.as_object()) + { + if (field.get_name() == "data") io_hash = field.as_value(); + else if (field.get_name() == "filename") file_name = field.as_value(); + } + + if (io_hash instanceof Uint8Array) + { + var ret = ""; + for (var x of io_hash) + ret += x.toString(16).padStart(2, "0"); + io_hash = ret; + } + + const row = table.add_row(file_name); + + const project = this.get_param("project"); + const oplog = this.get_param("oplog"); + const link = row.get_cell(0).link( + "/" + ["prj", project, "oplog", oplog, io_hash].join("/") + ); + + const do_nothing = () => void(0); + const action_tb = new Toolbar(row.get_cell(-1), true); + action_tb.left().add("copy-hash").on_click(async (v) => { + await navigator.clipboard.writeText(v); + }, io_hash); + action_tb.left().add("view"); + action_tb.left().add("drop"); + } + } + } + // props { const object = entry.to_js_object(); @@ -683,23 +757,32 @@ class Entry extends ZenPage if (pkg_id == undefined) continue; - for (var x of pkg_id.as_value().subarray(0, 8)) + pkg_id = pkg_id.as_value().subarray(0, 8); + for (var i = 7; i >= 0; --i) { id <<= 8n; - id |= BigInt(x); + id |= BigInt(pkg_id[i]); } break; } tree["$id"] = id; const pkgst_entry = entry.find("packagestoreentry").as_object(); - const imported = pkgst_entry.find("importedpackageids"); - if (imported == undefined) - return tree; - var out = tree["imported"] = []; - for (var item of imported.as_array()) - out.push(item.as_value(BigInt)); + for (const field of pkgst_entry) + { + const field_name = field.get_name() + if (!field_name.endsWith("importedpackageids")) + continue; + + var dep_name = field_name.slice(0, -18); + if (dep_name.length == 0) + dep_name = "imported"; + + var out = tree[dep_name] = []; + for (var item of field.as_array()) + out.push(item.as_value(BigInt)); + } return tree; } @@ -772,9 +855,7 @@ class Oplog extends ZenPage for (const entry of entries) { - var row = this._entry_table.add_row([ - entry["key"] - ]); + var row = this._entry_table.add_row(entry["key"]); row.get_cell(0).link("", { "page" : "entry", @@ -826,16 +907,20 @@ class Project extends ZenPage // oplog section = this.add_section("oplogs"); - var oplog_table = new Table(section, ["name", "actions"]) + var oplog_table = new Table( + section, + ["name", "marker", "size", "ops", "expired", "actions"], + Table.Flag_PackRight + ) var count = 0; for (const oplog of info["oplogs"]) { const name = oplog["id"]; - var row = oplog_table.add_row([ - name, - ]); + var info = new Fetcher().resource("prj", project, "oplog", name).json(); + + var row = oplog_table.add_row(name); var cell = row.get_cell(0); cell.link("", { @@ -847,6 +932,12 @@ class Project extends ZenPage cell = row.get_cell(-1); var action_tb = new Toolbar(cell, true); action_tb.left().add("drop").on_click((x) => this.drop_oplog(x), name); + + info = await info; + row.get_cell(1).text(Friendly.sep(info["markerpath"])); + row.get_cell(2).text(Friendly.kib(info["totalsize"])); + row.get_cell(3).text(Friendly.sep(info["opcount"])); + row.get_cell(4).text(Friendly.sep(info["expired"])); } } @@ -906,22 +997,43 @@ class Test extends ZenPage const cols = [gen_word(), gen_word(), gen_word(), gen_word()]; var tables = [ new Table(section0, cols), - new Table(section1, cols, 5), - new Table(section2, cols, -1), + new Table(section1, cols, Table.Flag_EvenSpacing, 5), + new Table(section2, cols, Table.Flag_EvenSpacing, -1), ]; for (const table of tables) { - table.add_row([gen_word()]); - table.add_row([gen_word(), gen_word(), gen_word(), gen_word()]); - table.add_row([gen_word(), gen_word(), gen_para(15, 25), gen_word(), gen_word(), gen_word(), gen_word(), gen_word()]); + table.add_row(gen_word()); + table.add_row(gen_word(), gen_word(), gen_word(), gen_word()); + table.add_row(gen_word(), gen_word(), gen_para(15, 25), gen_word(), gen_word(), gen_word(), gen_word(), gen_word()); + } + + // spacing tests + { + const spacing_section = section0.add_section("spacing"); + const flags = { + "EvenSpacing" : Table.Flag_EvenSpacing, + "EvenSpacing|BiasLeft" : Table.Flag_EvenSpacing | Table.Flag_BiasLeft, + "PackRight" : Table.Flag_PackRight, + }; + for (const flag_name in flags) + { + const flag = flags[flag_name]; + const another_table = new Table( + spacing_section, + [flag_name, gen_word(), gen_word(), gen_word(), gen_word()], + flag, + ); + for (var i = 0; i < 3; ++i) + another_table.add_row(gen_para(1, 5), gen_para(1, 3), gen_word(), gen_word(), gen_word()); + } } // prop-table var pt_section = section0.add_section("prop-table") var prop_table = new PropTable(pt_section); for (var i = 0; i < 7; ++i) - prop_table.add_property(gen_word(), gen_para(1, 14, "/")); + prop_table.add_property(gen_word(), gen_para(1, 20, "/")); // misc const misc_section = section0.add_section("misc").add_section("misc"); @@ -956,38 +1068,9 @@ class Test extends ZenPage toolbar.right().add("tbitem2").on_click(tb_item_clicked, 33, -55); toolbar.right().add("tbitem3").on_click(tb_item_clicked, 44, -88); - this._cbo_test(); - // error throw Error("deliberate error"); } - - async _cbo_test() - { - var data = new Uint8Array(await (await fetch("/prj/list")).arrayBuffer()); - for (var item of new CbObject(data).as_array()) - { - for (var subitem of item.as_object()) - { - console.log(subitem.get_name(), subitem.as_value()); - } - } - - data = new Uint8Array(await (await fetch("/stats")).arrayBuffer()); - { - var item = new CbObject(data).as_object().find("providers").as_array(); - console.log(item.num()); - for (var subitem of item) - { - console.log(subitem.as_value()); - data = new Uint8Array(await (await fetch("/stats/" + subitem.as_value())).arrayBuffer()); - for (var ssitem of new CbObject(data).as_object()) - { - console.log(ssitem.get_name(), ssitem.as_value()); - } - } - } - } } @@ -1010,11 +1093,11 @@ class Start extends ZenPage for (const project of await new Fetcher().resource("/prj/list").json()) { - var row = table.add_row([ + var row = table.add_row( "", project.ProjectRootDir, project.EngineRootDir, - ]); + ); var cell = row.get_cell(0); cell.tag().text(project.Id).on_click((x) => this.view_project(x), project.Id); @@ -1034,7 +1117,7 @@ class Start extends ZenPage "size mem", "cid total", ]; - const stats_table = new Table(section, columns); + const stats_table = new Table(section, columns, Table.Flag_PackRight); var providers = new Fetcher().resource("stats").json(); for (var provider of (await providers)["providers"]) { @@ -1048,7 +1131,7 @@ class Start extends ZenPage values.push(stats.cid.size.total); } catch {} - row = stats_table.add_row(values); + row = stats_table.add_row(...values); row.get_cell(0).tag().text(provider).on_click((x) => this.view_stat(x), provider); } } @@ -1153,10 +1236,8 @@ class Stat extends ZenPage tb_right.add("-none-").on_click((x) => this.update_filter("")); for (var preset of ["read.", "write.", ".request", ".bytes"]) tb_right.add(preset).on_click((x) => this.update_filter(x), preset); - { - var input = tb_right.add("", "input") - input.on("change", (x) => this.update_filter(x.inner().value), input); - } + this._filter_input = tb_right.add("", "input") + this._filter_input.on("change", (x) => this.update_filter(x.inner().value), this._filter_input); this._table = new PropTable(section); @@ -1170,10 +1251,11 @@ class Stat extends ZenPage toolbar.left().add(name).on_click((x) => this.view_category(x), name); } + var filter = this.get_param("filter"); + first = this.get_param("view", first); this.view_category(first); - var filter = this.get_param("filter"); if (filter) this.update_filter(filter); } @@ -1184,11 +1266,13 @@ class Stat extends ZenPage this._table.clear(); this._table.add_object(this._stats[name], friendly, 3); this.set_param("view", name); - this.set_param("filter", ""); + this.update_filter(""); } update_filter(needle) { + this._filter_input.attr("value", needle); + this.set_param("filter", needle); if (!needle) return this._table.filter(); @@ -1226,7 +1310,29 @@ class Stat extends ZenPage //////////////////////////////////////////////////////////////////////////////// -async function main_guarded() +function display_error(message, stack) +{ + const pane = new Component(document.body).tag().id("error"); + pane.tag().text("!"); + const content = pane.tag(); + content.tag("pre").text(message); + content.tag("pre").text(stack); +} + +window.addEventListener("error", function(evt) { + const reason = evt.error; + display_error(reason.message, reason.stack); +}); + +window.addEventListener("unhandledrejection", function(evt) { + const reason = evt.reason; + display_error(reason.message, reason.stack); +}); + + + +//////////////////////////////////////////////////////////////////////////////// +async function main() { const params = new URLSearchParams(window.location.search); const page = params.get("page"); @@ -1248,29 +1354,5 @@ async function main_guarded() return; } - return impl.main(); + impl.main(); } - -//////////////////////////////////////////////////////////////////////////////// -async function main() -{ - try - { - return await main_guarded(); - } - catch (e) - { - var pane = new Component(document.body).tag().id("error"); - pane.tag("pre").text(e); - pane.tag("pre").text(e.stack); - throw e; - } -} - -/* -_________ _______ __ -\____ /___ ___ / ___// |__ ___ ______ ____ - / __/ __ \ / \ \___ \\_ __// \\_ \/ __ \ - / \ __// | \/ \| | ( - )| |\/\ __/ -/______/\___/\__|__/\______/|__| \___/ |__| \___| -*/ diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp index a5bd1859b..0e6b2d3c9 100644 --- a/src/zenserver/projectstore/projectstore.cpp +++ b/src/zenserver/projectstore/projectstore.cpp @@ -3065,7 +3065,10 @@ ProjectStore::Project::ScanForOplogs() const Oplogs.reserve(DirContent.Directories.size()); for (const std::filesystem::path& DirPath : DirContent.Directories) { - Oplogs.push_back(DirPath.filename().string()); + if (Oplog::ExistsAt(DirPath)) + { + Oplogs.push_back(DirPath.filename().string()); + } } } |