import java.io.*; import java.net.*; /** * Soccrconnect * Connects to server and brings out server details for ball and team etc.. * Later was changed to be a thread to improve efficeny * @author Akbar Sherwani * @date 7th October * @verion 0.3 * * Version 0.3 * - Players Details * * Version 0.2 * - Ball * - Team names * * Version 0.1 * - Showing Play mode */ public class Soccerconnect extends Thread { private InetAddress address; // Address to connect to private String host; // Host to connect to private int port = 6000; // Port to connect to to private DatagramSocket socket; // UDP socket private byte[] buffer ; // Byte buffer private int BUFFER_SIZE =2048; // Size of buffer used by server private String lastmsg = ""; // Last messages by server private double scale = 65536.0; // Scale in terms of positions used by server private Player[] players = new Player[23]; // Player array private boolean firstrun = true; // Run first time connect public Thread t; // thread public GUI gui; // GUI to be passed public Ball ball = new Ball(); // Ball class public PitchView pitch = new PitchView(); // Voronoi Class public GameAnalyser game; // GA class /** * Constructor * holding the server name to connect and gui to pass to * @param server * @param gui */ public Soccerconnect(String server, GUI gui) { buffer = new byte[BUFFER_SIZE]; host = server; this.gui = gui; game = new GameAnalyser(ball, pitch, gui); setGUI(); } /** * Main - starts connection and starts commentray * @param args ignored just used for startup * @throws IOException */ public void run() { try { // Connect to server ss(host, 6000); } catch (UnknownHostException e) { System.out.println("Error connecting"); e.printStackTrace(); } catch (SocketException e) { System.out.println("Error connecting"); e.printStackTrace(); } // Send message below to start connection String msg = new String("(dispinit version 2)"); try { sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } // Start recieving method rec(); } /** * Run without GUI for debuging using below */ public void main(String[] args) throws IOException { ss("localhost", 6000); String msg = new String("(dispinit version 2)"); sendMessage(msg); rec(); } /** * Sends message to robocup server * @param msg string with the protocol message * @throws IOException */ private void sendMessage(String msg) throws IOException { byte[] rawMsg = msg.getBytes(); DatagramPacket packet = new DatagramPacket(rawMsg, rawMsg.length, address, port) ; try { socket.send(packet) ; } catch (IOException ie) { throw ie; } } /** * SS manages the connection to the server * @param hostname server for robocup * @param port servers port * @throws UnknownHostException * @throws SocketException */ public void ss(String hostname, int port) throws UnknownHostException, SocketException { try { address = InetAddress.getByName(hostname); } catch (UnknownHostException uhe) { throw uhe; } try { socket = new DatagramSocket(); } catch (SocketException se) { throw se; } } /** * Start Game * Linked from GUI */ public void startGame() { String msg = new String("(dispstart)"); try { sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } } /** * Rec method recieves packets from server */ public void rec() { DatagramPacket packet = new DatagramPacket(buffer, buffer.length) ; // Wait to receive a datagram while(true) { try { socket.receive(packet) ; } catch (IOException ie) { System.err.println(ie) ; } readpack(packet); } } /** * Readpack method reads packet and uses protocol to break down and get details * @param packet actual data packet from server */ public void readpack(DatagramPacket packet) { // Work out which type of the packet it is (struct with info detail) // Showinfo struct is equal to 1 int check = readShort(packet.getData(), 0); if(check == 1) { // Reads in Playmode Pmode mode = new Pmode(readChar(packet.getData(), 4)); // Call team details to intialse team details before playmode changes teamdetails(packet); if(lastmsg == mode.toString()) { //do nothing as play has not chaneged same as before } else { try { game.PlayModeChange(mode.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ball(packet); players(packet); lastmsg = mode.toString(); } } /** * Team details recieved from packets from server * @param packet data pakect from server */ public void teamdetails( DatagramPacket packet) { //Setting offset to be used to get teams names int offset = 6; int x = 0; int scorel; String templ = ""; while (offset < 23) { if (readChar(packet.getData(), offset) == 0) break; offset++; x++; } templ = new String(packet.getData(), 6, x); scorel = readShort(packet.getData(), 22); // System.out.println("Team 1: " + templ + ":" + scorel); offset = 24; x = 0; String temp = ""; while (offset < 40) { if (readChar(packet.getData(), offset) == 0) break; offset++; x++; } temp = new String(packet.getData(), 24, x); int score = readShort(packet.getData(), 40); // System.out.println("Team 2: " + temp + ":" + score); game.teamsScores(templ, scorel, temp, score); } /** * ball details recieved from packet * @param packet data packet from server */ public void ball(DatagramPacket packet) { // Offset is after team data which is 42 + 2 = 44 int offset = 44; // Ball x and y details double ballx = readLong(packet.getData(), offset) / scale; offset += 4; double bally = readLong(packet.getData(), offset) / scale; offset += 4; // Ball x and y velocity details double ballvelx = readLong(packet.getData(), offset) / scale; offset += 4; double ballvely = readLong(packet.getData(), offset) / scale; game.ballPosition(ballx, bally); ball.set(ballx, bally, ballvelx, ballvely); // System.out.println("Ball: x:" + ballx + " y:" + bally + " velx:" + ballvelx + " vely:" + ballvely); } /** * players details recieved from packet * @param packet data packet from server */ public void players(DatagramPacket packet) { // offset should now be 56 int offset = 60; int playernum = 1; while(playernum < 23) { // 1) Mode of player int mode = readShort(packet.getData(), offset); offset += 2; // 2) Type of player readShort(packet.getData(), offset); offset += 2; // 3) Player X cordinate double x = readLong(packet.getData(), offset) / scale; offset += 4; // 4) Player Y cordinate double y = readLong(packet.getData(), offset) / scale; offset += 4; // 5) Player Velocity X cordinate readLong(packet.getData(), offset); offset += 4; // 6) Player Velocity Y cordinate readLong(packet.getData(), offset); offset += 4; int kickcount = readShort(packet.getData(), offset+28); // offset to next player offset += 44; if(firstrun) { Player newplayer = new Player(playernum, mode, x, y, game, ball, pitch); players[playernum] = newplayer; } else { players[playernum].setDetails(playernum, mode, x, y, kickcount); } playernum++; } game.timeset(readUnsignedShort(packet.getData(), offset)); //System.out.println(readUnsignedShort(packet.getData(), offset)); firstrun = false; // System.out.println("Player:A x:" + x + " y:" + y); // if((test & 0x0002) == 0x0002) // { // System.out.println("Kick"); // } // if((test & 0x0008) == 0x0008) // { // System.out.println("Goalie"); // } } /** * Reads bytes to bring back short int * @param buf data buffer * @param offset offset in buffers byte * @return int */ private int readShort(byte[] buf, int offset) { return (short)((buf[offset] & 0xff) << 8) | (buf[offset+1] & 0xff); } /** * Reads bytes to bring back char * @param buf data buffer * @param offset offset in buffers byte * @return int */ private int readChar(byte[] buf, int offset) { return (buf[offset] & 0xff) ; } /** * Reads bytes to bring back long * @param buf data buffer * @param offset offset in buffers byte * @return long */ private long readLong(byte[] buf, int offset) { return ((buf[offset] & 0xff) << 24) | ((buf[offset+1] & 0xff) << 16) | ((buf[offset+2] & 0xff) << 8) | ((buf[offset+3] & 0xff)); } /** * Reads bytes to bring back unsigned short int * @param buf data buffer * @param offset offset in buffers byte * @return int */ private int readUnsignedShort(byte[] buf, int offset) { return ((buf[offset] & 0xff) << 8) | (buf[offset+1] & 0xff); } /** * Sets GUI */ public void setGUI() { game.setGUI(gui); } }