Skip to content

Instantly share code, notes, and snippets.

@aurorapar
Last active October 12, 2018 23:47
Show Gist options
  • Save aurorapar/690c24f12ad8553b57c08190e13e814d to your computer and use it in GitHub Desktop.
Save aurorapar/690c24f12ad8553b57c08190e13e814d to your computer and use it in GitHub Desktop.
ClubsMk2
import java.io.*;
import java.net.*;
import java.lang.*;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
class NetworkDiscovery
{
protected static final int BCAST_PORT = 9050;
protected static final int GAME_PORT = 9060;
protected static final int TIMEOUT = 10000;
protected static final int MAX_ATTEMPTS = 3;
protected static String server;
protected static boolean gameStarted = false;
protected static List<WorkerRunnable> players = new ArrayList<WorkerRunnable>();
protected static TCPConnection TCPServer;
//protected static List<Socket> players = new ArrayList<Socket>();
private static final String[] keywords = {"EXIT", "SERVERCLOSED"};
protected static final ArrayList<String> KEYWORDS = new ArrayList<String>(Arrays.asList(keywords));
protected static GameDef heartbeat;
public static void main(String args[])
{
for(String arg : args)
{
if(arg.equals(args[0]))
{
server = args[0];
}
}
ArrayList<String> deckOne = null;
ArrayList<String> deckTwo = null;
ArrayList<String> deckThree = null;
heartbeat = new GameDef(
false,true,
deckOne, deckTwo, deckThree,
"P1","NA","NA","NA",0,0,0
);
deckOne = new ArrayList<>(Arrays.asList("H3","D10","D2","C13","D4","S9","H7","D5","D8","S6","D3","S4","H4","S8","C5","S7","C4"));
deckTwo = new ArrayList<>(Arrays.asList("D2","S12","C9","C2","D7","C6","H12","H8","H2","C14","S13","H9","S14","C3","H14","D14","C10"));
deckThree = new ArrayList<>(Arrays.asList("C4","D9","S2","D6","H11","C7","H3","C8","D11","D12","C12","S10","S5","H5","S3","H6","S11"));
GameDef test = new GameDef(
false,false,
deckOne, deckTwo, deckThree,
"P1","NA","NA","NA",0,0,0
);
try
{
// Returns whether or not a server was found
if(server == null)
server = findGame();
switch(server)
{
// If a keyword is encountered, perform the following
case("EXIT"):
System.exit(0);
// If a keyword is encountered, perform the following
case("SERVERCLOSED"):
{
System.out.println("The server closed the game. Thanks for playing!");
}
// If no keyword is encountered, then attmept to connect
default:
if(!KEYWORDS.contains(server))
{
if(server.length() > 1)
{
// Start TCP connection here
server = server.replaceAll("\\/", "");
System.out.println("Connecting to " + server);
Client player = new Client(InetAddress.getByName(server));
int sent = 0;
while(player.connected())
{
// For whatever reason this will not break unless we're constantly printing something
// thread it or print something
if(sent<3)
{
System.out.println("Sending obj to server");
player.sendMessage(test);
sent++;
}
}
System.out.println("Client no longer connected " + player.socket.getInetAddress());
return;
}
}
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
// If no server was found, attempt to host a server
if(server.length() < 1)
{
// The server that can allow client connections
TCPServer = new TCPConnection(NetworkDiscovery.GAME_PORT+1);
new Thread(TCPServer).start();
// Lobby listens for clients trying to find a server and responds with a few keywords not listed above
// on an appropriate keyword, the client either disconnects or connects
Lobby lobby = new Lobby();
new Thread(lobby).start();
/*
LOBBYEXISTS
attempt a connection to existing server
CONNECTIONEXISTS
don't connect because you already are on a different client
*/
while(!TCPServer.isStopped())
{
// Just listen for connections
}
// Start game?
gameStarted = true;
lobby.close();
System.out.println("TCPServer Stopped");
// Players is a list of the server connections
// use the appropriate method to send a message to the player connected
for(WorkerRunnable serverConnection : players)
{
// Dont send strings, only GameDefs
//serverConnection.sendMessage("Hi! Welcome to the game, " + serverConnection.clientSocket.getInetAddress().toString());
}
}
return;
}
public static String findGame() throws IOException
{
InetAddress clientAddress = InetAddress.getLocalHost();
System.out.println("Client addr: " + clientAddress.toString());
InetAddress BCAST_ADDR = InetAddress.getByName("255.255.255.255");
// Try and find a server...
System.out.println("Finding lobbies");
DatagramSocket findLobby = new DatagramSocket();
int attempts = 0;
while(attempts < MAX_ATTEMPTS)
{
try
{
findLobby.setBroadcast(true);
findLobby.setSoTimeout(TIMEOUT/2);
byte[] msg = "FINDLOBBY".getBytes();
DatagramPacket packet = new DatagramPacket(msg, msg.length, InetAddress.getByName("255.255.255.255"), BCAST_PORT);
findLobby.send(packet);
byte[] byteData = new byte[512];
String response = "";
DatagramPacket receivedPacket = new DatagramPacket(byteData, byteData.length);
findLobby.receive(receivedPacket);
response = new String(receivedPacket.getData(), StandardCharsets.US_ASCII);
response = response.substring(0,receivedPacket.getLength());
switch(response)
{
case("LOBBYEXISTS"):
{
return receivedPacket.getAddress().toString().replaceAll("\\/", "");
}
case("CONNECTIONEXISTS"):
{
System.out.println("You are already connected to a game");
return "EXIT";
}
default:
{
System.out.println("bad response of '" + response + "'");
}
}
System.out.println("Game closed, exiting");
return "EXIT";
}
catch(Exception e)
{
attempts++;
System.out.println("No lobby found...");
}
}
findLobby.close();
return "";
}
public static String getBroadcastAddress(String address)
{
String bcastAddress = address;
int count = 0;
do
{
for (int i = 0; i < bcastAddress.length(); i++)
{
Character testChar = bcastAddress.charAt(i);
if (testChar.equals(".")) {
count++;
}
}
bcastAddress = bcastAddress.substring(0, bcastAddress.length() - 2);
}
while (count > 2);
bcastAddress = bcastAddress + ".255";
return bcastAddress;
}
public static void send(String response, DatagramSocket broadcastServer, DatagramPacket receivedPacket)
{
try
{
byte[] sendData = new byte[512];
sendData = response.getBytes(StandardCharsets.US_ASCII);
InetAddress IP = receivedPacket.getAddress();
DatagramPacket packetToSend = new DatagramPacket(
sendData,
sendData.length,
IP,
receivedPacket.getPort()
);
System.out.println("Client is attempting to connect" + receivedPacket.getAddress());
broadcastServer.send(packetToSend);
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
public static void close(Socket socket)
{
try
{
socket.close();
}
catch (Exception e)
{
System.out.println("Could not close conenction");
}
}
public static void trackConnection(WorkerRunnable connection)
{
players.add(connection);
System.out.println("Player connected! " + connection.getPlayer());
if(players.size() >= 2)
{
System.out.println("Enough players found!");
getRoster();
while(!TCPServer.isStopped())
{
TCPServer.stop();
}
}
}
public static void removeConnection(WorkerRunnable connection)
{
try
{
System.out.println("removing player " + connection.getPlayer());
System.out.println("\nCurrent Roster");
getRoster();
players.remove(players.indexOf(connection));
System.out.println("Player disconnected; " + connection.getPlayer());
}
catch(Exception e)
{
}
finally
{
if(gameStarted)
{
System.out.println("Closing game");
System.exit(0);
}
}
}
public static void readMessage(String message)
{
// do something with a message
System.out.println(message);
}
public static void getRoster()
{
if(players.size() > 0)
{
System.out.print("Current player roster:");
for(int i = 0; i < players.size(); i++)
{
System.out.print("\n\t" + players.get(i).getPlayer());
}
System.out.println();
return;
}
System.out.println("No players in roster");
}
public static void dummy(String something)
{
return;
}
public static GameDef heartbeat()
{
return heartbeat;
}
}
import java.io.*;
import java.util.*;
import java.net.*;
/**
*/
class WorkerRunnable implements Runnable
{
protected Socket clientSocket = null;
protected List<GameDef> outboundMessages = new ArrayList<GameDef>();
protected boolean connected = false;
public WorkerRunnable(Socket clientSocket) {
this.clientSocket = clientSocket;
System.out.println("Connected to " + clientSocket.getInetAddress());
this.connected = true;
NetworkDiscovery.trackConnection(this);
}
public void run()
{
ObjectInputStream inStream = null;
ObjectOutputStream outputStream = null;
try
{
inStream = new ObjectInputStream(clientSocket.getInputStream());
outputStream = new ObjectOutputStream(this.clientSocket.getOutputStream());
}
catch(Exception e)
{
}
while(this.connected)
{
try
{
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
long time = System.currentTimeMillis();
if(!this.outboundMessages.isEmpty())
{
GameDef gameState = this.outboundMessages.remove(0);
outputStream.writeObject(gameState);
outputStream.flush();
}
clientSocket.setSoTimeout(1);
try
{
GameDef gameState = (GameDef) inStream.readObject();
System.out.println(gameState.toString());
}
catch (SocketTimeoutException e)
{
continue;
}
catch (SocketException e)
{
System.out.println("Client disconnected");
NetworkDiscovery.removeConnection(this);
e.printStackTrace();
return;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
finally
{
clientSocket.setSoTimeout(NetworkDiscovery.TIMEOUT);
}
}
catch (IOException e)
{
//report exception somewhere.
e.printStackTrace();
}
}
System.out.println("Closing worker");
return;
}
public void close()
{
System.out.println("Closing connection");
this.connected = false;
}
public void sendMessage(GameDef gameState)
{
this.outboundMessages.add(gameState);
}
public String getPlayer()
{
return this.clientSocket.getInetAddress().toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment