0

I am making a game proxy in Java, I've done it but I have a problem where it seems that the client packets aren't getting sent to the server and vice versa.

I've posted 4 classes: Proxy, Client, Server and Send.

The Proxy class just starts everything. The Client class handles packets from the client The Server class handles packets from the server The Send class is supposed to send the packet to the correct DataOutputStream using the Getters.

I think the problem is because I can't access the nonstatic getters I know I have to use an instance of it but when you look at the code you will see that if I make a new Server Instance for example: Server serv = new Server(null); It means that the connection to the remote server will be restarted and I don't want that...

And if I do it for the client it means the clientSocket is restarted - and I don't want that either.

I've been looking at this problem for hours on end now and I have finally reached out for help to see if I can get this solved.

Proxy Class:

public class Proxy {

    private static ServerSocket server;
    private static int port = 9339;
    private static String originalHost = "game.boombeachgame.com.";

    public static void start() {
        Log.init();
        Log.logInfo("* Proxy started");
        Proxy.startThreadServer();
    }

    public static void startThreadServer() {
        try {
            server = new ServerSocket(port);
            Socket clientSocket = server.accept();
            new Thread(new Server(originalHost)).start();
            new Thread(new Client(clientSocket)).start();
        } catch (Exception e) {
            System.out.println(e);
        }
    }


}

Client Class:

public class Client implements Runnable {

    private Socket socket;
    private DataOutputStream os;
    private DataInputStream is;

    public Client(Socket clientSocket) throws IOException {
        setSocket(clientSocket);
        os = new DataOutputStream(getSocket().getOutputStream());
        is = new DataInputStream(getSocket().getInputStream());
        Log.logInfo("* Client connected....");
    }

    @Override
    public void run() {

        new Crypt();

        try {

            while (true) {


                 int type = is.readUnsignedShort();
                 int size = is.readUnsignedByte();
                 size <<= 8;
                 size |= is.readUnsignedByte();
                 size <<= 8;
                 size |= is.readUnsignedByte();
                 int fsize = size+7;
                 int version = is.readUnsignedShort();

                 byte array[] = new byte[7];
                 array[0] = (byte)((type >>> 8) & 0xFF);
                 array[1] = (byte)(type & 0xFF);
                 array[2] = (byte)((size >>> 16) & 0xFF);
                 array[3] = (byte)((size >>> 8) & 0xFF);
                 array[4] = (byte)(size & 0xFF);
                 array[5] = (byte)((version >>> 8) & 0xFF);
                 array[6] = (byte)(version & 0xFF);

                 final byte[] request = new byte[size];

                is.readFully(request,0,size);

                byte[] data = new byte[array.length + request.length];
                System.arraycopy(array, 0, data, 0, array.length);
                System.arraycopy(request, 0, data, array.length, request.length);

                System.out.println("\n\nPacket From Client");
                System.out.println("Type: " + type + "");
                System.out.println("Full Length: " + fsize+ "");
                System.out.println("Data Length: " + size + "");
                System.out.println("Version: " + version + "");
                System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(request, type)) + "\n");

                new Send(data,"Client");
            }
        } catch (Exception e) {
        }
    }

    public DataOutputStream getOutputStream() {
        return os;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

}

Server Class:

public class Server implements Runnable {

    private Socket socket;
    private DataOutputStream os;
    private DataInputStream is;
    public Server(String originalHost) throws Exception {
        setSocket(new Socket(originalHost, 9339));
        os = new DataOutputStream(getSocket().getOutputStream());
        is = new DataInputStream(getSocket().getInputStream());
        Log.logInfo("* Connected to Boom Beach Server");
    }


    @Override
    public void run() {

    new Crypt();

        try {

            while (true) {

                int type = is.readUnsignedShort();
                int size = is.readUnsignedByte();
                size <<= 8;
                size |= is.readUnsignedByte();
                size <<= 8;
                size |= is.readUnsignedByte();
                int fsize = size+7;
                int version = is.readUnsignedShort();

                byte array[] = new byte[7];
                array[0] = (byte)((type >>> 8) & 0xFF);
                array[1] = (byte)(type & 0xFF);
                array[2] = (byte)((size >>> 16) & 0xFF);
                array[3] = (byte)((size >>> 8) & 0xFF);
                array[4] = (byte)(size & 0xFF);
                array[5] = (byte)((version >>> 8) & 0xFF);
                array[6] = (byte)(version & 0xFF);

                byte[] reply = new byte[size];
                is.readFully(reply,0,size);

                byte[] data = new byte[array.length + reply.length];
                System.arraycopy(array, 0, data, 0, array.length);
                System.arraycopy(reply, 0, data, array.length, reply.length);

                System.out.println("\n\nPacket From Server");
                System.out.println("Type: " + type + "");
                System.out.println("Full Length: " + fsize+ "");
                System.out.println("Data Length: " + size + "");
                System.out.println("Version: " + version + "");
                System.out.println("Header: " + DatatypeConverter.printHexBinary(array) + "");    
                System.out.println("Packet Data: " + DatatypeConverter.printHexBinary(Crypt.decrypt(reply,type)) + "\n");    

                new Send(data,"Server");

            }
        } catch (Exception e) {
        }
    }

    public DataOutputStream getOutputStream() {
        return os;
    }


    public Socket getSocket() {
        return socket;
    }


    public void setSocket(Socket socket) {
        this.socket = socket;
    }

}

Send Class:

public class Send{

    private Socket sock = null;
    private DataOutputStream out;


    public Send(byte[] data, String from) throws IOException {

        if (from == "Client"){
            sock = Server.getSocket();
            out = new DataOutputStream(sock.getOutputStream());

        }else{

            sock = Client.getSocket();
            out = new DataOutputStream(sock.getOutputStream());
        }

        out.write(data);
    }

}

I know that full code shouldn't be posted but I've been trying for ages to find a fix. I know that I can't make the DataOutputStreams static, so I need a way to access them without an Instance of an alternative that will work.

Shivam Paw
  • 203
  • 3
  • 14
  • Instance of what ? I would like to understand what you are trying to do without looking at the code first. – John Aug 16 '15 at 07:56
  • @John a new Instance of the Server/Client class. I am trying to get the DataOutputStream variables from the Client and Server Class into the Send class in the correct place. I can't get this working though because it says I need to make everything static when for the proxy to work properly they can't be static. – Shivam Paw Aug 16 '15 at 07:59
  • it's too much of code and I think your problem can be explained even without so much code. As far as I understood, have you tried making `Server` singleton? – Karthik Aug 16 '15 at 07:59
  • @ReservoirSampling don't think it worked... – Shivam Paw Aug 16 '15 at 08:01
  • `you don't want to create multiple instances of Server or Client, yet you want to get an instance of it` - If this is your problem, making it singleton should work. – Karthik Aug 16 '15 at 08:04
  • @ReservoirSampling searched thart but how do i do it then? – Shivam Paw Aug 16 '15 at 08:16

2 Answers2

0

seems that the client packets aren't getting sent to the server and vice versa

Try

out.write(data);
out.flush();
IgorL
  • 1,169
  • 10
  • 19
0

If you don't want to create multiple instances of your Server class, then you can make it singleton. Make the constructor of Server as private so that you can not create instance of Server from anywhere outside of Server class.

public class Server implements Runnable {

    .......
    private Server instance = null;
    private Server(String originalHost) throws Exception {
        setSocket(new Socket(originalHost, 9339));
        os = new DataOutputStream(getSocket().getOutputStream());
        is = new DataInputStream(getSocket().getInputStream());
        Log.logInfo("* Connected to Boom Beach Server");
    }

    public static Server getInstance(String originalHost){
         if(instance == null){
             instance = new Server(originalHost);
         }
         return instance;
    }
    .........

}

Where ever you were creating a new instance of Server, just do

      Server instance = Server.getInstance(originalHost);

and you are guaranteed to get same instance every time (unless it's a multithreaded environment).

Karthik
  • 4,950
  • 6
  • 35
  • 65