diff --git a/build.gradle b/build.gradle index e632ff6..2edc861 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ buildscript { } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.0-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' } } diff --git a/build.properties b/build.properties index 83a6056..e0aca65 100644 --- a/build.properties +++ b/build.properties @@ -1,2 +1,2 @@ -minecraft_version=1.6.4 -forge_version=9.11.1.964 \ No newline at end of file +minecraft_version=1.7.2 +forge_version=10.12.1.1060 \ No newline at end of file diff --git a/pub_build/RecStatusMod-v1.3-MC1.7.2.jar b/pub_build/RecStatusMod-v1.3-MC1.7.2.jar new file mode 100644 index 0000000..705772c Binary files /dev/null and b/pub_build/RecStatusMod-v1.3-MC1.7.2.jar differ diff --git a/resources/mcmod.info b/resources/mcmod.info index 07e74b3..ece8203 100644 --- a/resources/mcmod.info +++ b/resources/mcmod.info @@ -3,8 +3,8 @@ "modid": "fuj1n.recmod", "name": "Recording Status Mod", "description": "Record/Stream status in the players list, /rec to toggle", - "version": "v1.1", - "mcversion": "1.6.4", + "version": "v1.3", + "mcversion": "1.7.2", "url": "", "updateUrl": "", "authors": [ diff --git a/src/fuj1n/recmod/RecMod.java b/src/fuj1n/recmod/RecMod.java index 932bbf5..be06be7 100644 --- a/src/fuj1n/recmod/RecMod.java +++ b/src/fuj1n/recmod/RecMod.java @@ -1,126 +1,132 @@ package fuj1n.recmod; -import fuj1n.recmod.command.CommandRec; +import java.io.*; +import java.util.*; import cpw.mods.fml.common.*; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.event.*; -import cpw.mods.fml.common.network.*; -import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import fuj1n.recmod.client.event.*; import fuj1n.recmod.client.keybind.KeyHandlerRecMod; -import fuj1n.recmod.network.*; -import java.io.*; -import java.util.*; +import fuj1n.recmod.command.CommandRec; +import fuj1n.recmod.network.PlayerTracker; +import fuj1n.recmod.network.packet.*; import net.minecraft.command.ServerCommandManager; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.packet.Packet250CustomPayload; +import net.minecraft.entity.player.*; import net.minecraft.server.MinecraftServer; import net.minecraftforge.common.MinecraftForge; -@Mod(name="Recording Status Mod", version="1.3", modid="fuj1n.recmod") -@NetworkMod(clientSideRequired=true, channels = {"recModData", "recModDataC", "recModUI"}, packetHandler=PacketHandler.class, serverSideRequired=false) -public class RecMod { +@Mod(name = "Recording Status Mod", version = "v1.3", modid = "fuj1n.recmod") +public class RecMod { + @Instance("fuj1n.recmod") public static RecMod instance; + + public static final PacketPipeline packetPipeline = new PacketPipeline(); private static HashMap recorders = new HashMap(); private static HashMap streamers = new HashMap(); - + public boolean showSelf = true; public boolean showUI = false; - + public String sheetLocation = "recmod:textures/sheets/indicators.png"; - + public boolean showSelfDef = false; - + public File configFile; - + @EventHandler - public void preinit(FMLPreInitializationEvent event){ - GameRegistry.registerPlayerTracker(new PlayerTracker()); + public void preinit(FMLPreInitializationEvent event) { + MinecraftForge.EVENT_BUS.register(new PlayerTracker()); configFile = new File(event.getModConfigurationDirectory(), "recmod.ui"); - - if(event.getSide() == Side.CLIENT){ + + if (event.getSide() == Side.CLIENT) { readFromFile(); MinecraftForge.EVENT_BUS.register(new EventRenderGame()); MinecraftForge.EVENT_BUS.register(new EventEntityJoinWorld()); - - //WIP + KeyHandlerRecMod.registerSelf(); } } - + @EventHandler - public void init(FMLInitializationEvent event){ + public void init(FMLInitializationEvent event) { + packetPipeline.initialise(); + PacketPipeline pp = packetPipeline; + //Packet Registration + pp.registerPacket(PacketUpdatePlayerStatus.class); + pp.registerPacket(PacketRemovePlayer.class); + pp.registerPacket(PacketChangeUISettings.class); + pp.registerPacket(PacketChangeUISheet.class); } - + @EventHandler - public void postinit(FMLPostInitializationEvent event){ - + public void postinit(FMLPostInitializationEvent event) { + packetPipeline.postInitialise(); } - + @EventHandler - public void serverStart(FMLServerStartedEvent event){ + public void serverStart(FMLServerStartedEvent event) { if (MinecraftServer.getServer() == null) { return; } - + recorders = new HashMap(); streamers = new HashMap(); - - ServerCommandManager handler = (ServerCommandManager)MinecraftServer.getServer().getCommandManager(); + + ServerCommandManager handler = (ServerCommandManager) MinecraftServer.getServer().getCommandManager(); handler.registerCommand(new CommandRec()); } - - public void updatePlayerInformation(String username, int type, boolean flag){ + + public void updatePlayerInformation(String username, int type, boolean flag) { HashMap modifyMap; - if(type == 0){ + if (type == 0) { modifyMap = recorders; - }else{ + } else { modifyMap = streamers; } - + modifyMap.put(username, flag); } - - public boolean isPlayerRecording(String username){ - if(username == null){ + + public boolean isPlayerRecording(String username) { + if (username == null) { return false; } return recorders.get(username) != null ? recorders.get(username) : false; } - - public boolean isPlayerStreaming(String username){ - if(username == null){ + + public boolean isPlayerStreaming(String username) { + if (username == null) { return false; } return streamers.get(username) != null ? streamers.get(username) : false; } - - public void onUIStateChanged(){ + + public void onUIStateChanged() { writeToFile(); } - - public void onSheetChanged(){ + + public void onSheetChanged() { writeToFile(); } - + public void readFromFile() { - if(!configFile.exists()){ + if (!configFile.exists()) { return; } - + try { BufferedReader b = new BufferedReader(new FileReader(configFile)); String line1 = b.readLine(); String line2 = b.readLine(); String line3 = b.readLine(); - + showSelfDef = convertToBoolean(line1); showUI = convertToBoolean(line2); sheetLocation = line3 != null && !line3.equals("") ? line3 : sheetLocation; @@ -131,14 +137,15 @@ public void readFromFile() { //e.printStackTrace(); } } - - public boolean convertToBoolean(String s){ - try{ + + public boolean convertToBoolean(String s) { + try { return Boolean.parseBoolean(s); - }catch(Exception e){} + } catch (Exception e) { + } return false; } - + public void writeToFile() { configFile.delete(); try { @@ -154,46 +161,36 @@ public void writeToFile() { e.printStackTrace(); } } - - public int calculateNumber(){ + + public int calculateNumber() { ArrayList list = new ArrayList(); - - - + return list.size(); } - - public void removeUnneededData(String username){ + + public void removeUnneededData(String username) { recorders.remove(username); streamers.remove(username); } - - public void sendDataToPlayer(EntityPlayer player){ - for(int i = 0; i < recorders.size(); i++){ + + public void sendDataToPlayer(EntityPlayer player) { + for (int i = 0; i < recorders.size(); i++) { sendPacket(player, recorders.keySet().toArray()[i].toString(), 0, Boolean.parseBoolean(recorders.values().toArray()[i].toString())); } - - for(int i = 0; i < streamers.size(); i++){ + + for (int i = 0; i < streamers.size(); i++) { sendPacket(player, streamers.keySet().toArray()[i].toString(), 1, Boolean.parseBoolean(streamers.values().toArray()[i].toString())); } } - - public void sendPacket(EntityPlayer target, String player, int type, boolean flag){ - ByteArrayOutputStream bos = new ByteArrayOutputStream(8); - DataOutputStream outputStream = new DataOutputStream(bos); - try { - outputStream.writeUTF(player); - outputStream.writeInt(type); - outputStream.writeBoolean(flag); - } catch (Exception ex) { - ex.printStackTrace(); - } - Packet250CustomPayload packet = new Packet250CustomPayload(); - packet.channel = "recModData"; - packet.data = bos.toByteArray(); - packet.length = bos.size(); - PacketDispatcher.sendPacketToPlayer(packet, (Player)target); + public void sendPacket(EntityPlayer target, String player, int type, boolean flag) { + PacketUpdatePlayerStatus pckt = new PacketUpdatePlayerStatus(player, type, flag); + if(target instanceof EntityPlayerMP){ + System.out.println("target = MP"); + packetPipeline.sendTo(pckt, (EntityPlayerMP)target); + }else{ + System.out.println("target != MP"); + } } - + } diff --git a/src/fuj1n/recmod/client/event/EventEntityJoinWorld.java b/src/fuj1n/recmod/client/event/EventEntityJoinWorld.java index dcff1e3..ea39533 100644 --- a/src/fuj1n/recmod/client/event/EventEntityJoinWorld.java +++ b/src/fuj1n/recmod/client/event/EventEntityJoinWorld.java @@ -1,14 +1,14 @@ package fuj1n.recmod.client.event; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; import fuj1n.recmod.RecMod; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.event.ForgeSubscribe; import net.minecraftforge.event.entity.EntityJoinWorldEvent; public class EventEntityJoinWorld { - @ForgeSubscribe + @SubscribeEvent public void onEntityJoin(EntityJoinWorldEvent event){ if(event.entity instanceof EntityPlayer){ Minecraft mc = Minecraft.getMinecraft().getMinecraft(); diff --git a/src/fuj1n/recmod/client/event/EventRenderGame.java b/src/fuj1n/recmod/client/event/EventRenderGame.java index 7a58a91..5dfbc59 100644 --- a/src/fuj1n/recmod/client/event/EventRenderGame.java +++ b/src/fuj1n/recmod/client/event/EventRenderGame.java @@ -1,26 +1,25 @@ package fuj1n.recmod.client.event; -import org.lwjgl.input.Keyboard; +import java.util.List; -import fuj1n.recmod.lib.IndexReference; +import org.lwjgl.opengl.GL11; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; import fuj1n.recmod.RecMod; -import java.util.List; +import fuj1n.recmod.lib.IndexReference; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.*; -import net.minecraft.client.multiplayer.NetClientHandler; -import net.minecraft.scoreboard.*; -import net.minecraft.util.*; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.event.ForgeSubscribe; -import org.lwjgl.opengl.GL11; public class EventRenderGame extends Gui { private String sheetLocation = RecMod.instance.sheetLocation; private ResourceLocation indicators = new ResourceLocation(sheetLocation); - @ForgeSubscribe + @SubscribeEvent public void onRenderGameOverlay(RenderGameOverlayEvent event) { if(!sheetLocation.equals(RecMod.instance.sheetLocation)){ sheetLocation = RecMod.instance.sheetLocation; @@ -31,9 +30,10 @@ public void onRenderGameOverlay(RenderGameOverlayEvent event) { return; } Minecraft mc = Minecraft.getMinecraft(); - if (mc.gameSettings.keyBindPlayerList.pressed && (!mc.isIntegratedServerRunning() || mc.thePlayer.sendQueue.playerInfoList.size() > 1)) { - NetClientHandler netclienthandler = mc.thePlayer.sendQueue; - List list = netclienthandler.playerInfoList; + if (mc.gameSettings.keyBindPlayerList.getIsKeyPressed() && (!mc.isIntegratedServerRunning() || mc.thePlayer.sendQueue.playerInfoList.size() > 1 || mc.theWorld.getScoreboard().func_96539_a(0) != null)) { + mc.mcProfiler.startSection("playerList"); + NetHandlerPlayClient nethandlerplayclient = mc.thePlayer.sendQueue; + List list = nethandlerplayclient.playerInfoList; int k = event.resolution.getScaledWidth(); int i2; @@ -43,7 +43,7 @@ public void onRenderGameOverlay(RenderGameOverlayEvent event) { int i3; int j3; int k3; - j2 = netclienthandler.currentServerMaxPlayers; + j2 = nethandlerplayclient.currentServerMaxPlayers; l2 = j2; for (k2 = 1; l2 > 20; l2 = (j2 + k2 - 1) / k2) { @@ -86,12 +86,12 @@ public void onRenderGameOverlay(RenderGameOverlayEvent event) { } } } - }else if(!mc.gameSettings.keyBindPlayerList.pressed && RecMod.instance.showSelf && mc.currentScreen == null){ + }else if(!mc.gameSettings.keyBindPlayerList.getIsKeyPressed() && RecMod.instance.showSelf && mc.currentScreen == null){ int x = event.resolution.getScaledWidth() - 32; int y = 0; - int indicatorRecIndex = RecMod.instance.isPlayerRecording(mc.thePlayer.username) ? 1 : 0; - int indicatorStrIndex = RecMod.instance.isPlayerStreaming(mc.thePlayer.username) ? 2 : 0; + int indicatorRecIndex = RecMod.instance.isPlayerRecording(mc.thePlayer.getCommandSenderName()) ? 1 : 0; + int indicatorStrIndex = RecMod.instance.isPlayerStreaming(mc.thePlayer.getCommandSenderName()) ? 2 : 0; mc.getTextureManager().bindTexture(indicators); drawTexturedModalRect(x, y, indicatorRecIndex * 16, (int)Math.floor(indicatorRecIndex / 16) * 16 + IndexReference.RESOLUTION_SPLIT_Y, 16, 16); diff --git a/src/fuj1n/recmod/client/gui/GuiSimple.java b/src/fuj1n/recmod/client/gui/GuiSimple.java index ad73251..1a9a0e2 100644 --- a/src/fuj1n/recmod/client/gui/GuiSimple.java +++ b/src/fuj1n/recmod/client/gui/GuiSimple.java @@ -17,7 +17,7 @@ public GuiSimple() { @Override public void drawGuiContainerForegroundLayer(int par1, int par2) { - this.fontRenderer.drawString("Simple Gui", 8, this.ySize - 96 + 2, 4210752); + this.fontRendererObj.drawString("Simple Gui", 8, this.ySize - 96 + 2, 4210752); } @Override diff --git a/src/fuj1n/recmod/client/keybind/KeyHandlerRecMod.java b/src/fuj1n/recmod/client/keybind/KeyHandlerRecMod.java index 06edb11..a94e04a 100644 --- a/src/fuj1n/recmod/client/keybind/KeyHandlerRecMod.java +++ b/src/fuj1n/recmod/client/keybind/KeyHandlerRecMod.java @@ -1,53 +1,106 @@ package fuj1n.recmod.client.keybind; +import java.util.ArrayList; + +import org.lwjgl.input.*; + +import com.google.common.collect.Lists; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.*; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.Type; +import cpw.mods.fml.relauncher.Side; import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.*; +import net.minecraftforge.common.MinecraftForge; -import cpw.mods.fml.client.registry.*; -import cpw.mods.fml.client.registry.KeyBindingRegistry.KeyHandler; -import cpw.mods.fml.common.TickType; -import java.util.EnumSet; -import net.minecraft.client.settings.KeyBinding; +public class KeyHandlerRecMod { -public class KeyHandlerRecMod extends KeyHandler { + public KeyBinding[] keyBindings; + public boolean[] keyDown; + public boolean[] repeatings; + public boolean isDummy; Minecraft mc = Minecraft.getMinecraft(); boolean b = false; - + public KeyHandlerRecMod(KeyBinding[] keyBindings, boolean[] repeatings) { - super(keyBindings, repeatings); + assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length"; + this.keyBindings = keyBindings; + this.repeatings = repeatings; + this.keyDown = new boolean[keyBindings.length]; + isDummy = false; } - @Override - public String getLabel() { - return "fuj1n.RecMod.KeyBindingTickHandler"; - } + @SubscribeEvent + public void onTick(TickEvent event) { + System.out.println("Key Tick"); + if (event.side == Side.CLIENT) { + if (event.phase == Phase.START) + keyTick(event.type, false); + else if (event.phase == Phase.END) + keyTick(event.type, true); + } - @Override - public void keyDown(EnumSet types, KeyBinding kb, boolean tickEnd, boolean isRepeat) { } - @Override - public void keyUp(EnumSet types, KeyBinding kb, boolean tickEnd) { - if(mc.theWorld != null && mc.currentScreen == null && /*mc.gameSettings.keyBindPlayerList.pressed &&*/ (!mc.isIntegratedServerRunning() || mc.thePlayer.sendQueue.playerInfoList.size() > 1)) - if(b){ - if (kb == keyBindings[0]) { - mc.thePlayer.sendChatMessage("/rec r"); - } else if (kb == keyBindings[1]) { - mc.thePlayer.sendChatMessage("/rec s"); + public void keyTick(Type type, boolean tickEnd) { + for (int i = 0; i < keyBindings.length; i++) { + KeyBinding keyBinding = keyBindings[i]; + int keyCode = keyBinding.getKeyCode(); + boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode)); + if (state != keyDown[i] || (state && repeatings[i])) { + if (state) { + keyDown(type, keyBinding, tickEnd, state != keyDown[i]); + } else { + keyUp(type, keyBinding, tickEnd); + } + if (tickEnd) { + keyDown[i] = state; + } } } - b = !b; } - @Override - public EnumSet ticks() { - return EnumSet.of(TickType.CLIENT); + public void keyDown(Type types, KeyBinding kb, boolean tickEnd, boolean isRepeat) { + + } + + public void keyUp(Type types, KeyBinding kb, boolean tickEnd) { + if (mc.theWorld != null && mc.currentScreen == null && /*mc.gameSettings.keyBindPlayerList.pressed &&*/(!mc.isIntegratedServerRunning() || mc.thePlayer.sendQueue.playerInfoList.size() > 1)) + if (b) { + if (kb == keyBindings[0]) { + mc.thePlayer.sendChatMessage("/rec r"); + } else if (kb == keyBindings[1]) { + mc.thePlayer.sendChatMessage("/rec s"); + } + } + b = !b; } public static void registerSelf() { - KeyBinding recBinding = new KeyBinding("ToggleRecording", 44); - KeyBinding streamBinding = new KeyBinding("ToggleStreaming", 45); - KeyBindingRegistry.registerKeyBinding(new KeyHandlerRecMod(new KeyBinding[] { recBinding, streamBinding }, new boolean[] { false, false })); + System.out.println("Key system register"); + String keyCategory = "Recording Mod Bindings"; + KeyBinding recBinding = new KeyBinding("Toggle Recording", 44, keyCategory); + KeyBinding streamBinding = new KeyBinding("Toggle Streaming", 45, keyCategory); + KeyHandlerRecMod keyh = new KeyHandlerRecMod(new KeyBinding[] { recBinding, streamBinding }, new boolean[] { false, false }); + MinecraftForge.EVENT_BUS.register(keyh); + keyh.aggregateKeys(); } + private void aggregateKeys() { + GameSettings settings = Minecraft.getMinecraft().gameSettings; + ArrayList harvestedBindings = Lists.newArrayList(); + for (KeyBinding kb : keyBindings) { + harvestedBindings.add(kb); + } + + KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]); + KeyBinding[] allKeys = new KeyBinding[settings.keyBindings.length + modKeyBindings.length]; + System.arraycopy(settings.keyBindings, 0, allKeys, 0, settings.keyBindings.length); + System.arraycopy(modKeyBindings, 0, allKeys, settings.keyBindings.length, modKeyBindings.length); + settings.keyBindings = allKeys; + settings.loadOptions(); + } } diff --git a/src/fuj1n/recmod/command/CommandRec.java b/src/fuj1n/recmod/command/CommandRec.java index c5c80b2..0f0a9fb 100644 --- a/src/fuj1n/recmod/command/CommandRec.java +++ b/src/fuj1n/recmod/command/CommandRec.java @@ -1,14 +1,15 @@ package fuj1n.recmod.command; -import cpw.mods.fml.common.network.*; -import fuj1n.recmod.RecMod; -import java.io.*; import java.util.*; + +import fuj1n.recmod.RecMod; +import fuj1n.recmod.network.packet.*; +import ibxm.Player; import net.minecraft.command.*; -import net.minecraft.network.packet.Packet250CustomPayload; +import net.minecraft.entity.player.*; import net.minecraft.network.rcon.RConConsoleSource; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.ChatMessageComponent; +import net.minecraft.util.ChatComponentText; public class CommandRec extends CommandBase { @@ -24,11 +25,11 @@ public String getCommandName() { @Override public String getCommandUsage(ICommandSender icommandsender) { - icommandsender.sendChatToPlayer(ChatMessageComponent.createFromText("\u00A7cRec Usage: ")); - icommandsender.sendChatToPlayer(ChatMessageComponent.createFromText("\u00A7c (displays an easy to use GUI)")); - icommandsender.sendChatToPlayer(ChatMessageComponent.createFromText("\u00A7c (toggle recording or streaming")); - icommandsender.sendChatToPlayer(ChatMessageComponent.createFromText("\u00A7c [p] (toggle self ui - p toggles disabled by default)")); - icommandsender.sendChatToPlayer(ChatMessageComponent.createFromText("\u00A7c (replace the texture sheet used)")); + icommandsender.addChatMessage(new ChatComponentText("\u00A7cRec Usage: ")); + icommandsender.addChatMessage(new ChatComponentText("\u00A7c (displays an easy to use GUI)")); + icommandsender.addChatMessage(new ChatComponentText("\u00A7c (toggle recording or streaming")); + icommandsender.addChatMessage(new ChatComponentText("\u00A7c [p] (toggle self ui - p toggles disabled by default)")); + icommandsender.addChatMessage(new ChatComponentText("\u00A7c (replace the texture sheet used)")); return "Wut?"; } @@ -51,9 +52,9 @@ public void processCommand(ICommandSender icommandsender, String[] astring) { } else if((astring.length == 2 || (astring.length == 3 && astring[2].equals("p"))) && astring[0].equals("ui") && (astring[1].equals("self") || astring[1].equals("sidebar")) && icommandsender instanceof Player){ boolean isSelf = astring[1].equals("self"); boolean isOverride = astring.length == 3 && astring[2].equals("p"); - sendUIUpdatePacket((Player)icommandsender, isSelf, isOverride); + sendUIUpdatePacket((EntityPlayer)icommandsender, isSelf, isOverride); } else if(astring.length == 2 && astring[0].equals("sheet")){ - sendSheetChangePacket((Player)icommandsender, astring[1]); + sendSheetChangePacket((EntityPlayer)icommandsender, astring[1]); } else if(astring.length == 1 && astring[0].equals("gui")){ } else { @@ -82,56 +83,22 @@ public void processCommand(ICommandSender icommandsender, String[] astring) { // } public void spreadData(String playerName, int typeData, boolean flag) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(8); - DataOutputStream outputStream = new DataOutputStream(bos); - try { - outputStream.writeUTF(playerName); - outputStream.writeInt(typeData); - outputStream.writeBoolean(flag); - } catch (Exception ex) { - ex.printStackTrace(); - } - - Packet250CustomPayload packet = new Packet250CustomPayload(); - packet.channel = "recModData"; - packet.data = bos.toByteArray(); - packet.length = bos.size(); - PacketDispatcher.sendPacketToAllPlayers(packet); + PacketUpdatePlayerStatus pckt = new PacketUpdatePlayerStatus(playerName, typeData, flag); + RecMod.packetPipeline.sendToAll(pckt); } - public void sendUIUpdatePacket(Player p, boolean isSelf, boolean isOverride){ - ByteArrayOutputStream bos = new ByteArrayOutputStream(8); - DataOutputStream outputStream = new DataOutputStream(bos); - try { - outputStream.writeInt(0); - outputStream.writeBoolean(isSelf); - outputStream.writeBoolean(isOverride); - } catch (Exception ex) { - ex.printStackTrace(); + public void sendUIUpdatePacket(EntityPlayer p, boolean isSelf, boolean isOverride){ + if(p instanceof EntityPlayerMP){ + PacketChangeUISettings pckt = new PacketChangeUISettings(isSelf, isOverride); + RecMod.packetPipeline.sendTo(pckt, (EntityPlayerMP)p); } - - Packet250CustomPayload packet = new Packet250CustomPayload(); - packet.channel = "recModUI"; - packet.data = bos.toByteArray(); - packet.length = bos.size(); - PacketDispatcher.sendPacketToPlayer(packet, p); } - public void sendSheetChangePacket(Player p, String newSheet){ - ByteArrayOutputStream bos = new ByteArrayOutputStream(8); - DataOutputStream outputStream = new DataOutputStream(bos); - try { - outputStream.writeInt(1); - outputStream.writeUTF(newSheet); - } catch (Exception ex) { - ex.printStackTrace(); + public void sendSheetChangePacket(EntityPlayer p, String newSheet){ + if(p instanceof EntityPlayerMP){ + PacketChangeUISheet pckt = new PacketChangeUISheet(newSheet); + RecMod.packetPipeline.sendTo(pckt, (EntityPlayerMP)p); } - - Packet250CustomPayload packet = new Packet250CustomPayload(); - packet.channel = "recModUI"; - packet.data = bos.toByteArray(); - packet.length = bos.size(); - PacketDispatcher.sendPacketToPlayer(packet, p); } @Override diff --git a/src/fuj1n/recmod/network/PacketHandler.java b/src/fuj1n/recmod/network/PacketHandler.java deleted file mode 100644 index 7ee39cf..0000000 --- a/src/fuj1n/recmod/network/PacketHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -package fuj1n.recmod.network; - -import net.minecraft.util.ChatMessageComponent; - -import cpw.mods.fml.common.network.*; -import fuj1n.recmod.RecMod; -import java.io.*; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.INetworkManager; -import net.minecraft.network.packet.Packet250CustomPayload; - -public class PacketHandler implements IPacketHandler { - - @Override - public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { - DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(packet.data)); - if (packet.channel.equals("recModData")) { - String playerName = ""; - int typeData = 0; - boolean flag = false; - - try { - playerName = inputStream.readUTF(); - typeData = inputStream.readInt(); - flag = inputStream.readBoolean(); - - } catch (IOException e) { - e.printStackTrace(); - } - RecMod.instance.updatePlayerInformation(playerName, typeData, flag); - } else if (packet.channel.equals("recModDataC")) { - String playerName = ""; - - try{ - playerName = inputStream.readUTF(); - }catch(IOException e){ - e.printStackTrace(); - } - RecMod.instance.removeUnneededData(playerName); - } else if (packet.channel.equals("recModUI")) { - int type = -1; - try { - type = inputStream.readInt(); - } catch (IOException e) { - e.printStackTrace(); - } - if (type == 0) { - boolean isSelf = false; - boolean isOverride = false; - - try { - isSelf = inputStream.readBoolean(); - isOverride = inputStream.readBoolean(); - } catch (IOException e) { - e.printStackTrace(); - } - - if (isSelf) { - RecMod.instance.showSelf = !RecMod.instance.showSelf; - RecMod.instance.showSelfDef = isOverride ? !RecMod.instance.showSelfDef : RecMod.instance.showSelfDef; - - RecMod.instance.onUIStateChanged(); - } else { - RecMod.instance.showUI = !RecMod.instance.showUI; - - RecMod.instance.onUIStateChanged(); - } - }else if(type == 1){ - String newSheet = RecMod.instance.sheetLocation; - - try { - newSheet = inputStream.readUTF(); - } catch (IOException e) { - e.printStackTrace(); - } - - net.minecraft.util.ResourceLocation testLocation = new net.minecraft.util.ResourceLocation(newSheet); -// if(!new File(testLocation.getResourcePath()).exists()){ -// if(player instanceof EntityPlayer){ -// ((EntityPlayer)player).sendChatToPlayer(ChatMessageComponent.createFromText("Location not found: " + testLocation.getResourcePath())); -// } -// }else{ - RecMod.instance.sheetLocation = newSheet; - RecMod.instance.onSheetChanged(); -// } - } - } - } -} diff --git a/src/fuj1n/recmod/network/PlayerTracker.java b/src/fuj1n/recmod/network/PlayerTracker.java index 1ea4039..7decc73 100644 --- a/src/fuj1n/recmod/network/PlayerTracker.java +++ b/src/fuj1n/recmod/network/PlayerTracker.java @@ -1,55 +1,35 @@ package fuj1n.recmod.network; -import cpw.mods.fml.common.*; -import cpw.mods.fml.common.network.PacketDispatcher; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; +import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent; import cpw.mods.fml.relauncher.Side; import fuj1n.recmod.RecMod; -import java.io.*; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.packet.Packet250CustomPayload; +import fuj1n.recmod.network.packet.PacketRemovePlayer; -public class PlayerTracker implements IPlayerTracker { +public class PlayerTracker { - @Override - public void onPlayerLogin(EntityPlayer player) { + @SubscribeEvent + public void onPlayerLogin(PlayerLoggedInEvent event) { if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { - RecMod.instance.updatePlayerInformation(player.getCommandSenderName(), 0, false); - RecMod.instance.updatePlayerInformation(player.getCommandSenderName(), 1, false); - RecMod.instance.sendDataToPlayer(player); + RecMod.instance.updatePlayerInformation(event.player.getCommandSenderName(), 0, false); + RecMod.instance.updatePlayerInformation(event.player.getCommandSenderName(), 1, false); + RecMod.instance.sendDataToPlayer(event.player); } } - @Override - public void onPlayerLogout(EntityPlayer player) { + @SubscribeEvent + public void onPlayerLogout(PlayerLoggedOutEvent event) { if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { - removePlayerName(player.getCommandSenderName()); + removePlayerName(event.player.getCommandSenderName()); } } public void removePlayerName(String name) { RecMod.instance.removeUnneededData(name); - ByteArrayOutputStream bos = new ByteArrayOutputStream(8); - DataOutputStream outputStream = new DataOutputStream(bos); - try { - outputStream.writeUTF(name); - } catch (Exception ex) { - ex.printStackTrace(); - } - - Packet250CustomPayload packet = new Packet250CustomPayload(); - packet.channel = "recModDataC"; - packet.data = bos.toByteArray(); - packet.length = bos.size(); - PacketDispatcher.sendPacketToAllPlayers(packet); - } - - @Override - public void onPlayerChangedDimension(EntityPlayer player) { + PacketRemovePlayer pckt = new PacketRemovePlayer(name); + RecMod.packetPipeline.sendToAll(pckt); } - - @Override - public void onPlayerRespawn(EntityPlayer player) { - } - } diff --git a/src/fuj1n/recmod/network/packet/AbstractPacket.java b/src/fuj1n/recmod/network/packet/AbstractPacket.java new file mode 100644 index 0000000..c9f7fa8 --- /dev/null +++ b/src/fuj1n/recmod/network/packet/AbstractPacket.java @@ -0,0 +1,43 @@ +package fuj1n.recmod.network.packet; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +import net.minecraft.entity.player.EntityPlayer; + +/** + * AbstractPacket class. Should be the parent of all packets wishing to use the PacketPipeline. + * @author sirgingalot + */ +public abstract class AbstractPacket { + + /** + * Encode the packet data into the ByteBuf stream. Complex data sets may need specific data handlers (See @link{cpw.mods.fml.common.network.ByteBuffUtils}) + * + * @param ctx channel context + * @param buffer the buffer to encode into + */ + public abstract void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer); + + /** + * Decode the packet data from the ByteBuf stream. Complex data sets may need specific data handlers (See @link{cpw.mods.fml.common.network.ByteBuffUtils}) + * + * @param ctx channel context + * @param buffer the buffer to decode from + */ + public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer); + + /** + * Handle a packet on the client side. Note this occurs after decoding has completed. + * + * @param player the player reference + */ + public abstract void handleClientSide(EntityPlayer player); + + /** + * Handle a packet on the server side. Note this occurs after decoding has completed. + * + * @param player the player reference + */ + public abstract void handleServerSide(EntityPlayer player); +} diff --git a/src/fuj1n/recmod/network/packet/PacketChangeUISettings.java b/src/fuj1n/recmod/network/packet/PacketChangeUISettings.java new file mode 100644 index 0000000..a34e16e --- /dev/null +++ b/src/fuj1n/recmod/network/packet/PacketChangeUISettings.java @@ -0,0 +1,49 @@ +package fuj1n.recmod.network.packet; + +import fuj1n.recmod.RecMod; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.entity.player.EntityPlayer; + +public class PacketChangeUISettings extends AbstractPacket { + + private boolean isSelf, isOverride; + + public PacketChangeUISettings(boolean isSelf, boolean isOverride) { + this.isSelf = isSelf; + this.isOverride = isOverride; + } + + public PacketChangeUISettings() {} + + @Override + public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + buffer.writeBoolean(isSelf); + buffer.writeBoolean(isOverride); + } + + @Override + public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + isSelf = buffer.readBoolean(); + isOverride = buffer.readBoolean(); + } + + @Override + public void handleClientSide(EntityPlayer player) { + if (isSelf) { + RecMod.instance.showSelf = !RecMod.instance.showSelf; + RecMod.instance.showSelfDef = isOverride ? !RecMod.instance.showSelfDef : RecMod.instance.showSelfDef; + + RecMod.instance.onUIStateChanged(); + } else { + RecMod.instance.showUI = !RecMod.instance.showUI; + + RecMod.instance.onUIStateChanged(); + } + } + + @Override + public void handleServerSide(EntityPlayer player) {} + +} diff --git a/src/fuj1n/recmod/network/packet/PacketChangeUISheet.java b/src/fuj1n/recmod/network/packet/PacketChangeUISheet.java new file mode 100644 index 0000000..812d091 --- /dev/null +++ b/src/fuj1n/recmod/network/packet/PacketChangeUISheet.java @@ -0,0 +1,39 @@ +package fuj1n.recmod.network.packet; + +import fuj1n.recmod.RecMod; + +import cpw.mods.fml.common.network.ByteBufUtils; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.entity.player.EntityPlayer; + +public class PacketChangeUISheet extends AbstractPacket { + + String newSheet; + + public PacketChangeUISheet(String newSheet) { + this.newSheet = newSheet; + } + + public PacketChangeUISheet() {} + + @Override + public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + ByteBufUtils.writeUTF8String(buffer, newSheet); + } + + @Override + public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + newSheet = ByteBufUtils.readUTF8String(buffer); + } + + @Override + public void handleClientSide(EntityPlayer player) { + RecMod.instance.sheetLocation = newSheet; + RecMod.instance.onSheetChanged(); + } + + @Override + public void handleServerSide(EntityPlayer player) {} +} diff --git a/src/fuj1n/recmod/network/packet/PacketPipeline.java b/src/fuj1n/recmod/network/packet/PacketPipeline.java new file mode 100644 index 0000000..a763485 --- /dev/null +++ b/src/fuj1n/recmod/network/packet/PacketPipeline.java @@ -0,0 +1,209 @@ +package fuj1n.recmod.network.packet; + +import java.util.*; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageCodec; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.network.FMLEmbeddedChannel; +import cpw.mods.fml.common.network.FMLOutboundHandler; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLProxyPacket; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * Packet pipeline class. Directs all registered packet data to be handled by the packets themselves. + * @author sirgingalot + * some code from: cpw + */ +@ChannelHandler.Sharable +public class PacketPipeline extends MessageToMessageCodec { + + private EnumMap channels; + private LinkedList> packets = new LinkedList>(); + private boolean isPostInitialised = false; + + /** + * Register your packet with the pipeline. Discriminators are automatically set. + * + * @param clazz the class to register + * + * @return whether registration was successful. Failure may occur if 256 packets have been registered or if the registry already contains this packet + */ + public boolean registerPacket(Class clazz) { + if (this.packets.size() > 256) { + // TODO Log + return false; + } + + if (this.packets.contains(clazz)) { + // TODO Log + return false; + } + + if (this.isPostInitialised) { + // TODO Log + return false; + } + + this.packets.add(clazz); + return true; + } + + // In line encoding of the packet, including discriminator setting + @Override + protected void encode(ChannelHandlerContext ctx, AbstractPacket msg, List out) throws Exception { + ByteBuf buffer = Unpooled.buffer(); + Class clazz = msg.getClass(); + if (!this.packets.contains(msg.getClass())) { + throw new NullPointerException("No Packet Registered for: " + msg.getClass().getCanonicalName()); + } + + byte discriminator = (byte) this.packets.indexOf(clazz); + buffer.writeByte(discriminator); + msg.encodeInto(ctx, buffer); + FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get()); + out.add(proxyPacket); + } + + // In line decoding and handling of the packet + @Override + protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List out) throws Exception { + ByteBuf payload = msg.payload(); + byte discriminator = payload.readByte(); + Class clazz = this.packets.get(discriminator); + if (clazz == null) { + throw new NullPointerException("No packet registered for discriminator: " + discriminator); + } + + AbstractPacket pkt = clazz.newInstance(); + pkt.decodeInto(ctx, payload.slice()); + + EntityPlayer player; + switch (FMLCommonHandler.instance().getEffectiveSide()) { + case CLIENT: + player = this.getClientPlayer(); + pkt.handleClientSide(player); + break; + + case SERVER: + INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); + player = ((NetHandlerPlayServer) netHandler).playerEntity; + pkt.handleServerSide(player); + break; + + default: + } + + out.add(pkt); + } + + // Method to call from FMLInitializationEvent + public void initialise() { + this.channels = NetworkRegistry.INSTANCE.newChannel("fuj1n.RecMod", this); + } + + // Method to call from FMLPostInitializationEvent + // Ensures that packet discriminators are common between server and client by using logical sorting + public void postInitialise() { + if (this.isPostInitialised) { + return; + } + + this.isPostInitialised = true; + Collections.sort(this.packets, new Comparator>() { + + @Override + public int compare(Class clazz1, Class clazz2) { + int com = String.CASE_INSENSITIVE_ORDER.compare(clazz1.getCanonicalName(), clazz2.getCanonicalName()); + if (com == 0) { + com = clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName()); + } + + return com; + } + }); + } + + @SideOnly(Side.CLIENT) + private EntityPlayer getClientPlayer() { + return Minecraft.getMinecraft().thePlayer; + } + + /** + * Send this message to everyone. + *

+ * Adapted from CPW's code in cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper + * + * @param message The message to send + */ + public void sendToAll(AbstractPacket message) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + /** + * Send this message to the specified player. + *

+ * Adapted from CPW's code in cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper + * + * @param message The message to send + * @param player The player to send it to + */ + public void sendTo(AbstractPacket message, EntityPlayerMP player) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + /** + * Send this message to everyone within a certain range of a point. + *

+ * Adapted from CPW's code in cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper + * + * @param message The message to send + * @param point The {@link cpw.mods.fml.common.network.NetworkRegistry.TargetPoint} around which to send + */ + public void sendToAllAround(AbstractPacket message, NetworkRegistry.TargetPoint point) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + /** + * Send this message to everyone within the supplied dimension. + *

+ * Adapted from CPW's code in cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper + * + * @param message The message to send + * @param dimensionId The dimension id to target + */ + public void sendToDimension(AbstractPacket message, int dimensionId) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + /** + * Send this message to the server. + *

+ * Adapted from CPW's code in cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper + * + * @param message The message to send + */ + public void sendToServer(AbstractPacket message) { + this.channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); + this.channels.get(Side.CLIENT).writeAndFlush(message); + } +} \ No newline at end of file diff --git a/src/fuj1n/recmod/network/packet/PacketRemovePlayer.java b/src/fuj1n/recmod/network/packet/PacketRemovePlayer.java new file mode 100644 index 0000000..e119ff1 --- /dev/null +++ b/src/fuj1n/recmod/network/packet/PacketRemovePlayer.java @@ -0,0 +1,41 @@ +package fuj1n.recmod.network.packet; + +import java.io.IOException; + +import fuj1n.recmod.RecMod; + +import cpw.mods.fml.common.network.ByteBufUtils; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.entity.player.EntityPlayer; + +public class PacketRemovePlayer extends AbstractPacket { + + private String player; + + public PacketRemovePlayer(String player){ + this.player = player; + } + + public PacketRemovePlayer(){} + + @Override + public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + ByteBufUtils.writeUTF8String(buffer, player); + } + + @Override + public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + player = ByteBufUtils.readUTF8String(buffer); + } + + @Override + public void handleClientSide(EntityPlayer player) { + RecMod.instance.removeUnneededData(this.player); + } + + @Override + public void handleServerSide(EntityPlayer player) {} + +} diff --git a/src/fuj1n/recmod/network/packet/PacketUpdatePlayerStatus.java b/src/fuj1n/recmod/network/packet/PacketUpdatePlayerStatus.java new file mode 100644 index 0000000..52be751 --- /dev/null +++ b/src/fuj1n/recmod/network/packet/PacketUpdatePlayerStatus.java @@ -0,0 +1,48 @@ +package fuj1n.recmod.network.packet; + +import java.io.IOException; + +import fuj1n.recmod.RecMod; + +import cpw.mods.fml.common.network.ByteBufUtils; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.entity.player.EntityPlayer; + +public class PacketUpdatePlayerStatus extends AbstractPacket { + + private String player; + private int type; + private boolean flag; + + public PacketUpdatePlayerStatus(String player, int type, boolean flag) { + this.player = player; + this.type = type; + this.flag = flag; + } + + public PacketUpdatePlayerStatus() {} + + @Override + public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + ByteBufUtils.writeUTF8String(buffer, player); + buffer.writeInt(type); + buffer.writeBoolean(flag); + } + + @Override + public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { + player = ByteBufUtils.readUTF8String(buffer); + type = buffer.readInt(); + flag = buffer.readBoolean(); + } + + @Override + public void handleClientSide(EntityPlayer player) { + RecMod.instance.updatePlayerInformation(this.player, type, flag); + } + + @Override + public void handleServerSide(EntityPlayer player) {} + +}