-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #73 from winglessraven/web-panel
Add Web Panel Option
- Loading branch information
Showing
8 changed files
with
559 additions
and
17 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace DiscordBotPlugin | ||
{ | ||
internal class ResourceReader | ||
{ | ||
public string ReadResource(string resourceName) | ||
{ | ||
var assembly = Assembly.GetExecutingAssembly(); | ||
|
||
// Resource name should include namespace | ||
string resourcePath = $"{assembly.GetName().Name}.{resourceName}"; | ||
|
||
using (Stream stream = assembly.GetManifestResourceStream(resourcePath)) | ||
{ | ||
if (stream == null) | ||
throw new FileNotFoundException($"Resource {resourceName} not found."); | ||
|
||
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8)) | ||
{ | ||
return reader.ReadToEnd(); | ||
} | ||
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Server Info Dashboard</title> | ||
<link rel="stylesheet" href="styles.css"> | ||
</head> | ||
<body> | ||
|
||
<div class="server-info"> | ||
<div class="status"> | ||
<h2>Server Status</h2> | ||
<p class="{{statusClass}}">{{status}}</p> | ||
</div> | ||
<div class="details"> | ||
<h2>Server Name</h2> | ||
<code id="server-name" onclick="copyToClipboard('server-name')"></code> | ||
</div> | ||
<div class="details"> | ||
<h2>Server IP</h2> | ||
<code id="server-ip" onclick="copyToClipboard('server-ip')"></code> | ||
</div> | ||
|
||
<div class="flex-container"> | ||
<div class="flex-item"> | ||
<h2>CPU Usage</h2> | ||
<p id="cpu-usage"></p> | ||
</div> | ||
<div class="flex-item"> | ||
<h2>Memory Usage</h2> | ||
<p id="memory-usage"></p> | ||
</div> | ||
<div class="flex-item"> | ||
<h2>Uptime</h2> | ||
<p id="uptime"></p> | ||
</div> | ||
</div> | ||
|
||
<!-- Containers for Online Players and Player Count --> | ||
<div id="online-players-container" class="flex-container" style="display: none;"> | ||
<div class="flex-item"> | ||
<!-- Players will be added here by script.js --> | ||
</div> | ||
</div> | ||
|
||
<div id="player-count-container" class="flex-container" style="display: none;"> | ||
<div class="flex-item"> | ||
<h2>Player Count</h2> | ||
<p id="player-count"></p> | ||
</div> | ||
</div> | ||
|
||
<div class="details"> | ||
<h2>Top 5 Players by Play Time</h2> | ||
<ol id="playtime-leaderboard"> | ||
<!-- Playtime leaderboard entries will be added here --> | ||
</ol> | ||
</div> | ||
</div> | ||
|
||
<script src="script.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"ServerName": "", | ||
"ServerIP": "", | ||
"ServerStatus": "", | ||
"ServerStatusClass": "", | ||
"CPUUsage": "", | ||
"MemoryUsage": "", | ||
"Uptime": "", | ||
"OnlinePlayers": [ | ||
"" | ||
], | ||
"PlayerCount": "", | ||
"PlaytimeLeaderBoard": [ | ||
"" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
function copyToClipboard(elementId) { | ||
var textElement = document.getElementById(elementId); | ||
var text = textElement.innerText; | ||
navigator.clipboard.writeText(text).then(function () { | ||
// Change text to "Copied to Clipboard" | ||
textElement.textContent = 'Copied to Clipboard'; | ||
setTimeout(function () { | ||
// Revert back to the original text | ||
textElement.textContent = text; | ||
}, 2000); // after 2 seconds | ||
}, function (err) { | ||
console.error('Could not copy text: ', err); | ||
}); | ||
} | ||
|
||
function incrementTime(timeString) { | ||
let [days, hours, minutes, seconds] = timeString.split(':').map(Number); | ||
seconds += 1; | ||
if (seconds >= 60) { | ||
seconds = 0; | ||
minutes += 1; | ||
if (minutes >= 60) { | ||
minutes = 0; | ||
hours += 1; | ||
if (hours >= 24) { | ||
hours = 0; | ||
days += 1; | ||
} | ||
} | ||
} | ||
return [ | ||
days.toString().padStart(2, '0'), | ||
hours.toString().padStart(2, '0'), | ||
minutes.toString().padStart(2, '0'), | ||
seconds.toString().padStart(2, '0') | ||
].join(':'); | ||
} | ||
|
||
function updateUptime() { | ||
const statusElement = document.querySelector('.status p'); // Get the current status | ||
const uptimeElement = document.getElementById('uptime'); | ||
|
||
// Check if the status text is "Ready" before incrementing the uptime | ||
if (statusElement && statusElement.textContent.includes('Ready')) { | ||
uptimeElement.textContent = incrementTime(uptimeElement.textContent); | ||
} | ||
} | ||
|
||
setInterval(updateUptime, 1000); // Call updateUptime every second | ||
|
||
let currentData = {}; // Variable to store the latest fetched data | ||
|
||
function fetchDataAndUpdateUI() { | ||
fetch('panel.json') | ||
.then(response => response.json()) | ||
.then(data => { | ||
currentData = data; // Store the latest data | ||
updateUI(data); | ||
}) | ||
.catch(error => console.error('Error fetching data:', error)); | ||
} | ||
|
||
function updateUI(data) { | ||
// Update elements based on JSON data | ||
document.getElementById('server-name').textContent = data.ServerName; | ||
document.getElementById('server-ip').textContent = data.ServerIP; | ||
document.querySelector('.status p').className = data.ServerStatusClass; | ||
document.querySelector('.status p').textContent = data.ServerStatus; | ||
document.getElementById('cpu-usage').textContent = data.CPUUsage; | ||
document.getElementById('memory-usage').textContent = data.MemoryUsage; | ||
document.getElementById('uptime').textContent = data.Uptime; | ||
|
||
console.log("Updating Online Players in UI"); | ||
const onlinePlayersContainer = document.getElementById('online-players-container'); | ||
if (data.OnlinePlayers && data.OnlinePlayers.length > 0) { | ||
console.log(`Online players from JSON: ${data.OnlinePlayers.join(', ')}`); | ||
onlinePlayersContainer.style.display = 'block'; | ||
const onlinePlayersList = onlinePlayersContainer.querySelector('.flex-item'); | ||
onlinePlayersList.innerHTML = '<h2>Online Players</h2>' + data.OnlinePlayers.map(player => `<p>${player}</p>`).join(''); | ||
} else { | ||
onlinePlayersContainer.style.display = 'none'; | ||
} | ||
|
||
// Update Player Count | ||
const playerCountContainer = document.getElementById('player-count-container'); | ||
if (data.PlayerCount) { | ||
playerCountContainer.style.display = 'block'; | ||
document.getElementById('player-count').textContent = data.PlayerCount; | ||
} else { | ||
playerCountContainer.style.display = 'none'; | ||
} | ||
|
||
// Update Playtime Leaderboard | ||
if (data.PlaytimeLeaderBoard && data.PlaytimeLeaderBoard.length > 0) { | ||
const playtimeLeaderboardList = document.getElementById('playtime-leaderboard'); | ||
playtimeLeaderboardList.innerHTML = data.PlaytimeLeaderBoard.map(entry => `<li>${entry}</li>`).join(''); | ||
} | ||
} | ||
|
||
// Function to increment player playtime in 'Xd Xh Xm Xs' format | ||
function incrementPlayerPlaytime(playtimeString) { | ||
let [days, hours, minutes, seconds] = playtimeString.split(/d |h |m |s/).map(Number); | ||
seconds++; | ||
if (seconds >= 60) { | ||
seconds = 0; | ||
minutes++; | ||
if (minutes >= 60) { | ||
minutes = 0; | ||
hours++; | ||
if (hours >= 24) { | ||
hours = 0; | ||
days++; | ||
} | ||
} | ||
} | ||
return `${days}d ${hours}h ${minutes}m ${seconds}s`; | ||
} | ||
|
||
// Function to increment playtime for online players | ||
function incrementPlaytimeForOnlinePlayers() { | ||
//console.log("incrementPlaytimeForOnlinePlayers function called"); | ||
|
||
if (!currentData.OnlinePlayers || currentData.OnlinePlayers.length === 0) { | ||
//console.log("No online players found"); | ||
return; | ||
} | ||
|
||
//console.log(`Found ${currentData.OnlinePlayers.length} online players from JSON`); | ||
|
||
currentData.OnlinePlayers.forEach(playerName => { | ||
//console.log(`Processing player: ${playerName}`); | ||
const playtimeElements = document.querySelectorAll('#playtime-leaderboard li'); | ||
//console.log(`Found ${playtimeElements.length} playtime elements`); | ||
|
||
playtimeElements.forEach(playtimeElement => { | ||
//console.log(`Checking playtime element: ${playtimeElement.textContent}`); | ||
|
||
if (playtimeElement.textContent.includes(playerName)) { | ||
//console.log(`Before Increment - Player: ${playerName}, Playtime: ${playtimeElement.textContent}`); | ||
const parts = playtimeElement.textContent.split(' - '); | ||
const incrementedPlaytime = incrementPlayerPlaytime(parts[1].trim()); | ||
playtimeElement.textContent = `${playerName} - ${incrementedPlaytime}`; | ||
//console.log(`After Increment - Player: ${playerName}, Playtime: ${playtimeElement.textContent}`); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
// Call this function periodically (e.g., every second) | ||
setInterval(incrementPlaytimeForOnlinePlayers, 1000); | ||
|
||
// Initial call to fetch and update data | ||
fetchDataAndUpdateUI(); | ||
|
||
// Set up interval to update data every 10 seconds | ||
setInterval(fetchDataAndUpdateUI, 10000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
body { | ||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | ||
/*background-color: #23272a;*/ | ||
color: #fff; | ||
margin: 0; /* Removed padding to fit better in an iframe */ | ||
} | ||
|
||
.server-info { | ||
background-color: #23272a; | ||
border-radius: 0px; | ||
padding: 10px; /* Reduced padding for a more compact layout */ | ||
width: 100%; /* Adjust width to 100% for iframe */ | ||
max-width: 380px; /* Adjust max-width if necessary */ | ||
margin: 10px auto; /* Reduced vertical margin */ | ||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | ||
} | ||
|
||
.server-info h2 { | ||
color: #7289da; | ||
font-size: 0.85rem; /* Slightly smaller font size for headings */ | ||
margin-bottom: 3px; /* Reduced margin-bottom */ | ||
} | ||
|
||
.status .ready { | ||
color: #43b581; /* Green for Ready */ | ||
} | ||
|
||
.status .pending { | ||
color: #ffbf00; /* Amber for Pending */ | ||
} | ||
|
||
.status .stopped { | ||
color: #f04747; /* Red for Stopped */ | ||
} | ||
|
||
.details { | ||
margin-bottom: 10px; /* Reduced margin between sections */ | ||
} | ||
|
||
.details h2 { | ||
margin-bottom: 3px; /* Reduced margin-bottom for headings */ | ||
} | ||
|
||
.details code { | ||
display: block; | ||
background-color: #2c2f33; | ||
padding: 3px; /* Reduced padding for code blocks */ | ||
margin-top: 3px; /* Reduced margin-top */ | ||
border-radius: 4px; | ||
font-family: 'Courier New', Courier, monospace; | ||
cursor: pointer; | ||
} | ||
|
||
.flex-container { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: flex-start; | ||
margin-bottom: 10px; /* Reduced margin between flex-items */ | ||
} | ||
|
||
.flex-item { | ||
flex: 1; | ||
padding: 0 5px; /* Maintain padding for separation */ | ||
text-align: left; | ||
} | ||
|
||
.flex-item h2 { | ||
margin-bottom: 3px; /* Reduced margin-bottom for headings */ | ||
} | ||
|
||
.flex-item p { | ||
margin-top: 0; | ||
margin-bottom: 0; | ||
} | ||
|
||
ol { | ||
padding-left: 15px; /* Reduced padding-left for ordered lists */ | ||
margin-top: 0; /* Removed default top margin for ordered lists */ | ||
} | ||
|
||
a { | ||
color: #00b0f4; | ||
text-decoration: none; | ||
} | ||
|
||
a:hover { | ||
text-decoration: underline; | ||
} | ||
|
||
/* If you find the layout still too wide for some iframes, consider adding a custom media query to adjust the max-width at that specific iframe width */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters