|
|
|
import java.io.BufferedInputStream;
|
|
|
|
import java.io.DataInputStream;
|
|
|
|
import java.io.DataOutputStream;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Queue;
|
|
|
|
import java.util.Timer;
|
|
|
|
import java.util.TimerTask;
|
|
|
|
import java.util.Map.Entry;
|
|
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
|
|
|
|
import java.awt.AWTException;
|
|
|
|
import java.awt.Color;
|
|
|
|
import java.awt.Rectangle;
|
|
|
|
import java.awt.Robot;
|
|
|
|
import java.awt.event.KeyEvent;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
|
|
|
|
import lc.kra.system.keyboard.GlobalKeyboardHook;
|
|
|
|
import lc.kra.system.keyboard.event.GlobalKeyAdapter;
|
|
|
|
import lc.kra.system.keyboard.event.GlobalKeyEvent;
|
|
|
|
|
|
|
|
class Client {
|
|
|
|
// initialize socket and input output streams
|
|
|
|
private Socket socket = null;
|
|
|
|
private DataInputStream input = null;
|
|
|
|
private DataOutputStream out = null;
|
|
|
|
|
|
|
|
private static boolean run = true;
|
|
|
|
boolean altHeld=false;
|
|
|
|
// constructor to put ip address and port
|
|
|
|
public Client(String address, int port)
|
|
|
|
{
|
|
|
|
GlobalKeyboardHook keyboardHook = new GlobalKeyboardHook(true); // Use false here to switch to hook instead of raw input
|
|
|
|
|
|
|
|
System.out.println("Global keyboard hook successfully started, press [escape] key to shutdown. Connected keyboards:");
|
|
|
|
for (Entry<Long, String> keyboard : GlobalKeyboardHook.listKeyboards().entrySet()) {
|
|
|
|
System.out.format("%d: %s\n", keyboard.getKey(), keyboard.getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
keyboardHook.addKeyListener(new GlobalKeyAdapter() {
|
|
|
|
@Override
|
|
|
|
public void keyPressed(GlobalKeyEvent event) {
|
|
|
|
try {
|
|
|
|
switch (event.getVirtualKeyCode()){
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD7:{
|
|
|
|
out.writeUTF("FOLLOW");
|
|
|
|
}break;
|
|
|
|
case 187:{
|
|
|
|
out.writeUTF("SPRINT");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD8:
|
|
|
|
case GlobalKeyEvent.VK_UP:{
|
|
|
|
out.writeUTF("FORWARD");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD5:
|
|
|
|
case GlobalKeyEvent.VK_DOWN:{
|
|
|
|
out.writeUTF("BACKWARD");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD4:
|
|
|
|
case GlobalKeyEvent.VK_LEFT:{
|
|
|
|
out.writeUTF("LEFT");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD6:
|
|
|
|
case GlobalKeyEvent.VK_RIGHT:{
|
|
|
|
out.writeUTF("RIGHT");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD1:
|
|
|
|
case GlobalKeyEvent.VK_1:
|
|
|
|
case GlobalKeyEvent.VK_2:{
|
|
|
|
out.writeUTF("FIGHT");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_3:{
|
|
|
|
if (altHeld){
|
|
|
|
out.writeUTF("FIGHTAOE");
|
|
|
|
} else {
|
|
|
|
out.writeUTF("FIGHT");
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_Z:
|
|
|
|
case GlobalKeyEvent.VK_X:{
|
|
|
|
out.writeUTF("FIGHTAOE");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD3:
|
|
|
|
case 110:
|
|
|
|
case GlobalKeyEvent.VK_DELETE:
|
|
|
|
case GlobalKeyEvent.VK_RETURN:{
|
|
|
|
out.writeUTF("CHILL");
|
|
|
|
}break;
|
|
|
|
case GlobalKeyEvent.VK_NUMPAD9:{
|
|
|
|
out.writeUTF("PASS");
|
|
|
|
}break;
|
|
|
|
case 18:{
|
|
|
|
altHeld=true;
|
|
|
|
}break;
|
|
|
|
default:{
|
|
|
|
//System.out.println(event.getVirtualKeyCode());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
if (event.getVirtualKeyCode() == GlobalKeyEvent.VK_ESCAPE) {
|
|
|
|
run = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void keyReleased(GlobalKeyEvent event) {
|
|
|
|
switch (event.getVirtualKeyCode()){
|
|
|
|
case 18:{
|
|
|
|
altHeld=false;
|
|
|
|
}break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// establish a connection
|
|
|
|
try {
|
|
|
|
socket = new Socket(address, port);
|
|
|
|
System.out.println("Connected");
|
|
|
|
// takes input from terminal
|
|
|
|
input = new DataInputStream(System.in);
|
|
|
|
|
|
|
|
// sends output to the socket
|
|
|
|
out = new DataOutputStream(
|
|
|
|
socket.getOutputStream());
|
|
|
|
}
|
|
|
|
catch (IOException u) {
|
|
|
|
System.out.println(u);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// string to read message from input
|
|
|
|
String line = "";
|
|
|
|
|
|
|
|
// keep reading until "Over" is input
|
|
|
|
while (!line.equals("Over")) {
|
|
|
|
try {
|
|
|
|
line = input.readLine();
|
|
|
|
out.writeUTF(line);
|
|
|
|
}
|
|
|
|
catch (IOException i) {
|
|
|
|
System.out.println(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// close the connection
|
|
|
|
try {
|
|
|
|
input.close();
|
|
|
|
out.close();
|
|
|
|
socket.close();
|
|
|
|
keyboardHook.shutdownHook();
|
|
|
|
}
|
|
|
|
catch (IOException i) {
|
|
|
|
System.out.println(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void main(String args[])
|
|
|
|
{
|
|
|
|
Client client = new Client("192.168.1.89", 5000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Target{
|
|
|
|
AYA,
|
|
|
|
MYTHRA
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Rotation{
|
|
|
|
SCHOLAR
|
|
|
|
}
|
|
|
|
|
|
|
|
class Server
|
|
|
|
{
|
|
|
|
//initialize socket and input stream
|
|
|
|
private Socket socket = null;
|
|
|
|
private ServerSocket server = null;
|
|
|
|
private DataInputStream in = null;
|
|
|
|
Robot r;
|
|
|
|
boolean fighting=false;
|
|
|
|
boolean fightingaoe=false;
|
|
|
|
|
|
|
|
private void PressKeyWithModifier(int modifier,int keycode) {
|
|
|
|
r.keyPress(modifier);
|
|
|
|
r.keyPress(keycode);
|
|
|
|
r.keyRelease(keycode);r.delay(100);
|
|
|
|
r.keyRelease(modifier);
|
|
|
|
}
|
|
|
|
private void PressKey(int keycode) {
|
|
|
|
r.keyPress(keycode);
|
|
|
|
r.keyRelease(keycode);
|
|
|
|
}
|
|
|
|
|
|
|
|
float GetMythraHealth(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(92, 171, 86, 1));
|
|
|
|
for (int i=img.getWidth()-1;i>=0;i--){
|
|
|
|
if ((img.getRGB(i,0)&255)>100){
|
|
|
|
return (float)i/(img.getWidth()-1)*100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
boolean MythraHasShield(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(92, 163, 1, 1));
|
|
|
|
Color c=new Color(img.getRGB(0,0));
|
|
|
|
return c.getRed()==255&&c.getRed()==211&&c.getBlue()==0;
|
|
|
|
}
|
|
|
|
float GetMythraMana(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(196, 171, 86, 1));
|
|
|
|
for (int i=img.getWidth()-1;i>=0;i--){
|
|
|
|
if ((img.getRGB(i,0)&255)>100){
|
|
|
|
return (float)i/(img.getWidth()-1)*100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
float GetAyaHealth(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(92, 211, 86, 1));
|
|
|
|
for (int i=img.getWidth()-1;i>=0;i--){
|
|
|
|
if ((img.getRGB(i,0)&255)>100){
|
|
|
|
return (float)i/(img.getWidth()-1)*100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
boolean AyaHasShield(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(92, 203, 1, 1));
|
|
|
|
Color c=new Color(img.getRGB(0,0));
|
|
|
|
return c.getRed()==255&&c.getRed()==211&&c.getBlue()==0;
|
|
|
|
}
|
|
|
|
float GetTargetHealth(){
|
|
|
|
BufferedImage img=r.createScreenCapture(new Rectangle(781, 134, 432, 1));
|
|
|
|
for (int i=img.getWidth()-1;i>=0;i--){
|
|
|
|
if ((img.getRGB(i,0)&255)>100){
|
|
|
|
return (float)i/(img.getWidth()-1)*100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
boolean MultipleTargets(){
|
|
|
|
return fightingaoe;
|
|
|
|
/*BufferedImage img=r.createScreenCapture(new Rectangle(75, 628, 1, 1));
|
|
|
|
Color c=new Color(img.getRGB(0,0));
|
|
|
|
return (c.getRed()==120&&c.getRed()==118&&c.getBlue()==120)||(c.getRed()==140&&c.getRed()==138&&c.getBlue()==140);*/
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
long bioTimer=0;
|
|
|
|
long lucidDreamingTimer=0;
|
|
|
|
long nextActionTimer=0;
|
|
|
|
long aetherflowTimer=0;
|
|
|
|
int aetherflowStacks=0;
|
|
|
|
long whisperingDawnTimer=0;
|
|
|
|
long feyIlluminationTimer=0;
|
|
|
|
boolean allowedToAetherflow=false;
|
|
|
|
boolean queueUpSprint=false;
|
|
|
|
|
|
|
|
long lastFrame=System.currentTimeMillis();
|
|
|
|
|
|
|
|
void Heal(Target target){
|
|
|
|
if (target==Target.AYA){
|
|
|
|
allowedToAetherflow=true;
|
|
|
|
}
|
|
|
|
if (aetherflowStacks>0){
|
|
|
|
PressKey(KeyEvent.VK_C);
|
|
|
|
aetherflowStacks--;
|
|
|
|
nextActionTimer=1000;
|
|
|
|
return;
|
|
|
|
} else
|
|
|
|
if (target==Target.AYA&&AyaHasShield()){
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_3);
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
} else
|
|
|
|
if (target==Target.MYTHRA&&MythraHasShield()){
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_3);
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
PressKey(KeyEvent.VK_5);
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Collection<String>commandQueue=Collections.synchronizedCollection(new ArrayList<>());
|
|
|
|
|
|
|
|
// constructor with port
|
|
|
|
public Server(int port)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
r = new Robot();
|
|
|
|
} catch (AWTException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
// starts server and waits for a connection
|
|
|
|
try
|
|
|
|
{
|
|
|
|
server = new ServerSocket(port);
|
|
|
|
System.out.println("Server started");
|
|
|
|
|
|
|
|
System.out.println("Waiting for a client ...");
|
|
|
|
|
|
|
|
socket = server.accept();
|
|
|
|
System.out.println("Client accepted");
|
|
|
|
|
|
|
|
// takes input from the client socket
|
|
|
|
in = new DataInputStream(
|
|
|
|
new BufferedInputStream(socket.getInputStream()));
|
|
|
|
|
|
|
|
String line = "";
|
|
|
|
|
|
|
|
Thread t = new Thread(new Runnable(){
|
|
|
|
|
|
|
|
|
|
|
|
void run(Rotation rot){
|
|
|
|
switch (rot){
|
|
|
|
case SCHOLAR:{
|
|
|
|
if (nextActionTimer==0){
|
|
|
|
if (GetMythraMana()<80&&lucidDreamingTimer==0){
|
|
|
|
lucidDreamingTimer=60000;
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_6);
|
|
|
|
nextActionTimer=1000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (allowedToAetherflow&&aetherflowTimer==0){
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_ALT, KeyEvent.VK_2);
|
|
|
|
nextActionTimer=1000;
|
|
|
|
aetherflowStacks=3;
|
|
|
|
aetherflowTimer=60000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
float ayaHealth=GetAyaHealth();
|
|
|
|
float mythraHealth=GetMythraHealth();
|
|
|
|
if (ayaHealth<40){
|
|
|
|
PressKey(KeyEvent.VK_F2);
|
|
|
|
r.delay(100);
|
|
|
|
Heal(Target.AYA);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ayaHealth<60){
|
|
|
|
if (whisperingDawnTimer==0&&feyIlluminationTimer<60000){
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_C);
|
|
|
|
whisperingDawnTimer=60000;
|
|
|
|
nextActionTimer=1000;
|
|
|
|
return;
|
|
|
|
} else
|
|
|
|
if (feyIlluminationTimer==0&&whisperingDawnTimer<30000){
|
|
|
|
PressKey(KeyEvent.VK_X);
|
|
|
|
feyIlluminationTimer=120000;
|
|
|
|
nextActionTimer=1000;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mythraHealth<40){
|
|
|
|
PressKey(KeyEvent.VK_F1);
|
|
|
|
r.delay(100);
|
|
|
|
Heal(Target.MYTHRA);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//Looks like we're attacking.
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_8);
|
|
|
|
float targetHealth=GetTargetHealth();
|
|
|
|
if (!MultipleTargets()){
|
|
|
|
if (targetHealth>50&&bioTimer==0){
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_2);
|
|
|
|
bioTimer=30000;
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_1);
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL, KeyEvent.VK_Z);
|
|
|
|
nextActionTimer=2500;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
while (true){
|
|
|
|
for (String command:commandQueue){
|
|
|
|
switch (command){
|
|
|
|
case "FOLLOW":{
|
|
|
|
PressKeyWithModifier(KeyEvent.VK_CONTROL,KeyEvent.VK_7);
|
|
|
|
}break;
|
|
|
|
case "FORWARD":{
|
|
|
|
r.keyPress(KeyEvent.VK_W);
|
|
|
|
r.delay(1000);
|
|
|
|
r.keyRelease(KeyEvent.VK_W);
|
|
|
|
}break;
|
|
|
|
case "BACKWARD":{
|
|
|
|
r.keyPress(KeyEvent.VK_S);
|
|
|
|
r.delay(1000);
|
|
|
|
r.keyRelease(KeyEvent.VK_S);
|
|
|
|
}break;
|
|
|
|
case "LEFT":{
|
|
|
|
r.keyPress(KeyEvent.VK_Q);
|
|
|
|
r.delay(1000);
|
|
|
|
r.keyRelease(KeyEvent.VK_Q);
|
|
|
|
}break;
|
|
|
|
case "RIGHT":{
|
|
|
|
r.keyPress(KeyEvent.VK_E);
|
|
|
|
r.delay(1000);
|
|
|
|
r.keyRelease(KeyEvent.VK_E);
|
|
|
|
}break;
|
|
|
|
case "FIGHT":{
|
|
|
|
fighting=true;
|
|
|
|
fightingaoe=false;
|
|
|
|
System.out.println("Fight mode: "+fighting);
|
|
|
|
}break;
|
|
|
|
case "FIGHTAOE":{
|
|
|
|
fighting=fightingaoe=true;
|
|
|
|
System.out.println("Fight mode: "+fighting);
|
|
|
|
}break;
|
|
|
|
case "CHILL":{
|
|
|
|
fighting=false;
|
|
|
|
System.out.println("Fight mode: "+fighting);
|
|
|
|
}break;
|
|
|
|
case "PASS":{
|
|
|
|
System.out.println("Mythra's Health: "+GetMythraHealth()+"%");
|
|
|
|
System.out.println("Aya's Health: "+GetAyaHealth()+"%");
|
|
|
|
System.out.println("Target's Health: "+GetTargetHealth()+"%");
|
|
|
|
}break;
|
|
|
|
case "SPRINT":{
|
|
|
|
if (nextActionTimer==0){
|
|
|
|
PressKey(KeyEvent.VK_N);
|
|
|
|
r.delay(100);
|
|
|
|
PressKey(KeyEvent.VK_N);
|
|
|
|
} else {
|
|
|
|
queueUpSprint=true;
|
|
|
|
}
|
|
|
|
}break;
|
|
|
|
case "UPDATE":{
|
|
|
|
|
|
|
|
}break;
|
|
|
|
default:{
|
|
|
|
System.out.println("Unknown command: "+command);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (queueUpSprint&&nextActionTimer==0){
|
|
|
|
PressKey(KeyEvent.VK_N);
|
|
|
|
r.delay(100);
|
|
|
|
PressKey(KeyEvent.VK_N);
|
|
|
|
nextActionTimer=100;
|
|
|
|
queueUpSprint=false;
|
|
|
|
} else {
|
|
|
|
if (fighting){
|
|
|
|
run(Rotation.SCHOLAR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
long difference=System.currentTimeMillis()-lastFrame;
|
|
|
|
bioTimer=Math.max(0,bioTimer-difference);
|
|
|
|
lucidDreamingTimer=Math.max(0,lucidDreamingTimer-difference);
|
|
|
|
nextActionTimer=Math.max(0,nextActionTimer-difference);
|
|
|
|
aetherflowTimer=Math.max(0,aetherflowTimer-difference);
|
|
|
|
whisperingDawnTimer=Math.max(0,whisperingDawnTimer-difference);
|
|
|
|
feyIlluminationTimer=Math.max(0,feyIlluminationTimer-difference);
|
|
|
|
lastFrame=System.currentTimeMillis();
|
|
|
|
r.delay(100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
|
|
|
|
// reads message from client until "Over" is sent
|
|
|
|
while (!line.equals("Over"))
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
line = in.readUTF();
|
|
|
|
System.out.println("Received: "+line);
|
|
|
|
commandQueue.add(line);
|
|
|
|
|
|
|
|
}
|
|
|
|
catch(IOException i)
|
|
|
|
{
|
|
|
|
System.out.println(i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
System.out.println("Closing connection");
|
|
|
|
|
|
|
|
// close connection
|
|
|
|
socket.close();
|
|
|
|
in.close();
|
|
|
|
}
|
|
|
|
catch(IOException i)
|
|
|
|
{
|
|
|
|
System.out.println(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void main(String args[])
|
|
|
|
{
|
|
|
|
Server server = new Server(5000);
|
|
|
|
}
|
|
|
|
}
|