sourcecode upload

This commit is contained in:
uttili 2025-11-12 08:36:16 +00:00
parent 87372179a9
commit acedb6ead2
3 changed files with 437 additions and 0 deletions

70
html/app.js Normal file
View File

@ -0,0 +1,70 @@
window.addEventListener("message", (event) => {
switch (event.data.action) {
case "open":
open(event.data);
break;
case "close":
close();
break;
case "setup":
setup(event.data);
break;
}
});
const open = (data) => {
const scoreboard = document.querySelector(".scoreboard-block");
scoreboard.style.display = "block";
const totalPlayers = document.getElementById("total-players");
if (totalPlayers) {
totalPlayers.innerHTML = `<p>${data.players} of ${data.maxPlayers}</p>`;
}
Object.entries(data.requiredCops).forEach(([category, info]) => {
const beam = document.querySelector(`.scoreboard-info [data-type="${category}"]`);
if (!beam) return;
const status = beam.querySelector(".info-beam-status");
if (!status) return;
if (info.busy) {
status.innerHTML = "⏳";
} else if (data.currentCops >= info.minimumPolice) {
status.innerHTML = "✅";
} else {
status.innerHTML = "❌";
}
});
};
const close = () => {
const scoreboard = document.querySelector(".scoreboard-block");
scoreboard.style.display = "flex";
};
const setup = (data) => {
const scoreboardInfo = document.querySelector(".scoreboard-info");
if (!scoreboardInfo) return;
scoreboardInfo.innerHTML = "";
Object.entries(data.items).forEach(([index, value]) => {
const beamElement = document.createElement("div");
beamElement.className = "scoreboard-info-beam";
beamElement.setAttribute("data-type", index);
const titleElement = document.createElement("div");
titleElement.className = "info-beam-title";
titleElement.innerHTML = `<p>${value}</p>`;
const statusElement = document.createElement("div");
statusElement.className = "info-beam-status";
beamElement.appendChild(titleElement);
beamElement.appendChild(statusElement);
scoreboardInfo.appendChild(beamElement);
});
const playersBeam = document.createElement("div");
playersBeam.className = "scoreboard-info-beam";
const playersTitle = document.createElement("div");
playersTitle.className = "info-beam-title";
playersTitle.innerHTML = "<p>Total Players</p>";
const playersStatus = document.createElement("div");
playersStatus.className = "info-beam-status";
playersStatus.id = "total-players";
playersBeam.appendChild(playersTitle);
playersBeam.appendChild(playersStatus);
scoreboardInfo.appendChild(playersBeam);
};

145
html/style.css Normal file
View File

@ -0,0 +1,145 @@
@import url("https://fonts.googleapis.com/css2?family=Exo+2:wght@300;400;500;600;700&display=swap");
:root {
--md-dark-primary: #f44336;
--md-dark-on-primary: #ffffff;
--md-dark-primary-container: #ffdad6;
--md-dark-on-primary-container: #410002;
--md-dark-secondary: #d32f2f;
--md-dark-on-secondary: #ffffff;
--md-dark-secondary-container: #ffdad5;
--md-dark-on-secondary-container: #410001;
--md-dark-tertiary: #ff8a65;
--md-dark-on-tertiary: #ffffff;
--md-dark-tertiary-container: #ffdacc;
--md-dark-on-tertiary-container: #410002;
--md-dark-surface: #1c1b1f;
--md-dark-on-surface: #e6e1e5;
--md-dark-surface-container-lowest: #0f0d13;
--md-dark-surface-container-low: #1d1b20;
--md-dark-surface-container: #211f26;
--md-dark-surface-container-high: #2b2930;
--md-dark-surface-container-highest: #36343b;
--md-dark-error: #b3261e;
--md-dark-on-error: #ffffff;
--md-dark-error-container: #93000a;
--md-dark-on-error-container: #ffdad5;
--md-dark-outline: #79747e;
--md-dark-outline-variant: #49454f;
--md-dark-inverse-surface: #e6e1e5;
--md-dark-inverse-on-surface: #1c1b1f;
--md-dark-scrim: rgba(0, 0, 0, 0.6);
--md-dark-shadow: rgba(0, 0, 0, 0.15);
--md-dark-success: #9bd880;
--md-dark-on-success: #193800;
--md-dark-success-container: #275000;
--md-dark-on-success-container: #b6f397;
--md-dark-warning: #ffba47;
--md-dark-on-warning: #422b00;
--md-dark-warning-container: #5f3f00;
--md-dark-on-warning-container: #ffddb0;
--md-dark-info: #b3c5ff;
--md-dark-on-info: #002a77;
--md-dark-info-container: #003ea7;
--md-dark-on-info-container: #dae1ff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Exo 2", sans-serif;
}
body {
height: 100vh;
width: 100vw;
overflow: hidden;
}
.container {
height: 100%;
width: 100%;
display: flex;
justify-content: flex-end;
align-items: flex-start;
padding: 3vh;
}
.scoreboard-block {
display: none;
width: 30vh;
background-color: var(--md-dark-surface-container-high);
overflow: hidden;
box-shadow: 0 4px 8px var(--md-dark-shadow);
margin-top: 30vh;
margin-top: 5vh; /* 30vh から変更 */
max-height: 90vh; /* 新規追加 */
display: flex; /* 新規追加 */
flex-direction: column; /* 新規追加 */
}
.scoreboard-header {
width: 100%;
background: var(--md-dark-primary);
padding: 1.5vh;
text-align: center;
}
.scoreboard-header p {
font-weight: 700;
color: var(--md-dark-on-primary);
font-size: 2.5vh;
}
.scoreboard-info {
display: flex;
flex-direction: column;
width: 100%;
overflow-y: auto; /* 新規追加 */
flex: 1; /* 新規追加 */
}
.scoreboard-info-beam {
display: flex;
justify-content: space-between;
align-items: center;
height: 4.25vh;
width: 100%;
background-color: var(--md-dark-surface-container);
padding: 0 2.7vh 0 2.7vh;
border-bottom: 1px solid var(--md-dark-surface-container-lowest);
}
.info-beam-title,
.info-beam-title-players {
font-size: 1.3vh;
letter-spacing: 0.1vh;
font-weight: 700;
color: var(--md-dark-on-surface);
}
.info-beam-status {
text-align: right;
display: flex;
align-items: center;
justify-content: center;
}
.info-beam-status p {
color: var(--md-dark-on-surface);
font-size: 1.3vh;
}
.scoreboard-info::-webkit-scrollbar {
width: 6px;
}
.scoreboard-info::-webkit-scrollbar-track {
background: var(--md-dark-surface-container-lowest);
}
.scoreboard-info::-webkit-scrollbar-thumb {
background: var(--md-dark-outline);
border-radius: 3px;
}

222
html/ui.html Normal file
View File

@ -0,0 +1,222 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>QBCore Scoreboard</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Exo+2:wght@300;400;500;600;700&display=swap");
:root {
--md-dark-primary: #f44336;
--md-dark-on-primary: #ffffff;
--md-dark-primary-container: #ffdad6;
--md-dark-on-primary-container: #410002;
--md-dark-secondary: #d32f2f;
--md-dark-on-secondary: #ffffff;
--md-dark-secondary-container: #ffdad5;
--md-dark-on-secondary-container: #410001;
--md-dark-tertiary: #ff8a65;
--md-dark-on-tertiary: #ffffff;
--md-dark-tertiary-container: #ffdacc;
--md-dark-on-tertiary-container: #410002;
--md-dark-surface: #1c1b1f;
--md-dark-on-surface: #e6e1e5;
--md-dark-surface-container-lowest: #0f0d13;
--md-dark-surface-container-low: #1d1b20;
--md-dark-surface-container: #211f26;
--md-dark-surface-container-high: #2b2930;
--md-dark-surface-container-highest: #36343b;
--md-dark-error: #b3261e;
--md-dark-on-error: #ffffff;
--md-dark-error-container: #93000a;
--md-dark-on-error-container: #ffdad5;
--md-dark-outline: #79747e;
--md-dark-outline-variant: #49454f;
--md-dark-inverse-surface: #e6e1e5;
--md-dark-inverse-on-surface: #1c1b1f;
--md-dark-scrim: rgba(0, 0, 0, 0.6);
--md-dark-shadow: rgba(0, 0, 0, 0.15);
--md-dark-success: #9bd880;
--md-dark-on-success: #193800;
--md-dark-success-container: #275000;
--md-dark-on-success-container: #b6f397;
--md-dark-warning: #ffba47;
--md-dark-on-warning: #422b00;
--md-dark-warning-container: #5f3f00;
--md-dark-on-warning-container: #ffddb0;
--md-dark-info: #b3c5ff;
--md-dark-on-info: #002a77;
--md-dark-info-container: #003ea7;
--md-dark-on-info-container: #dae1ff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Exo 2", sans-serif;
}
body {
height: 100vh;
width: 100vw;
overflow: hidden;
}
.container {
height: 100%;
width: 100%;
display: flex;
justify-content: flex-end;
align-items: flex-start;
padding: 3vh;
}
.scoreboard-block {
display: none;
width: 30vh;
background-color: var(--md-dark-surface-container-high);
overflow: hidden;
box-shadow: 0 4px 8px var(--md-dark-shadow);
margin-top: 5vh;
}
.scoreboard-header {
width: 100%;
background: var(--md-dark-primary);
padding: 1vh; /* 1.5vh */
text-align: center;
}
.scoreboard-header p {
font-weight: 700;
color: var(--md-dark-on-primary);
font-size: 2vh; /* 2.5vh */
}
.scoreboard-info {
display: flex;
flex-direction: column;
width: 100%;
}
.scoreboard-info-beam {
display: flex;
justify-content: space-between;
align-items: center;
height: 3.8vh; /* 4.25vh */
width: 100%;
background-color: var(--md-dark-surface-container);
padding: 0 1.9vh 0 1.9vh; /* 2.7vh */
border-bottom: 1px solid var(--md-dark-surface-container-lowest);
}
.info-beam-title,
.info-beam-title-players {
font-size: 1.2vh; /* 1.2vh */
letter-spacing: 0.05vh; /* 0.1vh */
font-weight: 600; /* 700 */
color: var(--md-dark-on-surface);
line-height: 1.1; /* 1.2 */
}
.info-beam-status {
text-align: right;
display: flex;
align-items: center;
justify-content: center;
}
.info-beam-status p {
color: var(--md-dark-on-surface);
font-size: 1.2vh; /* 1.2vh */
}
</style>
</head>
<body>
<div class="container">
<div class="scoreboard-block">
<div class="scoreboard-header">
<p>SERVER INFO</p>
</div>
<div class="scoreboard-info"></div>
</div>
</div>
<script>
window.addEventListener("message", (event) => {
switch (event.data.action) {
case "open":
open(event.data);
break;
case "close":
close();
break;
case "setup":
setup(event.data);
break;
}
});
const open = (data) => {
const scoreboard = document.querySelector(".scoreboard-block");
scoreboard.style.display = "block";
const totalPlayers = document.getElementById("total-players");
if (totalPlayers) {
totalPlayers.innerHTML = `<p>${data.players} of ${data.maxPlayers}</p>`;
}
Object.entries(data.requiredCops).forEach(([category, info]) => {
const beam = document.querySelector(`.scoreboard-info [data-type="${category}"]`);
if (!beam) return;
const status = beam.querySelector(".info-beam-status");
if (!status) return;
if (info.busy) {
status.innerHTML = "⏳";
} else if (data.currentCops >= info.minimumPolice) {
status.innerHTML = "✅";
} else {
status.innerHTML = "❌";
}
});
};
const close = () => {
const scoreboard = document.querySelector(".scoreboard-block");
scoreboard.style.display = "none";
};
const setup = (data) => {
const scoreboardInfo = document.querySelector(".scoreboard-info");
if (!scoreboardInfo) return;
scoreboardInfo.innerHTML = "";
Object.entries(data.items).forEach(([index, value]) => {
const beamElement = document.createElement("div");
beamElement.className = "scoreboard-info-beam";
beamElement.setAttribute("data-type", index);
const titleElement = document.createElement("div");
titleElement.className = "info-beam-title";
titleElement.innerHTML = `<p>${value}</p>`;
const statusElement = document.createElement("div");
statusElement.className = "info-beam-status";
beamElement.appendChild(titleElement);
beamElement.appendChild(statusElement);
scoreboardInfo.appendChild(beamElement);
});
const playersBeam = document.createElement("div");
playersBeam.className = "scoreboard-info-beam";
const playersTitle = document.createElement("div");
playersTitle.className = "info-beam-title";
playersTitle.innerHTML = "<p>Total Players</p>";
const playersStatus = document.createElement("div");
playersStatus.className = "info-beam-status";
playersStatus.id = "total-players";
playersBeam.appendChild(playersTitle);
playersBeam.appendChild(playersStatus);
scoreboardInfo.appendChild(playersBeam);
};
</script>
</body>
</html>