Skip to content

Commit cba2b19

Browse files
committed
Make Hypertale's dashboard more fun!
1 parent a72e3dd commit cba2b19

10 files changed

Lines changed: 125 additions & 11 deletions

File tree

launcher/src/main/java/com/fox2code/hypertale/dashboard/HypertaleDashboard.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
package com.fox2code.hypertale.dashboard;
2525

2626
import com.fox2code.hypertale.launcher.BuildConfig;
27+
import com.fox2code.hypertale.loader.HypertaleConfig;
28+
import com.fox2code.hypertale.loader.HypertaleIcons;
2729
import com.fox2code.hypertale.utils.HypertaleTextUtil;
2830
import com.fox2code.hypertale.utils.HypertaleUptimeManager;
2931
import com.fox2code.hypertale.utils.HypertaleUptimeReceiver;
@@ -79,13 +81,14 @@ public void build(@NonNull Ref<EntityStore> ref, @NonNull UICommandBuilder comma
7981
commandBuilder.set("#Description.Text", "Hypertale " + BuildConfig.HYPERTALE_VERSION + "\n" +
8082
"Running Hytale " + HytaleVersion.HYTALE_VERSION);
8183
long uptime = Instant.now().getEpochSecond() - HytaleServer.get().getBoot().getEpochSecond();
82-
buildUpdate(commandBuilder, uptime, HypertaleTextUtil.makeUptimeString(uptime));
84+
buildUpdate(commandBuilder, uptime, HypertaleTextUtil.makeUptimeString(uptime), true);
8385
HypertaleUptimeManager.addUptimeListener(this);
8486
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating,
8587
"#CloseButton", new EventData());
8688
}
8789

88-
public static void buildUpdate(@NonNull UICommandBuilder commandBuilder, long uptime, @NonNull String uptimeText) {
90+
public static void buildUpdate(@NonNull UICommandBuilder commandBuilder, long uptime,
91+
@NonNull String uptimeText, boolean building) {
8992
commandBuilder.set("#StatPlayers.Text", String.valueOf(Universe.get().getPlayerCount()));
9093
commandBuilder.set("#StatUptime.Text", uptimeText);
9194
commandBuilder.set("#StatUptime.Style", uptime >= TIME_48_HOURS ? labelSevere :
@@ -108,6 +111,53 @@ public static void buildUpdate(@NonNull UICommandBuilder commandBuilder, long up
108111
(ramUsagePercent > 95.0D || freeMemory < MEM_128MB) ? labelSevere :
109112
(ramUsagePercent > 90.0 || freeMemory < MEM_512MB) ? labelSerious :
110113
(ramUsagePercent > 80.0 || freeMemory < MEM_1536MB) ? labelWarn : labelFine);
114+
if (building) {
115+
if (HypertaleConfig.disableFox2CodeIcons) {
116+
commandBuilder.set("#Fox2CodeIndicator.Visible", false);
117+
return;
118+
}
119+
if (uptime < TIME_1_MINUTE) {
120+
commandBuilder.set("#Fox2CodeIndicator.Background", HypertaleIcons.FOX2WOW_ICON);
121+
return;
122+
}
123+
// For the warning level icon, the level are calculated slightly differently.
124+
int[] condition = new int[4]; // {warn, serious, severe, verySevere}
125+
addCond(condition, uptime >= TIME_48_HOURS ? 2 :
126+
uptime >= TIME_24_HOURS ? 1 : 0);
127+
addCond(condition, cpuLoad >= 0.95D ? 4 : cpuLoad >= 0.9D ? 3 :
128+
cpuLoad >= 0.75D ? 2 : cpuLoad >= 0.5D ? 1 : 0);
129+
addCond(condition, (ramUsagePercent > 95.0D || freeMemory < MEM_128MB) ? 4 :
130+
(ramUsagePercent > 90.0 || freeMemory < MEM_512MB) ? 3 :
131+
(ramUsagePercent > 80.0 || freeMemory < MEM_1536MB) ? 1 : 0);
132+
int warningLevel = condition.length - 1;
133+
while (warningLevel-->0) {
134+
if (condition[warningLevel] > 2 || condition[warningLevel + 1] != 0) {
135+
break;
136+
}
137+
}
138+
warningLevel++;
139+
if (warningLevel == 0 && condition[0] != 0) {
140+
// The heart icon is only for when everything is fine!
141+
warningLevel = 1;
142+
}
143+
commandBuilder.set("#Fox2CodeIndicator.Background", switch (warningLevel) {
144+
case 3 -> HypertaleIcons.FOX2XX_ICON;
145+
case 2 -> HypertaleIcons.FOX2PANIC_ICON;
146+
case 1 -> HypertaleIcons.FOX2PRR2_ICON;
147+
case 0 -> HypertaleIcons.FOX2HEART2_ICON;
148+
default -> HypertaleIcons.FOX2WOW_ICON;
149+
});
150+
}
151+
}
152+
153+
private static void addCond(int[] condition, int conditionType) {
154+
switch (conditionType) {
155+
case 4: condition[3]++; // fall through
156+
case 3: condition[2]++; // fall through
157+
case 2: condition[1]++; // fall through
158+
case 1: condition[0]++; // fall through
159+
case 0: break;
160+
}
111161
}
112162

113163
@Override
@@ -119,7 +169,7 @@ public void handleDataEvent(@NonNull Ref<EntityStore> ref, @NonNull Store<Entity
119169
@Override
120170
public void onReceiveUptime(long uptime, String uptimeText) {
121171
UICommandBuilder commandBuilder = new UICommandBuilder();
122-
buildUpdate(commandBuilder, uptime, uptimeText);
172+
buildUpdate(commandBuilder, uptime, uptimeText, false);
123173
// This works exactly like sendUpdate except it supports async calling
124174
this.cachedPageManager.updateCustomPage(new CustomPage(
125175
this.getClass().getName(), false, false,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2026 Fox2Code
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package com.fox2code.hypertale.loader;
25+
26+
public final class HypertaleIcons {
27+
// Icons of me from TheLazySense are still owned by TheLazySense, while I have a commercial license for the icons,
28+
// the commercial license is not transferable to other peoples.
29+
//
30+
// So you must remove or replace the icons when making a paid or commercial fork of Hypertale.
31+
private static final String THE_LAZY_SENSE_PATH = "Fox2Code/Copyrighted/TheLazySense/";
32+
33+
public static final String FOX2HEART2_ICON = THE_LAZY_SENSE_PATH + "Fox2Heart2.png";
34+
public static final String FOX2PANIC_ICON = THE_LAZY_SENSE_PATH + "Fox2Panic.png";
35+
public static final String FOX2PRR2_ICON = THE_LAZY_SENSE_PATH + "Fox2Prr2.png";
36+
public static final String FOX2WOW_ICON = THE_LAZY_SENSE_PATH + "Fox2Wow.png";
37+
public static final String FOX2XX_ICON = THE_LAZY_SENSE_PATH + "Fox2XX.png";
38+
39+
private HypertaleIcons() {}
40+
}
206 KB
Loading
181 KB
Loading
241 KB
Loading
226 KB
Loading
218 KB
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Legal copyright notice
2+
3+
The material copyright is owned by TheLazySense, while I (Fox2Code) have a license to use it commercially,
4+
this license is not transferable, as such, any commercial/paid fork of Hypertale must remove or replace these assets.
5+
6+
If you want to get icons of your own character, you can contact the artist and ask for additional copy of the icons!
7+
8+
VGen: https://vgen.co/thelazysense

launcher/src/main/resources/Common/UI/Custom/Pages/HypertaleDashboard.ui

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ $C = "../Common.ui";
22
$Theme = "HypertaleTheme.ui";
33

44
Group {
5-
Anchor: (Width: 600, Height: 400);
5+
Anchor: (Width: 800, Height: 500);
66
LayoutMode: Left;
77

88
Group #LeftPanel {
@@ -55,7 +55,7 @@ Group {
5555
FlexWeight: 1;
5656
Background: #141c26(0.98);
5757
LayoutMode: Top;
58-
Padding: (Full: 20);
58+
Padding: (Top: 20, Bottom: 0, Left: 20, Right: 20);
5959

6060
Label #PanelTitle {
6161
Text: "Overview";
@@ -157,13 +157,28 @@ Group {
157157
Group { FlexWeight: 1; }
158158

159159
Group {
160-
LayoutMode: Right;
161-
Anchor: (Height: 40);
160+
Anchor: (Height: 100);
161+
162+
Group {
163+
LayoutMode: Left;
164+
Anchor: (Height: 100);
165+
166+
Group #Fox2CodeIndicator {
167+
Anchor: (Height: 100, Width: 100);
168+
Background: #777777;
169+
}
170+
}
162171

163-
TextButton #CloseButton {
164-
Text: "CLOSE";
165-
Anchor: (Width: 100, Height: 36);
166-
Style: $Theme.@CloseButtonStyle;
172+
Group {
173+
LayoutMode: Right;
174+
Anchor: (Height: 40);
175+
Padding: (Top: 40, Bottom: 20);
176+
177+
TextButton #CloseButton {
178+
Text: "CLOSE";
179+
Anchor: (Width: 100, Height: 36);
180+
Style: $Theme.@CloseButtonStyle;
181+
}
167182
}
168183
}
169184
}

patcher/src/main/java/com/fox2code/hypertale/loader/HypertaleConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public final class HypertaleConfig {
4141
public static String hytaleBranch = "release";
4242
public static String secondaryJarName = "Server.jar";
4343
public static boolean allowDownloadLibraries = true; // Tell if Hypertale is allowed to download libraries
44+
public static boolean disableFox2CodeIcons = false; // Tell if Fox2Code icons should be disabled.
4445
public static boolean optimizePluginOnlyAPIs = true; // Tell if plugin-only APIs should be optimized
4546
public static boolean aggressivelyOptimizePluginOnlyAPIs = false; // Tell if APIs are allowed to change semantics
4647
public static boolean unsupportedDisablePluginServerVersionCheck = false; // Disable plugin server version check

0 commit comments

Comments
 (0)