Skip to content

Commit 80e48b2

Browse files
committed
[Savestates] Implement info command from LoTAS-Light
1 parent 3350160 commit 80e48b2

File tree

3 files changed

+185
-19
lines changed

3 files changed

+185
-19
lines changed

src/main/java/com/minecrafttas/tasmod/commands/CommandSavestate.java

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
package com.minecrafttas.tasmod.commands;
22

3+
import java.text.SimpleDateFormat;
34
import java.util.ArrayList;
45
import java.util.Arrays;
56
import java.util.List;
7+
import java.util.function.UnaryOperator;
68
import java.util.regex.Pattern;
79

810
import com.minecrafttas.tasmod.TASmod;
11+
import com.minecrafttas.tasmod.TASmodClient;
912
import com.minecrafttas.tasmod.networking.TASmodBufferBuilder;
13+
import com.minecrafttas.tasmod.registries.TASmodConfig;
1014
import com.minecrafttas.tasmod.registries.TASmodPackets;
1115
import com.minecrafttas.tasmod.savestates.SavestateHandlerServer.SavestateCallback;
16+
import com.minecrafttas.tasmod.savestates.SavestateIndexer.FailedSavestate;
1217
import com.minecrafttas.tasmod.savestates.SavestateIndexer.Savestate;
1318
import com.minecrafttas.tasmod.savestates.exceptions.LoadstateException;
1419
import com.minecrafttas.tasmod.savestates.exceptions.SavestateDeleteException;
1520
import com.minecrafttas.tasmod.savestates.exceptions.SavestateException;
21+
import com.minecrafttas.tasmod.util.Component;
22+
import com.minecrafttas.tasmod.util.Component.CClickEvent;
23+
import com.minecrafttas.tasmod.util.Component.CHoverEvent;
24+
import com.minecrafttas.tasmod.util.I18n;
1625
import com.minecrafttas.tasmod.util.LoggerMarkers;
1726

1827
import net.minecraft.command.CommandBase;
@@ -22,10 +31,16 @@
2231
import net.minecraft.entity.player.EntityPlayerMP;
2332
import net.minecraft.server.MinecraftServer;
2433
import net.minecraft.util.math.BlockPos;
34+
import net.minecraft.util.text.Style;
2535
import net.minecraft.util.text.TextComponentString;
36+
import net.minecraft.util.text.TextFormatting;
37+
import net.minecraft.util.text.event.ClickEvent;
38+
import net.minecraft.util.text.event.HoverEvent;
2639

2740
public class CommandSavestate extends CommandBase {
2841

42+
public static boolean once = true;
43+
2944
@Override
3045
public String getName() {
3146
return "savestate";
@@ -264,15 +279,129 @@ else if ("info".equals(first)) {
264279

265280
private void info(ICommandSender sender) {
266281
TASmod.LOGGER.trace(LoggerMarkers.Savestate, "Command Info");
267-
282+
infoIndexAmount(sender, null, null);
268283
}
269284

270-
private void infoIndex(ICommandSender sender, int index) {
285+
private void infoIndex(ICommandSender sender, Integer index) {
271286
TASmod.LOGGER.trace(LoggerMarkers.Savestate, "Command InfoIndex {}", index);
287+
infoIndexAmount(sender, index, null);
272288
}
273289

274-
private void infoIndexAmount(ICommandSender sender, int index, int amount) {
275-
TASmod.LOGGER.trace(LoggerMarkers.Savestate, "Command InfoIndexAmount {}|{}", index, amount);
290+
private void infoIndexAmount(ICommandSender sender, Integer indexToDisplay, Integer amount) {
291+
TASmod.LOGGER.trace(LoggerMarkers.Savestate, "Command InfoIndexAmount {}|{}", indexToDisplay, amount);
292+
293+
int currentIndex = TASmod.savestateHandlerServer.getCurrentIndex();
294+
int size = TASmod.savestateHandlerServer.size();
295+
if (indexToDisplay == null) {
296+
indexToDisplay = currentIndex;
297+
}
298+
if (amount == null) {
299+
amount = 10;
300+
}
301+
302+
sender.sendMessage(Component.literal("").build()); // Print an empty line
303+
304+
String format = I18n.format("msg.tasmod.savestate.dateformat");
305+
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
306+
307+
List<Savestate> savestateList = TASmod.savestateHandlerServer.getSavestateInfo(indexToDisplay, amount);
308+
309+
if (savestateList.size() < size && once) {
310+
sender.sendMessage(Component.translatable("gui.tasmod.savestate.omitted", "/savestate info all").withStyle(TextFormatting.RED, TextFormatting.ITALIC).build());
311+
once = false;
312+
}
313+
314+
for (Savestate savestate : savestateList) {
315+
316+
String index = savestate.getIndex() == null ? "" : Integer.toString(savestate.getIndex());
317+
boolean isCurrentIndex = savestate.getIndex() == currentIndex;
318+
String name = savestate.getName() == null ? "" : savestate.getName();
319+
String date = savestate.getDate() == null ? "" : dateFormat.format(savestate.getDate());
320+
321+
TextFormatting indexColor = isCurrentIndex ? TextFormatting.AQUA : TextFormatting.BLUE;
322+
TextFormatting nameColor = isCurrentIndex ? TextFormatting.WHITE : TextFormatting.GRAY;
323+
TextFormatting dateColor = isCurrentIndex ? TextFormatting.AQUA : TextFormatting.DARK_AQUA;
324+
TextFormatting saveColor = isCurrentIndex ? TextFormatting.LIGHT_PURPLE : TextFormatting.DARK_PURPLE;
325+
TextFormatting deleteColor = isCurrentIndex ? TextFormatting.RED : TextFormatting.DARK_RED;
326+
TextFormatting renameColor = isCurrentIndex ? TextFormatting.YELLOW : TextFormatting.GOLD;
327+
TextFormatting loadColor = isCurrentIndex ? TextFormatting.GREEN : TextFormatting.DARK_GREEN;
328+
329+
//@formatter:off
330+
UnaryOperator<Style> hover = t ->
331+
t.setHoverEvent (
332+
CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.literal(date).withStyle(dateColor))
333+
);
334+
335+
Component msg = null;
336+
337+
if(savestate instanceof FailedSavestate) {
338+
FailedSavestate failedSavestate = (FailedSavestate) savestate;
339+
msg = Component.translatable("%s: %s%s",
340+
Component.literal(index).withStyle(indexColor),
341+
Component.literal(name).withStyle(nameColor),
342+
Component.translatable("msg.tasmod.savestate.info.error", failedSavestate.getError().getMessage())
343+
.withStyle(TextFormatting.RED))
344+
.withStyle(t ->
345+
t.setHoverEvent(
346+
CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.literal(date).withStyle(TextFormatting.GOLD)
347+
)));
348+
} else {
349+
if(!TASmodClient.config.getBoolean(TASmodConfig.SAVESTATE_SHOW_CONTROLS)) {
350+
msg = Component.translatable("%s: %s",
351+
Component.literal(index).withStyle(indexColor),
352+
Component.literal(name).withStyle(nameColor))
353+
.withStyle(hover);
354+
355+
}
356+
else {
357+
Component saveComponent = Component.translatable("msg.tasmod.savestate.save.clickable").withStyle(saveColor)
358+
.withStyle(t->
359+
t.setHoverEvent(
360+
CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.translatable("msg.tasmod.savestate.save.hover", name).withStyle(saveColor)))
361+
)
362+
.withStyle(t->
363+
t.setClickEvent(
364+
CClickEvent.create(ClickEvent.Action.SUGGEST_COMMAND, String.format("/savestate save %s", index)))
365+
);
366+
367+
Component deleteComponent = Component.translatable("msg.tasmod.savestate.delete.clickable").withStyle(deleteColor)
368+
.withStyle(t->
369+
t.setClickEvent(CClickEvent.create(ClickEvent.Action.SUGGEST_COMMAND, String.format("/savestate delete %s", index)))
370+
)
371+
.withStyle(t->
372+
t.setHoverEvent(CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.translatable("msg.tasmod.savestate.delete.hover", name).withStyle(deleteColor)))
373+
);
374+
375+
Component renameComponent = Component.translatable("msg.tasmod.savestate.rename.clickable").withStyle(renameColor)
376+
.withStyle(t->
377+
t.setClickEvent(CClickEvent.create(ClickEvent.Action.SUGGEST_COMMAND, String.format("/savestate rename %s", index)))
378+
)
379+
.withStyle(t->
380+
t.setHoverEvent(CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.translatable("msg.tasmod.savestate.rename.hover", name).withStyle(renameColor)))
381+
);
382+
383+
Component loadComponent = Component.translatable("msg.tasmod.savestate.load.clickable").withStyle(loadColor)
384+
.withStyle(t->
385+
t.setClickEvent(CClickEvent.create(ClickEvent.Action.SUGGEST_COMMAND, String.format("/savestate load %s", index)))
386+
)
387+
.withStyle(t->
388+
t.setHoverEvent(CHoverEvent.create(HoverEvent.Action.SHOW_TEXT, Component.translatable("msg.tasmod.savestate.load.hover", name).withStyle(loadColor)))
389+
);
390+
391+
msg = Component.translatable("%s: %s %s %s %s %s",
392+
Component.literal(index).withStyle(indexColor),
393+
Component.literal(name).withStyle(nameColor),
394+
Component.wrap(saveComponent, nameColor),
395+
Component.wrap(deleteComponent, nameColor),
396+
Component.wrap(renameComponent, nameColor),
397+
Component.wrap(loadComponent, nameColor)
398+
).withStyle(hover);
399+
}
400+
}
401+
402+
//@formatter:on
403+
sender.sendMessage(msg.build());
404+
}
276405
}
277406

278407
private void infoAll(ICommandSender sender) {

src/main/java/com/minecrafttas/tasmod/registries/TASmodConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
public enum TASmodConfig implements ConfigOptions {
1111
FileToOpen("fileToOpen", ""),
1212
ServerConnection("serverConnection", ""),
13-
EnabledFileCommands("enabledFileCommands", "tasmod_desyncMonitor@v1, tasmod_label@v1, tasmod_options@v1");
13+
EnabledFileCommands("enabledFileCommands", "tasmod_desyncMonitor@v1, tasmod_label@v1, tasmod_options@v1"),
14+
SAVESTATE_SHOW_CONTROLS("savestateShowControls", "true");
1415

1516
private String configKey;
1617
private String defaultValue;

src/main/java/com/minecrafttas/tasmod/util/Component.java

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import net.minecraft.util.text.TextComponentString;
88
import net.minecraft.util.text.TextComponentTranslation;
99
import net.minecraft.util.text.TextFormatting;
10+
import net.minecraft.util.text.event.ClickEvent;
11+
import net.minecraft.util.text.event.HoverEvent;
1012

1113
/**
1214
* 1.20 Style Component library backported to 1.12
@@ -16,19 +18,53 @@
1618
public class Component {
1719

1820
private final ITextComponent component;
19-
private final Style style = new Style();
21+
private Style style = new Style();
2022

2123
private Component(ITextComponent component) {
2224
this.component = component;
2325
}
2426

25-
public Component withStyle(TextFormatting color) {
26-
style.setColor(color);
27+
public Component withStyle(TextFormatting... colors) {
28+
for (TextFormatting color : colors) {
29+
switch (color) {
30+
case BOLD:
31+
style.setBold(true);
32+
break;
33+
34+
case ITALIC:
35+
style.setItalic(true);
36+
break;
37+
38+
case UNDERLINE:
39+
style.setUnderlined(true);
40+
break;
41+
42+
case STRIKETHROUGH:
43+
style.setStrikethrough(true);
44+
break;
45+
46+
case OBFUSCATED:
47+
style.setObfuscated(true);
48+
break;
49+
50+
case RESET:
51+
style.setBold(false);
52+
style.setItalic(false);
53+
style.setUnderlined(false);
54+
style.setStrikethrough(false);
55+
style.setObfuscated(false);
56+
style.setColor(TextFormatting.WHITE);
57+
break;
58+
default:
59+
style.setColor(color);
60+
break;
61+
}
62+
}
2763
return this;
2864
}
2965

3066
public Component withStyle(UnaryOperator<Style> unaryOperator) {
31-
unaryOperator.apply(style);
67+
style = unaryOperator.apply(style);
3268
return this;
3369
}
3470

@@ -54,23 +90,23 @@ public static Component translatable(String string, Object... objects) {
5490
return new Component(new TextComponentTranslation(string, objects));
5591
}
5692

57-
public static Component wrap(ITextComponent component, TextFormatting color) {
58-
return wrap(component).withStyle(color);
93+
public static Component wrap(Component saveComponent, TextFormatting color) {
94+
return wrap(saveComponent).withStyle(color);
5995
}
6096

61-
public static Component wrap(ITextComponent component) {
62-
return Component.literal(String.format("[%]", component.getFormattedText()));
97+
public static Component wrap(Component component) {
98+
return Component.literal(String.format("[%s]", component.build().getFormattedText()));
6399
}
64100

65-
public static class ClickEvent {
66-
public static net.minecraft.util.text.event.ClickEvent create(net.minecraft.util.text.event.ClickEvent.Action action, String string) {
67-
return new net.minecraft.util.text.event.ClickEvent(action, string);
101+
public static class CClickEvent {
102+
public static ClickEvent create(ClickEvent.Action action, String string) {
103+
return new ClickEvent(action, string);
68104
}
69105
}
70106

71-
public static class HoverEvent {
72-
public static net.minecraft.util.text.event.HoverEvent create(net.minecraft.util.text.event.HoverEvent.Action action, ITextComponent string) {
73-
return new net.minecraft.util.text.event.HoverEvent(action, string);
107+
public static class CHoverEvent {
108+
public static HoverEvent create(HoverEvent.Action action, Component component) {
109+
return new HoverEvent(action, component.build());
74110
}
75111
}
76112
}

0 commit comments

Comments
 (0)