From bbc48c8f3ffe696e06a0d54a86d13f0ceb76563c Mon Sep 17 00:00:00 2001 From: shishcat Date: Wed, 28 May 2025 09:42:37 +0200 Subject: [PATCH] Initial commit --- Ping.java | 36 +++++++ Pingtool.java | 251 +++++++++++++++++++++++++++++++++++++++++++++++ PortConnect.java | 58 +++++++++++ ScanMaker.java | 48 +++++++++ 4 files changed, 393 insertions(+) create mode 100644 Ping.java create mode 100644 Pingtool.java create mode 100644 PortConnect.java create mode 100644 ScanMaker.java diff --git a/Ping.java b/Ping.java new file mode 100644 index 0000000..de70a82 --- /dev/null +++ b/Ping.java @@ -0,0 +1,36 @@ +import java.io.IOException; + +public class Ping implements ScanType { + private String accessString; + + public Ping(String accessString) { + this.accessString = accessString; + } + + public static String getName() { + return "Ping"; + } + + static boolean validateAccessString(String accessString) { + // Validate the access string format (e.g., "example.com") + if (accessString == null || accessString.isEmpty()) { + return false; + } + String regex = "^[a-zA-Z0-9.-]+$"; + return accessString.matches(regex); + } + + public boolean execute() throws IOException, InterruptedException { + boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win"); + + ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows? "-n" : "-c", "1", accessString); + Process proc = processBuilder.start(); + + int returnVal = proc.waitFor(); + return returnVal == 0; + } + + public String getAccessString() { + return accessString; + } +} diff --git a/Pingtool.java b/Pingtool.java new file mode 100644 index 0000000..57daf5d --- /dev/null +++ b/Pingtool.java @@ -0,0 +1,251 @@ +// Your imports here +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.io.IOException; +import java.util.*; +import java.util.List; +import java.util.Timer; + +public class Pingtool { + private JFrame frame; + private JPanel mainPanel; + private JPanel scanPanel; + private JButton addButton; + private JButton removeButton; + + private List scanTypes = new ArrayList<>(); + private Map scanComponents = new HashMap<>(); + private Map scanStatusPanels = new HashMap<>(); + private Map scanLabels = new HashMap<>(); + private Map customNames = new HashMap<>(); + + private Timer timer; + + public Pingtool() { + initializeUI(); + startMonitoring(); + } + + private void initializeUI() { + frame = new JFrame("Ping Tool"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(600, 400); + + mainPanel = new JPanel(new BorderLayout()); + + scanPanel = new JPanel(); + scanPanel.setLayout(new BoxLayout(scanPanel, BoxLayout.Y_AXIS)); + JScrollPane scrollPane = new JScrollPane(scanPanel); + mainPanel.add(scrollPane, BorderLayout.CENTER); + + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + addButton = new JButton("Add Scan"); + removeButton = new JButton("Remove Scan"); + buttonPanel.add(addButton); + buttonPanel.add(removeButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + + addButton.addActionListener(e -> showAddOrEditScanDialog(null)); + removeButton.addActionListener(e -> showRemoveScanDialog()); + + frame.setContentPane(mainPanel); + frame.setVisible(true); + } + + private void showAddOrEditScanDialog(ScanType scanToEdit) { + boolean isEdit = scanToEdit != null; + JDialog dialog = new JDialog(frame, isEdit ? "Edit Scan" : "Add New Scan", true); + dialog.setLayout(new BorderLayout()); + + JPanel inputPanel = new JPanel(new GridLayout(4, 2)); + JComboBox typeComboBox = new JComboBox<>(new String[]{ + "HTTP GET", "HTTP HEAD", "Ping", "Port Connect" + }); + JTextField accessStringField = new JTextField(); + JTextField customNameField = new JTextField(); + + if (isEdit) { + typeComboBox.setSelectedItem(ScanMaker.getDisplayLabel(scanToEdit.getClass().getSimpleName())); + accessStringField.setText(scanToEdit.getAccessString()); + customNameField.setText(customNames.getOrDefault(scanToEdit, "").trim()); + } + + inputPanel.add(new JLabel("Scan Type:")); + inputPanel.add(typeComboBox); + inputPanel.add(new JLabel("Access String:")); + inputPanel.add(accessStringField); + inputPanel.add(new JLabel("Custom Name (Optional):")); + inputPanel.add(customNameField); + + JButton okButton = new JButton("OK"); + okButton.addActionListener(e -> { + String label = (String) typeComboBox.getSelectedItem(); + String accessString = accessStringField.getText().trim(); + final String[] customName = {customNameField.getText().trim()}; + + ScanMaker.validateAndCreate(label, accessString).ifPresentOrElse(newScan -> { + if (customName[0].isEmpty()) { + customName[0] = newScan.getClass().getSimpleName() + ": " + accessString; + } + if (isEdit) removeScanType(scanToEdit); + addScanType(newScan, customName[0]); + dialog.dispose(); + }, () -> JOptionPane.showMessageDialog(dialog, + "Invalid access string for selected scan type.", + "Validation Error", JOptionPane.ERROR_MESSAGE)); + }); + + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(e -> dialog.dispose()); + + JPanel buttonPanel = new JPanel(); + buttonPanel.add(okButton); + buttonPanel.add(cancelButton); + + dialog.add(inputPanel, BorderLayout.CENTER); + dialog.add(buttonPanel, BorderLayout.SOUTH); + dialog.pack(); + dialog.setLocationRelativeTo(frame); + dialog.setVisible(true); + } + + private void showRemoveScanDialog() { + if (scanTypes.isEmpty()) { + JOptionPane.showMessageDialog(frame, "No scans to remove.", + "Information", JOptionPane.INFORMATION_MESSAGE); + return; + } + + String[] descriptions = scanTypes.stream() + .map(scan -> customNames.getOrDefault(scan, + scan.getClass().getSimpleName() + ": " + scan.getAccessString())) + .toArray(String[]::new); + + String selected = (String) JOptionPane.showInputDialog(frame, + "Select scan to remove:", "Remove Scan", JOptionPane.QUESTION_MESSAGE, + null, descriptions, descriptions[0]); + + if (selected != null) { + scanTypes.stream().filter(scan -> selected.equals(customNames.getOrDefault(scan, + scan.getClass().getSimpleName() + ": " + scan.getAccessString()))) + .findFirst() + .ifPresent(this::removeScanType); + } + } + + private void addScanType(ScanType scanType, String displayName) { + scanTypes.add(scanType); + customNames.put(scanType, displayName); + + JPanel scanComponent = new JPanel(new BorderLayout()); + scanComponent.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1), + BorderFactory.createEmptyBorder(2, 4, 2, 4))); + scanComponent.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30)); + + JLabel nameLabel = new JLabel(displayName); + nameLabel.setFont(new Font("SansSerif", Font.PLAIN, 12)); + nameLabel.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); + + JPanel statusPanel = new JPanel(); + statusPanel.setPreferredSize(new Dimension(14, 14)); + statusPanel.setBackground(Color.GRAY); + statusPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK)); + + scanComponent.add(nameLabel, BorderLayout.CENTER); + scanComponent.add(statusPanel, BorderLayout.EAST); + + scanComponent.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + showAddOrEditScanDialog(scanType); + } + }); + + scanComponents.put(scanType, scanComponent); + scanStatusPanels.put(scanType, statusPanel); + scanLabels.put(scanType, nameLabel); + + scanPanel.add(scanComponent); + scanPanel.revalidate(); + scanPanel.repaint(); + saveScansToStorage(); + } + + private void removeScanType(ScanType scanType) { + JPanel component = scanComponents.get(scanType); + if (component != null) { + scanPanel.remove(component); + scanComponents.remove(scanType); + scanStatusPanels.remove(scanType); + scanLabels.remove(scanType); + customNames.remove(scanType); + scanTypes.remove(scanType); + scanPanel.revalidate(); + scanPanel.repaint(); + } + saveScansToStorage(); + } + + private void startMonitoring() { + try { + List stored = Storage.loadScans(); + for (Storage.StoredScan s : stored) { + ScanMaker.createScan(s.type, s.accessString).ifPresent(scan -> { + String name = s.customName.isEmpty() + ? scan.getClass().getSimpleName() + ": " + s.accessString + : s.customName; + addScanType(scan, name); + }); + } + } catch (Exception e) { + e.printStackTrace(); + } + timer = new Timer(); + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + updateScanStatuses(); + } + }, 0, 1000); + } + + private void updateScanStatuses() { + List currentScans; + synchronized (scanTypes) { + currentScans = new ArrayList<>(scanTypes); + } + + for (ScanType scanType : currentScans) { + JPanel statusPanel = scanStatusPanels.get(scanType); + if (statusPanel != null) { + try { + boolean result = scanType.execute(); + SwingUtilities.invokeLater(() -> statusPanel.setBackground(result ? Color.GREEN : Color.RED)); + } catch (Exception e) { + SwingUtilities.invokeLater(() -> statusPanel.setBackground(Color.RED)); + } + } + } + } + + private void saveScansToStorage() { + List stored = new ArrayList<>(); + for (ScanType scan : scanTypes) { + String type = ScanMaker.getTypeName(scan); + String accessString = scan.getAccessString(); + String customName = customNames.getOrDefault(scan, ""); + stored.add(new Storage.StoredScan(type, accessString, customName)); + } + try { + Storage.saveScans(stored); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(Pingtool::new); + } +} diff --git a/PortConnect.java b/PortConnect.java new file mode 100644 index 0000000..f7fe4c3 --- /dev/null +++ b/PortConnect.java @@ -0,0 +1,58 @@ +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +public class PortConnect implements ScanType { + private String accessString; // Like "example.com:80" + + public PortConnect(String accessString) { + this.accessString = accessString; + } + + public static String getName() { + return "TCP Port"; + } + + static boolean validateAccessString(String accessString) { + // Validate the access string format (e.g., "host:port") + String[] parts = accessString.split(":"); + if (parts.length != 2) { + return false; + } + String portStr = parts[1]; + try { + int port = Integer.parseInt(portStr); + if(port > 0 && port <= 65535) return true; + } catch (NumberFormatException e) { + return false; + } + String host = parts[0]; + //Check if host is a valid IP address or hostname + if (host.isEmpty()) { + return false; + } + String regex = "^(?!-)[A-Za-z0-9-]{1,63}(? createScan(String type, String accessString) { + return switch (type) { + case "HTTPGet" -> Optional.of(new HTTPGet(accessString)); + case "HTTPHead" -> Optional.of(new HTTPHead(accessString)); + case "Ping" -> Optional.of(new Ping(accessString)); + case "PortConnect" -> Optional.of(new PortConnect(accessString)); + default -> Optional.empty(); + }; + } + + public static Optional validateAndCreate(String label, String accessString) { + return switch (label) { + case "HTTP GET" -> HTTPGet.validateAccessString(accessString) ? Optional.of(new HTTPGet(accessString)) : Optional.empty(); + case "HTTP HEAD" -> HTTPHead.validateAccessString(accessString) ? Optional.of(new HTTPHead(accessString)) : Optional.empty(); + case "Ping" -> Ping.validateAccessString(accessString) ? Optional.of(new Ping(accessString)) : Optional.empty(); + case "Port Connect" -> PortConnect.validateAccessString(accessString) ? Optional.of(new PortConnect(accessString)) : Optional.empty(); + default -> Optional.empty(); + }; + } + + public static String getTypeName(ScanType scan) { + return scan.getClass().getSimpleName(); + } + + public static String getDisplayLabel(String typeName) { + return switch (typeName) { + case "HTTPGet" -> "HTTP GET"; + case "HTTPHead" -> "HTTP HEAD"; + case "Ping" -> "Ping"; + case "PortConnect" -> "Port Connect"; + default -> typeName; + }; + } + + public static String getInternalTypeName(String label) { + return switch (label) { + case "HTTP GET" -> "HTTPGet"; + case "HTTP HEAD" -> "HTTPHead"; + case "Ping" -> "Ping"; + case "Port Connect" -> "PortConnect"; + default -> label; + }; + } +}