From a2ed881f409b2b172cebc467e3686842ba080af1 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Thu, 9 Mar 2017 16:08:47 +0100 Subject: [PATCH] Initial; Added: Gui, Save/Load- Option, Doubleplace option & wait slider --- .gitignore | 4 + src/mrbesen/cr/auto/clicker/Clicker.java | 215 +++++++++++++++++ src/mrbesen/cr/auto/clicker/Main.java | 20 ++ src/mrbesen/cr/auto/clicker/Point.java | 20 ++ src/mrbesen/cr/auto/clicker/PosSelector.java | 44 ++++ src/mrbesen/cr/auto/clicker/UI.java | 237 +++++++++++++++++++ 6 files changed, 540 insertions(+) create mode 100644 .gitignore create mode 100644 src/mrbesen/cr/auto/clicker/Clicker.java create mode 100644 src/mrbesen/cr/auto/clicker/Main.java create mode 100644 src/mrbesen/cr/auto/clicker/Point.java create mode 100644 src/mrbesen/cr/auto/clicker/PosSelector.java create mode 100644 src/mrbesen/cr/auto/clicker/UI.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4ec33a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/bin/ +export.jardesc +.project +.classpath \ No newline at end of file diff --git a/src/mrbesen/cr/auto/clicker/Clicker.java b/src/mrbesen/cr/auto/clicker/Clicker.java new file mode 100644 index 0000000..9520464 --- /dev/null +++ b/src/mrbesen/cr/auto/clicker/Clicker.java @@ -0,0 +1,215 @@ +package mrbesen.cr.auto.clicker; + +import java.awt.AWTException; +import java.awt.MouseInfo; +import java.awt.Robot; +import java.awt.event.InputEvent; + +public class Clicker implements Runnable{ + + private boolean running = false; + private boolean should_run = false; + private boolean inbattle = false; + private boolean skipbattle = false; + private Thread thread; + + private Point battle; + private Point end; + + private Point[] cardslots = new Point[4]; + private Point playout; + private boolean autoplay; + private boolean doubleplayout =false; + private int truppenwait = 2; + + public Clicker() { + } + + private void sleep( int ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) {//when skip is applyed + ; + } + } + + public void start() { + should_run = true; + if(!running) { + running = true; + thread = new Thread(this, "BOT"); + thread.start(); + } + } + + public void stop() { + should_run = false; + while(running) { + thread.interrupt();//stop that shit (its maybe sleeping) + } + } + + public void skip() { + if(isRunning()) + if(inbattle) + skipbattle = true; + + thread.interrupt(); + } + + public boolean isRunning() { + return running; + } + + @Override + public void run() { + sleep(1000);//chill ma + int card = 0; + try { + Robot rob = new Robot(); + while(should_run) { + clickL(rob, battle);//start knopf + sleep(1000); + if(!should_run) + break; + clickL(rob, battle);//start knopf bestätigen + //battle running + sleep(9000);//wait for the battle to start (loading screen) + Main.get().ui.info("Battle started."); + inbattle = true; + int modifier = 1; + long start = System.currentTimeMillis(); + long lastwait = start;//das delay der runde mit ein rechnen + while( ((System.currentTimeMillis() - start) / 6000) < 41 & should_run & !skipbattle) { + if(((System.currentTimeMillis() - start) / 60000f) > 2) //speed up! (nach her durch 2 teilen) + modifier = 2; + //try to play a round + if(autoplay) { + playout(card, rob); + card = (card +1) % 4;//next + if(doubleplayout) { + sleep(750); + playout(card, rob); + card = (card +1) % 4;//next + } + } + // eingestellter wert (0.1 sec) ggf. durch 2 teilen vergangene zeit abziehen (zeit fürs setztem der letzten truppen) + sleep((int) (((truppenwait * 100) / modifier) - (System.currentTimeMillis()- lastwait)));//chillen + lastwait = System.currentTimeMillis(); + } + skipbattle = false; + inbattle = false; + Main.get().ui.info("Battle ended."); + + if(!should_run) + break; + clickL(rob, end);//ok knopf + if(!should_run) + break; + sleep(10000);//10 sec-lade screen + } + } catch (AWTException e) { + e.printStackTrace(); + } + running = false; + } + + private void playout(int card, Robot rob) { + if(cardslots[card] != null) {//card is selectable + clickL(rob, cardslots[card]);//click on the card slot + sleep(450); + if(playout != null)//a specified playout spot + clickL(rob, playout);//click on the playout location + else + clickL(rob, battle);//non specified playout spot + } + } + + public void set(Point a, int num) { + if(num < 4) + cardslots[num] = a; + else if(num == 5) { + end = a; + Main.get().ui.refresh(); + } else if(num == 4) { + battle = a; + Main.get().ui.refresh(); + } else if(num == 6) + playout = a; + } + + public boolean isSet(int num) { + if(num < 0 ) throw new IllegalArgumentException("num >= 0 !"); + + return get(num) != null; + } + + private Point get(int num) { + if(num < 4) + return cardslots[num]; + else if(num == 5) + return end ; + else if(num == 4) + return battle; + else if(num == 6) + return playout; + + return null; + } + + public void setWait(int i) { + truppenwait = i; + } + + public void setDoublePlay(boolean a) { + doubleplayout = a; + } + + public void setAutoPlay(boolean a) { + autoplay = a; + } + + public boolean bothset() { + return (end != null & battle != null); + } + + private void clickL(Robot b, Point a) { + Point old = getMouse(); + b.mouseMove(a.x, a.y); + sleep(50); + clickL(b); + sleep(50); + b.mouseMove(old.x, old.y); + sleep(50); + } + + private void clickL(Robot b) {//40 ms delay + b.mousePress(InputEvent.BUTTON1_MASK); + sleep(40); + b.mouseRelease(InputEvent.BUTTON1_MASK); + sleep(10); + } + + private int getMousex() { + return MouseInfo.getPointerInfo().getLocation().x; + } + private int getMousey() { + return MouseInfo.getPointerInfo().getLocation().y; + } + + public Point getMouse() { + return new Point(getMousex(), getMousey()); + } + + public String serialize() { + String out = ""; + for(int i = 0; i < 7; i++) { + Point p = get(i); + String ps = "null"; + if(p != null) + ps = p.serialize(); + out += i + " " + ps + "\n"; + } + return out.substring(0, out.length()-1); + } +} \ No newline at end of file diff --git a/src/mrbesen/cr/auto/clicker/Main.java b/src/mrbesen/cr/auto/clicker/Main.java new file mode 100644 index 0000000..4d1c951 --- /dev/null +++ b/src/mrbesen/cr/auto/clicker/Main.java @@ -0,0 +1,20 @@ +package mrbesen.cr.auto.clicker; + +public class Main { + + private static Main main; + public UI ui; + + public static void main(String[] args) { + new Main(); + } + + public Main() { + main = this; + new UI(); + } + + public static Main get() { + return main; + } +} diff --git a/src/mrbesen/cr/auto/clicker/Point.java b/src/mrbesen/cr/auto/clicker/Point.java new file mode 100644 index 0000000..3750e3c --- /dev/null +++ b/src/mrbesen/cr/auto/clicker/Point.java @@ -0,0 +1,20 @@ +package mrbesen.cr.auto.clicker; + +public class Point { + + int x = 0, y = 0; + + public String serialize() { + return (x +"x"+y); + } + + public Point(String deserialize) { + String[] split = deserialize.split("x",2); + x = Integer.parseInt(split[0]); + y = Integer.parseInt(split[1]); + } + + public Point(int x, int y) { + this.x = x; this.y = y; + } +} \ No newline at end of file diff --git a/src/mrbesen/cr/auto/clicker/PosSelector.java b/src/mrbesen/cr/auto/clicker/PosSelector.java new file mode 100644 index 0000000..8455c63 --- /dev/null +++ b/src/mrbesen/cr/auto/clicker/PosSelector.java @@ -0,0 +1,44 @@ +package mrbesen.cr.auto.clicker; + +import java.awt.Color; + +import javax.swing.JButton; + +public class PosSelector implements Runnable { + + JButton button; + int num; + UI ui; + private boolean required; + + public PosSelector(UI ui, String text, boolean required, int num) { + this.ui = ui; this.required = required;this.num = num; + button = new JButton(text); + button.addActionListener(ui); + red(); + } + + @Override + public void run() { + try { + for(int i = 5; i > 0; i--) {//countdown + ui.info(i + ""); + Thread.sleep(1000); + } + } catch(InterruptedException e) {;} + ui.bot.set(ui.bot.getMouse(), num);//get and save the position + ui.info("Position saved!"); + green(); + } + + public void green() { + button.setBackground(Color.GREEN); + } + + public void red() { + if(required) + button.setBackground(Color.RED); + else + button.setBackground(Color.ORANGE); + } +} \ No newline at end of file diff --git a/src/mrbesen/cr/auto/clicker/UI.java b/src/mrbesen/cr/auto/clicker/UI.java new file mode 100644 index 0000000..60b53bb --- /dev/null +++ b/src/mrbesen/cr/auto/clicker/UI.java @@ -0,0 +1,237 @@ +package mrbesen.cr.auto.clicker; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public class UI implements ActionListener, ChangeListener{ + + JFrame frame = new JFrame("Clash Royale Bot · by MrBesen");; + + JPanel root = new JPanel(); + JPanel top = new JPanel(); + JPanel bottom = new JPanel(); + JPanel slider = new JPanel(); + + JMenuBar menubar = new JMenuBar(); + JMenu file_ = new JMenu("File"); + JMenuItem load = new JMenuItem(); + JMenuItem save = new JMenuItem(); + + JCheckBox autoplay = new JCheckBox("AutoPlay"); + JCheckBox doubleplace = new JCheckBox("DoublePlace"); + + PosSelector[] posselctors = { + new PosSelector(this, "Battle",true, 4), + new PosSelector(this, "End Battle",true, 5), + new PosSelector(this, "Card1",false, 0), + new PosSelector(this, "Card2",false, 1), + new PosSelector(this, "Card3",false, 2), + new PosSelector(this, "Card4", false, 3), + new PosSelector(this, "Playout", false, 6) + }; + + JButton skip = new JButton("SKIP"); // the button, to skip waiting + JButton start = new JButton("START"); + JButton exit = new JButton("EXIT"); + + JLabel info = new JLabel("Define positions, to start."); + + JSlider truppenwait = new JSlider(JSlider.HORIZONTAL, 1, 200, 180); + JLabel wait = new JLabel("18.0"); + + Clicker bot = new Clicker(); + + File file = new File(".profile"); + + public UI() { + Main.get().ui = this; + //init screen + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + frame.setSize(620, 140); + + save.setText("Save"); + save.addActionListener(this); + load.setText("Load"); + load.addActionListener(this); + + file_.add(save); + file_.add(load); + menubar.add(file_); + frame.setJMenuBar(menubar); + + skip.setEnabled(false); + start.setEnabled(false); + + doubleplace.setSelected(true); + + skip.addActionListener(this); + start.addActionListener(this); + exit.addActionListener(this); + autoplay.addActionListener(this); + doubleplace.addActionListener(this); + truppenwait.addChangeListener(this); + + for(PosSelector poss : posselctors) { + top.add(poss.button); + } + + bottom.add(start); + bottom.add(skip); + bottom.add(exit); + bottom.add(autoplay); + bottom.add(doubleplace); + bottom.add(info); + + slider.add(truppenwait); + slider.add(wait); + + root.add(top); + root.add(bottom); + root.add(slider); + + frame.add(root); + + frame.setVisible(true); + } + + @Override + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if(src instanceof JButton) { + JButton srcb = (JButton) src; + + //check for the Posselectors + for(PosSelector poss : posselctors) { + if(poss.button.equals(srcb)) { + new Thread(poss, "PositionSelector").start(); + break; + } + } + + if(srcb.equals(start)) { + if(bot.isRunning()) {//stop! + bot.stop(); + srcb.setText("START"); + skip.setEnabled(false); + info("Stoped!"); + } else { + bot.start();//start! + srcb.setText("STOP"); + skip.setEnabled(true); + info("Started!"); + } + } else if(srcb.equals(skip)) + bot.skip(); + else if(srcb.equals(exit)) { + bot.stop(); + frame.setVisible(false); + System.exit(0); + } + } else if(src instanceof JMenuItem) { + JMenuItem srcI = (JMenuItem) src; + if(srcI.equals(load)) { + load(true); + } else if(srcI.equals(save)) { + save(); + } + } else if(src instanceof JCheckBox) { + JCheckBox srcb = (JCheckBox) src; + if(srcb.equals(autoplay)) + bot.setAutoPlay(srcb.isSelected()); + else if(srcb.equals(doubleplace)) { + bot.setDoublePlay(srcb.isSelected()); + if(srcb.isSelected()) {//*2 + truppenwait.setValue(truppenwait.getValue()*2); + } else {// /2 + truppenwait.setValue(truppenwait.getValue()/2); + } + } + } + } + + @Override + public void stateChanged(ChangeEvent e) { + Object o = e.getSource(); + if(o instanceof JSlider) { + JSlider slider = (JSlider) o; + if(slider.equals(truppenwait)) { + bot.setWait(slider.getValue()); + wait.setText(""+(slider.getValue()/10f)); + } + } + } + + private void load(boolean info) { + if(file.exists()) { + try { + Scanner s = new Scanner(file); + while(s.hasNextLine()) { + String split[] = s.nextLine().split(" ",2); + if(!split[1].equals("null")) + bot.set(new Point(split[1]), Integer.parseInt(split[0])); + } + s.close(); + refresh(); + if(info) + info("loaded!"); + } catch(IOException | NumberFormatException e) { + e.printStackTrace(); + if(info) + info("Error."); + } + } else + if(info) + info("no profile found."); + } + + private void save() { + try { + if(!file.exists()) + file.createNewFile(); + + FileWriter fw = new FileWriter(file); + fw.write(bot.serialize()); + fw.flush(); + fw.close(); + + info("saved!"); + } catch(IOException e) { + e.printStackTrace(); + info("Error."); + } + } + + public void refresh() { + if(bot.bothset()) + start.setEnabled(true); + + for(PosSelector poss : posselctors) { + if(bot.isSet(poss.num)) + poss.green(); + else + poss.red(); + } + } + + public void info(String a) { + info.setText(a); + } + + +} \ No newline at end of file