修复改用网络发包,兼容多人游戏
This commit is contained in:
parent
44e7d356fc
commit
16e929470b
|
|
@ -29,7 +29,7 @@ public class ExtendedAEPlus {
|
|||
* 通用初始化设置
|
||||
*/
|
||||
private void commonSetup(final FMLCommonSetupEvent event) {
|
||||
// 注册网络处理器
|
||||
NetworkHandler.registerPackets();
|
||||
// 注册网络处理器(确保在注册窗口关闭前完成)
|
||||
event.enqueueWork(NetworkHandler::initialize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,13 @@ import appeng.menu.SlotSemantics;
|
|||
import appeng.menu.guisync.GuiSync;
|
||||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import appeng.menu.slot.AppEngSlot;
|
||||
import appeng.crafting.pattern.EncodedPatternItem;
|
||||
import appeng.crafting.pattern.AEProcessingPattern;
|
||||
import appeng.api.stacks.GenericStack;
|
||||
import appeng.api.crafting.PatternDetailsHelper;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
|
|
@ -14,12 +20,15 @@ import org.spongepowered.asm.mixin.Unique;
|
|||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mixin(value = ContainerExPatternProvider.class, priority = 3000)
|
||||
public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu {
|
||||
public abstract class ContainerExPatternProviderMixin extends PatternProviderMenu implements IActionHolder {
|
||||
|
||||
@GuiSync(11451)
|
||||
@Unique
|
||||
|
|
@ -31,6 +40,9 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
@Unique
|
||||
private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位
|
||||
|
||||
@Unique
|
||||
private final Map<String, Consumer<Paras>> actions = createHolder();
|
||||
|
||||
public ContainerExPatternProviderMixin(MenuType<? extends PatternProviderMenu> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host) {
|
||||
super(menuType, id, playerInventory, host);
|
||||
}
|
||||
|
|
@ -64,10 +76,20 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"), remap = false)
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
public void init(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||
int maxSlots = this.getSlots(SlotSemantics.ENCODED_PATTERN).size();
|
||||
this.maxPage = (maxSlots + SLOTS_PER_PAGE - 1) / SLOTS_PER_PAGE;
|
||||
|
||||
// 注册通用动作(供 CGenericPacket 分发)
|
||||
this.actions.put("multiply2", p -> { System.out.println("[EAE+][Server] multiply2"); modifyPatterns(2, false); });
|
||||
this.actions.put("divide2", p -> { System.out.println("[EAE+][Server] divide2"); modifyPatterns(2, true); });
|
||||
this.actions.put("multiply5", p -> { System.out.println("[EAE+][Server] multiply5"); modifyPatterns(5, false); });
|
||||
this.actions.put("divide5", p -> { System.out.println("[EAE+][Server] divide5"); modifyPatterns(5, true); });
|
||||
this.actions.put("multiply10",p -> { System.out.println("[EAE+][Server] multiply10");modifyPatterns(10, false);});
|
||||
this.actions.put("divide10", p -> { System.out.println("[EAE+][Server] divide10"); modifyPatterns(10, true); });
|
||||
|
||||
System.out.println("[EAE+][Server] ContainerExPatternProvider actions registered: " + this.actions.keySet());
|
||||
}
|
||||
|
||||
@Unique
|
||||
|
|
@ -79,4 +101,72 @@ public abstract class ContainerExPatternProviderMixin extends PatternProviderMen
|
|||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void modifyPatterns(int scale, boolean div) {
|
||||
if (scale <= 0) return;
|
||||
for (var slot : this.getSlots(SlotSemantics.ENCODED_PATTERN)) {
|
||||
var stack = slot.getItem();
|
||||
if (stack.getItem() instanceof EncodedPatternItem pattern) {
|
||||
var detail = pattern.decode(stack, this.getPlayer().level(), false);
|
||||
if (detail instanceof AEProcessingPattern process) {
|
||||
var input = process.getSparseInputs();
|
||||
var output = process.getOutputs();
|
||||
if (checkModify(input, scale, div) && checkModify(output, scale, div)) {
|
||||
var mulInput = new GenericStack[input.length];
|
||||
var mulOutput = new GenericStack[output.length];
|
||||
modifyStacks(input, mulInput, scale, div);
|
||||
modifyStacks(output, mulOutput, scale, div);
|
||||
var newPattern = PatternDetailsHelper.encodeProcessingPattern(mulInput, mulOutput);
|
||||
slot.set(newPattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private boolean checkModify(GenericStack[] stacks, int scale, boolean div) {
|
||||
if (stacks == null) return false;
|
||||
if (div) {
|
||||
for (var stack : stacks) {
|
||||
if (stack != null) {
|
||||
if (stack.amount() % scale != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
for (var stack : stacks) {
|
||||
if (stack != null) {
|
||||
long upper = 999999L * stack.what().getAmountPerUnit();
|
||||
if (stack.amount() * scale > upper) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void modifyStacks(GenericStack[] src, GenericStack[] dst, int scale, boolean div) {
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
var stack = src[i];
|
||||
if (stack != null) {
|
||||
long amt = stack.amount();
|
||||
long newAmt = div ? (amt / scale) : (amt * scale);
|
||||
dst[i] = new GenericStack(stack.what(), newAmt);
|
||||
} else {
|
||||
dst[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
return this.actions;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,25 @@
|
|||
package com.extendedae_plus.mixin;
|
||||
|
||||
import appeng.menu.guisync.GuiSync;
|
||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternTerminal;
|
||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||
import com.glodblock.github.glodium.network.packet.sync.Paras;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
@Mixin(ContainerExPatternTerminal.class)
|
||||
public abstract class ContainerExPatternTerminalMixin {
|
||||
public abstract class ContainerExPatternTerminalMixin implements IActionHolder {
|
||||
|
||||
@GuiSync(11452)
|
||||
@Unique
|
||||
|
|
@ -29,4 +39,34 @@ public abstract class ContainerExPatternTerminalMixin {
|
|||
public void toggleHidePatternSlots() {
|
||||
this.hidePatternSlots = !this.hidePatternSlots;
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private final Map<String, Consumer<Paras>> actions = createHolder();
|
||||
|
||||
@Unique
|
||||
private Player epp$player;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void init(int id, net.minecraft.world.entity.player.Inventory playerInventory, IConfigurableObject host, CallbackInfo ci) {
|
||||
this.epp$player = playerInventory.player;
|
||||
// 注册上传动作:参数顺序必须与客户端 CGenericPacket 保持一致
|
||||
this.actions.put("upload", p -> {
|
||||
try {
|
||||
int playerSlotIndex = p.get(0);
|
||||
long providerId = p.get(1);
|
||||
var sp = (ServerPlayer) this.epp$player;
|
||||
System.out.println("[EAE+][Server] upload: slot=" + playerSlotIndex + ", provider=" + providerId);
|
||||
ExtendedAEPatternUploadUtil.uploadPatternToProvider(sp, playerSlotIndex, providerId);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
System.out.println("[EAE+][Server] ExPatternTerminal actions registered: " + this.actions.keySet());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Consumer<Paras>> getActionMap() {
|
||||
return this.actions;
|
||||
}
|
||||
}
|
||||
|
|
@ -9,9 +9,10 @@ import appeng.menu.SlotSemantics;
|
|||
import com.extendedae_plus.NewIcon;
|
||||
import com.extendedae_plus.util.PatternProviderUIHelper;
|
||||
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
||||
import com.glodblock.github.extendedae.network.EPPNetworkHandler;
|
||||
import com.glodblock.github.glodium.network.packet.CGenericPacket;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
|
||||
import com.extendedae_plus.network.UpdatePagePacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
|
|
@ -271,194 +272,86 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
|||
public ActionEPPButton divideBy5Button;
|
||||
public ActionEPPButton x10Button;
|
||||
public ActionEPPButton divideBy10Button;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"), remap = false)
|
||||
|
||||
// 在构造器返回后初始化按钮与翻页控制
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void injectInit(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||
this.screenStyle = style;
|
||||
// 打印当前菜单类型,确认是否为扩展容器
|
||||
try {
|
||||
var m = this.getMenu();
|
||||
System.out.println("[EAE+][Client] Screen menu class = " + (m == null ? "null" : m.getClass().getName()));
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
// 只有当槽位数超过每页显示数量时才添加翻页按钮
|
||||
int maxSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size();
|
||||
if (maxSlots > SLOTS_PER_PAGE) {
|
||||
// 前进后退按钮
|
||||
this.prevPage = new ActionEPPButton((b) -> {
|
||||
int currentPage = getCurrentPage();
|
||||
int maxPage = getMaxPage();
|
||||
// 循环翻页:第一页向前翻到最后一页
|
||||
int newPage = (currentPage - 1 + maxPage) % maxPage;
|
||||
try {
|
||||
ContainerExPatternProvider menu1 = this.getMenu();
|
||||
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
|
||||
setPageMethod.invoke(menu1, newPage);
|
||||
} catch (Exception e) {
|
||||
// 忽略反射错误
|
||||
}
|
||||
}, Icon.ARROW_LEFT);
|
||||
// 翻页按钮(仅在需要时显示)
|
||||
int totalSlots = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN).size();
|
||||
if (totalSlots > SLOTS_PER_PAGE) {
|
||||
this.prevPage = new ActionEPPButton((b) -> {
|
||||
int currentPage = getCurrentPage();
|
||||
int maxPage = getMaxPage();
|
||||
int newPage = (currentPage - 1 + maxPage) % maxPage;
|
||||
try {
|
||||
ContainerExPatternProvider menu1 = this.getMenu();
|
||||
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
|
||||
setPageMethod.invoke(menu1, newPage);
|
||||
} catch (Exception ignored) {}
|
||||
}, Icon.ARROW_LEFT);
|
||||
|
||||
this.nextPage = new ActionEPPButton((b) -> {
|
||||
int currentPage = getCurrentPage();
|
||||
int maxPage = getMaxPage();
|
||||
// 循环翻页:最后一页向后翻到第一页
|
||||
int newPage = (currentPage + 1) % maxPage;
|
||||
try {
|
||||
ContainerExPatternProvider menu1 = this.getMenu();
|
||||
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
|
||||
setPageMethod.invoke(menu1, newPage);
|
||||
} catch (Exception e) {
|
||||
// 忽略反射错误
|
||||
}
|
||||
}, Icon.ARROW_RIGHT);
|
||||
this.nextPage = new ActionEPPButton((b) -> {
|
||||
int currentPage = getCurrentPage();
|
||||
int maxPage = getMaxPage();
|
||||
int newPage = (currentPage + 1) % maxPage;
|
||||
try {
|
||||
ContainerExPatternProvider menu1 = this.getMenu();
|
||||
java.lang.reflect.Method setPageMethod = menu1.getClass().getMethod("setPage", int.class);
|
||||
setPageMethod.invoke(menu1, newPage);
|
||||
} catch (Exception ignored) {}
|
||||
}, Icon.ARROW_RIGHT);
|
||||
|
||||
this.addToLeftToolbar(this.nextPage);
|
||||
this.addToLeftToolbar(this.prevPage);
|
||||
}
|
||||
|
||||
// x2 按钮 - 单机模式直接调用服务器端逻辑
|
||||
|
||||
// 倍增/除法按钮,通过 ExtendedAE 的通用包派发
|
||||
this.x2Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
// 单机模式:直接在逻辑服务器端执行样板倍增
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
// 获取逻辑服务器端的玩家实例
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
|
||||
if (serverPlayer != null) {
|
||||
// 在服务器端执行样板倍增逻辑
|
||||
executePatternScalingOnServer(serverPlayer, "MULTIPLY", 2.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板倍增时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("[EAE+][Client] click multiply2");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("multiply2"));
|
||||
}, NewIcon.MULTIPLY2);
|
||||
this.x2Button.setVisibility(true);
|
||||
|
||||
// /2 按钮 - 单机模式直接调用服务器端逻辑
|
||||
|
||||
this.divideBy2Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
// 单机模式:直接在逻辑服务器端执行样板除法
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
// 获取逻辑服务器端的玩家实例
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
|
||||
if (serverPlayer != null) {
|
||||
// 在服务器端执行样板除法逻辑
|
||||
executePatternScalingOnServer(serverPlayer, "DIVIDE", 2.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板除法时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("[EAE+][Client] click divide2");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("divide2"));
|
||||
}, NewIcon.DIVIDE2);
|
||||
this.divideBy2Button.setVisibility(true);
|
||||
|
||||
// 使用原版渲染注册,确保在屏幕中绘制
|
||||
this.addRenderableWidget(this.divideBy2Button);
|
||||
this.addRenderableWidget(this.x2Button);
|
||||
|
||||
// x10 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.x10Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
if (serverPlayer != null) {
|
||||
executePatternScalingOnServer(serverPlayer, "MULTIPLY", 10.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板x10倍增时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("[EAE+][Client] click multiply10");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("multiply10"));
|
||||
}, NewIcon.MULTIPLY10);
|
||||
this.x10Button.setVisibility(true);
|
||||
|
||||
// x5 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.x5Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
if (serverPlayer != null) {
|
||||
executePatternScalingOnServer(serverPlayer, "MULTIPLY", 5.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板x5倍增时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, NewIcon.MULTIPLY5);
|
||||
this.x5Button.setVisibility(true);
|
||||
|
||||
// /10 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.divideBy10Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
if (serverPlayer != null) {
|
||||
executePatternScalingOnServer(serverPlayer, "DIVIDE", 10.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板/10时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("[EAE+][Client] click divide10");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("divide10"));
|
||||
}, NewIcon.DIVIDE10);
|
||||
this.divideBy10Button.setVisibility(true);
|
||||
|
||||
// /5 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.divideBy5Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
if (serverPlayer != null) {
|
||||
executePatternScalingOnServer(serverPlayer, "DIVIDE", 5.0);
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 执行样板/5时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("[EAE+][Client] click divide5");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("divide5"));
|
||||
}, NewIcon.DIVIDE5);
|
||||
this.divideBy5Button.setVisibility(true);
|
||||
|
||||
// 注册新增按钮
|
||||
this.x5Button = new ActionEPPButton((b) -> {
|
||||
System.out.println("[EAE+][Client] click multiply5");
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("multiply5"));
|
||||
}, NewIcon.MULTIPLY5);
|
||||
this.x5Button.setVisibility(true);
|
||||
|
||||
// 注册可渲染按钮
|
||||
this.addRenderableWidget(this.divideBy2Button);
|
||||
this.addRenderableWidget(this.x2Button);
|
||||
this.addRenderableWidget(this.divideBy5Button);
|
||||
this.addRenderableWidget(this.x5Button);
|
||||
this.addRenderableWidget(this.divideBy10Button);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import appeng.client.gui.AEBaseScreen;
|
|||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.widgets.IconButton;
|
||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
||||
import com.glodblock.github.extendedae.network.EPPNetworkHandler;
|
||||
import com.glodblock.github.glodium.network.packet.CGenericPacket;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiWirelessExPAT;
|
||||
import com.glodblock.github.extendedae.container.ContainerExPatternTerminal;
|
||||
|
|
@ -109,28 +111,10 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<ContainerEx
|
|||
ItemStack itemToUpload = this.minecraft.player.getInventory().getItem(playerSlotIndex);
|
||||
|
||||
if (!itemToUpload.isEmpty() && PatternDetailsHelper.isEncodedPattern(itemToUpload)) {
|
||||
// 取消上传过程中的左下角提示
|
||||
|
||||
// 在单机游戏中,直接在客户端线程中执行服务器端逻辑
|
||||
// 因为单机游戏的客户端和服务器运行在同一个进程中
|
||||
this.minecraft.execute(() -> {
|
||||
// 获取服务器端的玩家实例
|
||||
if (this.minecraft.getSingleplayerServer() != null) {
|
||||
var serverPlayer = this.minecraft.getSingleplayerServer().getPlayerList()
|
||||
.getPlayer(this.minecraft.player.getUUID());
|
||||
|
||||
if (serverPlayer != null) {
|
||||
// 直接调用服务器端上传逻辑
|
||||
boolean success = ExtendedAEPatternUploadUtil.uploadPatternToProvider(
|
||||
serverPlayer,
|
||||
playerSlotIndex,
|
||||
currentlychooicepatterprovider
|
||||
);
|
||||
|
||||
// 取消上传完成后的左下角提示
|
||||
}
|
||||
}
|
||||
});
|
||||
// 通过 ExtendedAE 内置网络系统发送通用动作到服务端
|
||||
// 动作: "upload",参数: 槽位索引(int)、供应器ID(long)
|
||||
System.out.println("[EAE+][Client] send upload: slot=" + playerSlotIndex + ", provider=" + currentlychooicepatterprovider);
|
||||
EPPNetworkHandler.INSTANCE.sendToServer(new CGenericPacket("upload", playerSlotIndex, currentlychooicepatterprovider));
|
||||
|
||||
} else {
|
||||
this.minecraft.player.displayClientMessage(
|
||||
|
|
|
|||
|
|
@ -14,19 +14,40 @@ import net.minecraftforge.network.simple.SimpleChannel;
|
|||
public class NetworkHandler {
|
||||
|
||||
private static final String PROTOCOL_VERSION = "1";
|
||||
public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(
|
||||
new ResourceLocation("extendedae_plus", "main"),
|
||||
() -> PROTOCOL_VERSION,
|
||||
PROTOCOL_VERSION::equals,
|
||||
PROTOCOL_VERSION::equals
|
||||
);
|
||||
|
||||
private static SimpleChannel INSTANCE;
|
||||
private static int packetId = 0;
|
||||
private static boolean registered = false;
|
||||
|
||||
/**
|
||||
* 在合法的注册阶段创建通道。可重复调用(幂等)。
|
||||
*/
|
||||
private static void initChannel() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = NetworkRegistry.newSimpleChannel(
|
||||
new ResourceLocation("extendedae_plus", "main"),
|
||||
() -> PROTOCOL_VERSION,
|
||||
PROTOCOL_VERSION::equals,
|
||||
PROTOCOL_VERSION::equals
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 供 Mod 早期调用,确保在注册窗口关闭前完成通道与包注册。
|
||||
*/
|
||||
public static void initialize() {
|
||||
if (!registered) {
|
||||
initChannel();
|
||||
registerPackets();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册所有网络包
|
||||
*/
|
||||
public static void registerPackets() {
|
||||
if (registered) return;
|
||||
initChannel();
|
||||
// 样板上传请求包(客户端 -> 服务器)
|
||||
INSTANCE.messageBuilder(PatternUploadPacket.class, packetId++, NetworkDirection.PLAY_TO_SERVER)
|
||||
.decoder(PatternUploadPacket::decode)
|
||||
|
|
@ -54,12 +75,15 @@ public class NetworkHandler {
|
|||
.encoder(PatternScalingResultPacket::encode)
|
||||
.consumerMainThread(PatternScalingResultPacket::handle)
|
||||
.add();
|
||||
registered = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送包到服务器
|
||||
*/
|
||||
public static void sendToServer(Object packet) {
|
||||
// 如果出现 null,说明初始化阶段未被调用,避免在锁定后临时创建通道
|
||||
if (INSTANCE == null) throw new IllegalStateException("Network channel not initialized");
|
||||
INSTANCE.sendToServer(packet);
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +91,7 @@ public class NetworkHandler {
|
|||
* 发送包到指定客户端
|
||||
*/
|
||||
public static void sendToClient(Object packet, ServerPlayer player) {
|
||||
if (INSTANCE == null) throw new IllegalStateException("Network channel not initialized");
|
||||
INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user