Zatrzymywanie/zabijanie wątków w Java.

0

Witam. Dzisiaj wyrzeźbiłem taki oto kod:

Klasa bot.java

package me.przemovi;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.Proxy;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import com.github.steveice10.mc.protocol.MinecraftProtocol;
import com.github.steveice10.mc.protocol.data.SubProtocol;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
import com.github.steveice10.mc.protocol.data.status.handler.ServerInfoHandler;
import com.github.steveice10.mc.protocol.data.status.handler.ServerPingTimeHandler;
import com.github.steveice10.packetlib.Client;
import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.tcp.TcpSessionFactory;

public class bot{
	private static final Proxy PROXY = Proxy.NO_PROXY;
	private static final Proxy AUTH_PROXY = Proxy.NO_PROXY;
	private JFrame frame;
	private JTextField txtHostport;
	private JTextField txtThreads;
	private JTextField txtStay;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					bot window = new bot();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	private void status(String HOST, int PORT) {
	    MinecraftProtocol protocol = new MinecraftProtocol(SubProtocol.STATUS);
	    Client client = new Client(HOST, PORT, protocol, new TcpSessionFactory(PROXY));
	    client.getSession().setFlag("auth-proxy", AUTH_PROXY);
	    client.getSession().setFlag("server-info-handler", new ServerInfoHandler() {
	      public void handle(Session session, ServerStatusInfo info) {
	        System.out.println("Version: " + info.getVersionInfo().getVersionName() + ", " + info.getVersionInfo().getProtocolVersion());
	        System.out.println("Player Count: " + info.getPlayerInfo().getOnlinePlayers() + " / " + info.getPlayerInfo().getMaxPlayers());
	        System.out.println("Players: " + Arrays.toString(info.getPlayerInfo().getPlayers()));
	        System.out.println("Description: " + info.getDescription().getFullText());
	        System.out.println("Icon: " + info.getIcon());
	      }
	    });
	    client.getSession().setFlag("server-ping-time-handler", new ServerPingTimeHandler() {
	      public void handle(Session session, long pingTime) {
	        System.out.println("Server ping took " + pingTime + "ms");
	      }
	    });
	    client.getSession().connect();
	    while (client.getSession().isConnected()) {
	      try {
	        Thread.sleep(5L);
	      } catch (InterruptedException e) {
	        e.printStackTrace();
	      }
	    }
	  }
	/**
	 * Create the application.
	 */
	public bot() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings({ "unused" })
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 450, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);
		
		txtHostport = new JTextField();
		txtHostport.setBounds(112, 11, 86, 20);
		frame.getContentPane().add(txtHostport);
		txtHostport.setColumns(10);
		
		JLabel lblIpSerwera = new JLabel("server ip:");
		lblIpSerwera.setBounds(10, 14, 89, 14);
		frame.getContentPane().add(lblIpSerwera);
		
		JLabel lblIloWtkw = new JLabel("threads:");
		lblIloWtkw.setBounds(10, 39, 89, 14);
		frame.getContentPane().add(lblIloWtkw);
		
		txtThreads = new JTextField();
		txtThreads.setBounds(112, 36, 86, 20);
		frame.getContentPane().add(txtThreads);
		txtThreads.setColumns(10);
		
		JCheckBox chckbxOneTime = new JCheckBox("One time");
		chckbxOneTime.setBounds(204, 10, 108, 23);
		frame.getContentPane().add(chckbxOneTime);
		
		JCheckBox chckbxLoop = new JCheckBox("Loop");
		chckbxLoop.setBounds(314, 10, 110, 23);
		frame.getContentPane().add(chckbxLoop);
		
		JLabel lblWyjdzPo = new JLabel("stay:");
		lblWyjdzPo.setBounds(10, 64, 89, 14);
		frame.getContentPane().add(lblWyjdzPo);
		
		txtStay = new JTextField();
		txtStay.setBounds(112, 61, 86, 20);
		frame.getContentPane().add(txtStay);
		txtStay.setColumns(10);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(208, 36, 97, 215);
		frame.getContentPane().add(scrollPane);
		
		JTextArea txtrOneTime = new JTextArea();
		txtrOneTime.setText("/register 123456\r\n/login 123456\r\nhello!");
		scrollPane.setViewportView(txtrOneTime);
		
		JScrollPane scrollPane_1 = new JScrollPane();
		scrollPane_1.setBounds(318, 36, 97, 215);
		frame.getContentPane().add(scrollPane_1);
		
		JTextArea txtrLoop = new JTextArea();
		txtrLoop.setText("server hacked!\r\nby me!");
		scrollPane_1.setViewportView(txtrLoop);
		
		JScrollPane scrollPane_2 = new JScrollPane();
		scrollPane_2.setBounds(10, 98, 188, 119);
		frame.getContentPane().add(scrollPane_2);
		
		JLabel lblOutput = new JLabel(" Output:");
		lblOutput.setHorizontalAlignment(SwingConstants.LEFT);
		lblOutput.setVerticalAlignment(SwingConstants.TOP);
		scrollPane_2.setViewportView(lblOutput);
		
		Runnable[] runners = null;
	    Thread[] threads = null;
	    
		JButton btnStop = new JButton("Stop");
		JButton btnStart = new JButton("Start");
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int Threads =  Integer.valueOf(txtThreads.getText());
				btnStart.setEnabled(false);
				btnStop.setEnabled(true);
				String[] IpPort = new String[2];
			    String[] Ip = txtHostport.getText().split(":");
			    if (!indexExists(Ip, 1)) {
			      IpPort[1] = "25565";
			    } else {
			      IpPort[1] = Ip[1];
			    }
			    IpPort[0] = Ip[0];
			    status(IpPort[0], Integer.valueOf(IpPort[1]).intValue());
			    List<String> lines = null;
			    try {
			      lines = Files.readAllLines(Paths.get("Nicks.txt", new String[0]), StandardCharsets.UTF_8);
			    } catch (IOException ex) {
			      ex.printStackTrace();
			    }
			    String[] line = (String[])lines.toArray(new String[0]);
			    
			    String OneTime[] = null;
			    if(chckbxOneTime.isSelected()) {
			    	OneTime = txtrOneTime.getText().split("\\r?\\n");
			    }
			    String Loop[] = null;
			    if(chckbxLoop.isSelected()) {
			    	Loop = txtrLoop.getText().split("\\r?\\n");
			    }
			    
			    Runnable[] runners = new Runnable[Threads];
			    Thread[] threads = new Thread[Threads];
			    for (int i = 0; i < Threads; i++) {

				runners[i] = new login(i, IpPort[0], Integer.valueOf(IpPort[1]).intValue(), PROXY, AUTH_PROXY, line, OneTime, Loop);
			    }
			    for (int i = 0; i < Threads; i++) {
			      threads[i] = new Thread(runners[i]);
			    }
			    for (int i = 0; i < Threads; i++) {
			      threads[i].start();
			    }
			}
		});
		btnStart.setBounds(10, 228, 89, 23);
		frame.getContentPane().add(btnStart);
		btnStart.setEnabled(true);
		
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int Threads =  Integer.valueOf(txtThreads.getText());
				for (int i = 0; i < Threads; i++) {
					threads[i].interrupt();
				}
				btnStart.setEnabled(true);
			}
		});
		btnStop.setBounds(109, 228, 89, 23);
		frame.getContentPane().add(btnStop);
		btnStop.setEnabled(false);
	}
	public static boolean indexExists(String[] array, int index) {
	    return (array != null) && (index >= 0) && (index < array.length);
	}
}

Klasa login.java

package me.przemovi;

import java.io.IOException;
import java.net.Proxy;
import java.util.Arrays;
import com.github.steveice10.mc.protocol.MinecraftConstants;
import com.github.steveice10.mc.protocol.MinecraftProtocol;
import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.TranslationMessage;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import com.github.steveice10.packetlib.Client;
import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
import com.github.steveice10.packetlib.event.session.PacketReceivedEvent;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.tcp.TcpSessionFactory;

public class login implements Runnable{
	
    private static String HOST = "127.0.0.1";
    private static int PORT = 25565;
    private static Proxy PROXY = Proxy.NO_PROXY;
    private static Proxy AUTH_PROXY = Proxy.NO_PROXY;
    private static String[] line = null;
    private int id;
    private static String[] OneTime = null;
    private static String[] Loop = null;
    
    public login(int id, String HST, int PRT, Proxy PRX, Proxy Auth_PRX, String[] l, String[] O, String[] L) {
    	HOST=HST;
		PORT=PRT;
		PROXY=PRX;
		AUTH_PROXY=Auth_PRX;
        this.id = id;
        line = l;
        OneTime = O;
        Loop = L;
    }

	@Override
	public void run() {
		System.out.print(Integer.valueOf(id));
		System.out.print(" ");
		System.out.println(line[id]);
		MinecraftProtocol protocol = null;
        protocol = new MinecraftProtocol(line[id]);
        Client client = new Client(HOST, PORT, protocol, new TcpSessionFactory(PROXY));
        client.getSession().setFlag(MinecraftConstants.AUTH_PROXY_KEY, AUTH_PROXY);
        client.getSession().addListener(new SessionAdapter() {
            @Override
            public void packetReceived(PacketReceivedEvent event) {
                if(event.getPacket() instanceof ServerJoinGamePacket) {
                	int i = 0;
                	while(indexExists(OneTime, i)) {
                		event.getSession().send(new ClientChatPacket(OneTime[i]));
                		i++;
                	}
                	while(!(Thread.currentThread().isInterrupted())) { //true - run
                		int h = 0;
                		while(indexExists(OneTime, h)) {
                			event.getSession().send(new ClientChatPacket(Loop[h]));
                			h++;
                		}
                	}
                }
            }

            @Override
            public void disconnected(DisconnectedEvent event) {
                System.out.println("Disconnected: " + Message.fromString(event.getReason()).getFullText());
                if(event.getCause() != null) {
                    event.getCause().printStackTrace();
                }
            }
        });

        client.getSession().connect();
	}
    public static boolean indexExists(String[] array, int index) {
    	return (array != null) && (index >= 0) && (index < array.length);
    }
}

Klasa bot tworzy zadaną ilość nowych wątków i je uruchamia. Program wykonuje swoją funkcję w nieskończoność. Ale jest jeden problem. Mam w oknie taki przycisk "Stop". Chciałby, aby zatrzymał on wszystkie wątki w taki sposób, aby przyciskiem start można je było je znowu uruchomić. Oczywiście całkiem od nowa je "stworzyć" i podłożyć im inne dane do działania. W klasie login (wątki) mam taką lnijkę, prawie na końcu: client.getSession().connect();. Ona się wykonuje i wątek sobie w tym czasie "śpi". No chyba, że błędnie to rozumiem? Może po niej kiedyś zagości pętla, która będzie się wykonywała x razy, a po tym wątek powinien się też wyłączyć. Szukałem bardzo dużo w internecie, ale nic mi nie chce działać. Nie wiem, czy nie ma jakiegoś lepszego pomysłu na zrealizowanie tego kodu. W wątkach jestem naprawdę zielony.

Liczę na pomoc
Pozdrawiam

1

Poczytaj o ExecutorSerive :)

0

Zrób jakiś ThreadPoolExecutor albo przynajmniej CompletableFuture!

1 użytkowników online, w tym zalogowanych: 0, gości: 1