Build-Your-Own-World / byow / Networking / BYOWClient.java
BYOWClient.java
Raw
package byow.Networking;

import edu.princeton.cs.introcs.StdDraw;

import java.awt.*;
import java.io.*;
import java.net.Socket;
import java.nio.file.Paths;
import java.util.Scanner;

/**
 * Created by Boren Tsai and Arjun Sahai.
 */

public class BYOWClient {
    private int width;
    private int height;

    private Socket clientStringSocket;
    private Socket clientReadSocket;
    private BufferedWriter out;
    private BufferedReader in;
    private DataInputStream dis;

    static public final String CANVAS_FILE = ".client_canvas";

    static final String canvasPath = join(new File(System.getProperty("user.dir")), CANVAS_FILE).getAbsolutePath();
    static int magic = Integer.MIN_VALUE;

    /*
    Open socket, input/output streams, and create buffered writer & data input streams.
     */
    public void startConnection(String ip, int port) throws IOException {
        clientReadSocket = new Socket(ip, port);
        clientStringSocket = new Socket(ip, port);
        dis = new DataInputStream(clientReadSocket.getInputStream());
        out = new BufferedWriter(new OutputStreamWriter(clientStringSocket.getOutputStream()));
        in = new BufferedReader(new InputStreamReader(clientStringSocket.getInputStream()));
    }

    /*
    Check that the server has acknowledged that it is quitting in a nonblocking fasion
     */
    private boolean shouldClose() throws IOException {
        if (in.ready()) {
            char[] buf = new char[4];
            in.read(buf, 0, 4); // block client
            System.out.println(String.copyValueOf(buf));
            return true;
        }
        return false;
    }

    /*
    Close reader and writer then close socket.
     */
    private void stopConnection() throws IOException {
        dis.close();
        out.close();
        clientReadSocket.close();
        clientStringSocket.close();
    }

    /*
    Non Blocking
    Sends a String Command to the server i.e. W, A, S, D, etc.
     */
    private void sendCommand(String msg) throws IOException {
        out.write(msg);
        out.flush();
    }

    /*
    Blocking
    Displays a canvas if the server has sent the client something to read
    i.e. The server has sent a png file to the client
     */
    private void showCanvas() throws IOException {
        if (dis.available() > 0) {
            boolean configure = dis.readBoolean();
            if (configure) {
                System.out.println("CONFIGURING CANVAS");
                width = dis.readInt();
                height = dis.readInt();
                StdDraw.setCanvasSize(width, height);
                StdDraw.setXscale(0, width);
                StdDraw.setYscale(0, height);
                StdDraw.clear(new Color(0, 0, 0));
                StdDraw.enableDoubleBuffering();
                StdDraw.show();
            }

            StdDraw.clear();

            File newFile = new File(canvasPath + magic + ".png");
            File oldFile = new File(canvasPath + (magic - 1) + ".png");

            FileOutputStream fos = new FileOutputStream(newFile);

            // wait for incoming file size
            long size = dis.readLong();

            int bytes;
            byte[] buffer = new byte[4 * 1024];
            while (size > 0 && (bytes = dis.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
                fos.write(buffer, 0, bytes);
                size -= bytes;
            }
            // Write all buffered bytes into the file
            fos.flush();

            StdDraw.picture(width / 2, height / 2, canvasPath + magic + ".png");
            magic = magic + 1;

            oldFile.delete();
            StdDraw.show();
        }
    }

    private static File join(File first, String... others) {
        return Paths.get(first.getPath(), others).toFile();
    }


    public static void main(String[] args) throws IOException {
        System.out.println("BYOW Client. Please Enter the following information to connect to a server...");
        Scanner scanner = new Scanner(System.in);
        System.out.print("IP Address: ");
        String ip = scanner.next();
        System.out.print("Port (this must be a number): ");
        int port = scanner.nextInt();

        BYOWClient client = new BYOWClient();
        client.startConnection(ip, port); //ip port changes depending on link supplied by ngrok
        client.showCanvas();
        char command;

        try {
            while (true) {
                if (StdDraw.hasNextKeyTyped()) {
                    command = StdDraw.nextKeyTyped();
                    client.sendCommand(Character.toString(command));
                }
                client.showCanvas();
                StdDraw.clear();
                if (client.shouldClose()) {
                    client.stopConnection();
                    System.exit(0);
                }
            }
        } catch (java.net.SocketException e) {
            client.stopConnection();
            System.out.println("Disconnected from server");
            System.exit(0);
        }
        client.stopConnection();
        System.out.println("Disconnected from server");
        System.exit(0);
    }
}