package org.runite.client; import org.rs09.SystemLogger; import org.rs09.client.config.GameConfig; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableRowSorter; import java.awt.*; import java.awt.event.*; import java.util.EventObject; public class ModPanel extends JPanel { ButtonListener listener = new ButtonListener(); DebugMenu debugMenu = new DebugMenu(); ItemMenu itemMenu = new ItemMenu(); NPCMenu npcMenu = new NPCMenu(); PlayerMenu playerMenu = new PlayerMenu(); TeleMenu teleMenu = new TeleMenu(); public ModPanel() { setVisible(false); JButton teleMenu = new JButton("Tele"); teleMenu.setActionCommand("tele"); teleMenu.addActionListener(listener); JButton playerMenu = new JButton("Player"); playerMenu.setActionCommand("player"); playerMenu.addActionListener(listener); JButton npcMenu = new JButton("NPC"); npcMenu.setActionCommand("npc"); npcMenu.addActionListener(listener); JButton itemMenu = new JButton("Item"); itemMenu.setActionCommand("item"); itemMenu.addActionListener(listener); JButton debugMenu = new JButton("Debug"); debugMenu.setActionCommand("debug"); debugMenu.addActionListener(listener); JButton closeButton = new JButton("Close Panel"); closeButton.setActionCommand("close"); closeButton.addActionListener(listener); add(teleMenu); add(playerMenu); add(npcMenu); add(itemMenu); add(debugMenu); add(closeButton, BorderLayout.EAST); } private void sendCommand(String command) { TextureOperation12.outgoingBuffer.putOpcode(44); TextureOperation12.outgoingBuffer.writeByte(command.length() + -1); TextureOperation12.outgoingBuffer.writeString(command.substring(2)); } class ButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent actionEvent) { switch (actionEvent.getActionCommand()) { case "close": ClientLoader.setModPanelVisible(false); break; case "debug": debugMenu.setVisible(true); break; case "item": itemMenu.open(); break; case "npc": npcMenu.open(); break; case "player": playerMenu.open(); break; case "tele": teleMenu.open(); break; } } } class TeleMenu extends JFrame { Object[][] rowData = { {"2974,4383,2", "corporeal beast"}, {"2659,2649,0", "pest control"}, {"3293,3184,0", "al kharid"}, {"3222,3217,0", "lumbridge"}, {"3110,3168,0", "wizard's tower"}, {"3083,3249,0", "draynor village"}, {"3019,3244,0", "port sarim"}, {"2956,3209,0", "rimmington"}, {"2965,3380,0", "falador"}, {"2895,3436,0", "taverly"}, {"3080,3423,0", "barbarian village"}, {"3213,3428,0", "varrock"}, {"3164,3485,0", "grand exchange"}, {"2917,3175,0", "karamja"}, {"2450,5165,0", "tzhaar"}, {"2795,3177,0", "brimhaven"}, {"2849,2961,0", "shilo village"}, {"2605,3093,0", "yanille"}, {"2663,3305,0", "ardougne"}, {"2450,3422,0", "tree gnome stronghold"}, {"2730,3485,0", "camelot"}, {"2730,3485,0", "seer's village"}, {"2805,3435,0", "catherby"}, {"2658,3657,0", "relleka"}, {"2890,3676,0", "trollheim"}, {"2914,3746,0", "god wars dungeon"}, {"3180,3684,0", "bounty hunter"}, {"3272,3687,0", "clan wars"}, {"3090,3957,0", "mage arena"}, {"3069,10257,0", "king black dragon"}, {"3359,3416,0", "digsite"}, {"3488,3489,0", "canifis"}, {"3428,3526,0", "slayer tower"}, {"3502,9483,0", "kalphite queen"}, {"3233,2913,0", "pyramid"}, {"3419,2917,0", "nardah"}, {"3482,3090,0", "uzer"}, {"3358,2970,0", "pollnivneach"}, {"3305,2788,0", "sophanem"}, {"2898,3544,0", "burthorpe"}, {"3088,3491,0", "edgeville"}, {"3169,3034,0", "bedabin"}, {"3565,3289,0", "barrows"}, {"3016,3513,0", "black knight's fortress"}, {"3052,3481,0", "monastery"} }; JTextField playerNameField = new JTextField(); JTextField coordsField = new JTextField(); JCheckBox toMeToggle = new JCheckBox("To Me"); JTable table = new JTable(rowData, new Object[]{"Coords", "Name"}) { @Override public boolean editCellAt(int i, int i1, EventObject eventObject) { return false; } @Override public Object getValueAt(int i, int i1) { return rowData[i][i1]; } @Override public int getRowCount() { return rowData.length; } }; DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer(); ActionListener buttonListener = actionEvent -> { String command = actionEvent.getActionCommand(); switch (command) { case "telePlayer": if (toMeToggle.isSelected()) { sendCommand("::teletome " + playerNameField.getText()); } else { sendCommand("::teleto " + playerNameField.getText()); } break; case "teleCoords": String[] coordTokens = coordsField.getText().split(","); if (coordTokens.length < 2) { coordsField.setText(""); break; } int x, y, z = 0; try { x = Integer.parseInt(coordTokens[0]); y = Integer.parseInt(coordTokens[1]); if (coordTokens.length == 3) z = Integer.parseInt(coordTokens[2]); } catch (NumberFormatException e) { SystemLogger.logErr("(ModPanel.java:118) Invalid value passed to coords tele."); coordsField.setText(""); break; } sendCoordTele(x, y, z); break; } }; TeleMenu() { super("Teleport Menu"); setLayout(new BorderLayout()); JPanel playerTelePanel = new JPanel(); playerTelePanel.setLayout(new FlowLayout()); JLabel playerNameLabel = new JLabel("Player Name:"); JButton teleButton = new JButton("Tele"); teleButton.setActionCommand("telePlayer"); teleButton.addActionListener(buttonListener); playerNameField.setPreferredSize(new Dimension(100, 20)); playerTelePanel.add(playerNameLabel); playerTelePanel.add(playerNameField); playerTelePanel.add(toMeToggle); playerTelePanel.add(teleButton); JPanel coordTelePanel = new JPanel(); JLabel coordsLabel = new JLabel("Coordinates:"); teleButton = new JButton("Tele"); teleButton.setActionCommand("teleCoords"); teleButton.addActionListener(buttonListener); coordsField.setPreferredSize(new Dimension(60, 20)); coordTelePanel.add(coordsLabel); coordTelePanel.add(coordsField); coordTelePanel.add(teleButton); table.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2) { JTable table = (JTable) mouseEvent.getSource(); int row = table.getSelectedRow(); String coordTokens = table.getValueAt(row, 0).toString(); sendCommand("::tele " + coordTokens.replace(",", " ")); SystemLogger.logInfo("Sending teleport command to " + coordTokens); } } @Override public void mousePressed(MouseEvent mouseEvent) { } @Override public void mouseReleased(MouseEvent mouseEvent) { } @Override public void mouseEntered(MouseEvent mouseEvent) { } @Override public void mouseExited(MouseEvent mouseEvent) { } }); cellRenderer.setToolTipText("Double-click to teleport."); table.getColumnModel().getColumn(0).setMaxWidth(250); table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer); table.getColumnModel().getColumn(1).setCellRenderer(cellRenderer); JPanel fullTele = new JPanel(); fullTele.setLayout(new BoxLayout(fullTele, BoxLayout.PAGE_AXIS)); JScrollPane scrollPane = new JScrollPane(table); fullTele.add(scrollPane); add(playerTelePanel, BorderLayout.NORTH); add(coordTelePanel, BorderLayout.CENTER); add(fullTele, BorderLayout.SOUTH); pack(); } private void open() { setVisible(true); } private void sendCoordTele(int x, int y, int z) { sendCommand("::tele " + x + " " + y + " " + z); } private void sendCoordTele(int x, int y) { sendCoordTele(x, y, 0); } } class PlayerMenu extends JFrame { JTextField nameField = new JTextField(); JTextField durationField = new JTextField(); ItemListener itemListener = new ItemListener() { @Override public void itemStateChanged(ItemEvent itemEvent) { String title = ((JCheckBox) itemEvent.getItem()).getText(); switch (title) { case "God Mode": sendCommand("::god"); break; case "Instakill": sendCommand("::1hit"); break; } } }; ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { String actionName = actionEvent.getActionCommand(); switch (actionName) { case "jail": sendCommand("::jail " + durationField.getText() + " " + nameField.getText()); break; case "empty": sendCommand("::empty"); break; } } }; PlayerMenu() { super("Player Options"); setLayout(new BorderLayout()); JPanel jailPanel = new JPanel(); jailPanel.setLayout(new FlowLayout()); JLabel nameLabel = new JLabel("Name:"); JLabel durationLabel = new JLabel("Duration(seconds):"); JButton jailButton = new JButton("Jail"); jailPanel.add(nameLabel); jailPanel.add(nameField); nameField.setPreferredSize(new Dimension(100, 20)); jailPanel.add(durationLabel); jailPanel.add(durationField); durationField.setPreferredSize(new Dimension(55, 20)); jailPanel.add(jailButton); jailButton.setActionCommand("jail"); jailButton.addActionListener(listener); add(jailPanel, BorderLayout.NORTH); JPanel selfPanel = new JPanel(); selfPanel.setLayout(new FlowLayout()); JLabel selfLabel = new JLabel("Self: "); JCheckBox godCheck = new JCheckBox("God Mode"); JCheckBox instakillCheck = new JCheckBox("Instakill"); godCheck.addItemListener(itemListener); instakillCheck.addItemListener(itemListener); JButton emptyButton = new JButton("Empty Inv"); emptyButton.setActionCommand("empty"); emptyButton.addActionListener(listener); selfPanel.add(selfLabel); selfPanel.add(godCheck); selfPanel.add(instakillCheck); selfPanel.add(emptyButton); add(selfPanel, BorderLayout.SOUTH); pack(); setVisible(false); } public void open() { setVisible(true); } } class NPCMenu extends JFrame { DefaultTableModel model = new DefaultTableModel(); JTextField searchField = new JTextField(); JTextField amountField = new JTextField(); TableRowSorter sorter = new TableRowSorter<>(model); DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer(); boolean populated = false; NPCMenu() { super("NPC Spawning Menu"); setLayout(new BorderLayout()); cellRenderer.setToolTipText("Double-Click to spawn."); JPanel searchPanel = new JPanel(); JLabel searchLabel = new JLabel("Search for NPC:"); searchField.setPreferredSize(new Dimension(100, 20)); searchPanel.add(searchLabel); searchPanel.add(searchField); add(searchPanel, BorderLayout.NORTH); setLocationRelativeTo(null); JTable npcTable = new JTable(model) { @Override public boolean editCellAt(int i, int i1, EventObject eventObject) { return false; } }; model.addColumn("ID"); model.addColumn("Name"); npcTable.setRowSorter(sorter); npcTable.getColumnModel().getColumn(0).setMaxWidth(55); npcTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer); npcTable.getColumnModel().getColumn(1).setCellRenderer(cellRenderer); npcTable.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2) { JTable table = (JTable) mouseEvent.getSource(); int row = table.getSelectedRow(); sendCommand("::npc " + table.getValueAt(row, 0) + (amountField.getText().isEmpty() ? "" : (" " + amountField.getText()))); SystemLogger.logInfo("Sending spawn command for NPC: " + table.getValueAt(row, 1) + " " + amountField.getText()); } } @Override public void mousePressed(MouseEvent mouseEvent) { } @Override public void mouseReleased(MouseEvent mouseEvent) { } @Override public void mouseEntered(MouseEvent mouseEvent) { } @Override public void mouseExited(MouseEvent mouseEvent) { } }); searchField.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent keyEvent) { filter(); } @Override public void keyPressed(KeyEvent keyEvent) { } @Override public void keyReleased(KeyEvent keyEvent) { } }); JScrollPane scrollPane = new JScrollPane(npcTable); add(scrollPane, BorderLayout.SOUTH); pack(); setVisible(false); } private void filter() { RowFilter rf = null; //If current expression doesn't parse, don't update. try { rf = RowFilter.regexFilter(searchField.getText(), 1); } catch (java.util.regex.PatternSyntaxException e) { return; } sorter.setRowFilter(rf); } public void open() { if (!populated) { SwingUtilities.invokeLater(() -> { for (int i = 0; i < 14649; i++) { NPCDefinition def = NPCDefinition.getNPCDefinition(i); if (def == null) continue; model.addRow(new Object[]{i, def.NPCName.toLowercase()}); } setVisible(true); populated = true; }); } else { setVisible(true); } } } class ItemMenu extends JFrame { DefaultTableModel model = new DefaultTableModel(); JTextField searchField = new JTextField(); JTextField amountField = new JTextField(); TableRowSorter sorter = new TableRowSorter<>(model); DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer(); boolean populated = false; ItemMenu() { super("Item Spawning Menu"); setLayout(new BorderLayout()); cellRenderer.setToolTipText("Double-Click to spawn."); JPanel searchPanel = new JPanel(); JLabel searchLabel = new JLabel("Search for Item:"); JLabel amountLabel = new JLabel("Amount: "); amountField.setPreferredSize(new Dimension(45, 20)); searchField.setPreferredSize(new Dimension(100, 20)); searchPanel.add(searchLabel); searchPanel.add(searchField); searchPanel.add(amountLabel); searchPanel.add(amountField); add(searchPanel, BorderLayout.NORTH); setLocationRelativeTo(null); JTable itemTable = new JTable(model) { @Override public boolean editCellAt(int i, int i1, EventObject eventObject) { return false; } }; model.addColumn("ID"); model.addColumn("Name"); itemTable.setRowSorter(sorter); itemTable.getColumnModel().getColumn(0).setMaxWidth(55); itemTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer); itemTable.getColumnModel().getColumn(1).setCellRenderer(cellRenderer); itemTable.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2) { JTable table = (JTable) mouseEvent.getSource(); int row = table.getSelectedRow(); sendCommand("::item " + table.getValueAt(row, 0) + (amountField.getText().isEmpty() ? "" : (" " + amountField.getText()))); SystemLogger.logInfo("Sending spawn command for item: " + table.getValueAt(row, 1) + " " + amountField.getText()); } } @Override public void mousePressed(MouseEvent mouseEvent) { } @Override public void mouseReleased(MouseEvent mouseEvent) { } @Override public void mouseEntered(MouseEvent mouseEvent) { } @Override public void mouseExited(MouseEvent mouseEvent) { } }); searchField.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent keyEvent) { filter(); } @Override public void keyPressed(KeyEvent keyEvent) { } @Override public void keyReleased(KeyEvent keyEvent) { } }); JScrollPane scrollPane = new JScrollPane(itemTable); add(scrollPane, BorderLayout.SOUTH); pack(); setVisible(false); } private void filter() { RowFilter rf = null; //If current expression doesn't parse, don't update. try { rf = RowFilter.regexFilter(searchField.getText(), 1); } catch (java.util.regex.PatternSyntaxException e) { return; } sorter.setRowFilter(rf); } public void open() { if (!populated) { SwingUtilities.invokeLater(() -> { for (int i = 0; i < 14649; i++) { ItemDefinition def = ItemDefinition.getItemDefinition(i); if (def == null) continue; model.addRow(new Object[]{i, def.name.toLowercase()}); } setVisible(true); populated = true; }); } else { setVisible(true); } } } class DebugMenu extends JFrame { DebugMenu() { super("Debug Options"); ItemListener listener = new CheckBoxListener(); setResizable(false); setLayout(new FlowLayout()); setLocationRelativeTo(null); setDefaultCloseOperation(HIDE_ON_CLOSE); JCheckBox itemDebug = new JCheckBox("Item IDs"); JCheckBox npcDebug = new JCheckBox("NPC IDs"); JCheckBox objectDebug = new JCheckBox("Object IDs"); JCheckBox debugMode = new JCheckBox("Debug Output"); itemDebug.addItemListener(listener); npcDebug.addItemListener(listener); objectDebug.addItemListener(listener); debugMode.addItemListener(listener); add(itemDebug); add(npcDebug); add(objectDebug); add(debugMode); pack(); setVisible(false); } class CheckBoxListener implements ItemListener { @Override public void itemStateChanged(ItemEvent itemEvent) { String title = ((JCheckBox) itemEvent.getItem()).getText(); switch (title) { case "Item IDs": GameConfig.ITEM_DEBUG_ENABLED = itemEvent.getStateChange() == ItemEvent.SELECTED; break; case "NPC IDs": GameConfig.NPC_DEBUG_ENABLED = itemEvent.getStateChange() == ItemEvent.SELECTED; break; case "Object IDs": GameConfig.OBJECT_DEBUG_ENABLED = itemEvent.getStateChange() == ItemEvent.SELECTED; break; case "Debug Output": sendCommand("::debug"); break; } } } } }