BGames
Olá visitante! Seja bem vindo á BGames!

Para ter total acesso ao nosso fórum é preciso que você se registre.

Registre-se Aqui!


PARA VER LINKS E IMAGENS É PRECISO SE REGISTRAR!


BGames
Olá visitante! Seja bem vindo á BGames!

Para ter total acesso ao nosso fórum é preciso que você se registre.

Registre-se Aqui!


PARA VER LINKS E IMAGENS É PRECISO SE REGISTRAR!

BGames
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

BGamesEntrar

Fórum de Desenvolvimento de Jogos e Programação


description[Duvida] Conversão Java  Empty[Duvida] Conversão Java

more_horiz
Bom, eu achei um programa em java que simula LAN virtualmente, queria intender esse código para fazer o mesmo em delphi.

Primeira Parte :
JLanCraft.Java

Código:


import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


public class JLancraft implements Runnable {
   public static final int WAR3_UDP_PORT = 6112;
   public static final int WAR3_DEFAULT_VERSION = 24;
   
   // These threads must only be started/stopped while the current thread
   // holds the lock on the JLancraft object.
   private Thread jlancraftThread;
   private Thread hostCheckerThread;
   private Thread datagramSenderThread;
   private Map<Integer, Thread> proxyListeners;
   private Thread[] proxyPipes;
   
   // incomingGameinfos maps the hash of an incoming GAMEINFO packet an index
   // in the outgoingGameinfos list.  It is used to determine whether a
   // received GAMEINFO has been seen already and to remove GAMEINFOS that
   // are no longer being sent by the host. NOTE: The actual packet data
   // stored in outgoingGameinfos may not have the same hash as is used as
   // a key in incomingGameinfos due to port changes in the packet data.
   private Map<Integer, Integer> incomingGameinfos;
   
   // This list contains a set of byte arrays to send as datagrams to
   // Warcraft (that is, to localhost:6112).  This list should only be
   // accessed by the thread that holds its lock.
   private List<byte[]> outgoingGameinfos;
   
   private PrintStream out;
   private boolean error;

   private String hostname;
   private int[] checkPorts;
   private int gameVersion;
   private Map<Integer, Integer> portMappings;
   
   public static void main(String args[]) {
//      JLancraft jlc2 = new JLancraft("67.9.159.140", 24, new int[] {6112, 6111});
      JLancraft jlc2 = new JLancraft("localhost", 24, new int[] {6112, 6111});
//      jlc2.portMappings.put(6113, 14333);
      jlc2.run();
   }

   public JLancraft(String hostname) {
      this(hostname, WAR3_DEFAULT_VERSION, new int[] {WAR3_UDP_PORT}, System.out, null);
   }
   public JLancraft(String hostname, int gameVersion) {
      this(hostname, gameVersion, new int[] {WAR3_UDP_PORT}, System.out, null);
   }
   public JLancraft(String hostname, int gameVersion, int[] checkPorts) {
      this(hostname, gameVersion, checkPorts, System.out, null);
   }
   public JLancraft(String hostname, int gameVersion, int[] checkPorts,
         PrintStream out) {
      this(hostname, gameVersion, checkPorts, out, null);
   }
   
   public JLancraft(String hostname, int gameVersion, int[] checkPorts,
         PrintStream out, int[][] portMappings) {
      super();
      this.hostname = hostname;
      this.gameVersion = gameVersion;
      if (checkPorts != null)
         this.checkPorts = Arrays.copyOf(checkPorts, checkPorts.length);
      else
         this.checkPorts = new int[0];
      this.out = out;
      this.portMappings = new HashMap<Integer, Integer>();
      
      if (portMappings != null) {
         for (int[] mapping : portMappings) {
            this.portMappings.put(mapping[0], mapping[1]);
         }
      }
      
      this.incomingGameinfos = new HashMap<Integer, Integer>();
      this.outgoingGameinfos = new LinkedList<byte[]>();
      this.proxyListeners = new HashMap<Integer, Thread>();
      this.proxyPipes = new Thread[2];
   }

   public void run() {
      println("Running...");
      
      if (jlancraftThread != null) {
         println("Error: Cannot run multiple threads using the same JLancraft object");
         println("Exiting with error");
         return;
      }
      
      jlancraftThread = Thread.currentThread();
      
      InetAddress hostAddr;
      try {
         hostAddr = InetAddress.getByName(hostname);
      } catch (UnknownHostException e) {
         println("Error: Unknown host: " + hostname);
         return;
      }
      
      
      while (!Thread.currentThread().isInterrupted() && !error) {
         out.println();
         println("Starting host checker and datagram sender...");
         
         stopAllThreads();
         
         synchronized (outgoingGameinfos) {
            incomingGameinfos.clear();
            outgoingGameinfos.clear();
         }
         
         startHostChecker(hostAddr);
         startDatagramSender();

         println("Waiting for threads to exit...");
         try {
            hostCheckerThread.join();
            
            if (datagramSenderThread != null)
               datagramSenderThread.join();
            
            if (proxyPipes != null) {
               if (proxyPipes[0] != null)
                  proxyPipes[0].join();
               if (proxyPipes[1] != null)
                  proxyPipes[1].join();
            }
         } catch (InterruptedException e) {
            println("Interrupted");
            break;
         }

         println("All threads have exited");
         println("Restarting...");
      }
      
      if (error) {
         println("Exiting with error");
      } else {
         println("Exiting normally");
      }
      
      stopAllThreads();
   }
   
   private synchronized void startHostChecker(InetAddress addr) {
      if (Thread.currentThread().isInterrupted())
         return;
      
      if (hostCheckerThread != null && hostCheckerThread.isAlive())
         stopHostChecker();
      
      Runnable r = new HostChecker(addr);
      hostCheckerThread = new Thread(r, "HostChecker");
      hostCheckerThread.start();
   }
   
   private synchronized void startDatagramSender() {
      if (Thread.currentThread().isInterrupted())
         return;
      
      if (datagramSenderThread != null && datagramSenderThread.isAlive())
         stopDatagramSender();
      
      Runnable r = new DatagramSender();
      datagramSenderThread = new Thread(r, "DatagramSender");
      datagramSenderThread.start();
   }
   
   private synchronized void startProxyListener(ServerSocket socket, InetSocketAddress dest) {
      if (Thread.currentThread().isInterrupted())
         return;
      
      int port = socket.getLocalPort();
      
      if (proxyListeners.containsKey(port)) {
         Thread t = proxyListeners.get(port);
         if (t != null && t.isAlive())
            stopProxyListener(port);
      }
      
      Runnable r = new ProxyListener(socket, dest);
      Thread t = new Thread(r, "ProxyListener-" + port + "-" + dest.getPort());
      proxyListeners.put(port, t);
      t.start();
   }
   
   private synchronized void startProxyPipes(InputStream in1, OutputStream out1, InputStream in2, OutputStream out2) {
      if (Thread.currentThread().isInterrupted())
         return;
      
      stopProxyPipes();
      
      Runnable a = new ProxyPipe(in1, out2);
      Runnable b = new ProxyPipe(in2, out1);
      
      proxyPipes[0] = new Thread(a, "ProxyPipeA");
      proxyPipes[1] = new Thread(b, "ProxyPipeB");
      
      proxyPipes[0].start();
      proxyPipes[1].start();
      
   }
   
   private synchronized void stopHostChecker() {
      if (hostCheckerThread != null)
         hostCheckerThread.interrupt();
   }
   
   private synchronized void stopDatagramSender() {
      if (datagramSenderThread != null)
         datagramSenderThread.interrupt();
   }
   
   private synchronized void stopProxyListener(int port) {
      Thread t = proxyListeners.get(port);
      if (t != null) {
         t.interrupt();
         proxyListeners.remove(port);
      }
   }

   private synchronized void stopAllProxyListeners() {
      for (Thread t : proxyListeners.values()) {
         t.interrupt();
      }

      proxyListeners.clear();
   }
   
   private synchronized void stopProxyPipes() {
      if (proxyPipes[0] != null)
         proxyPipes[0].interrupt();
      if (proxyPipes[1] != null)
         proxyPipes[1].interrupt();
   }
   
   private synchronized void stopAllThreads() {
      stopHostChecker();
      stopDatagramSender();
      stopAllProxyListeners();
      stopProxyPipes();
   }
   
   private synchronized boolean setupProxy(Socket a, Socket b) {
      InputStream inA, inB;
      OutputStream outA, outB;
      try {
         inA = a.getInputStream();
         outA = a.getOutputStream();
         
         inB = b.getInputStream();
         outB = b.getOutputStream();
      } catch (IOException e) {
         println("Error: Received IOException while setting up proxy");
         println(e.toString());
         return false;
      }
      
      startProxyPipes(inA, outA, inB, outB);
      
      stopHostChecker();
      stopDatagramSender();
      stopAllProxyListeners();
      
      return true;
   }
   
   private void println(String s) {
      out.println("[" + Thread.currentThread().getName() + "] " + s);
   }
   
   private void printf(String fmt, Object... params) {
      out.print("[" + Thread.currentThread().getName() + "] ");
      out.printf(fmt, params);
   }
   
   private void abortWithError() {
      println("Exiting with error");
      error = true;
      jlancraftThread.interrupt();
   }
   
   private int getGamePort(byte[] data) {
      int len = data.length;
      int ret = ((data[len - 1] & 0xFF) << 8) | (data[len - 2] & 0xFF);
      return ret;
   }
   
   private void setGamePort(byte[] data, int port) {
      int len = data.length;
      data[len-1] = (byte)((port >> 8) & 0xFF);
      data[len-2] = (byte)(port & 0xFF);
   }
   
   private byte[] getSearchgameData() {

      byte[] ret = {
         (byte)247,               // W3GS_HEADER_CONSTANT
         47,                     // W3GS_SEARCHGAME
         16, 0,                  // total packet length (little-endian)
         80, 88, 51, 87,            // product ID ("W3XP", reversed);
         (byte)gameVersion, 0, 0, 0,   // warcraft minor version (little-endian)
         0, 0, 0, 0,               // unknown
      };
      
      return ret;
   }
   
   private class HostChecker implements Runnable {
      private InetAddress hostAddr;
      public static final int MAX_SEND_FAILURES = 2;
      public static final int MAX_RECV_FAILURES = 2;
      public static final int CHECK_INTERVAL = 5000;

      public HostChecker(InetAddress hostAddr) {
         super();
         this.hostAddr = hostAddr;
      }
      
      public void run() {
         println("Running...");
         
         DatagramSocket sock;
         try {
            sock = new DatagramSocket();
         } catch (IOException e) {
            println("Error: Caught exception when creating DatagramSocket");
            println(e.toString());
            abortWithError();
            return;
         }
         
         byte[] data = getSearchgameData();
         DatagramPacket pkt = new DatagramPacket(data, data.length);
         pkt.setAddress(hostAddr);
         
         byte[] buf = new byte[2048];
         DatagramPacket pktIn = new DatagramPacket(buf, buf.length);
         
         int sendFailCount = 0;
         int recvFailCount = 0;
         int remainingTime;
         long startTime, endTime;
         
         println("Checking for games every " + CHECK_INTERVAL + " ms...");
         
         while (!Thread.currentThread().isInterrupted()) {
            if (!sendSearchgames(sock, pkt)) {
               sendFailCount++;
               if (sendFailCount > MAX_SEND_FAILURES) {
                  println("Error: Failed to send any SEARCHGAMEs in the past " + sendFailCount + " attempts");
                  sock.close();
                  abortWithError();
                  return;
               }
            } else {
               sendFailCount = 0;
            }
            
            remainingTime = CHECK_INTERVAL;
            
            
            while (remainingTime > 0) {
               try {
                  sock.setSoTimeout(remainingTime);
                  
                  startTime = System.currentTimeMillis();
                  sock.receive(pktIn);
                  handleReply(pktIn);
                  endTime = System.currentTimeMillis();
                  
                  remainingTime -= (endTime - startTime);
                  recvFailCount = 0;
               } catch (SocketTimeoutException e) {
                  remainingTime = 0;
                  recvFailCount = 0;
               } catch (InterruptedIOException e) {
                  remainingTime = 0;
                  Thread.currentThread().interrupt();
                  break;
               } catch (IOException e) {
                  println("Warning: Exception occurred while waiting for GAMEINFO replies");
                  println(e.toString());
                  recvFailCount++;
                  
                  if (recvFailCount > MAX_RECV_FAILURES) {
                     println("Error: Failed to listen for packets for the past " + recvFailCount + " attempts");
                     sock.close();
                     abortWithError();
                     return;
                  }
               }
            }
            
            if (remainingTime > 0) {
               try {
                  Thread.sleep(remainingTime);
               } catch (InterruptedException e) {
                  break;
               }
            }
         }

         sock.close();
         println("Exiting normally");
      }
      
      private boolean sendSearchgames(DatagramSocket sock, DatagramPacket pkt) {
         boolean success = false;
         for (int i=0;i<checkPorts.length;i++) {
            pkt.setPort(checkPorts[i]);
            try {
               sock.send(pkt);
               success = true;
            } catch (IOException e) {
               println("Warning: Failed to send SEARCHGAME to port " + checkPorts[i]);
            }
         }
         return success;
      }
      
      private void handleReply(DatagramPacket pkt) {
         if (!pkt.getAddress().equals(hostAddr)) {
            println("Warning: Ignoring incoming packet from host " + pkt.getAddress() + " (expected " + hostAddr + ")");
            return;
         }
         
         if (pkt.getLength() < 6) {
            println("Warning: Packet from " + pkt.getAddress() + " is too short");
            return;
         }
         
         // Get the packet data
         byte[] data = new byte[pkt.getLength()];
         System.arraycopy(pkt.getData(), pkt.getOffset(), data, 0, pkt.getLength());
         
         // Check if this GAMEINFO has been seen before
         // Zero the uptime field because it changes from one GAMEINFO to
         // the next.
         
         byte[] uptime = new byte[4];
         System.arraycopy(data, data.length-6, uptime, 0, 4);
         Arrays.fill(data, data.length-6, data.length-2, (byte)0);
         
         int hash = Arrays.hashCode(data);
         
         System.arraycopy(uptime, 0, data, data.length-6, 4);
         
         
         // Add this packet's info to incomingGameinfos/outgoingGameinfos
         synchronized (outgoingGameinfos) {
         
            if (incomingGameinfos.containsKey(hash))
               return;
   
            String hashStr = Integer.toHexString(hash);
            println("Found new game with GAMEINFO hash 0x" + Integer.toHexString(hash));
            
            // Get the game port
            int gamePort = getGamePort(data);
            int listenPort = gamePort;
            
            println("Game 0x" + hashStr + ": GAMEINFO specifies gameport " + gamePort);
            
            if (portMappings.containsKey(gamePort) && portMappings.get(gamePort) != null) {
               println("Gameport " + gamePort + " has been redirected to port " + portMappings.get(gamePort));
               gamePort = portMappings.get(gamePort);
            }
            
            // Start a ServerSocket for a ProxyListener to listen on
            ServerSocket server = null;
            
            try {
               server = new ServerSocket(0, 0, InetAddress.getLocalHost());
            } catch (IOException e) {
               println("Error: Unable to bind to any TCP port");
               abortWithError();
               return;
            }
            listenPort = server.getLocalPort();
            println("Game 0x" + hashStr + ": Listening on TCP port " + listenPort);
            
            setGamePort(data, listenPort);
            
            
            println("Game 0x" + hashStr + ": Starting proxy listener for TCP port " + listenPort);
            println("Game 0x" + hashStr + ": Connections will be forwarded to remote port " + gamePort);
            
            // Start the ProxyListener for this game
            startProxyListener(server, new InetSocketAddress(hostAddr, gamePort));
         
            int idx = outgoingGameinfos.size();
            outgoingGameinfos.add(data);
            incomingGameinfos.put(hash, idx);
         }
      }
   }

   private class DatagramSender implements Runnable {
      public static final int MAX_SEND_FAILURES = 2;
      public static final int DATAGRAM_INTERVAL = 1000;
      
      public void run() {
         println("Running...");
         
         DatagramSocket sock;
         
         try {
            sock = new DatagramSocket();
         } catch (IOException e) {
            println("Error: Caught exception while creating DatagramSocket");
            println(e.toString());
            abortWithError();
            return;
         }
         
         println("Running on UDP port " + sock.getLocalPort());
         
         byte[] buf = new byte[0];
         DatagramPacket pkt = new DatagramPacket(buf, 0);
         try {
            pkt.setAddress(InetAddress.getLocalHost());
         } catch (UnknownHostException e) {
            println("Error: Unable to set datagram destination to local host");
            println(e.toString());
            sock.close();
            abortWithError();
            return;
         }
         pkt.setPort(WAR3_UDP_PORT);
         
         boolean success;
         int failCount = 0;
         
         while (!Thread.currentThread().isInterrupted()) {
            success = false;
            synchronized (outgoingGameinfos) {
               if (outgoingGameinfos.size() == 0)
                  success = true;
               for (byte[] data : outgoingGameinfos) {
                  pkt.setData(data);
                  try {
                     sock.send(pkt);
                     success = true;
                  } catch (IOException e) {
                     println("Warning: Failed to send datagram");
                     println(e.toString());
                  }
               }
            }
            
            if (!success) {
               failCount++;
               if (failCount > MAX_SEND_FAILURES) {
                  println("Error: Unable to send any datagrams in the past " + failCount + " attempts");
                  abortWithError();
                  sock.close();
                  return;
               }
            } else {
               failCount = 0;
            }
            
            try {
               Thread.sleep(DATAGRAM_INTERVAL);
            } catch (InterruptedException e) {
               break;
            }
         }

         sock.close();
         println("Exiting normally");
      }
   }
   
   private class ProxyListener implements Runnable {
      public static final int ACCEPT_TIMEOUT = 5000;
      
      ServerSocket server;
      InetSocketAddress dest;

      public ProxyListener(ServerSocket server, InetSocketAddress dest) {
         super();
         this.server = server;
         this.dest = dest;
      }
      
      public void run() {
         println("Running...");
         
         try {
            server.setSoTimeout(ACCEPT_TIMEOUT);
         } catch (IOException e) {
            println("Caught exception when setting accept timeout");
            println(e.toString());
            printErrorAndRespawn();
         }
         
         Socket incoming = null;
         while (!Thread.currentThread().isInterrupted() && incoming == null) {
            try {
               incoming = server.accept();
            } catch (SocketTimeoutException e) {
               // try again
            } catch (IOException e) {
               println("Error: Failed to accept connection");
               println(e.toString());
               printErrorAndRespawn();
               return;
            }
         }
         
         if (Thread.currentThread().isInterrupted()) {
            println("Exiting normally");
            return;
         }
         
         println("Received incoming connection from " + incoming.getRemoteSocketAddress());
         
         Socket outgoing;
         try {
            outgoing = new Socket(dest.getAddress(), dest.getPort());
         } catch (IOException e) {
            println("Error: Failed to connect to destination: " + dest);
            println(e.toString());
            println("Closing incoming connection...");
            try {
               incoming.close();
            } catch (IOException e2) {
               println("Caught exception while closing incoming connection");
               println(e2.toString());
            }
            printErrorAndRespawn();
            return;
         }
         
         println("Created outgoing connection to " + outgoing.getRemoteSocketAddress());
         
         if (setupProxy(incoming, outgoing))
            println("Exiting normally");
         else
            printErrorAndRespawn();
         
      }
      
      private void printErrorAndRespawn() {
         println("Exiting with error");
         println("Respawning...");
         startProxyListener(server, dest);
      }
   }
   
   private class ProxyPipe implements Runnable {
      private InputStream inStream;
      private OutputStream outStream;
      
      public ProxyPipe(InputStream inStream, OutputStream outStream) {
         super();
         this.inStream = inStream;
         this.outStream = outStream;
      }
      
      public void run() {
         println("Running...");
         
         byte[] buf = new byte[4096];
         int len;
         boolean error = false;
         
         while (!Thread.currentThread().isInterrupted()) {
            try {
               len = inStream.read(buf);
               if (len == -1)
                  break;
               outStream.write(buf, 0, len);
            } catch (InterruptedIOException e) {
               break;
            } catch (IOException e) {
               println("Warning: Caught exception while transferring data");
               println(e.toString());
               error = true;
               break;
            }
         }
         
         try {
            outStream.close();
         } catch (IOException e) {
         }
         
         try {
            inStream.close();
         } catch (IOException e) {
         }
         
         if (error)
            println("Exiting due to exception");
         else
            println("Exiting normally");
         
      }
   }
}



Segunda Parte :

JLancraftGUI.java:

Código:

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.prefs.Preferences;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.GroupLayout.Alignment;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;


public class JLancraftGUI extends JFrame implements ActionListener {
   
   private static final String VERSION = "0.3.0";

        private static final int MAX_HISTORY = 10;

   private static final Preferences PREFS = Preferences.userRoot().node("JLancraftGUI");
   
   private JDialog advancedSettingsDialog;
   
   private JComboBox hostnameCombo;
   private JTextArea outputArea;
   
   private JScrollPane outputScroller;
   
   private JButton startButton;
   private JButton stopButton;
   private JButton helpButton;
   private JButton advancedSettingsButton;
   

   private JTextField udpPortsField;
   private JTextField gameVersionField;
   private JTable portRedirectTable;

   private JScrollPane portRedirectScroller;
   
   private JButton addRedirectButton;
   private JButton removeRedirectButton;
   private JButton okButton;
   private JButton cancelButton;
   
   private PortRedirectTableModel portRedirectTableModel;
   
   private PrintStream out;
   private Thread pipeReaderThread;
   
   private Thread jlancraftThread;
   
   
   private String hostname;
   private int gameVersion = 24;
   private int[] udpPorts = { 6112 };
   private int[][] portRedirects = new int[0][];
   
   public static void main(String[] args) {
      Runnable r = new Runnable() {
         public void run() {
            JFrame f = new JLancraftGUI();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setLocationByPlatform(true);
            f.setVisible(true);
         }
      };
      SwingUtilities.invokeLater(r);
   }
   
   public JLancraftGUI() {
      super("JLancraft " + VERSION);
      buildMainGUI();
      buildSettingsGUI();
      startPipeThread();
      loadSettings();
   }
   
   private void startPipeThread() {
      PipedInputStream pipeIn;
      PipedOutputStream pipeOut;
      try {
         pipeIn = new PipedInputStream();
         pipeOut = new PipedOutputStream(pipeIn);
      } catch (IOException e) {
         appendOutput("[" + Thread.currentThread().getName() + "] Error: Unable to create pipes for output\n");
         appendOutput("[" + Thread.currentThread().getName() + "] " + e + "\n");
         return;
      }
      
      Runnable r = new PipeReader(pipeIn);
      pipeReaderThread = new Thread(r, "OutputPrinter");
      pipeReaderThread.start();
      
      out = new PrintStream(pipeOut);
   }
   
   private void buildMainGUI() {
      JLabel hostnameLabel = new JLabel("Hostname:");

      hostnameCombo = new JComboBox();
      
      startButton = new JButton("Start");
      stopButton = new JButton("Stop");
      helpButton = new JButton("Help");
      advancedSettingsButton = new JButton("Advanced Settings...");

      outputArea = new JTextArea(15, 40);
      outputScroller = new JScrollPane(outputArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

      startButton.addActionListener(this);
      stopButton.addActionListener(this);
      helpButton.addActionListener(this);
      advancedSettingsButton.addActionListener(this);
      advancedSettingsButton.setActionCommand("Settings");
      
                hostnameCombo.setEditable(true);
      stopButton.setEnabled(false);
      
      GroupLayout layout = new GroupLayout(getContentPane());
      setLayout(layout);
      
      layout.setHorizontalGroup(
      layout.createParallelGroup()
         .addGroup(
         layout.createSequentialGroup()
            .addGap(5)
            .addComponent(hostnameLabel)
            .addGap(5)
            .addComponent(hostnameCombo)
            .addGap(5)
            .addComponent(startButton)
            .addGap(5)
            .addComponent(stopButton)
            .addGap(5)
         )
         .addGroup(
         layout.createSequentialGroup()
            .addGap(0, 5, Short.MAX_VALUE)
            .addComponent(advancedSettingsButton)
            .addGap(5)
            .addComponent(helpButton)
            .addGap(0, 5, Short.MAX_VALUE)
         )
         .addComponent(outputScroller)
      );
      
      layout.setVerticalGroup(
      layout.createSequentialGroup()
         .addGap(5)
         .addGroup(
         layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
            .addComponent(hostnameLabel)
            .addComponent(hostnameCombo)
            .addComponent(startButton)
            .addComponent(stopButton)
         )
         .addGap(5)
         .addGroup(
         layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
            .addComponent(advancedSettingsButton)
            .addComponent(helpButton)
         )
         .addGap(5)
         .addComponent(outputScroller)
      );
               
      
      pack();
   }
   
   private void buildSettingsGUI() {
      advancedSettingsDialog = new JDialog(this, "Advanced Settings", true);
      
      JLabel udpPortsLabel = new JLabel("UDP Port(s):");
      JLabel gameVersionLabel = new JLabel("Game Minor Version:");
      JLabel portRedirectLabel = new JLabel("Game Port Redirections:");

      udpPortsField = new JTextField("6112", 10);
      gameVersionField = new JTextField("24", 2);
      addRedirectButton = new JButton("Add");
      removeRedirectButton = new JButton("Remove");
      okButton = new JButton("OK");
      cancelButton = new JButton("Cancel");

      createPortRedirectTable();
      portRedirectScroller = new JScrollPane(portRedirectTable);
      portRedirectScroller.setPreferredSize(new Dimension(300,200));

      addRedirectButton.addActionListener(this);
      removeRedirectButton.addActionListener(this);
      okButton.addActionListener(this);
      cancelButton.addActionListener(this);
      
      GroupLayout layout = new GroupLayout(advancedSettingsDialog.getContentPane());
      advancedSettingsDialog.getContentPane().setLayout(layout);
      
      layout.setHorizontalGroup(
      layout.createParallelGroup()
         .addGroup(
         layout.createSequentialGroup()
            .addGap(5)
            .addGroup(
            layout.createParallelGroup()
               .addComponent(udpPortsLabel)
               .addComponent(gameVersionLabel)
            )
            .addGap(5)
            .addGroup(
            layout.createParallelGroup()
               .addComponent(udpPortsField)
               .addComponent(gameVersionField)
            )
            .addGap(5)
         )
         .addGroup(
         layout.createSequentialGroup()
            .addGap(5)
            .addGroup(
            layout.createParallelGroup()
               .addComponent(portRedirectLabel)
               .addGroup(
               layout.createSequentialGroup()
                  .addComponent(portRedirectScroller)
                  .addGap(5)
                  .addGroup(
                  layout.createParallelGroup()
                     .addComponent(addRedirectButton)
                     .addComponent(removeRedirectButton)
                  )
               )
            )
            .addGap(5)
         )
         .addGroup(
         layout.createSequentialGroup()
            .addGap(5, 5, Short.MAX_VALUE)
            .addComponent(okButton)
            .addGap(5)
            .addComponent(cancelButton)
            .addGap(5)
         )
      );
      
      layout.setVerticalGroup(
      layout.createSequentialGroup()
         .addGap(5)
         .addGroup(
         layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(udpPortsLabel)
            .addComponent(udpPortsField)
         )
         .addGap(5)
         .addGroup(
         layout.createParallelGroup(Alignment.BASELINE)
            .addComponent(gameVersionLabel)
            .addComponent(gameVersionField)
         )
         .addGap(15)
         .addComponent(portRedirectLabel)
         .addGap(5)
         .addGroup(
         layout.createParallelGroup()
            .addComponent(portRedirectScroller)
            .addGroup(
            layout.createSequentialGroup()
               .addComponent(addRedirectButton)
               .addGap(5)
               .addComponent(removeRedirectButton)
            )
         )
         .addGap(10)
         .addGroup(
         layout.createParallelGroup()
            .addComponent(okButton)
            .addComponent(cancelButton)
         )
         .addGap(5)
      );
      
      advancedSettingsDialog.pack();
         
   }
   
   private void createPortRedirectTable() {
      portRedirectTableModel = new PortRedirectTableModel();
      portRedirectTable = new JTable(portRedirectTableModel);
   }
   
   private class PortRedirectTableModel extends AbstractTableModel {
      private static final long serialVersionUID = -9125638713537846044L;
      
      private List<int[]> redirs = new ArrayList<int[]>();
      
      public String getColumnName(int columnIndex) {
         if (columnIndex == 0)
            return "Game Port";
         if (columnIndex == 1)
            return "Redirected Port";
         return "";
      }
      
      public Class<?> getColumnClass(int columnIndex) {
         if (columnIndex == 0 || columnIndex == 1)
            return Integer.class;
         return null;
      }
      
      public boolean isCellEditable(int rowIndex, int columnIndex) {
         return rowIndex >= 0 && rowIndex < redirs.size()
               && columnIndex >= 0 && columnIndex < 2;
      }
      
      public void setValueAt(Object value, int rowIndex, int columnIndex) {
         if (!isCellEditable(rowIndex, columnIndex))
            return;
         if (!(value instanceof Integer))
            return;
         redirs.get(rowIndex)[columnIndex] = (Integer)value;
         fireTableCellUpdated(rowIndex, columnIndex);
      }
      
      public int getRowCount() {
         return redirs.size();
      }
      
      public int getColumnCount() {
         return 2;
      }
      
      public Object getValueAt(int rowIndex, int columnIndex) {
         return redirs.get(rowIndex)[columnIndex];
      }
      
      public int[] getMapping(int index) {
         return Arrays.copyOf(redirs.get(index), 2);
      }
      
      public void addMapping(int from, int to) {
         redirs.add(new int[] { from, to });
         fireTableRowsInserted(redirs.size()-1, redirs.size()-1);
      }
      
      public void removeMapping(int rowIdx) {
         redirs.remove(rowIdx);
         fireTableRowsDeleted(rowIdx, rowIdx);
      }
      
      public void removeMappings(int[] rowIdxs) {
         for (int i = rowIdxs.length - 1; i >= 0; i--) {
            removeMapping(rowIdxs[i]);
         }
      }
      
      public void clearMappings() {
         int size = redirs.size();
         redirs.clear();
         if (size > 0)
            fireTableRowsDeleted(0, size - 1);
      }
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      String cmd = e.getActionCommand();
      
      if (cmd.equals("Start")) {
         startJLancraft();
      } else if (cmd.equals("Stop")) {
         stopJLancraft();
      } else if (cmd.equals("Settings")) {
         displayAdvancedSettingsDialog();
      } else if (cmd.equals("Help")) {
         displayHelp();
      } else if (cmd.equals("Add")) {
         addPortRedirect();
      } else if (cmd.equals("Remove")) {
         removePortRedirect();
      } else if (cmd.equals("OK")) {
         closeAdvancedSettingsDialog(true);
      } else if (cmd.equals("Cancel")) {
         closeAdvancedSettingsDialog(false);
      }
   }
   
   private synchronized void startJLancraft() {
      if (jlancraftThread != null) {
         out.println("[" + Thread.currentThread().getName() + "] Error: A JLancraft thread is already running\n");
         return;
      }
      
      hostname = (String)hostnameCombo.getSelectedItem();
      saveSettings();
      
      Runnable r = new JLancraft(hostname, gameVersion, Arrays.copyOf(udpPorts, udpPorts.length), out, portRedirects);
      jlancraftThread = new Thread(r, "JLancraft");

      out.println("[" + Thread.currentThread().getName() + "] Starting JLancraft thread...\n");
      jlancraftThread.start();
      
      Runnable r2 = new Runnable() {
         public void run() {
            try {
               jlancraftThread.join();
            } catch (InterruptedException e) {}
            stopJLancraft();
         }
      };
      new Thread(r2).start();

      startButton.setEnabled(false);
      stopButton.setEnabled(true);
   }
   
   private synchronized void stopJLancraft() {
      if (jlancraftThread == null) {
         return;
      }
      
      out.println("[" + Thread.currentThread().getName() + "] Stopping JLancraft thread...\n");
      jlancraftThread.interrupt();
      jlancraftThread = null;
      
      startButton.setEnabled(true);
      stopButton.setEnabled(false);
   }
   
   private void displayAdvancedSettingsDialog() {
      StringBuffer sb = new StringBuffer();
      for (int port : udpPorts) {
         sb.append(port);
         sb.append(", ");
      }
      sb.delete(sb.length() - 2, sb.length());
      
      udpPortsField.setText(sb.toString());
      
      gameVersionField.setText("" + gameVersion);
      
      portRedirectTableModel.clearMappings();
      for (int[] redir : portRedirects) {
         portRedirectTableModel.addMapping(redir[0], redir[1]);
      }
      
      
      Rectangle mainWinBounds = this.getBounds();
      int centerX = mainWinBounds.x + mainWinBounds.width / 2;
      int centerY = mainWinBounds.y + mainWinBounds.height / 2;
      Rectangle advSetWinBounds = advancedSettingsDialog.getBounds();
      advSetWinBounds.x = centerX - advSetWinBounds.width / 2;
      advSetWinBounds.y = centerY - advSetWinBounds.height / 2;
      advancedSettingsDialog.setBounds(advSetWinBounds);
      
      
      advancedSettingsDialog.setVisible(true);
   }
   
   private void displayHelp() {
      clearOutput();
      appendOutput("No help available in this version");
   }
   
   private void addPortRedirect() {
      portRedirectTableModel.addMapping(JLancraft.WAR3_UDP_PORT, JLancraft.WAR3_UDP_PORT);
      int rowIdx = portRedirectTableModel.getRowCount() - 1;
      portRedirectTable.editCellAt(rowIdx, 0);
   }
   
   private void removePortRedirect() {
      portRedirectTableModel.removeMappings(portRedirectTable.getSelectedRows());
   }
   
   private void closeAdvancedSettingsDialog(boolean save) {
      if (save) {
         if (!validateAdvancedSettings())
            return;
         copyAdvancedSettings();
         saveAdvancedSettings();
      }
      advancedSettingsDialog.setVisible(false);
   }
   
   private boolean validateAdvancedSettings() {
      String portStr = udpPortsField.getText();
      String[] portArr = portStr.split(",");
      int port;
      for (String str : portArr) {
         str = str.trim();
         try {
            port = Integer.parseInt(str);
         } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(advancedSettingsDialog, "Invalid UDP port: \"" + str + "\" is not a number", "Error", JOptionPane.ERROR_MESSAGE);
            udpPortsField.requestFocus();
            return false;
         }
         
         if (port <= 0 || port >= 65536) {
            JOptionPane.showMessageDialog(advancedSettingsDialog, "Invalid UDP port: " + port + " is not within the range 1-65535", "Error", JOptionPane.ERROR_MESSAGE);
            udpPortsField.requestFocus();
            return false;
         }
      }
      
      int version;
      String versionStr = gameVersionField.getText();
      try {
         version = Integer.parseInt(versionStr);
      } catch (NumberFormatException e) {
         JOptionPane.showMessageDialog(advancedSettingsDialog, "Invalid game minor version: \"" + versionStr + "\" is not a number", "Error", JOptionPane.ERROR_MESSAGE);
         gameVersionField.requestFocus();
         return false;
      }
      
      return true;
   }
   
   private void copyAdvancedSettings() {
      String[] portStrArray = udpPortsField.getText().split(",");
      udpPorts = new int[portStrArray.length];
      for (int i=0;i<portStrArray.length;i++) {
         udpPorts[i] = Integer.parseInt(portStrArray[i].trim());
      }
      
      gameVersion = Integer.parseInt(gameVersionField.getText());
      
      int numRedirs = portRedirectTableModel.getRowCount();
      portRedirects = new int[numRedirs][2];
      for (int i=0;i<numRedirs;i++) {
         portRedirects[i] = Arrays.copyOf(portRedirectTableModel.getMapping(i), 2);
      }
   }
   
   private void saveSettings() {
                PREFS.put("lastHostname", hostname);

                if (hostnameCombo.getSelectedIndex() != -1)
                    hostnameCombo.removeItemAt(hostnameCombo.getSelectedIndex());

                hostnameCombo.insertItemAt(hostname, 0);
                hostnameCombo.setSelectedIndex(0);

                int hostnameCount = Math.min(hostnameCombo.getItemCount(), MAX_HISTORY);
                PREFS.putInt("hostnameCount", hostnameCount);
                for (int i = 0; i < hostnameCount; i++) {
                    PREFS.put("hostname" + i, (String)hostnameCombo.getItemAt(i));
                }

      saveAdvancedSettings();
   }
   
   private void saveAdvancedSettings() {
      StringBuffer sb = new StringBuffer();
      for (int port : udpPorts) {
         sb.append(port);
         sb.append(',');
      }
      PREFS.put("udpPorts", sb.toString());

      PREFS.putInt("gameVersion", gameVersion);
      
      sb = new StringBuffer();
      for (int[] redir : portRedirects) {
         sb.append(redir[0]);
         sb.append(':');
         sb.append(redir[1]);
         sb.append(',');
      }
      PREFS.put("portRedirects", sb.toString());
   }
   
   private void loadSettings() {
      hostname = PREFS.get("lastHostname", "localhost");
                int hostnameCount = PREFS.getInt("hostnameCount", 0);

                hostnameCombo.removeAllItems();
                for (int i=0;i<hostnameCount;i++) {
                    String currentHost = PREFS.get("hostname" + i, "");
                    if (currentHost.length() > 0)
                        hostnameCombo.addItem(currentHost);
                }

                hostnameCombo.setSelectedItem(hostname);

      // remaining fields will be set in displayAdvancedSettingsDialog()
      
      String[] udpPortStrArray = PREFS.get("udpPorts", "" + JLancraft.WAR3_UDP_PORT).split(",");
      int[] tempUDPPorts = new int[udpPortStrArray.length];
      try {
         for (int i=0;i<tempUDPPorts.length;i++) {
            tempUDPPorts[i] = Integer.parseInt(udpPortStrArray[i].trim());
         }
         udpPorts = tempUDPPorts;
      } catch (NumberFormatException e) {
         // use default for udpPorts
         out.println("[" + Thread.currentThread().getName() + "] Warning: Unable to load UDP Ports setting");
      }
      
      gameVersion = PREFS.getInt("gameVersion", JLancraft.WAR3_DEFAULT_VERSION);
      
      String redirStr = PREFS.get("portRedirects", "");
      if (redirStr.trim().length() > 0) {
         String[] redirStrArray = redirStr.split(",");
         int[][] tempPortRedirects = new int[redirStrArray.length][2];
         try {
            String[] redirPorts;
            for (int i=0;i<tempPortRedirects.length;i++) {
               redirPorts = redirStrArray[i].split(":");
               for (int j=0;j<2;j++) {
                  tempPortRedirects[i][j] = Integer.parseInt(redirPorts[j].trim());
               }
            }
            
            portRedirects = tempPortRedirects;
         } catch (NumberFormatException e) {
            // use default for portRedirects
            out.println("[" + Thread.currentThread().getName() + "] Warning: Unable to load Port Redirects setting");
         } catch (ArrayIndexOutOfBoundsException e) {
            // use default for portRedirects
            out.println("[" + Thread.currentThread().getName() + "] Warning: Unable to load Port Redirects setting");
         }
      }
   }

   private void appendOutput(final String str) {
      Runnable r = new Runnable() {
         public void run() {
            outputArea.append(str);
            outputArea.setCaretPosition(outputArea.getText().length());
         }
      };

      if (SwingUtilities.isEventDispatchThread()) {
         r.run();
      } else {
         SwingUtilities.invokeLater(r);
      }
   }
   
   private void clearOutput() {
      Runnable r = new Runnable() {
         public void run() {
            outputArea.setText("");
         }
      };

      if (SwingUtilities.isEventDispatchThread()) {
         r.run();
      } else {
         SwingUtilities.invokeLater(r);
      }
   }
   
   private class PipeReader implements Runnable {
      private InputStream in;

      public PipeReader(InputStream in) {
         this.in = in;
      }

      public void run() {
         appendOutput("[" + Thread.currentThread().getName() + "] Running...\n");
         
         int len;
         byte[] buf = new byte[4096];

         while (!Thread.currentThread().isInterrupted()) {
            try {
               len = in.read(buf);
            } catch (IOException e) {
               if (e.getMessage() != null && e.getMessage().equals("Write end dead")) {
                  try {
                     Thread.sleep(50);
                  } catch (InterruptedException e2) {
                     break;
                  }
                  continue;
               } else {
                  appendOutput("[" + Thread.currentThread().getName() + "] Error: Received exception while handling output\n");
                  appendOutput("[" + Thread.currentThread().getName() + "] " + e + "\n");
                  appendOutput("[" + Thread.currentThread().getName() + "] Exiting with error\n");
                  return;
               }
            }
            if (len == -1)
               break;
            appendOutput(new String(buf, 0, len));
         }
         appendOutput("[" + Thread.currentThread().getName() + "] Exiting normally\n");
      }
   }
}


Alguém que entenda de java poderia me explicar as partes de packets e as funções que as DUAS partes faz?

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Cara, o code não faz nada demais, ele apenas checa as portas e verifica se tem conexão ou não, e o code debaixo é para desenhar a interface, parabéns pro cara que fez isso tudo manualmente.

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Sim Ultimate.
Mais eu queria saber a parte que fala de proxy, ele faz alguma coisa?
Porque esse software faz com que quando a pessoa tem o jogo Warcraft IIII no seu próprio PC e libera a porta 6112 no modem, ela manda esse programa e o ip dela pras outras pessoas se conectarem, desse jeito o jogo que ela crio LOCALMENTE aparecerá pra ela também.

Lembrando : Quem criou o jogo não precisa abrir nenhum outro programa pra 'hostiar' , só precisa libera a porta 6112.

Queria saber assim, se tem jeito de fazer um servidor desse proxy pra colocar em um dedicado ( porque dedicado não funciona Warcraft , é claro ) e um cliente com o ip do dedicado pra mandar pros jogadores.

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
No code, ele define já as portas que ele quer:

Código:


public static void main(String args[]) {
      JLancraft jlc2 = new JLancraft("localhost", 24, new int[] {6112, 6111});
      jlc2.run();
  }


E depois com outras variáveis ele pega a porta da máquina e a da game e troca elas pela qual ele já definiu:

Máquina:

Código:


 private synchronized void startProxyListener(ServerSocket socket, InetSocketAddress dest) {
      if (Thread.currentThread().isInterrupted())
        return;
     
      int port = socket.getLocalPort();
     
      if (proxyListeners.containsKey(port)) {
        Thread t = proxyListeners.get(port);
        if (t != null && t.isAlive())
            stopProxyListener(port);
      }
     
      Runnable r = new ProxyListener(socket, dest);
      Thread t = new Thread(r, "ProxyListener-" + port + "-" + dest.getPort());
      proxyListeners.put(port, t);
      t.start();
  }


Game:

Código:


 private int getGamePort(byte[] data) {
      int len = data.length;
      int ret = ((data[len - 1] & 0xFF) << 8) | (data[len - 2] & 0xFF);
      return ret;
  }
 
  private void setGamePort(byte[] data, int port) {
      int len = data.length;
      data[len-1] = (byte)((port >> 8) & 0xFF);
      data[len-2] = (byte)(port & 0xFF);
  }
 
  private byte[] getSearchgameData() {

      byte[] ret = {
        (byte)247,              // W3GS_HEADER_CONSTANT
        47,                    // W3GS_SEARCHGAME
        16, 0,                  // total packet length (little-endian)
        80, 88, 51, 87,            // product ID ("W3XP", reversed);
        (byte)gameVersion, 0, 0, 0,  // warcraft minor version (little-endian)
        0, 0, 0, 0,              // unknown
      };
     
      return ret;
  }


E o programa roda em background, porque é java, qualquer programa java irá rodar virtualmente. Pois o java é uma máquina virtual para rodar os aplicativos feito em java.

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Certo, nesse segundo code que você postou , ele mostra os bytes dos games do Warcraft, correto?

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Acredito que seja do game sim, eu não posso afirmar porque eu não sei se realmente é.

Spoiler :


[Tens de ter uma conta e sessão iniciada para poderes visualizar esta imagem]

Onde ele usa para "setar" a porta do game.

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Sim, a parte que você colocou Bytes do game, é ela mesmo.. isso que eu quero saber
Isso é pra mostra o game pras outras pessoa?

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
_Netrunner escreveu:
Sim, a parte que você colocou Bytes do game, é ela mesmo.. isso que eu quero saber
Isso é pra mostra o game pras outras pessoa?


Sim pois ele seta a porta do game pelo byte, com os numeros de porta que ele escolheu.

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
Ah sim, vou tentar fazer o mesmo sistema em delphi..

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
_Netrunner escreveu:
Ah sim, vou tentar fazer o mesmo sistema em delphi..


Lhe desejo boa sorte. ^^

description[Duvida] Conversão Java  EmptyRe: [Duvida] Conversão Java

more_horiz
privacy_tip Permissões neste sub-fórum
Não podes responder a tópicos
power_settings_newInicie sessão para responder