Nbacon Posted June 6, 2020 Share Posted June 6, 2020 (edited) Hello, I hope this code helps you. [edited 06072020] Over heads is about 10-20mb of ram but is worth it becuase of how flexable it is. How to use new Packets Packets are usefull because you can send data and both sides know what is being sent and how to use it. Examples of packets I have made mouse packet that takes an x and a y and a mouse button and when executed will click on the screen. The example below is from my login packet takes a name, password and a world. The server will send this to a client and using code in the script will log in. Goto src/com/bacon/eco/server/shared/packets Make a new Packet that "implements IPacket" Go to PacketType enum add this line ClassName(last number ++ , com.bacon.eco.server.shared.packets.ClassName.class), You will see 4 override methods echo, send, receive, execute in the new Class you just made Make 2 constructors like This. One needs to have 0 args taken, other can take what ever you want. public LoginPacket() { } public LoginPacket(final String username, final String password, final int world){ this.username = username; this.password = password; this.world = world; } echo -has a boolean and if the server ever gets this packet it will send the info to everone- good for pking and ge merching. send - Inside send you need to use connection.writeString, connection.writeInt, ... and others in the order that you want to send them @Override public void send(ActiveConnection connection) { connection.writeString( this.username); connection.writeString( this.password); connection.writeInt( this.world ); } receive - Inside receive use connection.readString,connection.writeInt in the same order as above. @Override public void receive(ActiveConnection connection) { this.username =connection.readString(); this.password=connection.readString(); this.world =connection.readInt(); } execute - put what you want your bot to do here @Override public void execute(ActiveConnection connection) { if ( Client.mp !=null) Client.mp.loginToAccount( username,password ); if ( Client.mp !=null) Client.mp.hopto( world ); } This will does the same this as excute inside the packet (just rember to leave execute blank or it will do both). make getters and inside Client -> handlePacket -> add code like this if (clazz == LoginPacket.class) { final LoginPacket packet = (LoginPacket)Ipacket; if ( Client.mp !=null) Client.mp.loginToAccount( packet.username() ,packet.password() ); if ( Client.mp !=null) Client.mp.hopto( packet.world() ); return; } How to add P2P messages Make a new Class Quote package com.bacon.eco.server.shared.packets; import com.bacon.eco.server.shared.ActiveConnection; public class P2PMessagesPacket implements IPacket{ public P2PMessagesPacket(){ } Long time ; String senderName,receiversName,message; public P2PMessagesPacket(String senderName,String receiversName,String message){ this.time =System.nanoTime(); this.senderName=senderName; this.receiversName=receiversName; this.message=message; } @Override public boolean broadCast() { return false; } @Override public void send(ActiveConnection connection) { connection.writeLong(time); connection.writeString(senderName); connection.writeString(receiversName); connection.writeString(message); } @Override public void receive(ActiveConnection connection) { this.time = connection.readLong(); this.senderName = connection.readString(); this.receiversName = connection.readString(); this.message = connection.readString(); } @Override public void execute(ActiveConnection connection) { System.out.println(time+":"+senderName+" :"+message); //does something } public String getReceiversName() { return receiversName; } public Long getTime() { return time; } } Add it to the Enum PacketType Quote Information(1, InformationPacket.class), Ping(2, PingPacket.class), LogoutPacket(3, com.bacon.eco.server.shared.packets.LogoutPacket.class), ExamplePacket(4, com.bacon.eco.server.shared.packets.ExamplePacket.class), P2PMessagesPacket(5, com.bacon.eco.server.shared.packets.P2PMessagesPacket.class)//new Goto com.bacon.eco.server.server.network.Controller under handlePacket make code like this Quote if (clazz == P2PMessagesPacket.class) { final P2PMessagesPacket packet = (P2PMessagesPacket)iPacket; sendToOnePerson( packet.getReceiversName(),packet); return true; } Test your code (example P2PMessagePacket) go to TestClient write some code like this. compile and run Quote public static void startClient(final String address, final int port) { .... Example.Username ="test1"; while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } connection.addPacket(new P2PMessagesPacket("test2","hi")); } } Change the code to un comment to see them talk to each other. Quote public static void startClient(final String address, final int port) { ..... while (true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //connection.addPacket(new P2PMessagesPacket("test1","hi")); } } out put shoud look like Quote 278887291440685:test1 :hi 278888291729010:test1 :hi 278889292070128:test1 :hi 278890292315712:test1 :hi Adding useful info AbstractPingPongPacket these send a request for data [Advance] PingPacket this updates the server ever 3 seconds. info that could go in here userloged in username [example script you need write this your self] current script runnign User location much,much more Sever-side Tuning Basicly you can make methods that can be controlled by a gui or CLA with a scanner : Example Quote while (true) { String command = sc.nextLine(); if (command.equals("-lo")) { mainserver.controller.sendlogouts(-1); } } This tells all accounts to log out or just some amount. public void sendlogouts(int logoutAmount) { final Set<ActiveConnection> clientSet = clients.keySet(); int count = 0; for (final ActiveConnection connection : clientSet) { if (connection.getType() == 1 && (count < logoutAmount || logoutAmount == -1)) { count++; connection.addPacket(new LogoutPacket()); } } } Adding it to your scripts Examples from my scripts Quote Inside a banking class if(productAmount()>3000){ connection.addPacket(new MulePacket( this.getWorlds().getCurrentWorld() , 1)); } if(suppliesAmount()<500){ connection.addPacket(new MulePacket( this.getWorlds().getCurrentWorld() ,2)); } if(suppliesAmount()==0){ connection.addPacket(new MulePacket( this.getWorlds().getCurrentWorld() ,3)); } Quote simple multi-boxer getBot().addKeyListener(new BotKeyListener() { @Override public void checkKeyEvent(KeyEvent keyEvent) { if (holdkeys.contains(keyEvent.getKeyCode())) { if (keyEvent.toString().contains("KEY_RELEASED")) { connection.addPacket( new HoldPacket(keyEvent.getKeyCode(), 1)); } if (keyEvent.toString().contains("KEY_PRESSED")) { connection.addPacket( new HoldPacket(keyEvent.getKeyCode(), 0)); } } if (keyEvent.toString().contains("KEY_TYPED")&&keyEvent.getKeyChar()!=32) { connection.addPacket( new TypePacket(keyEvent.getKeyChar())); } } }); getBot().addMouseListener(new BotMouseListener() { @Override public void checkMouseEvent(MouseEvent mouseEvent) { if (mouseEvent.toString().contains("MOUSE_CLICKED")) { if (mouseEvent.getButton() == 1) { log("" + mouseEvent); connection.addPacket( new ClickPacket( mouseEvent.getX(), mouseEvent.getY(), 1)); } if (mouseEvent.getButton() == 3) { log("" + mouseEvent); connection.addPacket( new ClickPacket( mouseEvent.getX(), mouseEvent.getY(), 3)); } } } }); This is code was my frist draft on networking.Code update to add change in How to use [06072020] Things that can be added: if your connection drops out then try to reconnect. Better way to drop old conections- at the moment if you get sent 10 null messages in a row the connetion is droped. Things that can be ran TestClient Mainserver Example (script) Any questions or help just ask. update [06072020] Username is example script needs to be defined in some way by you. code_06072020.zip Edited June 7, 2020 by Nbacon 4 Quote Link to comment Share on other sites More sharing options...
Eagle Scripts Posted June 6, 2020 Share Posted June 6, 2020 Looks very good, well done . Quote Link to comment Share on other sites More sharing options...
dreameo Posted June 7, 2020 Share Posted June 7, 2020 I think there's a bit of over complication here. Instead of defining a 'packet' for every kind of message, just define a protocol. This way, you have a single send and receive. Internally, you decide how you make sense of the data. I'd also suggest keeping your classes minimal and light. Quote Link to comment Share on other sites More sharing options...
Nbacon Posted June 7, 2020 Author Share Posted June 7, 2020 6 hours ago, dreameo said: I think there's a bit of over complication here. Instead of defining a 'packet' for every kind of message, just define a protocol. I don't think I under stand this fully explain more. Becuase to me they are protocol becuase both sides agree on info that is sent over the sockets. You dont need packets to be mono taskers. But they can keeping a theme in a packet, this is usefull for expandability (for me at least). For my bot at least I have never needed more then 5 "packet", The bots are kept in the dark about the 30 other packets they cant see but the server can handle all 35. 6 hours ago, dreameo said: This way, you have a single send and receive. Internally, you decide how you make sense of the data. This sounds like what it is doing.(I don't Know how you would do this externally) Quote Link to comment Share on other sites More sharing options...
dreameo Posted June 7, 2020 Share Posted June 7, 2020 41 minutes ago, Nbacon said: I don't think I under stand this fully explain more. Becuase to me they are protocol becuase both sides agree on info that is sent over the sockets. You dont need packets to be mono taskers. But they can keeping a theme in a packet, this is usefull for expandability (for me at least). For my bot at least I have never needed more then 5 "packet", The bots are kept in the dark about the 30 other packets they cant see but the server can handle all 35. This sounds like what it is doing.(I don't Know how you would do this externally) Both sides don't agree, you have to manually go in and define a new packet for every type of message. Quote Link to comment Share on other sites More sharing options...
Nbacon Posted June 7, 2020 Author Share Posted June 7, 2020 2 hours ago, dreameo said: Both sides don't agree I don't know what you mean I have packet x with String i, int j, long k I make an x packet. I give you an packet with only the info. You read the packet and see id, oh its an x packet so you know it has a string i, int j and a long k. We both agree that all x packets need string i, int j, and a long k but we dont care what the others dose with info. 2 hours ago, dreameo said: you have to manually go in and define a new packet for every type of message. There only so much you can do and having molds for the grabage in and garbage out is usefull. Quote Link to comment Share on other sites More sharing options...
Camaro Posted June 7, 2020 Share Posted June 7, 2020 37 minutes ago, Nbacon said: I don't know what you mean I have packet x with String i, int j, long k I make an x packet. I give you an packet with only the info. You read the packet and see id, oh its an x packet so you know it has a string i, int j and a long k. We both agree that all x packets need string i, int j, and a long k but we dont care what the others dose with info. There only so much you can do and having molds for the grabage in and garbage out is usefull. Wouldnt it be easier for a 'Packet' to only contain one String which senders and receivers can parse accordingly? That way, the protocal can know even less about the data being sent and theres no need to define multiple 'Packets' Quote Link to comment Share on other sites More sharing options...
Nbacon Posted June 7, 2020 Author Share Posted June 7, 2020 1 hour ago, Camaro said: Wouldnt it be easier for a 'Packet' to only contain one String which senders and receivers can parse accordingly? That way, the protocal can know even less about the data being sent and theres no need to define multiple 'Packets' You could do that, there is nothing wrong with that. Its almost the same amount or more work(When i used that method it seemed like 3 times more work) as what this code does. This code is just Id10t proofing the sending, resiving and execution of data. No need to encode and decode data, No need to cast Strings to objects, and No need to make a parsing tree that only you can use because you made it. All you have to do is connection.addPacket(new YourPacket(info , info, info....)); Quote Link to comment Share on other sites More sharing options...