Skip to content

Commit

Permalink
Tip编辑器:
Browse files Browse the repository at this point in the history
1.添加了将内容转换为翻译键值并复制到剪贴板的功能;
2.添加了将当前编辑的提示发送给所有玩家的功能
  • Loading branch information
goumo committed Jan 14, 2025
1 parent 0b829f9 commit 7e7398f
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 42 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/teammoeg/frostedheart/FHNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import com.teammoeg.frostedheart.content.steamenergy.HeatNetworkRequestC2SPacket;
import com.teammoeg.frostedheart.content.steamenergy.HeatNetworkResponseS2CPacket;
import com.teammoeg.frostedheart.content.tips.network.DisplayCustomTipPacket;
import com.teammoeg.frostedheart.content.tips.network.DisplayCustomTipRequestPacket;
import com.teammoeg.frostedheart.content.tips.network.DisplayTipPacket;
import com.teammoeg.frostedheart.content.town.TeamTownDataS2CPacket;
import com.teammoeg.frostedheart.content.trade.network.BargainRequestPacket;
Expand Down Expand Up @@ -197,6 +198,7 @@ public static void register() {
// Tip Messages
registerMessage("single_tip", DisplayTipPacket.class);
registerMessage("custom_tip", DisplayCustomTipPacket.class);
registerMessage("display_request", DisplayCustomTipRequestPacket.class);

// Waypoint Messages
registerMessage("waypoint_remove", WaypointRemovePacket.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.teammoeg.frostedheart.base.client.gui.widget;

import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.NotNull;

/**
* 按下后显示另一条信息的 IconButton
*/
public class ActionStateIconButton extends IconButton {
private final Component originalMessage;
@Getter
@Setter
private Component clickedMessage;

public ActionStateIconButton(int x, int y, Icon icon, int color, Component message, Component clickedMessage, OnPress pressedAction) {
this(x, y, icon, color, 1, message, clickedMessage, pressedAction);
}

public ActionStateIconButton(int x, int y, Icon icon, int color, int scale, Component message, Component clickedMessage, OnPress pressedAction) {
super(x, y, icon, color, scale, message, pressedAction);
this.originalMessage = message;
this.clickedMessage = clickedMessage;
}

@Override
public void renderWidget(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
super.renderWidget(graphics, mouseX, mouseY, partialTicks);
if (!isHovered()) {
setMessage(originalMessage);
}
}

@Override
public void onClick(double pMouseX, double pMouseY) {
super.onClick(pMouseX, pMouseY);
setMessage(clickedMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void renderWidget(@NotNull GuiGraphics graphics, int mouseX, int mouseY,
PoseStack pose = graphics.pose();
pose.pushPose();
pose.translate(1, 1, 0);
graphics.fill(getX()+getWidth()+2, getY(), getX()+getWidth()+getHeight()+2, getY()+getHeight(), FHColorHelper.makeDark(getColorValue(), 0.25F));
graphics.fill(getX()+getWidth()+2, getY(), getX()+getWidth()+getHeight()+2, getY()+getHeight(), FHColorHelper.makeDark(getColorValue(), 0.75F));
pose.translate(-1, -1, 0);
graphics.fill(getX()+getWidth()+2, getY(), getX()+getWidth()+getHeight()+2, getY()+getHeight(), getColorValue());
pose.popPose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ public IconButton(int x, int y, Icon icon, int color, int scale, Component title

@Override
public void renderWidget(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
int color = isActive() ? this.color : 0xFF666666;
int backgroundColor = FHColorHelper.makeDark(color, 0.3F);
float alpha = 0.5F;
if (isHoveredOrFocused()) {
graphics.fill(getX(), getY(), getX()+getWidth(), getY()+getHeight(), FHColorHelper.setAlpha(color, 50));
graphics.fill(getX(), getY(), getX()+getWidth(), getY()+getHeight(), FHColorHelper.setAlpha(backgroundColor, alpha));
if (!getMessage().getString().isBlank() && isHovered()) {
int textWidth = ClientUtils.font().width(getMessage());
int renderX = getX()-textWidth+8;
Expand All @@ -50,21 +53,21 @@ public void renderWidget(@NotNull GuiGraphics graphics, int mouseX, int mouseY,
getY()-12,
getX()+2 + textWidth,
getY(),
FHColorHelper.setAlpha(color, 50));
FHColorHelper.setAlpha(backgroundColor, alpha));
graphics.drawString(ClientUtils.font(), getMessage(), getX()+2, getY()-10, color);
} else {
graphics.fill(getX()-textWidth+getWidth()-1,
getY()-12,
getX()+getWidth(),
getY(),
FHColorHelper.setAlpha(color, 50));
FHColorHelper.setAlpha(backgroundColor, alpha));
graphics.drawString(ClientUtils.font(), getMessage(), getX()-textWidth+getWidth(), getY()-10, color);
}
}
}

FHGuiHelper.bindTexture(ICON_LOCATION);
FHGuiHelper.blitColored(graphics.pose(), getX(), getY(), getWidth(), getHeight(), icon.x*scale, icon.y*scale, getWidth(), getHeight(), TEXTURE_WIDTH*scale, TEXTURE_HEIGHT*scale, color, alpha);
FHGuiHelper.blitColored(graphics.pose(), getX(), getY(), getWidth(), getHeight(), icon.x*scale, icon.y*scale, getWidth(), getHeight(), TEXTURE_WIDTH*scale, TEXTURE_HEIGHT*scale, color, this.alpha);
}

public void setScale(int scale) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.PacketDistributor;

public class TipAPI {
public class ServerTipSender {

/**
* 使客户端显示对应 id 的 tip
Expand All @@ -18,13 +18,23 @@ public static void sendGeneral(String id, ServerPlayer player) {
}

/**
* 向客户端发送自定义 tip
* 向所有玩家发送自定义 tip
* <p>
* 注意:自定义 tip 不会储存任何状态
* @param tip tip
*/
public static void sendCustomToAll(Tip tip) {
FHNetwork.sendToServer(new DisplayCustomTipPacket(tip));
}

/**
* 向玩家发送自定义 tip
* <p>
* 注意:自定义 tip 不会储存任何状态
* @param tip tip
* @param player 目标玩家
*/
public static void sendCustom(Tip tip, ServerPlayer player) {
FHNetwork.send(PacketDistributor.PLAYER.with(() -> player), new DisplayCustomTipPacket(tip));
FHNetwork.sendPlayer(player, new DisplayCustomTipPacket(tip));
}
}
18 changes: 9 additions & 9 deletions src/main/java/com/teammoeg/frostedheart/content/tips/Tip.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ protected Tip(Tip.Builder builder) {
this.backgroundColor = builder.BGColor;
}

public void display() {
TipManager.INSTANCE.display().general(this);
}

public void forceDisplay() {
TipManager.INSTANCE.display().force(this);
}

public boolean hasNext() {
return TipManager.INSTANCE.hasTip(nextTip);
}
Expand All @@ -126,7 +134,7 @@ public boolean saveAsFile() {
return true;
} catch (IOException e) {
LOGGER.error("Unable to save file: '{}'", file, e);
Tip.builder("exception").error(ErrorType.SAVE, e, Lang.str(file.getName())).forceDisplay();
Tip.builder("exception").error(ErrorType.SAVE, e, Lang.str(file.getName())).build().forceDisplay();
return false;
}
}
Expand Down Expand Up @@ -225,14 +233,6 @@ public Builder(String id) {
setTemporary();
}

public void display() {
TipManager.INSTANCE.display().general(build());
}

public void forceDisplay() {
TipManager.INSTANCE.display().force(build());
}

public Tip build() {
return new Tip(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.teammoeg.frostedheart.content.tips.client.gui;

import com.teammoeg.frostedheart.FHNetwork;
import com.teammoeg.frostedheart.base.client.gui.widget.ActionStateIconButton;
import com.teammoeg.frostedheart.content.tips.Tip;
import com.teammoeg.frostedheart.base.client.gui.widget.IconButton;
import com.teammoeg.frostedheart.content.tips.client.gui.widget.TipEditsList;
import com.teammoeg.frostedheart.content.tips.network.DisplayCustomTipRequestPacket;
import com.teammoeg.frostedheart.util.client.ClientUtils;
import com.teammoeg.frostedheart.util.client.FHColorHelper;
import com.teammoeg.frostedheart.util.lang.Lang;
Expand All @@ -14,18 +17,11 @@

public class TipEditorScreen extends Screen {
private final TipEditsList list;
private final IconButton saveButton;

public TipEditorScreen() {
super(Lang.str("Tip Editor"));
this.list = new TipEditsList(ClientUtils.mc(), ClientUtils.screenWidth(), ClientUtils.screenHeight(), 10, ClientUtils.screenHeight() - 30, 28);
list.setRenderBackground(false);
this.saveButton = new IconButton(ClientUtils.screenWidth()/2 - 10, ClientUtils.screenHeight()-25, IconButton.Icon.FOLDER, FHColorHelper.CYAN, 2, Component.literal("Save"), (b) -> {
var json = list.getJson();
if (json != null) {
Tip.builder("").fromJson(json).build().saveAsFile();
}
});
}

@Override
Expand All @@ -39,14 +35,32 @@ public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY,
public void resize(@NotNull Minecraft pMinecraft, int pWidth, int pHeight) {
super.resize(pMinecraft, pWidth, pHeight);
list.updateSize(ClientUtils.screenWidth(), ClientUtils.screenHeight(), 10, ClientUtils.screenHeight() - 30);
saveButton.setPosition(ClientUtils.screenWidth()/2 - 10, ClientUtils.screenHeight()-25);
}

@Override
protected void init() {
super.init();
addWidget(list);
addRenderableWidget(saveButton);
// 保存按钮
addRenderableWidget(new ActionStateIconButton(ClientUtils.screenWidth()/2 - 30, ClientUtils.screenHeight()-25, IconButton.Icon.FOLDER, FHColorHelper.CYAN, 2, Component.translatable("gui.frostedheart.save_as_file"), Component.translatable("gui.frostedheart.saved"), (b) -> {
var json = list.getJson();
if (json != null) {
Tip.builder("").fromJson(json).build().saveAsFile();
}
}));
// 发送按钮
ActionStateIconButton sendButton = new ActionStateIconButton(ClientUtils.screenWidth()/2 + 5, ClientUtils.screenHeight()-25, IconButton.Icon.GIVE, FHColorHelper.CYAN, 2, Component.translatable("gui.frostedheart.tip_editor.send"), Component.translatable("gui.frostedheart.sent"), (b) -> {
var json = list.getJson();
if (json != null) {
Tip tip = Tip.builder("").fromJson(json).build();
FHNetwork.sendToServer(new DisplayCustomTipRequestPacket(tip));
}
});
if (!ClientUtils.getPlayer().hasPermissions(2)) {
sendButton.active = false;
sendButton.setMessage(Component.translatable("gui.frostedheart.tip_editor.no_permission"));
}
addRenderableWidget(sendButton);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.teammoeg.frostedheart.base.client.gui.widget.ActionStateIconButton;
import com.teammoeg.frostedheart.base.client.gui.widget.ColorEditbox;
import com.teammoeg.frostedheart.base.client.gui.widget.IconButton;
import com.teammoeg.frostedheart.base.client.gui.widget.IconCheckbox;
import com.teammoeg.frostedheart.content.tips.Tip;
import com.teammoeg.frostedheart.content.tips.TipRenderer;
import com.teammoeg.frostedheart.util.client.ClientUtils;
import com.teammoeg.frostedheart.util.client.FHColorHelper;
import com.teammoeg.frostedheart.util.lang.Lang;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
Expand All @@ -28,6 +29,7 @@

public class TipEditsList extends ContainerObjectSelectionList<TipEditsList.EditEntry> {
private final Font font;
private String cachedId;

public TipEditsList(Minecraft pMinecraft, int pWidth, int pHeight, int pY0, int pY1, int pItemHeight) {
super(pMinecraft, pWidth, pHeight, pY0, pY1, pItemHeight);
Expand All @@ -50,7 +52,9 @@ public TipEditsList(Minecraft pMinecraft, int pWidth, int pHeight, int pY0, int
public void updatePreview() {
TipRenderer.TIP_QUEUE.clear();
TipRenderer.forceClose();
Tip.builder("").fromJson(getJson()).alwaysVisible(true).forceDisplay();
Tip tip = Tip.builder("").fromJson(getJson()).alwaysVisible(true).build();
tip.forceDisplay();
this.cachedId = tip.getId();
}

public JsonObject getJson() {
Expand Down Expand Up @@ -109,21 +113,46 @@ public JsonElement getValue() {
public class MultiComponentEntry extends StringEntry {
protected final IconButton addButton;
protected final IconButton deleteButton;
protected final List<Component> contents = new ArrayList<>();
protected final IconButton translationButton;
protected final List<String> contents = new ArrayList<>();

public MultiComponentEntry(String property, Component message) {
super(property, message);
this.addButton = new IconButton(0, 0, IconButton.Icon.CHECK, FHColorHelper.CYAN, Component.translatable("gui.add"), b -> {
this.addButton = new IconButton(0, 0, IconButton.Icon.CHECK, FHColorHelper.CYAN, Component.translatable("gui.frostedheart.tip_editor.add_line"), b -> {
if (input.getValue().isBlank()) return;

contents.add(Lang.str(this.input.getValue()));
contents.add(this.input.getValue());
input.setValue("");
updatePreview();
});

this.deleteButton = new IconButton(0, 0, IconButton.Icon.TRASH_CAN, FHColorHelper.CYAN, Component.translatable("key.keyboard.delete"), b -> {
if (!contents.isEmpty()) contents.remove(contents.size()-1);
updatePreview();
this.deleteButton = new IconButton(0, 0, IconButton.Icon.TRASH_CAN, FHColorHelper.CYAN, Component.translatable("gui.frostedheart.tip_editor.delete_last_line"), b -> {
if (!contents.isEmpty()) {
contents.remove(contents.size() - 1);
updatePreview();
}
});

this.translationButton = new ActionStateIconButton(0, 0, IconButton.Icon.LIST, FHColorHelper.CYAN, Component.translatable("gui.frostedheart.tip_editor.convert_and_copy"), Component.translatable("gui.frostedheart.copied"), b -> {
if (!contents.isEmpty()) {
String prefix = "tips.frostedheart." + cachedId;
StringBuilder copy = new StringBuilder();
List<String> converted = new ArrayList<>();

converted.add(prefix + ".title");
copy.append(prefix).append(".title: \"").append(contents.get(0)).append("\",\n");
for (int i = 1; i < contents.size(); i++) {
//tips.frostedheart.example.desc1
String s = prefix + ".desc" + i;
converted.add(s);
copy.append(s).append(": \"").append(contents.get(i)).append("\",\n");
}

contents.clear();
contents.addAll(converted);
ClientUtils.mc().keyboardHandler.setClipboard(copy.substring(0, copy.length()-2)); // 删除最后一行的逗号和换行
updatePreview();
}
});
}

Expand All @@ -134,23 +163,25 @@ public void render(@NotNull GuiGraphics pGuiGraphics, int pIndex, int pTop, int
addButton.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
deleteButton.setPosition(pLeft + 132, pTop + (pHeight/2) - 10);
deleteButton.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
translationButton.setPosition(pLeft + 118, pTop + (pHeight/2) - 10);
translationButton.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
}

@Override
public JsonElement getValue() {
JsonArray contents = new JsonArray();
this.contents.stream().map(Lang::getKeyOrElseStr).forEach(contents::add);
this.contents.forEach(contents::add);
return contents;
}

@Override
public @NotNull List<? extends NarratableEntry> narratables() {
return ImmutableList.of(addButton, deleteButton, input);
return ImmutableList.of(addButton, deleteButton, translationButton, input);
}

@Override
public @NotNull List<? extends GuiEventListener> children() {
return ImmutableList.of(addButton, deleteButton, input);
return ImmutableList.of(addButton, deleteButton, translationButton, input);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.teammoeg.frostedheart.content.tips.network;

import com.teammoeg.frostedheart.FHMain;
import com.teammoeg.frostedheart.base.network.FHMessage;
import com.teammoeg.frostedheart.content.tips.ServerTipSender;
import com.teammoeg.frostedheart.content.tips.Tip;
import com.teammoeg.frostedheart.util.lang.Lang;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;

import java.util.function.Supplier;

public record DisplayCustomTipRequestPacket(Tip tip) implements FHMessage {

public DisplayCustomTipRequestPacket(FriendlyByteBuf buffer) {
this(Tip.builder("").fromNBT(buffer.readNbt()).build());
}

@Override
public void encode(FriendlyByteBuf buffer) {
tip.write(buffer);
}

@Override
public void handle(Supplier<NetworkEvent.Context> context) {
var player = context.get().getSender();
if (player != null) {
if (!player.hasPermissions(2)) {
FHMain.LOGGER.warn("{} IS A HACKER!", player.getName().getString());
ServerTipSender.sendCustom(Tip.builder("warning").line(Lang.str("HACKER!")).pin(true).alwaysVisible(true).build(), player);
} else {
context.get().enqueueWork(() -> ServerTipSender.sendCustomToAll(tip));
}
}
context.get().setPacketHandled(true);
}
}
Loading

0 comments on commit 7e7398f

Please sign in to comment.