Code
My handy dandy Socket subclass
import java.nio.*;
import java.io.*;
import java.net.*;
public class SocketAction extends Thread {
private DataInputStream inStream = null;
protected PrintStream outStream = null;
protected ObjectOutput out = null;
private Socket socket = null;
private String initMessage = null;
public SocketAction(Socket sock, String initMessage) {
this(sock);
initMessage = null;
}
public SocketAction(Socket sock) {
super("SocketAction");
try {
inStream = new DataInputStream(new
BufferedInputStream(sock.getInputStream(), 64652));
outStream = new PrintStream(new
BufferedOutputStream(sock.getOutputStream(), 64652), true);
socket = sock;
out = new ObjectOutputStream(outStream);
}
catch (IOException e) {
System.out.println("Couldn't initialize SocketAction: " + e);
System.exit(1);
}
}
public String getInitMessage() {
return initMessage;
}
public void send(String s) {
outStream.println(s);
}
public void send(Object o) throws IOException {
out.writeObject(o);
}
public String receive() throws IOException {
return inStream.readLine();
}
public boolean isConnected() {
return ((inStream != null) && (outStream != null) && (socket != null));
}
protected void finalize () {
if (socket != null) {
try {
socket.close();
}
catch (IOException e) {
System.out.println("Couldn't close socket: " + e);
}
socket = null;
}
}
public void closeConnections() {
try {
socket.close();
socket = null;
}
catch (IOException e) {
System.out.println("Couldn't close socket: " + e);
}
}
}
GameManager
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.midi.*;
import java.io.*;
import javax.sound.sampled.*;
import java.text.DecimalFormat;
import java.net.*;
import java.nio.*;
public class GameManager extends GameCanvas {
public static GameManager INSTANCE = new GameManager();
public static final int PORT = 64652; //spells ninja on a phone ^^
public static final String ADDR = "localhost";
private SocketAction host;
private int fps;
private SpriteManager sm = SpriteManager.INSTANCE;
private ClientListener cl = ClientListener.INSTANCE;
private HostListener hl;
private String lastMessage;
public void init(String type) {
try {
if (type.equals("host")) {
ClientListener cl = new ClientListener();
host = new SocketAction(new Socket(ADDR, PORT));
}
else if (type.equals("client")) {
host = new SocketAction(new Socket(ADDR, PORT));
sm = null;
cl = null;
}
hl = new HostListener(host);
}
catch (IOException e) {
System.err.println(e);
}
}
public synchronized void setLastMessage(String message) {
lastMessage = message;
}
public void Update(long elapsedTime) {
cl.sendString("beep");
if (elapsedTime > 0) {
fps = (int) (1000L / elapsedTime);
}
try {
if (cl != null) {
cl.sendObject(sm);
}
}
catch (IOException e) {
System.err.println(e);
}
synchronized (lastMessage) {
System.out.println("Last Message: " + lastMessage);
}
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Render game here
g.setColor(Color.GREEN);
g.fillRect(0, 0, getWidth(), getHeight());
// Display data
g.setColor(Color.WHITE);
g.setFont(new Font("Dialog", Font.PLAIN, 18));
g.drawString("FPS: " + fps, getWidth() - 90, getHeight() - 10);
}
}
Thingy that listens for clients trying to connect and adds them to a list
import java.nio.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.*;
public class ClientAdder extends Thread {
private ServerSocket serv;
private ClientListener cl;
public ClientAdder(ServerSocket serv, ClientListener c) {
this.serv = serv;
cl = c;
}
public void run() {
while (true) {
try {
SocketAction sock = new SocketAction(serv.accept());
cl.addPlayer(new Player(sock, new Sprite(Color.red)));
}
catch (IOException e) {
System.err.println(e);
}
}
}
}
Thingy that listens to the clients for input information
import java.nio.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.awt.*;
public class ClientListener extends Thread {
public static ClientListener INSTANCE = new ClientListener();
private ClientAdder ca;
private ServerSocket serv;
private LinkedList<Player> players;
public ClientListener() {
try {
serv = new ServerSocket(GameManager.PORT);
ca = new ClientAdder(serv, this);
ca.start();
}
catch (IOException e) {
System.err.println(e);
}
players = new LinkedList<Player>();
start();
}
public void run() {
while (true) {
try {
synchronized (players) {
for (Player p : players) {
String action = p.getSock().receive();
if (action != null) {
p.addAction(action);
}
}
}
Thread.sleep(10);
}
catch (IOException e) {
System.err.println(e);
}
catch (InterruptedException e) {
System.err.println(e);
}
}
}
public synchronized void addPlayer(Player p) {
players.add(p);
}
public synchronized void sendString(String s) {
for (Player p : players) {
p.getSock().send(s);
}
}
public synchronized void sendObject(Object o) throws IOException {
for (Player p : players) {
p.getSock().send(o);
}
}
}
My “player” class which i really have no idea where I am going with
import java.util.*;
public class Player {
private LinkedList<String> actionsLine;
private Sprite sprite;
private SocketAction sock;
public Player(SocketAction sock, Sprite sprite) {
actionsLine = new LinkedList<String>();
this.sock = sock;
this.sprite = sprite;
}
public SocketAction getSock() {
return sock;
}
public Sprite getSprite() {
return sprite;
}
public void addAction(String s) {
actionsLine.add(s);
}
public String proccessFirstAction() {
String action = actionsLine.get(0);
actionsLine.remove(0);
return action;
}
}
The Idea I came up with was to have the client and host applicatins differ by simply having a socket point either to another machine or to itself. If certain variables aren’t null then it gets input from clients and then sends it out, treating itself as a client which I know is stupid but I couldn’t think of any other way.
Anyway if I run it with the arg “host” it makes a clientListener and clientAdder which hold the ServerSocket. In the init I attatch a socket to itself because I am a genius. In the update method I send the message “beep” to all clients. The clients, the only one is the host itself, is recieving “q~beep”. Also “sr” is being sent sometime between the init method and the first update.
Feel free to point me to a good reference (which I havn’t managed to find) for good ways to organize this.