├── .github
└── workflows
│ └── maven.yml
├── README.md
├── pom.xml
├── screenshot.png
└── src
└── main
└── java
└── com
└── cubk
└── nsc2
├── Agent.java
├── JavaPlugin.java
├── NSC.java
├── gui
├── AddressSwapperFrame.java
└── DebugFrame.java
├── handler
├── PacketManager.java
├── PacketProcessor.java
└── ThreadScanner.java
├── module
├── Module.java
└── modules
│ ├── AbuseDetector.java
│ └── MotionCalculator.java
├── packet
├── ClientPacketWrapper.java
├── Packet.java
├── PacketData.java
├── ServerPacketWrapper.java
├── ToString.java
└── wrappers
│ ├── client
│ ├── C00PacketKeepAlive.java
│ ├── C01PacketChatMessage.java
│ ├── C02PacketUseEntity.java
│ ├── C03PacketPlayer.java
│ ├── C04PacketPlayerPosition.java
│ ├── C05PacketPlayerLook.java
│ ├── C06PacketPlayerPosLook.java
│ ├── C07PacketPlayerDigging.java
│ ├── C08PacketPlayerBlockPlacement.java
│ ├── C09PacketHeldItemChange.java
│ ├── C0APacketAnimation.java
│ ├── C0BPacketEntityAction.java
│ ├── C0CPacketInput.java
│ ├── C0DPacketCloseWindow.java
│ ├── C0EPacketClickWindow.java
│ ├── C0FPacketConfirmTransaction.java
│ ├── C10PacketCreativeInventoryAction.java
│ ├── C11PacketEnchantItem.java
│ ├── C13PacketPlayerAbilities.java
│ ├── C14PacketTabComplete.java
│ └── C17PacketCustomPayload.java
│ └── server
│ └── S12PacketEntityVelocity.java
├── plugin
├── Parser.java
├── PluginAPI.java
├── PluginData.java
└── PluginLoader.java
├── struct
├── Constant.java
├── EnumFacing.java
├── ItemStack.java
├── Position.java
├── Vector3.java
└── nbt
│ ├── NBTBase.java
│ ├── NBTException.java
│ ├── NBTSizeTracker.java
│ ├── NBTTagByte.java
│ ├── NBTTagByteArray.java
│ ├── NBTTagCompound.java
│ ├── NBTTagDouble.java
│ ├── NBTTagEnd.java
│ ├── NBTTagFloat.java
│ ├── NBTTagInt.java
│ ├── NBTTagIntArray.java
│ ├── NBTTagList.java
│ ├── NBTTagLong.java
│ ├── NBTTagShort.java
│ └── NBTTagString.java
├── transformer
├── Transformer.java
├── TransformerManager.java
└── transformers
│ └── BootstrapTransformer.java
└── util
├── MathHelper.java
├── MathUtil.java
└── TimerUtil.java
/.github/workflows/maven.yml:
--------------------------------------------------------------------------------
1 | name: Build and Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - Dev
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repository
14 | uses: actions/checkout@v2
15 |
16 | - name: Set up Java
17 | uses: actions/setup-java@v2
18 | with:
19 | java-version: '17'
20 | distribution: 'adopt'
21 |
22 | - name: Build JAR
23 | run: mvn package
24 |
25 | - name: Upload JAR
26 | uses: actions/upload-artifact@v2
27 | with:
28 | name: Release
29 | path: target/NSC2-2.0.jar
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NSC2
2 |
3 | A Packet logger for minecraft 1.8.9 (WIP)
4 |
5 | Just for fun, do not use this project to steal any client's bypasses (except sleep).
6 |
7 | ## Features
8 |
9 | - Log obfuscated client (tested: faiths, novoline, moon, phantom)
10 | - Decode packet detailed information
11 | - Work in online server
12 | - Calculate timer speed
13 | - Display real motionXYZ bps and position
14 |
15 | ## Function not implemented
16 |
17 | - Support 1.8.9 only, Incompatible with viaversion
18 | - Packet decoding only available for client packet
19 |
20 | ## Usage
21 |
22 | - Call `NSC.getInstance().start();` using any method.
23 | - Use Agent `-javaagent:NSC2.jar`
24 |
25 | 
26 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | com.cubk
7 | NSC2
8 | 2.0
9 |
10 |
11 | 1.8
12 | 1.8
13 | UTF-8
14 | UTF-8
15 | UTF-8
16 | 9.6
17 |
18 |
19 |
20 |
21 | org.ow2.asm
22 | asm
23 | ${asm.version}
24 |
25 |
26 | org.ow2.asm
27 | asm-tree
28 | ${asm.version}
29 |
30 |
31 | org.ow2.asm
32 | asm-util
33 | ${asm.version}
34 |
35 |
36 | org.ow2.asm
37 | asm-analysis
38 | ${asm.version}
39 |
40 |
41 | org.ow2.asm
42 | asm-commons
43 | ${asm.version}
44 |
45 |
46 | io.netty
47 | netty-all
48 | 4.0.23.Final
49 | provided
50 |
51 |
52 | com.google.code.gson
53 | gson
54 | 2.2.4
55 | provided
56 |
57 |
58 | org.projectlombok
59 | lombok
60 | 1.18.22
61 | provided
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-assembly-plugin
70 | 3.6.0
71 |
72 |
73 | jar-with-dependencies
74 |
75 |
76 |
77 | com.cubk.nsc2.Agent
78 | true
79 |
80 |
81 |
82 |
83 |
84 |
85 | make-assembly
86 | package
87 |
88 | single
89 |
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-compiler-plugin
96 | 3.10.1
97 |
98 | 1.8
99 | 1.8
100 |
101 |
102 | org.projectlombok
103 | lombok
104 | 1.18.22
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/union4dev/MinecraftPacketLogger/f63de7ae4130a08f71ff13b51fced04ccc08915a/screenshot.png
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/Agent.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2;
2 |
3 | import com.cubk.nsc2.transformer.TransformerManager;
4 |
5 | import java.lang.instrument.Instrumentation;
6 |
7 | public class Agent {
8 | public static Instrumentation instrumentation;
9 |
10 | public static void premain(String args, Instrumentation instrumentation) {
11 | System.out.println("[NSC] Loaded.");
12 | Agent.instrumentation = instrumentation;
13 | instrumentation.addTransformer(new TransformerManager());
14 | NSC.getInstance().start();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/JavaPlugin.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2;
2 |
3 | import com.cubk.nsc2.plugin.PluginData;
4 |
5 | public interface JavaPlugin {
6 |
7 | ThreadLocal descriptionFile = new ThreadLocal<>();
8 |
9 | void onLoad();
10 |
11 | void onUnload();
12 |
13 | default PluginData getDescriptionFile() {
14 | return descriptionFile.get();
15 | }
16 |
17 | default void setDescriptionFile(PluginData descriptionFile) {
18 | if (this.descriptionFile.get() != null) {
19 | throw new RuntimeException("Can't set the description file. Its already set!");
20 | }
21 | this.descriptionFile.set(descriptionFile);
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/NSC.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2;
2 |
3 | import com.cubk.nsc2.gui.DebugFrame;
4 | import com.cubk.nsc2.handler.PacketManager;
5 | import com.cubk.nsc2.handler.PacketProcessor;
6 | import com.cubk.nsc2.handler.ThreadScanner;
7 | import com.cubk.nsc2.plugin.PluginAPI;
8 | import com.cubk.nsc2.plugin.PluginLoader;
9 | import lombok.Getter;
10 |
11 | import java.io.File;
12 | import java.io.PrintWriter;
13 | import java.io.StringWriter;
14 |
15 | public class NSC {
16 |
17 | @Getter
18 | private PacketProcessor packetProcessor;
19 |
20 | private DebugFrame debugFrame;
21 | @Getter
22 | private PluginAPI pluginAPI;
23 |
24 | @Getter
25 | private static NSC instance = new NSC();
26 |
27 | public static void printStacktrace(Throwable throwable) {
28 | throwable.printStackTrace();
29 | }
30 |
31 | public DebugFrame getClickGui() {
32 | return debugFrame;
33 | }
34 |
35 | public String getStacktrace(final Throwable throwable) {
36 | final StringWriter sw = new StringWriter();
37 | final PrintWriter pw = new PrintWriter(sw, true);
38 | throwable.printStackTrace(pw);
39 | return sw.getBuffer().toString();
40 | }
41 |
42 | public void start() {
43 | System.out.println("[NSC] Initializing...");
44 | instance = this;
45 |
46 | File plugins = new File("nsc_plugins");
47 |
48 | if (!plugins.exists())
49 | plugins.mkdir();
50 |
51 | PacketManager packetManager = new PacketManager();
52 | packetProcessor = new PacketProcessor();
53 |
54 | new ThreadScanner().start();
55 | new Thread(packetManager::onLoop).start();
56 |
57 | pluginAPI = PluginAPI.getApi(pluginLoader -> new PluginLoader(), "loader");
58 | System.out.println("[NSC] Loading plugins form " + plugins.getAbsolutePath());
59 | pluginAPI.loadAll(plugins);
60 |
61 | debugFrame = new DebugFrame();
62 | debugFrame.setVisible(true);
63 |
64 |
65 | }
66 |
67 | public static native void log(String string);
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/gui/AddressSwapperFrame.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.gui;
2 |
3 | import lombok.Getter;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 |
8 | public class AddressSwapperFrame extends JFrame {
9 | @Getter
10 | private static JCheckBox use = new JCheckBox("Use Address Swapper");
11 | @Getter
12 | private static JTextField originalHostField;
13 | @Getter
14 | private static JTextField targetServerField;
15 | @Getter
16 | private static JTextField targetPortField;
17 |
18 | public AddressSwapperFrame() {
19 | setTitle("Address Swapper");
20 | setLayout(new GridBagLayout());
21 | setAlwaysOnTop(true);
22 | GridBagConstraints gbc = new GridBagConstraints();
23 | gbc.insets = new Insets(5, 5, 5, 5);
24 | originalHostField = new JTextField("mc.hypixel.net");
25 | targetServerField = new JTextField();
26 | targetPortField = new JTextField("25565");
27 |
28 | Dimension textFieldDimension = new Dimension(200, 25);
29 | originalHostField.setPreferredSize(textFieldDimension);
30 | targetServerField.setPreferredSize(textFieldDimension);
31 | targetPortField.setPreferredSize(textFieldDimension);
32 |
33 | JButton confirmButton = new JButton("Dispose");
34 | confirmButton.addActionListener(e -> dispose());
35 |
36 | gbc.gridx = 0;
37 | gbc.gridy = 0;
38 | add(new JLabel("Enable"), gbc);
39 | gbc.gridx = 1;
40 | add(use, gbc);
41 |
42 | gbc.gridx = 0;
43 | gbc.gridy = 1;
44 | add(new JLabel("Original Host:"), gbc);
45 | gbc.gridx = 1;
46 | add(originalHostField, gbc);
47 |
48 | gbc.gridx = 0;
49 | gbc.gridy = 2;
50 | add(new JLabel("Target Server:"), gbc);
51 | gbc.gridx = 1;
52 | add(targetServerField, gbc);
53 |
54 | gbc.gridx = 0;
55 | gbc.gridy = 3;
56 | add(new JLabel("Target Port:"), gbc);
57 | gbc.gridx = 1;
58 | add(targetPortField, gbc);
59 |
60 | gbc.gridx = 1;
61 | gbc.gridy = 4;
62 | add(confirmButton, gbc);
63 |
64 | pack();
65 | setLocationRelativeTo(null);
66 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/gui/DebugFrame.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.gui;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 |
5 | import javax.swing.*;
6 | import javax.swing.table.DefaultTableModel;
7 | import java.awt.*;
8 | import java.awt.event.MouseAdapter;
9 | import java.awt.event.MouseEvent;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | public class DebugFrame extends JFrame {
15 | private final JTable packetTable;
16 | private final JTable packetInfoTable;
17 | private final JTextArea logTextArea;
18 | private final JTextArea otherInfoTextArea;
19 | private final JTextField searchField;
20 | private final JCheckBox clientCheckBox;
21 | private final JCheckBox serverCheckBox;
22 | private final JButton startPauseButton;
23 | private JLabel data;
24 | private final Map> dataMap = new HashMap<>();
25 | private boolean isRunning = false;
26 |
27 | public DebugFrame() {
28 | super("N.S.C. 2.0");
29 | String[] columnNames = {"#", "Event Type", "Event Data", "Side", "Timestamp"};
30 | DefaultTableModel tableModel = new DefaultTableModel(columnNames, 0) {
31 | @Override
32 | public boolean isCellEditable(int row, int column) {
33 | return false;
34 | }
35 | };
36 | packetTable = new JTable(tableModel);
37 |
38 | packetTable.addMouseListener(new MouseAdapter() {
39 | public void mouseClicked(MouseEvent e) {
40 | if (e.getClickCount() == 2) {
41 | int selectedRow = packetTable.getSelectedRow();
42 | DefaultTableModel infoTableModel = (DefaultTableModel) packetInfoTable.getModel();
43 | infoTableModel.setRowCount(0);
44 | for (PacketData.Data data : dataMap.get(Integer.parseInt(tableModel.getValueAt(selectedRow, 0).toString()))) {
45 | infoTableModel.addRow(new Object[]{data.type.getSimpleName(), data.name, data.value});
46 | }
47 | }
48 | }
49 | });
50 |
51 | searchField = new JTextField(20);
52 | clientCheckBox = new JCheckBox("Client");
53 | clientCheckBox.setSelected(true);
54 | serverCheckBox = new JCheckBox("Server");
55 | serverCheckBox.setSelected(false);
56 |
57 | JButton searchButton = new JButton("Search");
58 | searchButton.addActionListener(e -> searchPackets());
59 |
60 | String[] infoColumnNames = {"Data Type", "Data Name", "Data"};
61 | DefaultTableModel infoTableModel = new DefaultTableModel(infoColumnNames, 0) {
62 | @Override
63 | public boolean isCellEditable(int row, int column) {
64 | return false;
65 | }
66 | };
67 | packetInfoTable = new JTable(infoTableModel);
68 |
69 | JTabbedPane tabbedPane = new JTabbedPane();
70 | logTextArea = new JTextArea();
71 | logTextArea.setFont(new Font("Consolas", Font.PLAIN, 12));
72 | otherInfoTextArea = new JTextArea();
73 |
74 | tabbedPane.addTab("Log", new JScrollPane(logTextArea));
75 | tabbedPane.addTab("Packet Information", new JScrollPane(packetInfoTable));
76 | tabbedPane.addTab("Other Information", new JScrollPane(otherInfoTextArea));
77 |
78 | JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
79 | splitPane.setTopComponent(createUpperPanel());
80 | splitPane.setBottomComponent(tabbedPane);
81 | splitPane.setResizeWeight(0.7);
82 |
83 | startPauseButton = new JButton("Start");
84 | startPauseButton.addActionListener(e -> {
85 | if (isRunning) {
86 | stop();
87 | } else {
88 | run();
89 | }
90 | });
91 |
92 | setLayout(new BorderLayout());
93 | add(splitPane, BorderLayout.CENTER);
94 | add(startPauseButton, BorderLayout.SOUTH);
95 |
96 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
97 | setSize(800, 600);
98 | setLocationRelativeTo(null);
99 |
100 | JMenuBar menuBar = createMenu();
101 | setJMenuBar(menuBar);
102 | }
103 |
104 | private static JMenuBar createMenu() {
105 | JMenuBar menuBar = new JMenuBar();
106 | JMenu toolMenu = new JMenu("Tools");
107 |
108 | JMenuItem swapperItem = new JMenuItem("Address Swapper");
109 | swapperItem.addActionListener(e -> new AddressSwapperFrame().setVisible(true));
110 |
111 | toolMenu.add(swapperItem);
112 |
113 | menuBar.add(toolMenu);
114 | return menuBar;
115 | }
116 |
117 | private JPanel createUpperPanel() {
118 | JPanel upperPanel = new JPanel(new BorderLayout());
119 | JPanel topPanel = new JPanel(new FlowLayout());
120 | topPanel.add(searchField);
121 | topPanel.add(clientCheckBox);
122 | topPanel.add(serverCheckBox);
123 | topPanel.add(new JButton("Search"));
124 | topPanel.add(data = new JLabel("Data"));
125 | upperPanel.add(topPanel, BorderLayout.NORTH);
126 |
127 | JScrollPane scrollPane = new JScrollPane(packetTable);
128 | scrollPane.setAutoscrolls(true);
129 | upperPanel.add(scrollPane, BorderLayout.CENTER);
130 |
131 | return upperPanel;
132 | }
133 |
134 |
135 | private void searchPackets() {
136 | String searchText = searchField.getText().toLowerCase();
137 |
138 | // TODO
139 | }
140 |
141 | private void run() {
142 | isRunning = true;
143 | startPauseButton.setText("Pause");
144 | }
145 |
146 | private void stop() {
147 | isRunning = false;
148 | startPauseButton.setText("Start");
149 | }
150 |
151 | public void addPacket(PacketData packetData) {
152 | if (!isRunning) return;
153 |
154 | if (!serverCheckBox.isSelected() && !packetData.outgoing) return;
155 | if (!clientCheckBox.isSelected() && packetData.outgoing) return;
156 |
157 | DefaultTableModel tableModel = (DefaultTableModel) packetTable.getModel();
158 | String[] rowData = {String.valueOf(tableModel.getRowCount() + 1), packetData.packetClass.getSimpleName(), packetData.packetName, packetData.outgoing ? "Outgoing" : "Incoming", String.valueOf(packetData.time)};
159 | tableModel.addRow(rowData);
160 |
161 | dataMap.put(tableModel.getRowCount(), packetData.getDataList());
162 |
163 | int rowCount = packetTable.getRowCount();
164 | if (rowCount > 0) {
165 | Rectangle rect = packetTable.getCellRect(rowCount - 1, 0, true);
166 | packetTable.scrollRectToVisible(rect);
167 | }
168 | }
169 |
170 | public void log(String message, String suffix) {
171 | logTextArea.append(String.format("[%s][%s] %s", System.currentTimeMillis(), suffix, message) + "\n");
172 | }
173 |
174 | public void setOtherInfo(String info) {
175 | otherInfoTextArea.setText(info);
176 | }
177 |
178 | public void setData(String info) {
179 | data.setText(info);
180 | }
181 |
182 | }
183 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/handler/PacketManager.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.handler;
2 |
3 | import com.cubk.nsc2.NSC;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.Constant;
6 | import io.netty.buffer.ByteBuf;
7 | import io.netty.buffer.Unpooled;
8 | import io.netty.channel.*;
9 |
10 | import javax.swing.*;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Method;
13 |
14 | public class PacketManager {
15 |
16 | public void onLoop() {
17 | while (true) {
18 | try {
19 | Object nh = Constant.method_getNetHandler.invoke(Constant.object_theMinecraft);
20 | if (nh != null) {
21 | Object nm = Constant.method_getNetworkManager.invoke(nh);
22 | if (nm != null)
23 | inject(Constant.method_getNetworkManager.getReturnType(), nm);
24 | }
25 |
26 | } catch (Exception ignored) {
27 | }
28 | }
29 | }
30 |
31 | public void inject(Class> netClass, Object networkManager) {
32 | Channel channel = null;
33 |
34 | for (Field field : netClass.getDeclaredFields()) {
35 | try {
36 | if (field.getType().getName().equals("io.netty.channel.Channel")) {
37 | try {
38 | field.setAccessible(true);
39 | channel = (Channel) field.get(networkManager);
40 | } catch (Exception e) {
41 | NSC.printStacktrace(e);
42 | }
43 | }
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | }
47 | }
48 | if (channel != null) {
49 | ChannelPipeline pipeline = channel.pipeline();
50 | if (pipeline.context(PacketListener.class) == null && pipeline.context("packet_handler") != null) {
51 | channel.pipeline().addBefore("packet_handler", "lunarclient", new PacketListener());
52 |
53 | }
54 |
55 | } else {
56 | JOptionPane.showMessageDialog(null, "Error [2]", "Internal error, failed to initialize\nNo channel found", JOptionPane.ERROR_MESSAGE);
57 | }
58 | }
59 | }
60 |
61 | class PacketListener extends ChannelDuplexHandler {
62 | @Override
63 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
64 | PacketData wrapper = new PacketData(msg.getClass(), msg.getClass().getSimpleName(), false);
65 | if (!handle(false, msg, wrapper))
66 | super.channelRead(ctx, msg);
67 | }
68 |
69 | @Override
70 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
71 | PacketData wrapper = new PacketData(msg.getClass(), msg.getClass().getSimpleName(), true);
72 | if (!handle(true, msg, wrapper))
73 | super.write(ctx, msg, promise);
74 | }
75 |
76 | private boolean handle(boolean outgoing, Object packet, PacketData wrapper) {
77 | if (outgoing) {
78 | try {
79 | Object sb = Constant.class_EnumConnectionState.getDeclaredField("PLAY").get(null);
80 | Object sb2 = Constant.class_EnumPacketDirection.getDeclaredField("SERVERBOUND").get(null);
81 | Integer id = (Integer) Constant.method_getPacketId.invoke(sb, sb2, packet);
82 | if (id == 3 && Constant.name_writeData == null) {
83 | for (Method method : packet.getClass().getMethods()) {
84 | try {
85 | if (method.getParameters()[0].getType() != boolean.class) {
86 | ByteBuf buf = Unpooled.buffer();
87 | Constant.class_PacketBuffer = method.getParameters()[0].getType().getConstructor(ByteBuf.class);
88 | Object packetBuffer = method.getParameters()[0].getType().getConstructor(ByteBuf.class).newInstance(buf);
89 | try {
90 | method.invoke(packet, packetBuffer);
91 | Constant.name_writeData = method.getName();
92 | } catch (Throwable ignored) {
93 | }
94 | }
95 | } catch (Exception ignored) {
96 |
97 | }
98 | }
99 | }
100 | if (Constant.name_writeData != null) {
101 | return NSC.getInstance().getPacketProcessor().processClientPacket(id, packet, wrapper);
102 | }
103 | } catch (Exception e) {
104 | NSC.printStacktrace(e);
105 | }
106 | } else {
107 | try {
108 | Object sb = Constant.class_EnumConnectionState.getDeclaredField("PLAY").get(null);
109 | Object sb2 = Constant.class_EnumPacketDirection.getDeclaredField("CLIENTBOUND").get(null);
110 | Integer id = (Integer) Constant.method_getPacketId.invoke(sb, sb2, packet);
111 | return NSC.getInstance().getPacketProcessor().processServerPacket(id, packet, wrapper);
112 | } catch (Exception e) {
113 | NSC.printStacktrace(e);
114 | }
115 | }
116 | return false;
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/handler/PacketProcessor.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.handler;
2 |
3 | import com.cubk.nsc2.NSC;
4 | import com.cubk.nsc2.module.Module;
5 | import com.cubk.nsc2.module.modules.AbuseDetector;
6 | import com.cubk.nsc2.module.modules.MotionCalculator;
7 | import com.cubk.nsc2.packet.ClientPacketWrapper;
8 | import com.cubk.nsc2.packet.PacketData;
9 | import com.cubk.nsc2.packet.ServerPacketWrapper;
10 | import com.cubk.nsc2.packet.wrappers.client.*;
11 | import com.cubk.nsc2.packet.wrappers.server.S12PacketEntityVelocity;
12 | import com.cubk.nsc2.struct.Constant;
13 | import com.cubk.nsc2.util.TimerUtil;
14 | import io.netty.buffer.ByteBuf;
15 | import io.netty.buffer.Unpooled;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 | import java.util.Map;
20 | import java.util.concurrent.ConcurrentHashMap;
21 | import java.util.concurrent.atomic.AtomicBoolean;
22 |
23 | public class PacketProcessor {
24 | private static final Map wrappersClient = new ConcurrentHashMap<>();
25 | private static final Map wrappersServer = new ConcurrentHashMap<>();
26 |
27 | private final TimerUtil timer = new TimerUtil();
28 | private final List modules = new ArrayList<>();
29 | private final List tick = new ArrayList<>();
30 |
31 | private final MotionCalculator motionCalculator;
32 |
33 | static {
34 | wrappersClient.put(0x00, new C00PacketKeepAlive());
35 | wrappersClient.put(0x01, new C01PacketChatMessage());
36 | wrappersClient.put(0x02, new C02PacketUseEntity());
37 | wrappersClient.put(0x03, new C03PacketPlayer());
38 | wrappersClient.put(0x04, new C04PacketPlayerPosition());
39 | wrappersClient.put(0x05, new C05PacketPlayerLook());
40 | wrappersClient.put(0x06, new C06PacketPlayerPosLook());
41 | wrappersClient.put(0x07, new C07PacketPlayerDigging());
42 | wrappersClient.put(0x08, new C08PacketPlayerBlockPlacement());
43 | wrappersClient.put(0x09, new C09PacketHeldItemChange());
44 | wrappersClient.put(0x0A, new C0APacketAnimation());
45 | wrappersClient.put(0x0B, new C0BPacketEntityAction());
46 | wrappersClient.put(0x0C, new C0CPacketInput());
47 | wrappersClient.put(0x0D, new C0DPacketCloseWindow());
48 | wrappersClient.put(0x0E, new C0EPacketClickWindow());
49 | wrappersClient.put(0x0F, new C0FPacketConfirmTransaction());
50 | wrappersClient.put(0x10, new C10PacketCreativeInventoryAction());
51 | wrappersClient.put(0x11, new C11PacketEnchantItem());
52 | wrappersClient.put(0x13, new C13PacketPlayerAbilities());
53 | wrappersClient.put(0x14, new C14PacketTabComplete());
54 | wrappersClient.put(0x17, new C17PacketCustomPayload());
55 |
56 | wrappersServer.put(0x12, new S12PacketEntityVelocity());
57 | }
58 |
59 | public PacketProcessor() {
60 | modules.add(new AbuseDetector());
61 | modules.add(motionCalculator = new MotionCalculator());
62 | }
63 |
64 | public void loop() {
65 |
66 | NSC.getInstance().getClickGui().setData("");
67 |
68 | StringBuilder sb = new StringBuilder();
69 |
70 | sb.append("Timer: ").append(getPPS() / 20f).append("\n");
71 | sb.append("MotionX: ").append(motionCalculator.motionX).append("\n");
72 | sb.append("MotionY: ").append(motionCalculator.motionY).append("\n");
73 | sb.append("MotionZ: ").append(motionCalculator.motionZ).append("\n");
74 |
75 | sb.append("Rotation: (").append(motionCalculator.yaw).append("/").append(motionCalculator.pitch).append(")\n");
76 |
77 | if (motionCalculator.motionX != 0 || motionCalculator.motionZ != 0) {
78 | sb.append("Speed: ").append(motionCalculator.speed).append("\n");
79 | sb.append("Movement Yaw: ").append(motionCalculator.movementYaw);
80 |
81 | sb.append(" (").append(motionCalculator.getStrafeDifferences()).append(")");
82 |
83 | sb.append("\n");
84 | }
85 |
86 | if (motionCalculator.lastPosition != null) {
87 | sb.append("Position: ").append(motionCalculator.lastPosition).append("\n");
88 | }
89 |
90 | NSC.getInstance().getClickGui().setOtherInfo(sb.toString());
91 |
92 | timer.reset();
93 | }
94 |
95 | private int getPPS() {
96 | long time = System.currentTimeMillis();
97 | this.tick.removeIf(aLong -> aLong + 1000L < time);
98 | return this.tick.size();
99 | }
100 |
101 |
102 | public boolean processServerPacket(int id, Object packet, PacketData pw) {
103 |
104 | try {
105 | if (Constant.class_PacketBuffer == null) return false;
106 |
107 | ServerPacketWrapper wrapper = wrappersServer.getOrDefault(id, null);
108 |
109 | if (wrapper == null) {
110 | return false;
111 | }
112 |
113 | wrapper = wrapper.getClass().newInstance();
114 |
115 | ByteBuf buf = Unpooled.buffer();
116 | Object buffer = Constant.class_PacketBuffer.newInstance(buf);
117 | packet.getClass().getDeclaredMethod(Constant.name_writeData, buffer.getClass()).invoke(packet, buffer);
118 | wrapper.parser(buf, pw);
119 |
120 | NSC.getInstance().getClickGui().addPacket(pw);
121 |
122 | AtomicBoolean AtomicFuck = new AtomicBoolean(false);
123 | ServerPacketWrapper finalWrapper = wrapper;
124 | modules.forEach(module -> AtomicFuck.set(module.handleServerPacket(finalWrapper)));
125 | loop();
126 | return AtomicFuck.get();
127 | } catch (Exception e) {
128 | NSC.printStacktrace(e);
129 | }
130 | return false;
131 | }
132 |
133 | public boolean processClientPacket(int id, Object packet, PacketData pw) {
134 | try {
135 | if (Constant.class_PacketBuffer == null) return false;
136 |
137 | ClientPacketWrapper wrapper = wrappersClient.getOrDefault(id, null);
138 |
139 | if (wrapper == null) {
140 | NSC.getInstance().getClickGui().log("Failed to parse packet: " + id + " " + packet.getClass().getSimpleName(), "warn");
141 | return false;
142 | }
143 |
144 | wrapper = wrapper.getClass().newInstance();
145 |
146 | ByteBuf buf = Unpooled.buffer();
147 | Object buffer = Constant.class_PacketBuffer.newInstance(buf);
148 | packet.getClass().getDeclaredMethod(Constant.name_writeData, buffer.getClass()).invoke(packet, buffer);
149 | pw.setPacketName(wrapper.getClass().getSimpleName());
150 | wrapper.parser(buf, pw);
151 |
152 | NSC.getInstance().getClickGui().addPacket(pw);
153 |
154 | if (wrapper instanceof C03PacketPlayer) {
155 | tick.add(System.currentTimeMillis() + 10L);
156 | }
157 |
158 | AtomicBoolean AtomicFuck = new AtomicBoolean(false);
159 | ClientPacketWrapper finalWrapper = wrapper;
160 | modules.forEach(module -> AtomicFuck.set(module.handleClientPacket(finalWrapper)));
161 | loop();
162 | return AtomicFuck.get();
163 | } catch (Exception e) {
164 | NSC.printStacktrace(e);
165 | }
166 | return false;
167 | }
168 |
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/handler/ThreadScanner.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.handler;
2 |
3 | import com.cubk.nsc2.struct.Constant;
4 | import io.netty.util.AttributeKey;
5 |
6 | import javax.swing.*;
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Method;
9 | import java.lang.reflect.Modifier;
10 |
11 | public class ThreadScanner extends Thread {
12 |
13 | @Override
14 | public void run() {
15 | Thread[] threads = new Thread[1024];
16 | long start = System.currentTimeMillis();
17 | Object minecraftObj = null;
18 | Class> minecraftClass = null;
19 | do {
20 | int count = Thread.enumerate(threads);
21 | for (int i = 0; i < count; i++) {
22 | if (threads[i].getName().equals("Client thread")) {
23 | StackTraceElement[] stack = threads[i].getStackTrace();
24 | for (StackTraceElement element : stack) {
25 | try {
26 | Class> clazz = Class.forName(element.getClassName(), true, threads[i].getContextClassLoader());
27 | for (Field f : clazz.getDeclaredFields()) {
28 | if (Modifier.isStatic(f.getModifiers()) && f.getType() == clazz) {
29 | f.setAccessible(true);
30 | minecraftClass = clazz;
31 | minecraftObj = f.get(null);
32 | break;
33 | }
34 | }
35 | } catch (ClassNotFoundException e) {
36 | ;
37 | } catch (Exception e) {
38 | System.exit(0);
39 | }
40 | }
41 | }
42 | }
43 | try {
44 | Thread.sleep(5L);
45 | } catch (InterruptedException e) {
46 | return;
47 | }
48 | } while (minecraftObj == null && System.currentTimeMillis() - start < 60000);
49 |
50 | if (minecraftObj == null) {
51 | try {
52 | Class> clazz = Class.forName("net.minecraft.client.Minecraft");
53 | for (Field f : clazz.getDeclaredFields()) {
54 | if (Modifier.isStatic(f.getModifiers()) && f.getType() == clazz) {
55 | Field.setAccessible(new Field[]{f}, true);
56 | minecraftObj = f.get(null);
57 | }
58 | }
59 | } catch (Throwable t) {
60 | }
61 | }
62 | if (minecraftObj != null && minecraftClass != null) {
63 | Constant.object_theMinecraft = minecraftObj;
64 | Field netMgr = null;
65 |
66 | for (Field field : minecraftClass.getDeclaredFields()) {
67 | try {
68 | if (field.getType().getSuperclass().getName().equals("io.netty.channel.SimpleChannelInboundHandler")) {
69 | netMgr = field;
70 | }
71 | } catch (Exception ignored) {
72 |
73 | }
74 | }
75 |
76 | if (netMgr != null) {
77 | netMgr.setAccessible(true);
78 |
79 | for (Method method : minecraftClass.getMethods()) {
80 | if (method.getReturnType().getInterfaces().length == 1) {
81 | try {
82 | if (method.getReturnType().getInterfaces()[0].getInterfaces()[0].getMethods().length == 1) {
83 | Constant.method_getNetHandler = method;
84 | for (Method method1 : method.getReturnType().getDeclaredMethods()) {
85 | if (Modifier.isPublic(method1.getModifiers())) {
86 | if (method1.getReturnType().getName().equals(netMgr.getType().getName())) {
87 | Constant.method_getNetworkManager = method1;
88 | }
89 | }
90 | }
91 | }
92 | } catch (Exception e) {
93 |
94 | }
95 | }
96 | }
97 | for (Method method : netMgr.getType().getDeclaredMethods()) {
98 | try {
99 | if (method.getParameters()[0].getType().getSuperclass() == Enum.class) {
100 | Constant.class_EnumConnectionState = method.getParameters()[0].getType();
101 | for (Method method1 : Constant.class_EnumConnectionState.getMethods()) {
102 | try {
103 | if (method1.getParameters()[0].getType().getSuperclass() == Enum.class && method1.getReturnType() == Integer.class) {
104 | Constant.class_EnumPacketDirection = method1.getParameters()[0].getType();
105 | Constant.method_getPacketId = method1;
106 | }
107 | } catch (Exception e) {
108 | }
109 | }
110 | }
111 | } catch (Exception e) {
112 | }
113 | }
114 |
115 | for (Field field : netMgr.getType().getDeclaredFields()) {
116 | if (field.getType() == AttributeKey.class) {
117 | try {
118 | field.setAccessible(true);
119 | Constant.object_attribute_key = (AttributeKey) field.get(null);
120 | } catch (IllegalAccessException e) {
121 | throw new RuntimeException(e);
122 |
123 | }
124 | }
125 | }
126 | } else {
127 | JOptionPane.showMessageDialog(null, "Error [0]", "Internal error, failed to initialize\nNo network manager found", JOptionPane.ERROR_MESSAGE);
128 | }
129 |
130 | } else {
131 | JOptionPane.showMessageDialog(null, "Error [1]", "Internal error, failed to initialize\nNo minecraft found", JOptionPane.ERROR_MESSAGE);
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/module/Module.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.module;
2 |
3 | import com.cubk.nsc2.NSC;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import com.cubk.nsc2.packet.ServerPacketWrapper;
6 |
7 | public interface Module {
8 |
9 | // Return true for cancel
10 |
11 | default boolean handleClientPacket(ClientPacketWrapper wrapper) {
12 | return false;
13 | }
14 |
15 | default boolean handleServerPacket(ServerPacketWrapper wrapper) {
16 | return false;
17 | }
18 |
19 | String getName();
20 |
21 | default void log(String message) {
22 | NSC.getInstance().getClickGui().log(message, getName());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/module/modules/AbuseDetector.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.module.modules;
2 |
3 | import com.cubk.nsc2.module.Module;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import com.cubk.nsc2.packet.wrappers.client.C03PacketPlayer;
6 | import com.cubk.nsc2.packet.wrappers.client.C05PacketPlayerLook;
7 | import com.cubk.nsc2.packet.wrappers.client.C06PacketPlayerPosLook;
8 |
9 | public class AbuseDetector implements Module {
10 |
11 | @Override
12 | public boolean handleClientPacket(ClientPacketWrapper wrapper) {
13 | if (wrapper instanceof C03PacketPlayer) {
14 | if (wrapper instanceof C05PacketPlayerLook || wrapper instanceof C06PacketPlayerPosLook) {
15 | if (((C03PacketPlayer) wrapper).pitch > 90 || ((C03PacketPlayer) wrapper).pitch < -90) {
16 | log("Invalid pitch detected, possibly exploit abuse! (" + ((C03PacketPlayer) wrapper).pitch + ")");
17 | }
18 | }
19 | }
20 | return false;
21 | }
22 |
23 | @Override
24 | public String getName() {
25 | return "Exploit Abuse Detector";
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/module/modules/MotionCalculator.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.module.modules;
2 |
3 | import com.cubk.nsc2.module.Module;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import com.cubk.nsc2.packet.wrappers.client.C04PacketPlayerPosition;
6 | import com.cubk.nsc2.packet.wrappers.client.C05PacketPlayerLook;
7 | import com.cubk.nsc2.packet.wrappers.client.C06PacketPlayerPosLook;
8 | import com.cubk.nsc2.struct.Position;
9 | import com.cubk.nsc2.util.MathHelper;
10 |
11 | public class MotionCalculator implements Module {
12 | public Position lastPosition = null;
13 | public float yaw;
14 | public float pitch;
15 |
16 | public double speed;
17 | public double motionX;
18 | public double motionY;
19 | public double motionZ;
20 | public float movementYaw;
21 |
22 | @Override
23 | public String getName() {
24 | return "Motion";
25 | }
26 |
27 | @Override
28 | public boolean handleClientPacket(ClientPacketWrapper packet) {
29 | if (packet instanceof C04PacketPlayerPosition || packet instanceof C06PacketPlayerPosLook || packet instanceof C05PacketPlayerLook) {
30 | double speed = 0;
31 | if (packet instanceof C04PacketPlayerPosition) {
32 | final C04PacketPlayerPosition playerPosition = (C04PacketPlayerPosition) packet;
33 | if (lastPosition != null) {
34 | motionX = playerPosition.x - lastPosition.getX();
35 | motionY = playerPosition.y - lastPosition.getY();
36 | motionZ = playerPosition.z - lastPosition.getZ();
37 | speed = Math.sqrt(motionX * motionX + motionZ * motionZ);
38 | double movementYawRad = Math.atan2(-motionX, motionZ);
39 | movementYaw = (float) Math.toDegrees(movementYawRad);
40 | movementYaw = MathHelper.wrapAngleTo180_float(movementYaw);
41 | }
42 | lastPosition = new Position(playerPosition.x, playerPosition.y, playerPosition.z);
43 | } else if (packet instanceof C06PacketPlayerPosLook) {
44 | final C06PacketPlayerPosLook playerPosLook = (C06PacketPlayerPosLook) packet;
45 | if (lastPosition != null) {
46 | this.yaw = playerPosLook.yaw;
47 | this.pitch = playerPosLook.pitch;
48 | motionX = playerPosLook.x - lastPosition.getX();
49 | motionY = playerPosLook.y - lastPosition.getY();
50 | motionZ = playerPosLook.z - lastPosition.getZ();
51 | speed = Math.sqrt(motionX * motionX + motionZ * motionZ);
52 | double movementYawRad = Math.atan2(-motionX, motionZ);
53 | movementYaw = (float) Math.toDegrees(movementYawRad);
54 | movementYaw = MathHelper.wrapAngleTo180_float(movementYaw);
55 | }
56 | lastPosition = new Position(playerPosLook.x, playerPosLook.y, playerPosLook.z);
57 | } else {
58 | C05PacketPlayerLook packetPlayerLook = (C05PacketPlayerLook) packet;
59 | this.yaw = packetPlayerLook.yaw;
60 | this.pitch = packetPlayerLook.pitch;
61 | }
62 | this.speed = speed * 20;
63 | }
64 | return false;
65 | }
66 |
67 | public float getStrafeDifferences() {
68 | return Math.abs(MathHelper.wrapAngleTo180_float(movementYaw - yaw));
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/ClientPacketWrapper.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet;
2 |
3 |
4 | public interface ClientPacketWrapper extends Packet, ToString {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/Packet.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet;
2 |
3 | import com.cubk.nsc2.struct.ItemStack;
4 | import com.cubk.nsc2.struct.Position;
5 | import com.cubk.nsc2.struct.nbt.NBTBase;
6 | import com.cubk.nsc2.struct.nbt.NBTSizeTracker;
7 | import com.cubk.nsc2.struct.nbt.NBTTagCompound;
8 | import com.cubk.nsc2.struct.nbt.NBTTagEnd;
9 | import io.netty.buffer.ByteBuf;
10 | import io.netty.buffer.ByteBufInputStream;
11 | import io.netty.handler.codec.DecoderException;
12 |
13 | import java.io.*;
14 | import java.nio.charset.StandardCharsets;
15 |
16 | public interface Packet {
17 | void parser(ByteBuf buf, PacketData packetData);
18 |
19 | default Position readPosition(ByteBuf buf) {
20 | return Position.fromLong(buf.readLong());
21 | }
22 |
23 | default > T readEnumValue(Class enumClass, ByteBuf buf) {
24 | return (T) ((Enum[]) enumClass.getEnumConstants())[readVarIntFromBuffer(buf)];
25 | }
26 |
27 | default String readStringFromBuffer(ByteBuf buf, int maxLength) {
28 | int i = this.readVarIntFromBuffer(buf);
29 |
30 | if (i > maxLength * 4) {
31 | throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + i + " > " + maxLength * 4 + ")");
32 | } else if (i < 0) {
33 | throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!");
34 | } else {
35 | String s = new String(buf.readBytes(i).array(), StandardCharsets.UTF_8);
36 |
37 | if (s.length() > maxLength) {
38 | throw new DecoderException("The received string length is longer than maximum allowed (" + i + " > " + maxLength + ")");
39 | } else {
40 | return s;
41 | }
42 | }
43 | }
44 |
45 | default ItemStack readItemStackFromBuffer(ByteBuf buf) {
46 | ItemStack itemstack = null;
47 | int i = buf.readShort();
48 |
49 | if (i >= 0) {
50 | try {
51 | int j = buf.readByte();
52 | int k = buf.readShort();
53 | itemstack = new ItemStack(i, j, k);
54 | this.readNBTTagCompoundFromBuffer(buf);
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | }
59 |
60 | return itemstack;
61 | }
62 |
63 | default NBTTagCompound readNBTTagCompoundFromBuffer(ByteBuf buf) throws IOException {
64 | int i = buf.readerIndex();
65 | byte b0 = buf.readByte();
66 |
67 | if (b0 == 0) {
68 | return null;
69 | } else {
70 | buf.readerIndex(i);
71 | return read(new ByteBufInputStream(buf), new NBTSizeTracker(2097152L));
72 | }
73 | }
74 |
75 | default NBTTagCompound read(File p_74797_0_) throws IOException {
76 | if (!p_74797_0_.exists()) {
77 | return null;
78 | } else {
79 | DataInputStream datainputstream = new DataInputStream(new FileInputStream(p_74797_0_));
80 | NBTTagCompound nbttagcompound;
81 |
82 | try {
83 | nbttagcompound = read(datainputstream, NBTSizeTracker.INFINITE);
84 | } finally {
85 | datainputstream.close();
86 | }
87 |
88 | return nbttagcompound;
89 | }
90 | }
91 |
92 | default NBTTagCompound read(DataInput p_152456_0_, NBTSizeTracker p_152456_1_) throws IOException {
93 | NBTBase nbtbase = func_152455_a(p_152456_0_, 0, p_152456_1_);
94 |
95 | if (nbtbase instanceof NBTTagCompound) {
96 | return (NBTTagCompound) nbtbase;
97 | } else {
98 | throw new IOException("Root tag must be a named compound tag");
99 | }
100 | }
101 |
102 | default NBTBase func_152455_a(DataInput p_152455_0_, int p_152455_1_, NBTSizeTracker p_152455_2_) throws IOException {
103 | byte b0 = p_152455_0_.readByte();
104 |
105 | if (b0 == 0) {
106 | return new NBTTagEnd();
107 | } else {
108 |
109 |
110 | try {
111 | p_152455_0_.readUTF();
112 | NBTBase nbtbase = NBTBase.createNewByType(b0);
113 | nbtbase.read(p_152455_0_, p_152455_1_, p_152455_2_);
114 | return nbtbase;
115 | } catch (IOException ioexception) {
116 | ioexception.printStackTrace();
117 | return null;
118 | }
119 | }
120 | }
121 |
122 |
123 | default int readVarIntFromBuffer(ByteBuf buf) {
124 | int i = 0;
125 | int j = 0;
126 |
127 | while (true) {
128 | byte b0 = buf.readByte();
129 | i |= (b0 & 127) << j++ * 7;
130 |
131 | if (j > 5) {
132 | throw new RuntimeException("VarInt too big");
133 | }
134 |
135 | if ((b0 & 128) != 128) {
136 | break;
137 | }
138 | }
139 |
140 | return i;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/PacketData.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | public class PacketData {
10 | public final Class> packetClass;
11 | @Getter
12 | private final List dataList;
13 | public final boolean outgoing;
14 | public final long time;
15 | @Setter
16 | public String packetName;
17 |
18 | public PacketData(Class> packetClass, String packetName, boolean outgoing) {
19 | this.packetClass = packetClass;
20 | this.packetName = packetName;
21 | this.outgoing = outgoing;
22 | this.time = System.currentTimeMillis();
23 | this.dataList = new ArrayList<>();
24 | }
25 |
26 | public static class Data {
27 | public final Class> type;
28 | public final String name;
29 | public final String value;
30 |
31 | public Data(Class> type, String name, Object value) {
32 | this.type = type;
33 | this.name = name;
34 | this.value = String.valueOf(value);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/ServerPacketWrapper.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet;
2 |
3 | public interface ServerPacketWrapper extends Packet {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/ToString.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet;
2 |
3 | public interface ToString {
4 | String wrapToString();
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C00PacketKeepAlive.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C00PacketKeepAlive implements ClientPacketWrapper {
8 | public int key;
9 |
10 | @Override
11 | public void parser(ByteBuf buf, PacketData packetData) {
12 | this.key = readVarIntFromBuffer(buf);
13 | packetData.getDataList().add(new PacketData.Data(Integer.class, "key", key));
14 | }
15 |
16 | @Override
17 | public String wrapToString() {
18 | return String.format("new C00PacketKeepAlive(%s)", key);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C01PacketChatMessage.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C01PacketChatMessage implements ClientPacketWrapper {
8 | private String message;
9 |
10 | @Override
11 | public void parser(ByteBuf buf, PacketData packetData) {
12 | this.message = readStringFromBuffer(buf, 100);
13 | packetData.getDataList().add(new PacketData.Data(String.class, "message", message));
14 | }
15 |
16 | @Override
17 | public String wrapToString() {
18 | return String.format("new C01PacketChatMessage(%s)", message);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C02PacketUseEntity.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.Vector3;
6 | import io.netty.buffer.ByteBuf;
7 |
8 | public class C02PacketUseEntity implements ClientPacketWrapper {
9 | public int entityId;
10 | public Action action;
11 | public Vector3 hitVec;
12 |
13 |
14 | @Override
15 | public void parser(ByteBuf buf, PacketData packetData) {
16 | this.entityId = readVarIntFromBuffer(buf);
17 | this.action = readEnumValue(Action.class, buf);
18 | packetData.getDataList().add(new PacketData.Data(Integer.class, "entityId", entityId));
19 | packetData.getDataList().add(new PacketData.Data(Action.class, "action", action));
20 | if (this.action == Action.INTERACT_AT) {
21 | this.hitVec = new Vector3(buf.readFloat(), buf.readFloat(), buf.readFloat());
22 | packetData.getDataList().add(new PacketData.Data(Vector3.class, "hitVec", hitVec));
23 | }
24 | }
25 |
26 | @Override
27 | public String wrapToString() {
28 | if (action == Action.INTERACT_AT) {
29 | return String.format("new C02PacketUseEntity(%s,new Vec3(%s,%s,%s))", entityId, hitVec.getX(), hitVec.getY(), hitVec.getZ());
30 | } else {
31 | return String.format("new C02PacketUseEntity(%s,C02PacketUseEntity.Action.%s)", entityId, action.name());
32 | }
33 | }
34 |
35 | @SuppressWarnings("unused")
36 | public enum Action {
37 | INTERACT,
38 | ATTACK,
39 | INTERACT_AT;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C03PacketPlayer.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C03PacketPlayer implements ClientPacketWrapper {
8 |
9 | public double x;
10 | public double y;
11 | public double z;
12 | public float yaw;
13 | public float pitch;
14 | public boolean onGround;
15 | public boolean rotating;
16 |
17 | @Override
18 | public void parser(ByteBuf buf, PacketData data) {
19 | onGround = buf.readUnsignedByte() != 0;
20 | data.getDataList().add(new PacketData.Data(Boolean.class, "onGround", onGround));
21 | data.getDataList().add(new PacketData.Data(Boolean.class, "rotating", rotating));
22 |
23 | data.getDataList().add(new PacketData.Data(Double.class, "x", this.x));
24 | data.getDataList().add(new PacketData.Data(Double.class, "y", this.y));
25 | data.getDataList().add(new PacketData.Data(Double.class, "z", this.z));
26 |
27 | data.getDataList().add(new PacketData.Data(Float.class, "yaw", this.yaw));
28 | data.getDataList().add(new PacketData.Data(Float.class, "pitch", this.pitch));
29 | }
30 |
31 | @Override
32 | public String wrapToString() {
33 | return String.format("new C03PacketPlayer(%s)", onGround);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C04PacketPlayerPosition.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import io.netty.buffer.ByteBuf;
5 |
6 | public class C04PacketPlayerPosition extends C03PacketPlayer {
7 |
8 | @Override
9 | public void parser(ByteBuf buf, PacketData packetData) {
10 | this.x = buf.readDouble();
11 | this.y = buf.readDouble();
12 | this.z = buf.readDouble();
13 | super.parser(buf, packetData);
14 | }
15 |
16 | @Override
17 | public String wrapToString() {
18 | return String.format("new C03PacketPlayer.C04PacketPlayerPosition(%s,%s,%s,%s)", x, y, z, onGround);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C05PacketPlayerLook.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import io.netty.buffer.ByteBuf;
5 |
6 | public class C05PacketPlayerLook extends C03PacketPlayer {
7 | @Override
8 | public void parser(ByteBuf buf, PacketData packetData) {
9 | this.rotating = true;
10 | this.yaw = buf.readFloat();
11 | this.pitch = buf.readFloat();
12 |
13 |
14 | super.parser(buf, packetData);
15 | }
16 |
17 | @Override
18 | public String wrapToString() {
19 | return String.format("new C03PacketPlayer.C05PacketPlayerLook(%s,%s,%s)", yaw, pitch, onGround);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C06PacketPlayerPosLook.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import io.netty.buffer.ByteBuf;
5 |
6 |
7 | public class C06PacketPlayerPosLook extends C03PacketPlayer {
8 |
9 | @Override
10 | public void parser(ByteBuf buf, PacketData packetData) {
11 | this.x = buf.readDouble();
12 | this.y = buf.readDouble();
13 | this.z = buf.readDouble();
14 | this.yaw = buf.readFloat();
15 | this.pitch = buf.readFloat();
16 | super.parser(buf, packetData);
17 | }
18 |
19 | @Override
20 | public String wrapToString() {
21 | return String.format("new C03PacketPlayer.C06PacketPlayerPosLook(%s,%s,%s,%s,%s,%s)", x, y, z, yaw, pitch, onGround);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C07PacketPlayerDigging.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.EnumFacing;
6 | import com.cubk.nsc2.struct.Position;
7 | import io.netty.buffer.ByteBuf;
8 |
9 | public class C07PacketPlayerDigging implements ClientPacketWrapper {
10 | public Position position;
11 | public EnumFacing facing;
12 | public Action status;
13 |
14 | @Override
15 | public void parser(ByteBuf buf, PacketData packetData) {
16 | this.status = readEnumValue(Action.class, buf);
17 | this.position = readPosition(buf);
18 | this.facing = EnumFacing.getFront(buf.readUnsignedByte());
19 | packetData.getDataList().add(new PacketData.Data(Position.class, "position", position));
20 | packetData.getDataList().add(new PacketData.Data(EnumFacing.class, "facing", facing));
21 | packetData.getDataList().add(new PacketData.Data(Action.class, "action", status));
22 | }
23 |
24 | @Override
25 | public String wrapToString() {
26 | return String.format("new C07PacketPlayerDigging(C07PacketPlayerDigging.Action.%s,new BlockPos(%s,%s,%s),EnumFacing.%s)", status.name(), position.getX(), position.getY(), position.getZ(), facing.name());
27 | }
28 |
29 | @SuppressWarnings("unused")
30 | public enum Action {
31 | START_DESTROY_BLOCK,
32 | ABORT_DESTROY_BLOCK,
33 | STOP_DESTROY_BLOCK,
34 | DROP_ALL_ITEMS,
35 | DROP_ITEM,
36 | RELEASE_USE_ITEM,
37 | SWAP_HELD_ITEMS,
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C08PacketPlayerBlockPlacement.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.ItemStack;
6 | import com.cubk.nsc2.struct.Position;
7 | import io.netty.buffer.ByteBuf;
8 |
9 | public class C08PacketPlayerBlockPlacement implements ClientPacketWrapper {
10 |
11 | public Position position;
12 | public int placedBlockDirection;
13 | public ItemStack stack;
14 | public float facingX;
15 | public float facingY;
16 | public float facingZ;
17 |
18 | @Override
19 | public void parser(ByteBuf buf, PacketData packetData) {
20 | this.position = readPosition(buf);
21 | this.placedBlockDirection = buf.readUnsignedByte();
22 | this.stack = readItemStackFromBuffer(buf);
23 | this.facingX = (float) buf.readUnsignedByte() / getOffset();
24 | this.facingY = (float) buf.readUnsignedByte() / getOffset();
25 | this.facingZ = (float) buf.readUnsignedByte() / getOffset();
26 |
27 | packetData.getDataList().add(new PacketData.Data(Position.class, "position", position));
28 | packetData.getDataList().add(new PacketData.Data(Integer.class, "placedBlockDirection", placedBlockDirection));
29 | packetData.getDataList().add(new PacketData.Data(ItemStack.class, "stack", stack));
30 | packetData.getDataList().add(new PacketData.Data(Float.class, "facingX", facingX));
31 | packetData.getDataList().add(new PacketData.Data(Float.class, "facingY", facingY));
32 | packetData.getDataList().add(new PacketData.Data(Float.class, "facingZ", facingZ));
33 | }
34 |
35 | private float getOffset() {
36 | return 16.0F;
37 | }
38 |
39 | @Override
40 | public String wrapToString() {
41 | return String.format("new C08PacketPlayerBlockPlacement(new BlockPos(%s,%s,%s),%s,%s,%s,%s,%s)", position.getX(), position.getY(), position.getZ(), placedBlockDirection, "item", facingX, facingY, facingZ);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C09PacketHeldItemChange.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C09PacketHeldItemChange implements ClientPacketWrapper {
8 | public int slotId;
9 |
10 | @Override
11 | public void parser(ByteBuf buf, PacketData packetData) {
12 | this.slotId = buf.readShort();
13 | packetData.getDataList().add(new PacketData.Data(Integer.class, "slot", slotId));
14 | }
15 |
16 | @Override
17 | public String wrapToString() {
18 | return String.format("new C09PacketHeldItemChange(%s)", slotId);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0APacketAnimation.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C0APacketAnimation implements ClientPacketWrapper {
8 |
9 | @Override
10 | public void parser(ByteBuf buf, PacketData packetData) {
11 | }
12 |
13 | @Override
14 | public String wrapToString() {
15 | return "new C0APacketAnimation()";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0BPacketEntityAction.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C0BPacketEntityAction implements ClientPacketWrapper {
8 | public int entityID;
9 | public Action action;
10 | public int auxData;
11 |
12 | @Override
13 | public void parser(ByteBuf buf, PacketData packetData) {
14 | this.entityID = readVarIntFromBuffer(buf);
15 | this.action = readEnumValue(Action.class, buf);
16 | this.auxData = readVarIntFromBuffer(buf);
17 | packetData.getDataList().add(new PacketData.Data(Integer.class, "entityID", entityID));
18 | packetData.getDataList().add(new PacketData.Data(Action.class, "action", action));
19 | packetData.getDataList().add(new PacketData.Data(Integer.class, "auxData", auxData));
20 | }
21 |
22 | @Override
23 | public String wrapToString() {
24 | if (auxData == 0) {
25 | return String.format("new C0BPacketEntityAction(%s,C0BPacketEntityAction.Action.%s)", entityID, action.name());
26 | } else {
27 | return String.format("new C0BPacketEntityAction(%s,C0BPacketEntityAction.Action.%s,%s)", entityID, action.name(), auxData);
28 | }
29 | }
30 |
31 | @SuppressWarnings("unused")
32 | public enum Action {
33 | START_SNEAKING,
34 | STOP_SNEAKING,
35 | STOP_SLEEPING,
36 | START_SPRINTING,
37 | STOP_SPRINTING,
38 | RIDING_JUMP,
39 | OPEN_INVENTORY;
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0CPacketInput.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C0CPacketInput implements ClientPacketWrapper {
8 | public float strafeSpeed;
9 |
10 | /**
11 | * Positive for forward, negative for backward
12 | */
13 | public float forwardSpeed;
14 | public boolean jumping;
15 | public boolean sneaking;
16 |
17 | @Override
18 | public void parser(ByteBuf buf, PacketData packetData) {
19 | this.strafeSpeed = buf.readFloat();
20 | this.forwardSpeed = buf.readFloat();
21 | byte b0 = buf.readByte();
22 | this.jumping = (b0 & 1) > 0;
23 | this.sneaking = (b0 & 2) > 0;
24 | packetData.getDataList().add(new PacketData.Data(Float.class, "strafe", strafeSpeed));
25 | packetData.getDataList().add(new PacketData.Data(Float.class, "forward", forwardSpeed));
26 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "jumping", jumping));
27 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "sneaking", sneaking));
28 | }
29 |
30 | @Override
31 | public String wrapToString() {
32 | return String.format("new C0CPacketInput(%s,%s,%s,%s)", strafeSpeed, forwardSpeed, jumping, sneaking);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0DPacketCloseWindow.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C0DPacketCloseWindow implements ClientPacketWrapper {
8 |
9 | public int windowId;
10 |
11 | @Override
12 | public void parser(ByteBuf buf, PacketData packetData) {
13 | this.windowId = buf.readByte();
14 | packetData.getDataList().add(new PacketData.Data(Integer.class, "windowId", windowId));
15 | }
16 |
17 | @Override
18 | public String wrapToString() {
19 | return String.format("new C0DPacketCloseWindow(%s)", windowId);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0EPacketClickWindow.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.ItemStack;
6 | import io.netty.buffer.ByteBuf;
7 |
8 | public class C0EPacketClickWindow implements ClientPacketWrapper {
9 | public int windowId;
10 | public int slotId;
11 | public int usedButton;
12 | public short actionNumber;
13 | public ItemStack clickedItem;
14 | public int mode;
15 |
16 | @Override
17 | public void parser(ByteBuf buf, PacketData packetData) {
18 | this.windowId = buf.readByte();
19 | this.slotId = buf.readShort();
20 | this.usedButton = buf.readByte();
21 | this.actionNumber = buf.readShort();
22 | this.mode = buf.readByte();
23 | this.clickedItem = readItemStackFromBuffer(buf);
24 |
25 | packetData.getDataList().add(new PacketData.Data(Integer.class, "windowId", windowId));
26 | packetData.getDataList().add(new PacketData.Data(Integer.class, "slotId", slotId));
27 | packetData.getDataList().add(new PacketData.Data(Integer.class, "usedButton", usedButton));
28 | packetData.getDataList().add(new PacketData.Data(Short.class, "actionNumber", actionNumber));
29 | packetData.getDataList().add(new PacketData.Data(ItemStack.class, "clickedItem", clickedItem));
30 | packetData.getDataList().add(new PacketData.Data(Integer.class, "mode", mode));
31 | }
32 |
33 | @Override
34 | public String wrapToString() {
35 | return String.format("new C0EPacketClickWindow(%s,%s,%s,%s,%s,%s)", windowId, slotId, usedButton, mode, "item", actionNumber);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C0FPacketConfirmTransaction.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C0FPacketConfirmTransaction implements ClientPacketWrapper {
8 | public int windowId;
9 | public short uid;
10 | public boolean accepted;
11 |
12 | @Override
13 | public void parser(ByteBuf buf, PacketData packetData) {
14 | this.windowId = buf.readByte();
15 | this.uid = buf.readShort();
16 | this.accepted = buf.readByte() != 0;
17 |
18 | packetData.getDataList().add(new PacketData.Data(Integer.class, "windowId", windowId));
19 | packetData.getDataList().add(new PacketData.Data(Short.class, "uid", uid));
20 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "accepted", accepted));
21 | }
22 |
23 | @Override
24 | public String wrapToString() {
25 | return String.format("new C0FPacketConfirmTransaction(%s,%s,%s)", windowId, uid, accepted);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C10PacketCreativeInventoryAction.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.ItemStack;
6 | import io.netty.buffer.ByteBuf;
7 |
8 | public class C10PacketCreativeInventoryAction implements ClientPacketWrapper {
9 | public int slotId;
10 | public ItemStack stack;
11 |
12 | @Override
13 | public void parser(ByteBuf buf, PacketData packetData) {
14 | this.slotId = buf.readShort();
15 | this.stack = readItemStackFromBuffer(buf);
16 | packetData.getDataList().add(new PacketData.Data(Integer.class, "slotId", slotId));
17 | packetData.getDataList().add(new PacketData.Data(ItemStack.class, "stack", stack));
18 | }
19 |
20 | @Override
21 | public String wrapToString() {
22 | return String.format("new C10PacketCreativeInventoryAction(%s, %s)", slotId, stack != null ? stack.toString() : "null");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C11PacketEnchantItem.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C11PacketEnchantItem implements ClientPacketWrapper {
8 | public int windowId;
9 | public int button;
10 |
11 | @Override
12 | public void parser(ByteBuf buf, PacketData packetData) {
13 | this.windowId = buf.readByte();
14 | this.button = buf.readByte();
15 | packetData.getDataList().add(new PacketData.Data(Integer.class, "windowId", windowId));
16 | packetData.getDataList().add(new PacketData.Data(Integer.class, "button", button));
17 | }
18 |
19 | @Override
20 | public String wrapToString() {
21 | return String.format("new C11PacketEnchantItem(%s, %s)", windowId, button);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C13PacketPlayerAbilities.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import com.cubk.nsc2.packet.ClientPacketWrapper;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C13PacketPlayerAbilities implements ClientPacketWrapper {
8 | public boolean invulnerable;
9 | public boolean flying;
10 | public boolean allowFlying;
11 | public boolean creativeMode;
12 | public float flySpeed;
13 | public float walkSpeed;
14 |
15 | @Override
16 | public void parser(ByteBuf buf, PacketData packetData) {
17 | byte b0 = buf.readByte();
18 | this.invulnerable = (b0 & 1) > 0;
19 | this.flying = (b0 & 2) > 0;
20 | this.allowFlying = (b0 & 4) > 0;
21 | this.creativeMode = (b0 & 8) > 0;
22 | this.flySpeed = buf.readFloat();
23 | this.walkSpeed = buf.readFloat();
24 |
25 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "invulnerable", invulnerable));
26 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "flying", flying));
27 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "allowFlying", allowFlying));
28 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "creativeMode", creativeMode));
29 | packetData.getDataList().add(new PacketData.Data(Float.class, "flySpeed", flySpeed));
30 | packetData.getDataList().add(new PacketData.Data(Float.class, "walkSpeed", walkSpeed));
31 | }
32 |
33 | @Override
34 | public String wrapToString() {
35 | return "Wrap你妈大逼自己看不懂是不是";
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C14PacketTabComplete.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import com.cubk.nsc2.struct.Position;
6 | import io.netty.buffer.ByteBuf;
7 |
8 | public class C14PacketTabComplete implements ClientPacketWrapper {
9 | public String message;
10 | public Position targetBlock;
11 |
12 | @Override
13 | public void parser(ByteBuf buf, PacketData packetData) {
14 | this.message = readStringFromBuffer(buf, 32767);
15 | boolean flag = buf.readBoolean();
16 |
17 | if (flag) {
18 | this.targetBlock = readPosition(buf);
19 | packetData.getDataList().add(new PacketData.Data(Position.class, "targetBlock", targetBlock));
20 | }
21 |
22 | packetData.getDataList().add(new PacketData.Data(String.class, "message", message));
23 | packetData.getDataList().add(new PacketData.Data(Boolean.class, "hasTargetBlock", flag));
24 | }
25 |
26 | @Override
27 | public String wrapToString() {
28 | return "Wrap你妈大逼自己看不懂是不是";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/client/C17PacketCustomPayload.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.client;
2 |
3 | import com.cubk.nsc2.packet.ClientPacketWrapper;
4 | import com.cubk.nsc2.packet.PacketData;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class C17PacketCustomPayload implements ClientPacketWrapper {
8 | public String channel;
9 | public ByteBuf data;
10 |
11 | @Override
12 | public void parser(ByteBuf buf, PacketData packetData) {
13 | this.channel = readStringFromBuffer(buf, 20);
14 | int length = buf.readableBytes();
15 |
16 | if (length >= 0 && length <= 32767) {
17 | this.data = buf.readBytes(length).readSlice(length); // Retain the slice to prevent early release
18 | packetData.getDataList().add(new PacketData.Data(String.class, "channel", channel));
19 | packetData.getDataList().add(new PacketData.Data(ByteBuf.class, "data", data));
20 | }
21 | }
22 |
23 | @Override
24 | public String wrapToString() {
25 | return String.format("new C17PacketCustomPayload(\"%s\", %s)", channel, data);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/packet/wrappers/server/S12PacketEntityVelocity.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.packet.wrappers.server;
2 |
3 | import com.cubk.nsc2.packet.PacketData;
4 | import com.cubk.nsc2.packet.ServerPacketWrapper;
5 | import io.netty.buffer.ByteBuf;
6 |
7 | public class S12PacketEntityVelocity implements ServerPacketWrapper {
8 | public int entityID;
9 | public int motionX;
10 | public int motionY;
11 | public int motionZ;
12 |
13 | @Override
14 | public void parser(ByteBuf buf, PacketData packetData) {
15 | this.entityID = readVarIntFromBuffer(buf);
16 | this.motionX = buf.readShort();
17 | this.motionY = buf.readShort();
18 | this.motionZ = buf.readShort();
19 |
20 | packetData.getDataList().add(new PacketData.Data(Integer.class, "entityId", entityID));
21 | packetData.getDataList().add(new PacketData.Data(Integer.class, "motionX", motionX));
22 | packetData.getDataList().add(new PacketData.Data(Integer.class, "motionY", motionY));
23 | packetData.getDataList().add(new PacketData.Data(Integer.class, "motionZ", motionZ));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/plugin/Parser.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.plugin;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonParseException;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.io.InputStream;
9 | import java.io.InputStreamReader;
10 | import java.util.Enumeration;
11 | import java.util.zip.ZipEntry;
12 | import java.util.zip.ZipFile;
13 |
14 | public class Parser {
15 |
16 | private PluginData data = null;
17 |
18 | public Parser(File file) {
19 | try {
20 | ZipFile zipFile = new ZipFile(file);
21 |
22 | Enumeration extends ZipEntry> entries = zipFile.entries();
23 |
24 | PluginData pluginJson = null;
25 |
26 | while (entries.hasMoreElements() && pluginJson == null) {
27 | ZipEntry entry = entries.nextElement();
28 |
29 | if (!entry.isDirectory() && entry.getName().equals("plugin.json")) {
30 | InputStream stream = zipFile.getInputStream(entry);
31 | try {
32 | pluginJson = new Gson().fromJson(new InputStreamReader(stream), PluginData.class);
33 | } catch (JsonParseException jsonParseException) {
34 | throw new RuntimeException("Failed to parse JSON:", jsonParseException);
35 | }
36 | }
37 | }
38 |
39 | if (pluginJson == null) {
40 | zipFile.close();
41 | throw new RuntimeException("Failed to find plugin.json in the root of the jar.");
42 | }
43 |
44 | zipFile.close();
45 | this.data = pluginJson;
46 | } catch (IOException e) {
47 | throw new RuntimeException("Failed to open the jar as a zip:", e);
48 | }
49 | }
50 |
51 | public PluginData getObject() {
52 | return data;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/plugin/PluginAPI.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.plugin;
2 |
3 |
4 | import java.io.File;
5 | import java.util.Objects;
6 | import java.util.function.Consumer;
7 |
8 | public class PluginAPI {
9 |
10 | private static PluginLoader loader;
11 | private String outName;
12 |
13 | private PluginAPI(PluginLoader loader) {
14 | PluginAPI.loader = loader;
15 | }
16 |
17 | public static PluginAPI getApi(Consumer consumer, String outName) {
18 | consumer.accept(loader = new PluginLoader());
19 | PluginAPI api = new PluginAPI(loader);
20 | api.outName = outName;
21 | return api;
22 | }
23 |
24 | public PluginLoader getLoader() {
25 | return loader;
26 | }
27 |
28 | public void loadAll(File folder) {
29 | try {
30 | if (!folder.exists())
31 | folder.mkdir();
32 |
33 | for (File fileIndex : Objects.requireNonNull(folder.listFiles())) {
34 | if (fileIndex.getName().endsWith(".jar")) {
35 | loader.load(fileIndex);
36 | System.out.println(outName + " " + "Loaded: " + fileIndex.getName());
37 | }
38 | }
39 | } catch (NullPointerException e) { // 通常是没有这个文件夹
40 |
41 | } catch (Exception e) {
42 | e.printStackTrace();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/plugin/PluginData.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.plugin;
2 |
3 |
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public class PluginData {
8 |
9 | private final String main;
10 | private final String name;
11 | private final String version;
12 |
13 | public PluginData(String main, String name, String version) {
14 | this.main = main;
15 | this.name = name;
16 | this.version = version;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/plugin/PluginLoader.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.plugin;
2 |
3 | import com.cubk.nsc2.JavaPlugin;
4 |
5 | import java.io.File;
6 | import java.lang.reflect.Constructor;
7 | import java.lang.reflect.InvocationTargetException;
8 | import java.net.MalformedURLException;
9 | import java.net.URL;
10 | import java.net.URLClassLoader;
11 | import java.util.HashMap;
12 |
13 | public class PluginLoader {
14 | private final HashMap map = new HashMap<>();
15 |
16 | public JavaPlugin load(File file) {
17 | if (!(file.getName().endsWith(".jar"))) throw new RuntimeException("File have to be a Jar! " + file.getName());
18 | try {
19 | if (map.containsKey(file)) {
20 | throw new RuntimeException(file.getName() + " " + "Plugin already loaded.");
21 | }
22 | PluginData dataFile = new Parser(file).getObject();
23 | ClassLoader loader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, getClass().getClassLoader());
24 | Class> clazz = Class.forName(dataFile.getMain(), true, loader);
25 | Class extends JavaPlugin> instanceClass = clazz.asSubclass(JavaPlugin.class);
26 | Constructor extends JavaPlugin> instanceClassConstructor = instanceClass.getConstructor();
27 | JavaPlugin addon = instanceClassConstructor.newInstance();
28 | addon.setDescriptionFile(dataFile);
29 | map.put(file, addon);
30 | addon.onLoad();
31 | return addon;
32 | } catch (MalformedURLException e) {
33 | throw new RuntimeException("Failed to convert the file path to a URL.", e);
34 | } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException |
35 | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
36 | throw new RuntimeException("Failed to create a new instance of the addon.", e);
37 | }
38 | }
39 |
40 |
41 | public JavaPlugin unload(File file) {
42 | if (!(file.getName().endsWith(".jar"))) throw new RuntimeException("File have to be a Jar! " + file.getName());
43 | if (!map.containsKey(file)) {
44 | throw new RuntimeException("Can't unload a addon that wasn't loaded in the first place.");
45 | }
46 | JavaPlugin addon = map.get(file);
47 | addon.onUnload();
48 | map.remove(file);
49 | return addon;
50 | }
51 |
52 | public void reload(File file) {
53 | unload(file);
54 | load(file);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/Constant.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct;
2 |
3 | import io.netty.util.AttributeKey;
4 |
5 | import java.lang.reflect.Constructor;
6 | import java.lang.reflect.Method;
7 |
8 | @SuppressWarnings("all")
9 | public class Constant {
10 | public static Method method_getNetHandler;
11 | public static Method method_getNetworkManager;
12 | public static Object object_theMinecraft;
13 | public static String name_writeData;
14 | public static Method method_getPacketId;
15 | public static AttributeKey object_attribute_key;
16 | public static Class> class_EnumConnectionState;
17 | public static Constructor> class_PacketBuffer;
18 | public static Class> class_EnumPacketDirection;
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/EnumFacing.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct;
2 |
3 | import com.cubk.nsc2.util.MathHelper;
4 |
5 | public enum EnumFacing {
6 | DOWN,
7 | UP,
8 | NORTH,
9 | SOUTH,
10 | WEST,
11 | EAST;
12 |
13 | public static EnumFacing getFront(int index) {
14 | return values()[MathHelper.abs_int(index % values().length)];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/ItemStack.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct;
2 |
3 | public class ItemStack {
4 |
5 | public int id, amount, meta;
6 |
7 | public ItemStack(int itemIn, int amount, int meta) {
8 | this.id = itemIn;
9 | this.amount = amount;
10 | this.meta = meta;
11 | }
12 |
13 | @Override
14 | public String toString() {
15 | return "ItemStack{" +
16 | "id=" + id +
17 | ", amount=" + amount +
18 | ", meta=" + meta +
19 | '}';
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/Position.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct;
2 |
3 | import com.cubk.nsc2.util.MathHelper;
4 | import lombok.Getter;
5 |
6 | @Getter
7 | public class Position {
8 | private static final int NUM_X_BITS = 1 + MathHelper.calculateLogBaseTwo(MathHelper.roundUpToPowerOfTwo(30000000));
9 | private static final int NUM_Z_BITS = NUM_X_BITS;
10 | private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
11 | private static final int Y_SHIFT = 0 + NUM_Z_BITS;
12 | private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
13 |
14 | private double x, y, z;
15 |
16 | public Position(double x, double y, double z) {
17 | this.x = x;
18 | this.y = y;
19 | this.z = z;
20 | }
21 |
22 | public void add(double x, double y, double z) {
23 | this.x += x;
24 | this.y += y;
25 | this.z += z;
26 | }
27 |
28 | public void add(Position position) {
29 | this.x += position.getX();
30 | this.y += position.getY();
31 | this.z += position.getZ();
32 | }
33 |
34 | public static Position fromLong(long serialized) {
35 | int i = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS);
36 | int j = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS);
37 | int k = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS);
38 | return new Position(i, j, k);
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "Position{" +
44 | "x=" + x +
45 | ", y=" + y +
46 | ", z=" + z +
47 | '}';
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/Vector3.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct;
2 |
3 |
4 | import lombok.Data;
5 |
6 | @Data
7 | public final class Vector3 {
8 | private float x;
9 | private float y;
10 | private float z;
11 |
12 | public Vector3(float f, float g, float h) {
13 | this.x = f;
14 | this.y = g;
15 | this.z = h;
16 | }
17 |
18 | public void add(float f, float g, float h) {
19 | this.x += f;
20 | this.y += g;
21 | this.z += h;
22 | }
23 |
24 | public void add(Vector3 vector3) {
25 | this.x += vector3.x;
26 | this.y += vector3.y;
27 | this.z += vector3.z;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTBase.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public abstract class NBTBase {
8 | public static final String[] NBT_TYPES = new String[]{"END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]"};
9 |
10 | /**
11 | * Write the actual data contents of the tag, implemented in NBT extension classes
12 | */
13 | abstract void write(DataOutput output) throws IOException;
14 |
15 | public abstract void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException;
16 |
17 | public abstract String toString();
18 |
19 | /**
20 | * Gets the type byte for the tag.
21 | */
22 | public abstract byte getId();
23 |
24 | /**
25 | * Creates a new NBTBase object that corresponds with the passed in id.
26 | */
27 | public static NBTBase createNewByType(byte id) {
28 | switch (id) {
29 | case 0:
30 | return new NBTTagEnd();
31 |
32 | case 1:
33 | return new NBTTagByte();
34 |
35 | case 2:
36 | return new NBTTagShort();
37 |
38 | case 3:
39 | return new NBTTagInt();
40 |
41 | case 4:
42 | return new NBTTagLong();
43 |
44 | case 5:
45 | return new NBTTagFloat();
46 |
47 | case 6:
48 | return new NBTTagDouble();
49 |
50 | case 7:
51 | return new NBTTagByteArray();
52 |
53 | case 8:
54 | return new NBTTagString();
55 |
56 | case 9:
57 | return new NBTTagList();
58 |
59 | case 10:
60 | return new NBTTagCompound();
61 |
62 | case 11:
63 | return new NBTTagIntArray();
64 |
65 | default:
66 | return null;
67 | }
68 | }
69 |
70 | /**
71 | * Creates a clone of the tag.
72 | */
73 | public abstract NBTBase copy();
74 |
75 | /**
76 | * Return whether this compound has no tags.
77 | */
78 | public boolean hasNoTags() {
79 | return false;
80 | }
81 |
82 | public boolean equals(Object p_equals_1_) {
83 | if (!(p_equals_1_ instanceof NBTBase)) {
84 | return false;
85 | } else {
86 | NBTBase nbtbase = (NBTBase) p_equals_1_;
87 | return this.getId() == nbtbase.getId();
88 | }
89 | }
90 |
91 | public int hashCode() {
92 | return this.getId();
93 | }
94 |
95 | protected String getString() {
96 | return this.toString();
97 | }
98 |
99 | public abstract static class NBTPrimitive extends NBTBase {
100 | public abstract long getLong();
101 |
102 | public abstract int getInt();
103 |
104 | public abstract short getShort();
105 |
106 | public abstract byte getByte();
107 |
108 | public abstract double getDouble();
109 |
110 | public abstract float getFloat();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTException.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | public class NBTException extends Exception {
4 | public NBTException(String p_i45136_1_) {
5 | super(p_i45136_1_);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTSizeTracker.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | public class NBTSizeTracker {
4 | public static final NBTSizeTracker INFINITE = new NBTSizeTracker(0L) {
5 | public void read(long bits) {
6 | }
7 | };
8 | private final long max;
9 | private long read;
10 |
11 | public NBTSizeTracker(long max) {
12 | this.max = max;
13 | }
14 |
15 | /**
16 | * Tracks the reading of the given amount of bits(!)
17 | */
18 | public void read(long bits) {
19 | this.read += bits / 8L;
20 |
21 | if (this.read > this.max) {
22 | throw new RuntimeException("Tried to read NBT tag that was too big; tried to allocate: " + this.read + "bytes where max allowed: " + this.max);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagByte.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagByte extends NBTBase.NBTPrimitive {
8 | /**
9 | * The byte value for the tag.
10 | */
11 | private byte data;
12 |
13 | NBTTagByte() {
14 | }
15 |
16 | public NBTTagByte(byte data) {
17 | this.data = data;
18 | }
19 |
20 | /**
21 | * Write the actual data contents of the tag, implemented in NBT extension classes
22 | */
23 | void write(DataOutput output) throws IOException {
24 | output.writeByte(this.data);
25 | }
26 |
27 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
28 | sizeTracker.read(72L);
29 | this.data = input.readByte();
30 | }
31 |
32 | /**
33 | * Gets the type byte for the tag.
34 | */
35 | public byte getId() {
36 | return (byte) 1;
37 | }
38 |
39 | public String toString() {
40 | return "" + this.data + "b";
41 | }
42 |
43 | /**
44 | * Creates a clone of the tag.
45 | */
46 | public NBTBase copy() {
47 | return new NBTTagByte(this.data);
48 | }
49 |
50 | public boolean equals(Object p_equals_1_) {
51 | if (super.equals(p_equals_1_)) {
52 | NBTTagByte nbttagbyte = (NBTTagByte) p_equals_1_;
53 | return this.data == nbttagbyte.data;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 | public int hashCode() {
60 | return super.hashCode() ^ this.data;
61 | }
62 |
63 | public long getLong() {
64 | return (long) this.data;
65 | }
66 |
67 | public int getInt() {
68 | return this.data;
69 | }
70 |
71 | public short getShort() {
72 | return (short) this.data;
73 | }
74 |
75 | public byte getByte() {
76 | return this.data;
77 | }
78 |
79 | public double getDouble() {
80 | return (double) this.data;
81 | }
82 |
83 | public float getFloat() {
84 | return (float) this.data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagByteArray.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 | import java.util.Arrays;
7 |
8 | public class NBTTagByteArray extends NBTBase {
9 | /**
10 | * The byte array stored in the tag.
11 | */
12 | private byte[] data;
13 |
14 | NBTTagByteArray() {
15 | }
16 |
17 | public NBTTagByteArray(byte[] data) {
18 | this.data = data;
19 | }
20 |
21 | /**
22 | * Write the actual data contents of the tag, implemented in NBT extension classes
23 | */
24 | void write(DataOutput output) throws IOException {
25 | output.writeInt(this.data.length);
26 | output.write(this.data);
27 | }
28 |
29 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
30 | sizeTracker.read(192L);
31 | int i = input.readInt();
32 | sizeTracker.read((long) (8 * i));
33 | this.data = new byte[i];
34 | input.readFully(this.data);
35 | }
36 |
37 | /**
38 | * Gets the type byte for the tag.
39 | */
40 | public byte getId() {
41 | return (byte) 7;
42 | }
43 |
44 | public String toString() {
45 | return "[" + this.data.length + " bytes]";
46 | }
47 |
48 | /**
49 | * Creates a clone of the tag.
50 | */
51 | public NBTBase copy() {
52 | byte[] abyte = new byte[this.data.length];
53 | System.arraycopy(this.data, 0, abyte, 0, this.data.length);
54 | return new NBTTagByteArray(abyte);
55 | }
56 |
57 | public boolean equals(Object p_equals_1_) {
58 | return super.equals(p_equals_1_) ? Arrays.equals(this.data, ((NBTTagByteArray) p_equals_1_).data) : false;
59 | }
60 |
61 | public int hashCode() {
62 | return super.hashCode() ^ Arrays.hashCode(this.data);
63 | }
64 |
65 | public byte[] getByteArray() {
66 | return this.data;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagCompound.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 | import java.util.Map;
7 | import java.util.Map.Entry;
8 | import java.util.Set;
9 | import java.util.concurrent.ConcurrentHashMap;
10 |
11 | public class NBTTagCompound extends NBTBase {
12 | private Map tagMap = new ConcurrentHashMap<>();
13 |
14 | private static void writeEntry(String name, NBTBase data, DataOutput output) throws IOException {
15 | output.writeByte(data.getId());
16 |
17 | if (data.getId() != 0) {
18 | output.writeUTF(name);
19 | data.write(output);
20 | }
21 | }
22 |
23 | private static byte readType(DataInput input, NBTSizeTracker sizeTracker) throws IOException {
24 | return input.readByte();
25 | }
26 |
27 | private static String readKey(DataInput input, NBTSizeTracker sizeTracker) throws IOException {
28 | return input.readUTF();
29 | }
30 |
31 | static NBTBase readNBT(byte id, String key, DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
32 | NBTBase nbtbase = createNewByType(id);
33 |
34 | try {
35 | nbtbase.read(input, depth, sizeTracker);
36 | return nbtbase;
37 | } catch (IOException ioexception) {
38 | return new NBTBase() {
39 | @Override
40 | void write(DataOutput output) throws IOException {
41 |
42 | }
43 |
44 | @Override
45 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
46 |
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return null;
52 | }
53 |
54 | @Override
55 | public byte getId() {
56 | return 0;
57 | }
58 |
59 | @Override
60 | public NBTBase copy() {
61 | return null;
62 | }
63 | };
64 | }
65 | }
66 |
67 | /**
68 | * Write the actual data contents of the tag, implemented in NBT extension classes
69 | */
70 | void write(DataOutput output) throws IOException {
71 | for (String s : this.tagMap.keySet()) {
72 | NBTBase nbtbase = (NBTBase) this.tagMap.get(s);
73 | writeEntry(s, nbtbase, output);
74 | }
75 |
76 | output.writeByte(0);
77 | }
78 |
79 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
80 | sizeTracker.read(384L);
81 |
82 | if (depth > 512) {
83 | throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
84 | } else {
85 | this.tagMap.clear();
86 | byte b0;
87 |
88 | while ((b0 = readType(input, sizeTracker)) != 0) {
89 | String s = readKey(input, sizeTracker);
90 | sizeTracker.read((long) (224 + 16 * s.length()));
91 | NBTBase nbtbase = readNBT(b0, s, input, depth + 1, sizeTracker);
92 |
93 | if (this.tagMap.put(s, nbtbase) != null) {
94 | sizeTracker.read(288L);
95 | }
96 | }
97 | }
98 | }
99 |
100 | public Set getKeySet() {
101 | return this.tagMap.keySet();
102 | }
103 |
104 | /**
105 | * Gets the type byte for the tag.
106 | */
107 | public byte getId() {
108 | return (byte) 10;
109 | }
110 |
111 | /**
112 | * Stores the given tag into the map with the given string key. This is mostly used to store tag lists.
113 | */
114 | public void setTag(String key, NBTBase value) {
115 | this.tagMap.put(key, value);
116 | }
117 |
118 | /**
119 | * Stores a new NBTTagByte with the given byte value into the map with the given string key.
120 | */
121 | public void setByte(String key, byte value) {
122 | this.tagMap.put(key, new NBTTagByte(value));
123 | }
124 |
125 | /**
126 | * Stores a new NBTTagShort with the given short value into the map with the given string key.
127 | */
128 | public void setShort(String key, short value) {
129 | this.tagMap.put(key, new NBTTagShort(value));
130 | }
131 |
132 | /**
133 | * Stores a new NBTTagInt with the given integer value into the map with the given string key.
134 | */
135 | public void setInteger(String key, int value) {
136 | this.tagMap.put(key, new NBTTagInt(value));
137 | }
138 |
139 | /**
140 | * Stores a new NBTTagLong with the given long value into the map with the given string key.
141 | */
142 | public void setLong(String key, long value) {
143 | this.tagMap.put(key, new NBTTagLong(value));
144 | }
145 |
146 | /**
147 | * Stores a new NBTTagFloat with the given float value into the map with the given string key.
148 | */
149 | public void setFloat(String key, float value) {
150 | this.tagMap.put(key, new NBTTagFloat(value));
151 | }
152 |
153 | /**
154 | * Stores a new NBTTagDouble with the given double value into the map with the given string key.
155 | */
156 | public void setDouble(String key, double value) {
157 | this.tagMap.put(key, new NBTTagDouble(value));
158 | }
159 |
160 | /**
161 | * Stores a new NBTTagString with the given string value into the map with the given string key.
162 | */
163 | public void setString(String key, String value) {
164 | this.tagMap.put(key, new NBTTagString(value));
165 | }
166 |
167 | /**
168 | * Stores a new NBTTagByteArray with the given array as data into the map with the given string key.
169 | */
170 | public void setByteArray(String key, byte[] value) {
171 | this.tagMap.put(key, new NBTTagByteArray(value));
172 | }
173 |
174 | /**
175 | * Stores a new NBTTagIntArray with the given array as data into the map with the given string key.
176 | */
177 | public void setIntArray(String key, int[] value) {
178 | this.tagMap.put(key, new NBTTagIntArray(value));
179 | }
180 |
181 | /**
182 | * Stores the given boolean value as a NBTTagByte, storing 1 for true and 0 for false, using the given string key.
183 | */
184 | public void setBoolean(String key, boolean value) {
185 | this.setByte(key, (byte) (value ? 1 : 0));
186 | }
187 |
188 | /**
189 | * gets a generic tag with the specified name
190 | */
191 | public NBTBase getTag(String key) {
192 | return (NBTBase) this.tagMap.get(key);
193 | }
194 |
195 | /**
196 | * Gets the ID byte for the given tag key
197 | */
198 | public byte getTagId(String key) {
199 | NBTBase nbtbase = (NBTBase) this.tagMap.get(key);
200 | return nbtbase != null ? nbtbase.getId() : 0;
201 | }
202 |
203 | /**
204 | * Returns whether the given string has been previously stored as a key in the map.
205 | */
206 | public boolean hasKey(String key) {
207 | return this.tagMap.containsKey(key);
208 | }
209 |
210 | public boolean hasKey(String key, int type) {
211 | int i = this.getTagId(key);
212 |
213 | if (i == type) {
214 | return true;
215 | } else if (type != 99) {
216 | if (i > 0) {
217 | ;
218 | }
219 |
220 | return false;
221 | } else {
222 | return i == 1 || i == 2 || i == 3 || i == 4 || i == 5 || i == 6;
223 | }
224 | }
225 |
226 | /**
227 | * Retrieves a byte value using the specified key, or 0 if no such key was stored.
228 | */
229 | public byte getByte(String key) {
230 | try {
231 | return !this.hasKey(key, 99) ? 0 : ((NBTPrimitive) this.tagMap.get(key)).getByte();
232 | } catch (ClassCastException var3) {
233 | return (byte) 0;
234 | }
235 | }
236 |
237 | /**
238 | * Retrieves a short value using the specified key, or 0 if no such key was stored.
239 | */
240 | public short getShort(String key) {
241 | try {
242 | return !this.hasKey(key, 99) ? 0 : ((NBTPrimitive) this.tagMap.get(key)).getShort();
243 | } catch (ClassCastException var3) {
244 | return (short) 0;
245 | }
246 | }
247 |
248 | /**
249 | * Retrieves an integer value using the specified key, or 0 if no such key was stored.
250 | */
251 | public int getInteger(String key) {
252 | try {
253 | return !this.hasKey(key, 99) ? 0 : ((NBTPrimitive) this.tagMap.get(key)).getInt();
254 | } catch (ClassCastException var3) {
255 | return 0;
256 | }
257 | }
258 |
259 | /**
260 | * Retrieves a long value using the specified key, or 0 if no such key was stored.
261 | */
262 | public long getLong(String key) {
263 | try {
264 | return !this.hasKey(key, 99) ? 0L : ((NBTPrimitive) this.tagMap.get(key)).getLong();
265 | } catch (ClassCastException var3) {
266 | return 0L;
267 | }
268 | }
269 |
270 | /**
271 | * Retrieves a float value using the specified key, or 0 if no such key was stored.
272 | */
273 | public float getFloat(String key) {
274 | try {
275 | return !this.hasKey(key, 99) ? 0.0F : ((NBTPrimitive) this.tagMap.get(key)).getFloat();
276 | } catch (ClassCastException var3) {
277 | return 0.0F;
278 | }
279 | }
280 |
281 | /**
282 | * Retrieves a double value using the specified key, or 0 if no such key was stored.
283 | */
284 | public double getDouble(String key) {
285 | try {
286 | return !this.hasKey(key, 99) ? 0.0D : ((NBTPrimitive) this.tagMap.get(key)).getDouble();
287 | } catch (ClassCastException var3) {
288 | return 0.0D;
289 | }
290 | }
291 |
292 | /**
293 | * Retrieves a string value using the specified key, or an empty string if no such key was stored.
294 | */
295 | public String getString(String key) {
296 | try {
297 | return !this.hasKey(key, 8) ? "" : ((NBTBase) this.tagMap.get(key)).getString();
298 | } catch (ClassCastException var3) {
299 | return "";
300 | }
301 | }
302 |
303 | /**
304 | * Retrieves a byte array using the specified key, or a zero-length array if no such key was stored.
305 | */
306 | public byte[] getByteArray(String key) {
307 | try {
308 | return !this.hasKey(key, 7) ? new byte[0] : ((NBTTagByteArray) this.tagMap.get(key)).getByteArray();
309 | } catch (ClassCastException classcastexception) {
310 | throw new NullPointerException(this.createCrashReport(key, 7, classcastexception));
311 | }
312 | }
313 |
314 | /**
315 | * Retrieves an int array using the specified key, or a zero-length array if no such key was stored.
316 | */
317 | public int[] getIntArray(String key) {
318 | try {
319 | return !this.hasKey(key, 11) ? new int[0] : ((NBTTagIntArray) this.tagMap.get(key)).getIntArray();
320 | } catch (ClassCastException classcastexception) {
321 | throw new NullPointerException(this.createCrashReport(key, 11, classcastexception));
322 | }
323 | }
324 |
325 | /**
326 | * Retrieves a NBTTagCompound subtag matching the specified key, or a new empty NBTTagCompound if no such key was
327 | * stored.
328 | */
329 | public NBTTagCompound getCompoundTag(String key) {
330 | try {
331 | return !this.hasKey(key, 10) ? new NBTTagCompound() : (NBTTagCompound) this.tagMap.get(key);
332 | } catch (ClassCastException classcastexception) {
333 | throw new NullPointerException(this.createCrashReport(key, 10, classcastexception));
334 | }
335 | }
336 |
337 | /**
338 | * Gets the NBTTagList object with the given name. Args: name, NBTBase type
339 | */
340 | public NBTTagList getTagList(String key, int type) {
341 | try {
342 | if (this.getTagId(key) != 9) {
343 | return new NBTTagList();
344 | } else {
345 | NBTTagList nbttaglist = (NBTTagList) this.tagMap.get(key);
346 | return nbttaglist.tagCount() > 0 && nbttaglist.getTagType() != type ? new NBTTagList() : nbttaglist;
347 | }
348 | } catch (ClassCastException classcastexception) {
349 | throw new NullPointerException(this.createCrashReport(key, 9, classcastexception));
350 | }
351 | }
352 |
353 | /**
354 | * Retrieves a boolean value using the specified key, or false if no such key was stored. This uses the getByte
355 | * method.
356 | */
357 | public boolean getBoolean(String key) {
358 | return this.getByte(key) != 0;
359 | }
360 |
361 | /**
362 | * Remove the specified tag.
363 | */
364 | public void removeTag(String key) {
365 | this.tagMap.remove(key);
366 | }
367 |
368 | public String toString() {
369 | StringBuilder stringbuilder = new StringBuilder("{");
370 |
371 | for (Entry entry : this.tagMap.entrySet()) {
372 | if (stringbuilder.length() != 1) {
373 | stringbuilder.append(',');
374 | }
375 |
376 | stringbuilder.append((String) entry.getKey()).append(':').append(entry.getValue());
377 | }
378 |
379 | return stringbuilder.append('}').toString();
380 | }
381 |
382 | /**
383 | * Return whether this compound has no tags.
384 | */
385 | public boolean hasNoTags() {
386 | return this.tagMap.isEmpty();
387 | }
388 |
389 | /**
390 | * Create a crash report which indicates a NBT read error.
391 | */
392 | private String createCrashReport(final String key, final int expectedType, ClassCastException ex) {
393 | return key;
394 | }
395 |
396 | /**
397 | * Creates a clone of the tag.
398 | */
399 | public NBTBase copy() {
400 | NBTTagCompound nbttagcompound = new NBTTagCompound();
401 |
402 | for (String s : this.tagMap.keySet()) {
403 | nbttagcompound.setTag(s, ((NBTBase) this.tagMap.get(s)).copy());
404 | }
405 |
406 | return nbttagcompound;
407 | }
408 |
409 | public boolean equals(Object p_equals_1_) {
410 | if (super.equals(p_equals_1_)) {
411 | NBTTagCompound nbttagcompound = (NBTTagCompound) p_equals_1_;
412 | return this.tagMap.entrySet().equals(nbttagcompound.tagMap.entrySet());
413 | } else {
414 | return false;
415 | }
416 | }
417 |
418 | public int hashCode() {
419 | return super.hashCode() ^ this.tagMap.hashCode();
420 | }
421 |
422 | /**
423 | * Merges this NBTTagCompound with the given compound. Any sub-compounds are merged using the same methods, other
424 | * types of tags are overwritten from the given compound.
425 | */
426 | public void merge(NBTTagCompound other) {
427 | for (String s : other.tagMap.keySet()) {
428 | NBTBase nbtbase = (NBTBase) other.tagMap.get(s);
429 |
430 | if (nbtbase.getId() == 10) {
431 | if (this.hasKey(s, 10)) {
432 | NBTTagCompound nbttagcompound = this.getCompoundTag(s);
433 | nbttagcompound.merge((NBTTagCompound) nbtbase);
434 | } else {
435 | this.setTag(s, nbtbase.copy());
436 | }
437 | } else {
438 | this.setTag(s, nbtbase.copy());
439 | }
440 | }
441 | }
442 | }
443 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagDouble.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import com.cubk.nsc2.util.MathHelper;
4 |
5 | import java.io.DataInput;
6 | import java.io.DataOutput;
7 | import java.io.IOException;
8 |
9 | public class NBTTagDouble extends NBTBase.NBTPrimitive {
10 | /**
11 | * The double value for the tag.
12 | */
13 | private double data;
14 |
15 | NBTTagDouble() {
16 | }
17 |
18 | public NBTTagDouble(double data) {
19 | this.data = data;
20 | }
21 |
22 | /**
23 | * Write the actual data contents of the tag, implemented in NBT extension classes
24 | */
25 | void write(DataOutput output) throws IOException {
26 | output.writeDouble(this.data);
27 | }
28 |
29 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
30 | sizeTracker.read(128L);
31 | this.data = input.readDouble();
32 | }
33 |
34 | /**
35 | * Gets the type byte for the tag.
36 | */
37 | public byte getId() {
38 | return (byte) 6;
39 | }
40 |
41 | public String toString() {
42 | return "" + this.data + "d";
43 | }
44 |
45 | /**
46 | * Creates a clone of the tag.
47 | */
48 | public NBTBase copy() {
49 | return new NBTTagDouble(this.data);
50 | }
51 |
52 | public boolean equals(Object p_equals_1_) {
53 | if (super.equals(p_equals_1_)) {
54 | NBTTagDouble nbttagdouble = (NBTTagDouble) p_equals_1_;
55 | return this.data == nbttagdouble.data;
56 | } else {
57 | return false;
58 | }
59 | }
60 |
61 | public int hashCode() {
62 | long i = Double.doubleToLongBits(this.data);
63 | return super.hashCode() ^ (int) (i ^ i >>> 32);
64 | }
65 |
66 | public long getLong() {
67 | return (long) Math.floor(this.data);
68 | }
69 |
70 | public int getInt() {
71 | return MathHelper.floor_double(this.data);
72 | }
73 |
74 | public short getShort() {
75 | return (short) (MathHelper.floor_double(this.data) & 65535);
76 | }
77 |
78 | public byte getByte() {
79 | return (byte) (MathHelper.floor_double(this.data) & 255);
80 | }
81 |
82 | public double getDouble() {
83 | return this.data;
84 | }
85 |
86 | public float getFloat() {
87 | return (float) this.data;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagEnd.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagEnd extends NBTBase {
8 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
9 | sizeTracker.read(64L);
10 | }
11 |
12 | /**
13 | * Write the actual data contents of the tag, implemented in NBT extension classes
14 | */
15 | void write(DataOutput output) throws IOException {
16 | }
17 |
18 | /**
19 | * Gets the type byte for the tag.
20 | */
21 | public byte getId() {
22 | return (byte) 0;
23 | }
24 |
25 | public String toString() {
26 | return "END";
27 | }
28 |
29 | /**
30 | * Creates a clone of the tag.
31 | */
32 | public NBTBase copy() {
33 | return new NBTTagEnd();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagFloat.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 |
4 | import com.cubk.nsc2.util.MathHelper;
5 |
6 | import java.io.DataInput;
7 | import java.io.DataOutput;
8 | import java.io.IOException;
9 |
10 | public class NBTTagFloat extends NBTBase.NBTPrimitive {
11 | /**
12 | * The float value for the tag.
13 | */
14 | private float data;
15 |
16 | NBTTagFloat() {
17 | }
18 |
19 | public NBTTagFloat(float data) {
20 | this.data = data;
21 | }
22 |
23 | /**
24 | * Write the actual data contents of the tag, implemented in NBT extension classes
25 | */
26 | void write(DataOutput output) throws IOException {
27 | output.writeFloat(this.data);
28 | }
29 |
30 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
31 | sizeTracker.read(96L);
32 | this.data = input.readFloat();
33 | }
34 |
35 | /**
36 | * Gets the type byte for the tag.
37 | */
38 | public byte getId() {
39 | return (byte) 5;
40 | }
41 |
42 | public String toString() {
43 | return "" + this.data + "f";
44 | }
45 |
46 | /**
47 | * Creates a clone of the tag.
48 | */
49 | public NBTBase copy() {
50 | return new NBTTagFloat(this.data);
51 | }
52 |
53 | public boolean equals(Object p_equals_1_) {
54 | if (super.equals(p_equals_1_)) {
55 | NBTTagFloat nbttagfloat = (NBTTagFloat) p_equals_1_;
56 | return this.data == nbttagfloat.data;
57 | } else {
58 | return false;
59 | }
60 | }
61 |
62 | public int hashCode() {
63 | return super.hashCode() ^ Float.floatToIntBits(this.data);
64 | }
65 |
66 | public long getLong() {
67 | return (long) this.data;
68 | }
69 |
70 | public int getInt() {
71 | return MathHelper.floor_float(this.data);
72 | }
73 |
74 | public short getShort() {
75 | return (short) (MathHelper.floor_float(this.data) & 65535);
76 | }
77 |
78 | public byte getByte() {
79 | return (byte) (MathHelper.floor_float(this.data) & 255);
80 | }
81 |
82 | public double getDouble() {
83 | return (double) this.data;
84 | }
85 |
86 | public float getFloat() {
87 | return this.data;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagInt.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagInt extends NBTBase.NBTPrimitive {
8 | /**
9 | * The integer value for the tag.
10 | */
11 | private int data;
12 |
13 | NBTTagInt() {
14 | }
15 |
16 | public NBTTagInt(int data) {
17 | this.data = data;
18 | }
19 |
20 | /**
21 | * Write the actual data contents of the tag, implemented in NBT extension classes
22 | */
23 | void write(DataOutput output) throws IOException {
24 | output.writeInt(this.data);
25 | }
26 |
27 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
28 | sizeTracker.read(96L);
29 | this.data = input.readInt();
30 | }
31 |
32 | /**
33 | * Gets the type byte for the tag.
34 | */
35 | public byte getId() {
36 | return (byte) 3;
37 | }
38 |
39 | public String toString() {
40 | return "" + this.data;
41 | }
42 |
43 | /**
44 | * Creates a clone of the tag.
45 | */
46 | public NBTBase copy() {
47 | return new NBTTagInt(this.data);
48 | }
49 |
50 | public boolean equals(Object p_equals_1_) {
51 | if (super.equals(p_equals_1_)) {
52 | NBTTagInt nbttagint = (NBTTagInt) p_equals_1_;
53 | return this.data == nbttagint.data;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 | public int hashCode() {
60 | return super.hashCode() ^ this.data;
61 | }
62 |
63 | public long getLong() {
64 | return (long) this.data;
65 | }
66 |
67 | public int getInt() {
68 | return this.data;
69 | }
70 |
71 | public short getShort() {
72 | return (short) (this.data & 65535);
73 | }
74 |
75 | public byte getByte() {
76 | return (byte) (this.data & 255);
77 | }
78 |
79 | public double getDouble() {
80 | return (double) this.data;
81 | }
82 |
83 | public float getFloat() {
84 | return (float) this.data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagIntArray.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 | import java.util.Arrays;
7 |
8 | public class NBTTagIntArray extends NBTBase {
9 | /**
10 | * The array of saved integers
11 | */
12 | private int[] intArray;
13 |
14 | NBTTagIntArray() {
15 | }
16 |
17 | public NBTTagIntArray(int[] p_i45132_1_) {
18 | this.intArray = p_i45132_1_;
19 | }
20 |
21 | /**
22 | * Write the actual data contents of the tag, implemented in NBT extension classes
23 | */
24 | void write(DataOutput output) throws IOException {
25 | output.writeInt(this.intArray.length);
26 |
27 | for (int i = 0; i < this.intArray.length; ++i) {
28 | output.writeInt(this.intArray[i]);
29 | }
30 | }
31 |
32 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
33 | sizeTracker.read(192L);
34 | int i = input.readInt();
35 | sizeTracker.read((long) (32 * i));
36 | this.intArray = new int[i];
37 |
38 | for (int j = 0; j < i; ++j) {
39 | this.intArray[j] = input.readInt();
40 | }
41 | }
42 |
43 | /**
44 | * Gets the type byte for the tag.
45 | */
46 | public byte getId() {
47 | return (byte) 11;
48 | }
49 |
50 | public String toString() {
51 | String s = "[";
52 |
53 | for (int i : this.intArray) {
54 | s = s + i + ",";
55 | }
56 |
57 | return s + "]";
58 | }
59 |
60 | /**
61 | * Creates a clone of the tag.
62 | */
63 | public NBTBase copy() {
64 | int[] aint = new int[this.intArray.length];
65 | System.arraycopy(this.intArray, 0, aint, 0, this.intArray.length);
66 | return new NBTTagIntArray(aint);
67 | }
68 |
69 | public boolean equals(Object p_equals_1_) {
70 | return super.equals(p_equals_1_) ? Arrays.equals(this.intArray, ((NBTTagIntArray) p_equals_1_).intArray) : false;
71 | }
72 |
73 | public int hashCode() {
74 | return super.hashCode() ^ Arrays.hashCode(this.intArray);
75 | }
76 |
77 | public int[] getIntArray() {
78 | return this.intArray;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagList.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | public class NBTTagList extends NBTBase {
10 | private List tagList = new ArrayList<>();
11 |
12 | /**
13 | * The type byte for the tags in the list - they must all be of the same type.
14 | */
15 | private byte tagType = 0;
16 |
17 | /**
18 | * Write the actual data contents of the tag, implemented in NBT extension classes
19 | */
20 | void write(DataOutput output) throws IOException {
21 | if (!this.tagList.isEmpty()) {
22 | this.tagType = ((NBTBase) this.tagList.get(0)).getId();
23 | } else {
24 | this.tagType = 0;
25 | }
26 |
27 | output.writeByte(this.tagType);
28 | output.writeInt(this.tagList.size());
29 |
30 | for (int i = 0; i < this.tagList.size(); ++i) {
31 | ((NBTBase) this.tagList.get(i)).write(output);
32 | }
33 | }
34 |
35 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
36 | sizeTracker.read(296L);
37 |
38 | if (depth > 512) {
39 | throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
40 | } else {
41 | this.tagType = input.readByte();
42 | int i = input.readInt();
43 |
44 | if (this.tagType == 0 && i > 0) {
45 | throw new RuntimeException("Missing type on ListTag");
46 | } else {
47 | sizeTracker.read(32L * (long) i);
48 | this.tagList = newArrayListWithCapacity(i);
49 |
50 | for (int j = 0; j < i; ++j) {
51 | NBTBase nbtbase = NBTBase.createNewByType(this.tagType);
52 | nbtbase.read(input, depth + 1, sizeTracker);
53 | this.tagList.add(nbtbase);
54 | }
55 | }
56 | }
57 | }
58 |
59 | public static ArrayList newArrayListWithCapacity(int initialArraySize) {
60 | return new ArrayList(initialArraySize);
61 | }
62 |
63 |
64 | /**
65 | * Gets the type byte for the tag.
66 | */
67 | public byte getId() {
68 | return (byte) 9;
69 | }
70 |
71 | public String toString() {
72 | StringBuilder stringbuilder = new StringBuilder("[");
73 |
74 | for (int i = 0; i < this.tagList.size(); ++i) {
75 | if (i != 0) {
76 | stringbuilder.append(',');
77 | }
78 |
79 | stringbuilder.append(i).append(':').append(this.tagList.get(i));
80 | }
81 |
82 | return stringbuilder.append(']').toString();
83 | }
84 |
85 | /**
86 | * Adds the provided tag to the end of the list. There is no check to verify this tag is of the same type as any
87 | * previous tag.
88 | */
89 | public void appendTag(NBTBase nbt) {
90 | if (nbt.getId() == 0) {
91 | } else {
92 | if (this.tagType == 0) {
93 | this.tagType = nbt.getId();
94 | } else if (this.tagType != nbt.getId()) {
95 | return;
96 | }
97 |
98 | this.tagList.add(nbt);
99 | }
100 | }
101 |
102 | /**
103 | * Set the given index to the given tag
104 | */
105 | public void set(int idx, NBTBase nbt) {
106 | if (nbt.getId() == 0) {
107 | } else if (idx >= 0 && idx < this.tagList.size()) {
108 | if (this.tagType == 0) {
109 | this.tagType = nbt.getId();
110 | } else if (this.tagType != nbt.getId()) {
111 | return;
112 | }
113 |
114 | this.tagList.set(idx, nbt);
115 | } else {
116 | }
117 | }
118 |
119 | /**
120 | * Removes a tag at the given index.
121 | */
122 | public NBTBase removeTag(int i) {
123 | return (NBTBase) this.tagList.remove(i);
124 | }
125 |
126 | /**
127 | * Return whether this compound has no tags.
128 | */
129 | public boolean hasNoTags() {
130 | return this.tagList.isEmpty();
131 | }
132 |
133 | /**
134 | * Retrieves the NBTTagCompound at the specified index in the list
135 | */
136 | public NBTTagCompound getCompoundTagAt(int i) {
137 | if (i >= 0 && i < this.tagList.size()) {
138 | NBTBase nbtbase = (NBTBase) this.tagList.get(i);
139 | return nbtbase.getId() == 10 ? (NBTTagCompound) nbtbase : new NBTTagCompound();
140 | } else {
141 | return new NBTTagCompound();
142 | }
143 | }
144 |
145 | public int[] getIntArrayAt(int i) {
146 | if (i >= 0 && i < this.tagList.size()) {
147 | NBTBase nbtbase = (NBTBase) this.tagList.get(i);
148 | return nbtbase.getId() == 11 ? ((NBTTagIntArray) nbtbase).getIntArray() : new int[0];
149 | } else {
150 | return new int[0];
151 | }
152 | }
153 |
154 | public double getDoubleAt(int i) {
155 | if (i >= 0 && i < this.tagList.size()) {
156 | NBTBase nbtbase = (NBTBase) this.tagList.get(i);
157 | return nbtbase.getId() == 6 ? ((NBTTagDouble) nbtbase).getDouble() : 0.0D;
158 | } else {
159 | return 0.0D;
160 | }
161 | }
162 |
163 | public float getFloatAt(int i) {
164 | if (i >= 0 && i < this.tagList.size()) {
165 | NBTBase nbtbase = (NBTBase) this.tagList.get(i);
166 | return nbtbase.getId() == 5 ? ((NBTTagFloat) nbtbase).getFloat() : 0.0F;
167 | } else {
168 | return 0.0F;
169 | }
170 | }
171 |
172 | /**
173 | * Retrieves the tag String value at the specified index in the list
174 | */
175 | public String getStringTagAt(int i) {
176 | if (i >= 0 && i < this.tagList.size()) {
177 | NBTBase nbtbase = (NBTBase) this.tagList.get(i);
178 | return nbtbase.getId() == 8 ? nbtbase.getString() : nbtbase.toString();
179 | } else {
180 | return "";
181 | }
182 | }
183 |
184 | /**
185 | * Get the tag at the given position
186 | */
187 | public NBTBase get(int idx) {
188 | return (NBTBase) (idx >= 0 && idx < this.tagList.size() ? (NBTBase) this.tagList.get(idx) : new NBTTagEnd());
189 | }
190 |
191 | /**
192 | * Returns the number of tags in the list.
193 | */
194 | public int tagCount() {
195 | return this.tagList.size();
196 | }
197 |
198 | /**
199 | * Creates a clone of the tag.
200 | */
201 | public NBTBase copy() {
202 | NBTTagList nbttaglist = new NBTTagList();
203 | nbttaglist.tagType = this.tagType;
204 |
205 | for (NBTBase nbtbase : this.tagList) {
206 | NBTBase nbtbase1 = nbtbase.copy();
207 | nbttaglist.tagList.add(nbtbase1);
208 | }
209 |
210 | return nbttaglist;
211 | }
212 |
213 | public boolean equals(Object p_equals_1_) {
214 | if (super.equals(p_equals_1_)) {
215 | NBTTagList nbttaglist = (NBTTagList) p_equals_1_;
216 |
217 | if (this.tagType == nbttaglist.tagType) {
218 | return this.tagList.equals(nbttaglist.tagList);
219 | }
220 | }
221 |
222 | return false;
223 | }
224 |
225 | public int hashCode() {
226 | return super.hashCode() ^ this.tagList.hashCode();
227 | }
228 |
229 | public int getTagType() {
230 | return this.tagType;
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagLong.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagLong extends NBTBase.NBTPrimitive {
8 | /**
9 | * The long value for the tag.
10 | */
11 | private long data;
12 |
13 | NBTTagLong() {
14 | }
15 |
16 | public NBTTagLong(long data) {
17 | this.data = data;
18 | }
19 |
20 | /**
21 | * Write the actual data contents of the tag, implemented in NBT extension classes
22 | */
23 | void write(DataOutput output) throws IOException {
24 | output.writeLong(this.data);
25 | }
26 |
27 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
28 | sizeTracker.read(128L);
29 | this.data = input.readLong();
30 | }
31 |
32 | /**
33 | * Gets the type byte for the tag.
34 | */
35 | public byte getId() {
36 | return (byte) 4;
37 | }
38 |
39 | public String toString() {
40 | return "" + this.data + "L";
41 | }
42 |
43 | /**
44 | * Creates a clone of the tag.
45 | */
46 | public NBTBase copy() {
47 | return new NBTTagLong(this.data);
48 | }
49 |
50 | public boolean equals(Object p_equals_1_) {
51 | if (super.equals(p_equals_1_)) {
52 | NBTTagLong nbttaglong = (NBTTagLong) p_equals_1_;
53 | return this.data == nbttaglong.data;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 | public int hashCode() {
60 | return super.hashCode() ^ (int) (this.data ^ this.data >>> 32);
61 | }
62 |
63 | public long getLong() {
64 | return this.data;
65 | }
66 |
67 | public int getInt() {
68 | return (int) (this.data & -1L);
69 | }
70 |
71 | public short getShort() {
72 | return (short) ((int) (this.data & 65535L));
73 | }
74 |
75 | public byte getByte() {
76 | return (byte) ((int) (this.data & 255L));
77 | }
78 |
79 | public double getDouble() {
80 | return (double) this.data;
81 | }
82 |
83 | public float getFloat() {
84 | return (float) this.data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagShort.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagShort extends NBTBase.NBTPrimitive {
8 | /**
9 | * The short value for the tag.
10 | */
11 | private short data;
12 |
13 | public NBTTagShort() {
14 | }
15 |
16 | public NBTTagShort(short data) {
17 | this.data = data;
18 | }
19 |
20 | /**
21 | * Write the actual data contents of the tag, implemented in NBT extension classes
22 | */
23 | void write(DataOutput output) throws IOException {
24 | output.writeShort(this.data);
25 | }
26 |
27 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
28 | sizeTracker.read(80L);
29 | this.data = input.readShort();
30 | }
31 |
32 | /**
33 | * Gets the type byte for the tag.
34 | */
35 | public byte getId() {
36 | return (byte) 2;
37 | }
38 |
39 | public String toString() {
40 | return "" + this.data + "s";
41 | }
42 |
43 | /**
44 | * Creates a clone of the tag.
45 | */
46 | public NBTBase copy() {
47 | return new NBTTagShort(this.data);
48 | }
49 |
50 | public boolean equals(Object p_equals_1_) {
51 | if (super.equals(p_equals_1_)) {
52 | NBTTagShort nbttagshort = (NBTTagShort) p_equals_1_;
53 | return this.data == nbttagshort.data;
54 | } else {
55 | return false;
56 | }
57 | }
58 |
59 | public int hashCode() {
60 | return super.hashCode() ^ this.data;
61 | }
62 |
63 | public long getLong() {
64 | return (long) this.data;
65 | }
66 |
67 | public int getInt() {
68 | return this.data;
69 | }
70 |
71 | public short getShort() {
72 | return this.data;
73 | }
74 |
75 | public byte getByte() {
76 | return (byte) (this.data & 255);
77 | }
78 |
79 | public double getDouble() {
80 | return (double) this.data;
81 | }
82 |
83 | public float getFloat() {
84 | return (float) this.data;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/struct/nbt/NBTTagString.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.struct.nbt;
2 |
3 | import java.io.DataInput;
4 | import java.io.DataOutput;
5 | import java.io.IOException;
6 |
7 | public class NBTTagString extends NBTBase {
8 | /**
9 | * The string value for the tag (cannot be empty).
10 | */
11 | private String data;
12 |
13 | public NBTTagString() {
14 | this.data = "";
15 | }
16 |
17 | public NBTTagString(String data) {
18 | this.data = data;
19 |
20 | if (data == null) {
21 | throw new IllegalArgumentException("Empty string not allowed");
22 | }
23 | }
24 |
25 | /**
26 | * Write the actual data contents of the tag, implemented in NBT extension classes
27 | */
28 | void write(DataOutput output) throws IOException {
29 | output.writeUTF(this.data);
30 | }
31 |
32 | public void read(DataInput input, int depth, NBTSizeTracker sizeTracker) throws IOException {
33 | sizeTracker.read(288L);
34 | this.data = input.readUTF();
35 | sizeTracker.read((long) (16 * this.data.length()));
36 | }
37 |
38 | /**
39 | * Gets the type byte for the tag.
40 | */
41 | public byte getId() {
42 | return (byte) 8;
43 | }
44 |
45 | public String toString() {
46 | return "\"" + this.data.replace("\"", "\\\"") + "\"";
47 | }
48 |
49 | /**
50 | * Creates a clone of the tag.
51 | */
52 | public NBTBase copy() {
53 | return new NBTTagString(this.data);
54 | }
55 |
56 | /**
57 | * Return whether this compound has no tags.
58 | */
59 | public boolean hasNoTags() {
60 | return this.data.isEmpty();
61 | }
62 |
63 | public boolean equals(Object p_equals_1_) {
64 | if (!super.equals(p_equals_1_)) {
65 | return false;
66 | } else {
67 | NBTTagString nbttagstring = (NBTTagString) p_equals_1_;
68 | return this.data == null && nbttagstring.data == null || this.data != null && this.data.equals(nbttagstring.data);
69 | }
70 | }
71 |
72 | public int hashCode() {
73 | return super.hashCode() ^ this.data.hashCode();
74 | }
75 |
76 | public String getString() {
77 | return this.data;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/transformer/Transformer.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.transformer;
2 |
3 | import org.objectweb.asm.Opcodes;
4 | import org.objectweb.asm.tree.ClassNode;
5 |
6 | public interface Transformer extends Opcodes {
7 | void handle(ClassNode classNode);
8 |
9 | String getTarget();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/transformer/TransformerManager.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.transformer;
2 |
3 | import com.cubk.nsc2.Agent;
4 | import com.cubk.nsc2.transformer.transformers.BootstrapTransformer;
5 | import org.objectweb.asm.ClassReader;
6 | import org.objectweb.asm.ClassWriter;
7 | import org.objectweb.asm.tree.ClassNode;
8 |
9 | import java.io.File;
10 | import java.io.FileOutputStream;
11 | import java.lang.instrument.ClassFileTransformer;
12 | import java.lang.instrument.IllegalClassFormatException;
13 | import java.security.ProtectionDomain;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | public class TransformerManager implements ClassFileTransformer {
18 |
19 | private final List transformers = new ArrayList<>();
20 |
21 | public TransformerManager() {
22 | transformers.add(new BootstrapTransformer());
23 |
24 | //retransformClasses();
25 | }
26 |
27 | public void retransformClasses() {
28 | for (Transformer transformer : transformers) {
29 | try {
30 | Class> target = Class.forName(transformer.getTarget().replace("/", "."));
31 | System.out.println("[NSC] Transforming: " + target.getName());
32 | Agent.instrumentation.retransformClasses(target);
33 | } catch (Exception e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | }
38 |
39 | @Override
40 | public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
41 | for (Transformer transformer : transformers) {
42 | if (transformer.getTarget().equals(className)) {
43 |
44 | byte[] data = classfileBuffer;
45 | try {
46 | ClassNode classNode = new ClassNode();
47 | ClassReader reader = new ClassReader(classfileBuffer);
48 | reader.accept(classNode, 0);
49 |
50 | transformer.handle(classNode);
51 |
52 | ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
53 | classNode.accept(classWriter);
54 |
55 | data = classWriter.toByteArray();
56 |
57 | transformers.remove(transformer);
58 | File file = new File("NSC_" + classNode.name.replace("/", ".") + ".class");
59 | FileOutputStream fos = new FileOutputStream(file);
60 | fos.write(data);
61 | fos.close();
62 | } catch (Exception e) {
63 | e.printStackTrace();
64 | }
65 | return data;
66 | }
67 | }
68 | return classfileBuffer;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/transformer/transformers/BootstrapTransformer.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.transformer.transformers;
2 |
3 | import com.cubk.nsc2.gui.AddressSwapperFrame;
4 | import com.cubk.nsc2.transformer.Transformer;
5 | import io.netty.bootstrap.AbstractBootstrap;
6 | import io.netty.bootstrap.Bootstrap;
7 | import io.netty.channel.ChannelFuture;
8 | import org.objectweb.asm.tree.*;
9 |
10 | import java.lang.reflect.Method;
11 | import java.net.InetSocketAddress;
12 | import java.net.SocketAddress;
13 |
14 | public class BootstrapTransformer implements Transformer {
15 |
16 | public static ChannelFuture connectHook(Bootstrap bootstrap, SocketAddress remoteAddress) {
17 | if (remoteAddress instanceof InetSocketAddress) {
18 | InetSocketAddress address = (InetSocketAddress) remoteAddress;
19 |
20 | if (AddressSwapperFrame.getUse().isSelected()) {
21 | if (address.getHostName().startsWith(AddressSwapperFrame.getOriginalHostField().getText())) {
22 | remoteAddress = new InetSocketAddress(AddressSwapperFrame.getTargetServerField().getText(), Integer.parseInt(AddressSwapperFrame.getTargetPortField().getText()));
23 | }
24 | }
25 |
26 | try {
27 | Method localAddressMethod = AbstractBootstrap.class.getDeclaredMethod("localAddress");
28 | localAddressMethod.setAccessible(true);
29 | SocketAddress localAddress = (SocketAddress) localAddressMethod.invoke(bootstrap);
30 |
31 | Method doConnectMethod = Bootstrap.class.getDeclaredMethod("doConnect", SocketAddress.class, SocketAddress.class);
32 | doConnectMethod.setAccessible(true);
33 | return (ChannelFuture) doConnectMethod.invoke(bootstrap, remoteAddress, localAddress);
34 | } catch (Exception e) {
35 | e.printStackTrace();
36 | return null;
37 | }
38 | }
39 | return null;
40 | }
41 |
42 | @Override
43 | public void handle(ClassNode classNode) {
44 | for (MethodNode methodNode : classNode.methods) {
45 | if (methodNode.name.equals("connect") && methodNode.desc.equals("(Ljava/net/SocketAddress;)Lio/netty/channel/ChannelFuture;")) {
46 | InsnList instructions = methodNode.instructions;
47 |
48 | instructions.clear();
49 |
50 | instructions.add(new VarInsnNode(ALOAD, 0));
51 | instructions.add(new VarInsnNode(ALOAD, 1));
52 | instructions.add(new MethodInsnNode(INVOKESTATIC, BootstrapTransformer.class.getName().replace(".", "/"), "connectHook", "(Lio/netty/bootstrap/Bootstrap;Ljava/net/SocketAddress;)Lio/netty/channel/ChannelFuture;", false));
53 | instructions.add(new InsnNode(ARETURN));
54 |
55 | methodNode.instructions = instructions;
56 | }
57 | }
58 | }
59 |
60 | @Override
61 | public String getTarget() {
62 | return "io/netty/bootstrap/Bootstrap";
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/util/MathHelper.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.util;
2 |
3 | import java.util.Random;
4 | import java.util.UUID;
5 |
6 | public class MathHelper {
7 | public static final float SQRT_2 = sqrt_float(2.0F);
8 | private static final int SIN_BITS = 12;
9 | private static final int SIN_MASK = 4095;
10 | private static final int SIN_COUNT = 4096;
11 | private static final int SIN_COUNT_D4 = 1024;
12 | public static final float PI = MathUtil.roundToFloat(Math.PI);
13 | public static final float PI2 = MathUtil.roundToFloat((Math.PI * 2D));
14 | public static final float PId2 = MathUtil.roundToFloat((Math.PI / 2D));
15 | private static final float radToIndex = MathUtil.roundToFloat(651.8986469044033D);
16 | public static final float deg2Rad = MathUtil.roundToFloat(0.017453292519943295D);
17 | private static final float[] SIN_TABLE_FAST = new float[4096];
18 | public static boolean fastMath = false;
19 |
20 | /**
21 | * A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with steps of 2*PI / 65536.
22 | */
23 | private static final float[] SIN_TABLE = new float[65536];
24 |
25 | /**
26 | * Though it looks like an array, this is really more like a mapping. Key (index of this array) is the upper 5 bits
27 | * of the result of multiplying a 32-bit unsigned integer by the B(2, 5) De Bruijn sequence 0x077CB531. Value
28 | * (value stored in the array) is the unique index (from the right) of the leftmost one-bit in a 32-bit unsigned
29 | * integer that can cause the upper 5 bits to get that value. Used for highly optimized "find the log-base-2 of
30 | * this number" calculations.
31 | */
32 | private static final int[] multiplyDeBruijnBitPosition;
33 | private static final double field_181163_d;
34 | private static final double[] field_181164_e;
35 | private static final double[] field_181165_f;
36 |
37 | static {
38 | for (int i = 0; i < 65536; ++i) {
39 | SIN_TABLE[i] = (float) Math.sin((double) i * Math.PI * 2.0D / 65536.0D);
40 | }
41 |
42 | for (int j = 0; j < SIN_TABLE_FAST.length; ++j) {
43 | SIN_TABLE_FAST[j] = MathUtil.roundToFloat(Math.sin((double) j * Math.PI * 2.0D / 4096.0D));
44 | }
45 |
46 | multiplyDeBruijnBitPosition = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
47 | field_181163_d = Double.longBitsToDouble(4805340802404319232L);
48 | field_181164_e = new double[257];
49 | field_181165_f = new double[257];
50 |
51 | for (int k = 0; k < 257; ++k) {
52 | double d0 = (double) k / 256.0D;
53 | double d1 = Math.asin(d0);
54 | field_181165_f[k] = Math.cos(d1);
55 | field_181164_e[k] = d1;
56 | }
57 | }
58 |
59 | /**
60 | * sin looked up in a table
61 | */
62 | public static float sin(float p_76126_0_) {
63 | return fastMath ? SIN_TABLE_FAST[(int) (p_76126_0_ * radToIndex) & 4095] : SIN_TABLE[(int) (p_76126_0_ * 10430.378F) & 65535];
64 | }
65 |
66 | /**
67 | * cos looked up in the sin table with the appropriate offset
68 | */
69 | public static float cos(float value) {
70 | return fastMath ? SIN_TABLE_FAST[(int) (value * radToIndex + 1024.0F) & 4095] : SIN_TABLE[(int) (value * 10430.378F + 16384.0F) & 65535];
71 | }
72 |
73 | public static float sqrt_float(float value) {
74 | return (float) Math.sqrt((double) value);
75 | }
76 |
77 | public static float sqrt_double(double value) {
78 | return (float) Math.sqrt(value);
79 | }
80 |
81 | /**
82 | * Returns the greatest integer less than or equal to the float argument
83 | */
84 | public static int floor_float(float value) {
85 | int i = (int) value;
86 | return value < (float) i ? i - 1 : i;
87 | }
88 |
89 | /**
90 | * returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024
91 | */
92 | public static int truncateDoubleToInt(double value) {
93 | return (int) (value + 1024.0D) - 1024;
94 | }
95 |
96 | /**
97 | * Returns the greatest integer less than or equal to the double argument
98 | */
99 | public static int floor_double(double value) {
100 | int i = (int) value;
101 | return value < (double) i ? i - 1 : i;
102 | }
103 |
104 | /**
105 | * Long version of floor_double
106 | */
107 | public static long floor_double_long(double value) {
108 | long i = (long) value;
109 | return value < (double) i ? i - 1L : i;
110 | }
111 |
112 | public static int func_154353_e(double value) {
113 | return (int) (value >= 0.0D ? value : -value + 1.0D);
114 | }
115 |
116 | public static float abs(float value) {
117 | return value >= 0.0F ? value : -value;
118 | }
119 |
120 | /**
121 | * Returns the unsigned value of an int.
122 | */
123 | public static int abs_int(int value) {
124 | return value >= 0 ? value : -value;
125 | }
126 |
127 | public static int ceiling_float_int(float value) {
128 | int i = (int) value;
129 | return value > (float) i ? i + 1 : i;
130 | }
131 |
132 | public static int ceiling_double_int(double value) {
133 | int i = (int) value;
134 | return value > (double) i ? i + 1 : i;
135 | }
136 |
137 | /**
138 | * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and
139 | * third parameters.
140 | */
141 | public static int clamp_int(int num, int min, int max) {
142 | return num < min ? min : (num > max ? max : num);
143 | }
144 |
145 | /**
146 | * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and
147 | * third parameters
148 | */
149 | public static float clamp_float(float num, float min, float max) {
150 | return num < min ? min : (num > max ? max : num);
151 | }
152 |
153 | public static double clamp_double(double num, double min, double max) {
154 | return num < min ? min : (num > max ? max : num);
155 | }
156 |
157 | public static double denormalizeClamp(double lowerBnd, double upperBnd, double slide) {
158 | return slide < 0.0D ? lowerBnd : (slide > 1.0D ? upperBnd : lowerBnd + (upperBnd - lowerBnd) * slide);
159 | }
160 |
161 | /**
162 | * Maximum of the absolute value of two numbers.
163 | */
164 | public static double abs_max(double p_76132_0_, double p_76132_2_) {
165 | if (p_76132_0_ < 0.0D) {
166 | p_76132_0_ = -p_76132_0_;
167 | }
168 |
169 | if (p_76132_2_ < 0.0D) {
170 | p_76132_2_ = -p_76132_2_;
171 | }
172 |
173 | return p_76132_0_ > p_76132_2_ ? p_76132_0_ : p_76132_2_;
174 | }
175 |
176 | /**
177 | * Buckets an integer with specifed bucket sizes. Args: i, bucketSize
178 | */
179 | public static int bucketInt(int p_76137_0_, int p_76137_1_) {
180 | return p_76137_0_ < 0 ? -((-p_76137_0_ - 1) / p_76137_1_) - 1 : p_76137_0_ / p_76137_1_;
181 | }
182 |
183 | public static int getRandomIntegerInRange(Random p_76136_0_, int p_76136_1_, int p_76136_2_) {
184 | return p_76136_1_ >= p_76136_2_ ? p_76136_1_ : p_76136_0_.nextInt(p_76136_2_ - p_76136_1_ + 1) + p_76136_1_;
185 | }
186 |
187 | public static float randomFloatClamp(Random p_151240_0_, float p_151240_1_, float p_151240_2_) {
188 | return p_151240_1_ >= p_151240_2_ ? p_151240_1_ : p_151240_0_.nextFloat() * (p_151240_2_ - p_151240_1_) + p_151240_1_;
189 | }
190 |
191 | public static double getRandomDoubleInRange(Random p_82716_0_, double p_82716_1_, double p_82716_3_) {
192 | return p_82716_1_ >= p_82716_3_ ? p_82716_1_ : p_82716_0_.nextDouble() * (p_82716_3_ - p_82716_1_) + p_82716_1_;
193 | }
194 |
195 | public static double average(long[] values) {
196 | long i = 0L;
197 |
198 | for (long j : values) {
199 | i += j;
200 | }
201 |
202 | return (double) i / (double) values.length;
203 | }
204 |
205 | public static boolean epsilonEquals(float p_180185_0_, float p_180185_1_) {
206 | return abs(p_180185_1_ - p_180185_0_) < 1.0E-5F;
207 | }
208 |
209 | public static int normalizeAngle(int p_180184_0_, int p_180184_1_) {
210 | return (p_180184_0_ % p_180184_1_ + p_180184_1_) % p_180184_1_;
211 | }
212 |
213 | /**
214 | * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check
215 | */
216 | public static float wrapAngleTo180_float(float value) {
217 | value = value % 360.0F;
218 |
219 | if (value >= 180.0F) {
220 | value -= 360.0F;
221 | }
222 |
223 | if (value < -180.0F) {
224 | value += 360.0F;
225 | }
226 |
227 | return value;
228 | }
229 |
230 | /**
231 | * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check
232 | */
233 | public static double wrapAngleTo180_double(double value) {
234 | value = value % 360.0D;
235 |
236 | if (value >= 180.0D) {
237 | value -= 360.0D;
238 | }
239 |
240 | if (value < -180.0D) {
241 | value += 360.0D;
242 | }
243 |
244 | return value;
245 | }
246 |
247 | /**
248 | * parses the string as integer or returns the second parameter if it fails
249 | */
250 | public static int parseIntWithDefault(String p_82715_0_, int p_82715_1_) {
251 | try {
252 | return Integer.parseInt(p_82715_0_);
253 | } catch (Throwable var3) {
254 | return p_82715_1_;
255 | }
256 | }
257 |
258 | /**
259 | * parses the string as integer or returns the second parameter if it fails. this value is capped to par2
260 | */
261 | public static int parseIntWithDefaultAndMax(String p_82714_0_, int p_82714_1_, int p_82714_2_) {
262 | return Math.max(p_82714_2_, parseIntWithDefault(p_82714_0_, p_82714_1_));
263 | }
264 |
265 | /**
266 | * parses the string as double or returns the second parameter if it fails.
267 | */
268 | public static double parseDoubleWithDefault(String p_82712_0_, double p_82712_1_) {
269 | try {
270 | return Double.parseDouble(p_82712_0_);
271 | } catch (Throwable var4) {
272 | return p_82712_1_;
273 | }
274 | }
275 |
276 | public static double parseDoubleWithDefaultAndMax(String p_82713_0_, double p_82713_1_, double p_82713_3_) {
277 | return Math.max(p_82713_3_, parseDoubleWithDefault(p_82713_0_, p_82713_1_));
278 | }
279 |
280 | /**
281 | * Returns the input value rounded up to the next highest power of two.
282 | */
283 | public static int roundUpToPowerOfTwo(int value) {
284 | int i = value - 1;
285 | i = i | i >> 1;
286 | i = i | i >> 2;
287 | i = i | i >> 4;
288 | i = i | i >> 8;
289 | i = i | i >> 16;
290 | return i + 1;
291 | }
292 |
293 | /**
294 | * Is the given value a power of two? (1, 2, 4, 8, 16, ...)
295 | */
296 | private static boolean isPowerOfTwo(int value) {
297 | return value != 0 && (value & value - 1) == 0;
298 | }
299 |
300 | /**
301 | * Uses a B(2, 5) De Bruijn sequence and a lookup table to efficiently calculate the log-base-two of the given
302 | * value. Optimized for cases where the input value is a power-of-two. If the input value is not a power-of-two,
303 | * then subtract 1 from the return value.
304 | */
305 | private static int calculateLogBaseTwoDeBruijn(int value) {
306 | value = isPowerOfTwo(value) ? value : roundUpToPowerOfTwo(value);
307 | return multiplyDeBruijnBitPosition[(int) ((long) value * 125613361L >> 27) & 31];
308 | }
309 |
310 | /**
311 | * Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the
312 | * highest bit that is set. For example, if the number in binary is 0...100101, this will return 5.
313 | */
314 | public static int calculateLogBaseTwo(int value) {
315 | return calculateLogBaseTwoDeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1);
316 | }
317 |
318 | public static int roundUp(int p_154354_0_, int p_154354_1_) {
319 | if (p_154354_1_ == 0) {
320 | return 0;
321 | } else if (p_154354_0_ == 0) {
322 | return p_154354_1_;
323 | } else {
324 | if (p_154354_0_ < 0) {
325 | p_154354_1_ *= -1;
326 | }
327 |
328 | int i = p_154354_0_ % p_154354_1_;
329 | return i == 0 ? p_154354_0_ : p_154354_0_ + p_154354_1_ - i;
330 | }
331 | }
332 |
333 | public static int func_180183_b(float p_180183_0_, float p_180183_1_, float p_180183_2_) {
334 | return func_180181_b(floor_float(p_180183_0_ * 255.0F), floor_float(p_180183_1_ * 255.0F), floor_float(p_180183_2_ * 255.0F));
335 | }
336 |
337 | public static int func_180181_b(int p_180181_0_, int p_180181_1_, int p_180181_2_) {
338 | int i = (p_180181_0_ << 8) + p_180181_1_;
339 | i = (i << 8) + p_180181_2_;
340 | return i;
341 | }
342 |
343 | public static int func_180188_d(int p_180188_0_, int p_180188_1_) {
344 | int i = (p_180188_0_ & 16711680) >> 16;
345 | int j = (p_180188_1_ & 16711680) >> 16;
346 | int k = (p_180188_0_ & 65280) >> 8;
347 | int l = (p_180188_1_ & 65280) >> 8;
348 | int i1 = (p_180188_0_ & 255) >> 0;
349 | int j1 = (p_180188_1_ & 255) >> 0;
350 | int k1 = (int) ((float) i * (float) j / 255.0F);
351 | int l1 = (int) ((float) k * (float) l / 255.0F);
352 | int i2 = (int) ((float) i1 * (float) j1 / 255.0F);
353 | return p_180188_0_ & -16777216 | k1 << 16 | l1 << 8 | i2;
354 | }
355 |
356 | public static double func_181162_h(double p_181162_0_) {
357 | return p_181162_0_ - Math.floor(p_181162_0_);
358 | }
359 |
360 | public static long getCoordinateRandom(int x, int y, int z) {
361 | long i = (long) (x * 3129871) ^ (long) z * 116129781L ^ (long) y;
362 | i = i * i * 42317861L + i * 11L;
363 | return i;
364 | }
365 |
366 | public static UUID getRandomUuid(Random rand) {
367 | long i = rand.nextLong() & -61441L | 16384L;
368 | long j = rand.nextLong() & 4611686018427387903L | Long.MIN_VALUE;
369 | return new UUID(i, j);
370 | }
371 |
372 | public static double func_181160_c(double p_181160_0_, double p_181160_2_, double p_181160_4_) {
373 | return (p_181160_0_ - p_181160_2_) / (p_181160_4_ - p_181160_2_);
374 | }
375 |
376 | public static double atan2(double p_181159_0_, double p_181159_2_) {
377 | double d0 = p_181159_2_ * p_181159_2_ + p_181159_0_ * p_181159_0_;
378 |
379 | if (Double.isNaN(d0)) {
380 | return Double.NaN;
381 | } else {
382 | boolean flag = p_181159_0_ < 0.0D;
383 |
384 | if (flag) {
385 | p_181159_0_ = -p_181159_0_;
386 | }
387 |
388 | boolean flag1 = p_181159_2_ < 0.0D;
389 |
390 | if (flag1) {
391 | p_181159_2_ = -p_181159_2_;
392 | }
393 |
394 | boolean flag2 = p_181159_0_ > p_181159_2_;
395 |
396 | if (flag2) {
397 | double d1 = p_181159_2_;
398 | p_181159_2_ = p_181159_0_;
399 | p_181159_0_ = d1;
400 | }
401 |
402 | double d9 = func_181161_i(d0);
403 | p_181159_2_ = p_181159_2_ * d9;
404 | p_181159_0_ = p_181159_0_ * d9;
405 | double d2 = field_181163_d + p_181159_0_;
406 | int i = (int) Double.doubleToRawLongBits(d2);
407 | double d3 = field_181164_e[i];
408 | double d4 = field_181165_f[i];
409 | double d5 = d2 - field_181163_d;
410 | double d6 = p_181159_0_ * d4 - p_181159_2_ * d5;
411 | double d7 = (6.0D + d6 * d6) * d6 * 0.16666666666666666D;
412 | double d8 = d3 + d7;
413 |
414 | if (flag2) {
415 | d8 = (Math.PI / 2D) - d8;
416 | }
417 |
418 | if (flag1) {
419 | d8 = Math.PI - d8;
420 | }
421 |
422 | if (flag) {
423 | d8 = -d8;
424 | }
425 |
426 | return d8;
427 | }
428 | }
429 |
430 | public static double func_181161_i(double p_181161_0_) {
431 | double d0 = 0.5D * p_181161_0_;
432 | long i = Double.doubleToRawLongBits(p_181161_0_);
433 | i = 6910469410427058090L - (i >> 1);
434 | p_181161_0_ = Double.longBitsToDouble(i);
435 | p_181161_0_ = p_181161_0_ * (1.5D - d0 * p_181161_0_ * p_181161_0_);
436 | return p_181161_0_;
437 | }
438 |
439 | public static int hsvToRGB(float p_181758_0_, float p_181758_1_, float p_181758_2_) {
440 | int i = (int) (p_181758_0_ * 6.0F) % 6;
441 | float f = p_181758_0_ * 6.0F - (float) i;
442 | float f1 = p_181758_2_ * (1.0F - p_181758_1_);
443 | float f2 = p_181758_2_ * (1.0F - f * p_181758_1_);
444 | float f3 = p_181758_2_ * (1.0F - (1.0F - f) * p_181758_1_);
445 | float f4;
446 | float f5;
447 | float f6;
448 |
449 | switch (i) {
450 | case 0:
451 | f4 = p_181758_2_;
452 | f5 = f3;
453 | f6 = f1;
454 | break;
455 |
456 | case 1:
457 | f4 = f2;
458 | f5 = p_181758_2_;
459 | f6 = f1;
460 | break;
461 |
462 | case 2:
463 | f4 = f1;
464 | f5 = p_181758_2_;
465 | f6 = f3;
466 | break;
467 |
468 | case 3:
469 | f4 = f1;
470 | f5 = f2;
471 | f6 = p_181758_2_;
472 | break;
473 |
474 | case 4:
475 | f4 = f3;
476 | f5 = f1;
477 | f6 = p_181758_2_;
478 | break;
479 |
480 | case 5:
481 | f4 = p_181758_2_;
482 | f5 = f1;
483 | f6 = f2;
484 | break;
485 |
486 | default:
487 | throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + p_181758_0_ + ", " + p_181758_1_ + ", " + p_181758_2_);
488 | }
489 |
490 | int j = clamp_int((int) (f4 * 255.0F), 0, 255);
491 | int k = clamp_int((int) (f5 * 255.0F), 0, 255);
492 | int l = clamp_int((int) (f6 * 255.0F), 0, 255);
493 | return j << 16 | k << 8 | l;
494 | }
495 | }
496 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/util/MathUtil.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.util;
2 |
3 | public class MathUtil {
4 | public static final float PI = (float) Math.PI;
5 | public static final float PI2 = ((float) Math.PI * 2F);
6 | public static final float PId2 = ((float) Math.PI / 2F);
7 | private static final float[] ASIN_TABLE = new float[65536];
8 |
9 | static {
10 | for (int i = 0; i < 65536; ++i) {
11 | ASIN_TABLE[i] = (float) Math.asin((double) i / 32767.5D - 1.0D);
12 | }
13 |
14 | for (int j = -1; j < 2; ++j) {
15 | ASIN_TABLE[(int) (((double) j + 1.0D) * 32767.5D) & 65535] = (float) Math.asin((double) j);
16 | }
17 | }
18 |
19 | public static float asin(float value) {
20 | return ASIN_TABLE[(int) ((double) (value + 1.0F) * 32767.5D) & 65535];
21 | }
22 |
23 | public static float acos(float value) {
24 | return ((float) Math.PI / 2F) - ASIN_TABLE[(int) ((double) (value + 1.0F) * 32767.5D) & 65535];
25 | }
26 |
27 | public static int getAverage(int[] vals) {
28 | if (vals.length <= 0) {
29 | return 0;
30 | } else {
31 | int i = getSum(vals);
32 | int j = i / vals.length;
33 | return j;
34 | }
35 | }
36 |
37 | public static int getSum(int[] vals) {
38 | if (vals.length <= 0) {
39 | return 0;
40 | } else {
41 | int i = 0;
42 |
43 | for (int j = 0; j < vals.length; ++j) {
44 | int k = vals[j];
45 | i += k;
46 | }
47 |
48 | return i;
49 | }
50 | }
51 |
52 | public static int roundDownToPowerOfTwo(int val) {
53 | int i = MathHelper.roundUpToPowerOfTwo(val);
54 | return val == i ? i : i / 2;
55 | }
56 |
57 | public static boolean equalsDelta(float f1, float f2, float delta) {
58 | return Math.abs(f1 - f2) <= delta;
59 | }
60 |
61 | public static float toDeg(float angle) {
62 | return angle * 180.0F / MathHelper.PI;
63 | }
64 |
65 | public static float toRad(float angle) {
66 | return angle / 180.0F * MathHelper.PI;
67 | }
68 |
69 | public static float roundToFloat(double d) {
70 | return (float) ((double) Math.round(d * 1.0E8D) / 1.0E8D);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/cubk/nsc2/util/TimerUtil.java:
--------------------------------------------------------------------------------
1 | package com.cubk.nsc2.util;
2 |
3 | public class TimerUtil {
4 | public long lastMS = System.currentTimeMillis();
5 | public long time;
6 |
7 | public void reset() {
8 | lastMS = System.currentTimeMillis();
9 | }
10 |
11 | public boolean hasTimeElapsed(long time, boolean reset) {
12 | if (System.currentTimeMillis() - lastMS > time) {
13 | if (reset) reset();
14 | return true;
15 | }
16 |
17 | return false;
18 | }
19 |
20 | public long elapsed() {
21 | return System.currentTimeMillis() - lastMS;
22 | }
23 |
24 | public boolean hasTimeElapsed(long time) {
25 | this.time = time;
26 | return System.currentTimeMillis() - lastMS > this.time;
27 | }
28 |
29 | public long getTime() {
30 | return System.currentTimeMillis() - lastMS;
31 | }
32 |
33 | public void setTime(long time) {
34 | lastMS = time;
35 | }
36 |
37 | public static final class CPSDelay {
38 | private final TimerUtil timerUtils = new TimerUtil();
39 |
40 | public boolean shouldAttack(int cps) {
41 | int aps = 20 / cps;
42 | return timerUtils.hasTimeElapsed(50 * aps, true);
43 | }
44 |
45 | public void reset() {
46 | timerUtils.reset();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------