| @@ -1,6 +1,6 @@ | ||
| package common.networking; | ||
|
|
||
| public class UpdateFooter { | ||
| private long youAre; | ||
|
|
||
| public long getYouAre() { | ||
| @@ -1,8 +1,11 @@ | ||
| package main; | ||
|
|
||
| import client.GUI; | ||
|
|
||
| public class Blerg { | ||
|
|
||
| public static void main(String[] args) { | ||
| System.out.println("Initializing Client"); | ||
| GUI.main(args); | ||
| } | ||
| } |
| @@ -0,0 +1,26 @@ | ||
| package main; | ||
|
|
||
| import java.util.concurrent.ScheduledExecutorService; | ||
| import java.util.concurrent.ScheduledThreadPoolExecutor; | ||
|
|
||
| import org.codehaus.jackson.map.ObjectMapper; | ||
| import org.codehaus.jackson.map.ObjectReader; | ||
|
|
||
| import common.ControlState; | ||
| import server.ConnectionManager; | ||
| import server.Game; | ||
|
|
||
| public class BlergServer { | ||
| public static void main(String args[]) { | ||
| System.out.println("Initializing server"); | ||
| ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(4); | ||
| ObjectMapper mapper = new ObjectMapper(); | ||
|
|
||
| Game game = new Game(executor); | ||
| ConnectionManager connectionManager = new ConnectionManager(mapper, game, executor); | ||
|
|
||
| game.startGame(); | ||
| connectionManager.beginAcceptingConnections(); | ||
|
|
||
| } | ||
| } |
| @@ -0,0 +1,77 @@ | ||
| package server; | ||
|
|
||
| import java.io.InputStream; | ||
| import java.io.OutputStream; | ||
| import java.net.Socket; | ||
| import java.util.concurrent.ScheduledExecutorService; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| import org.codehaus.jackson.map.ObjectReader; | ||
|
|
||
| import common.ControlState; | ||
| import common.networking.UpdateFooter; | ||
|
|
||
| public class Client { | ||
| private Socket socket; | ||
| private Game game; | ||
| private NetworkPacketCreator packetCreator; | ||
| private ObjectReader controlStateReader; | ||
|
|
||
| private volatile boolean isConnected = true; | ||
| private long id; | ||
| private Player player; | ||
|
|
||
| public Client(Socket socket, Game game, ScheduledExecutorService executor, NetworkPacketCreator packetCreator, ObjectReader controlStateReader) throws Exception { | ||
| this.socket = socket; | ||
| this.game = game; | ||
| this.packetCreator = packetCreator; | ||
| this.controlStateReader = controlStateReader; | ||
| this.id = game.getUniqueIdentifier(); | ||
| player = new Player(id); | ||
| game.addEntity(player); | ||
|
|
||
| executor.scheduleWithFixedDelay(() -> sendGameState(), 100, 100, TimeUnit.MILLISECONDS); | ||
| executor.scheduleWithFixedDelay(() -> getControlState(), 100, 100, TimeUnit.MILLISECONDS); | ||
| } | ||
|
|
||
| private void getControlState() { | ||
| if (socket.isClosed()) { | ||
| isConnected = false; | ||
| } | ||
| if (isConnected) { | ||
| try { | ||
| InputStream is = socket.getInputStream(); | ||
| byte[] bytes = new byte[is.available()]; | ||
| is.read(bytes); | ||
| String input = new String(bytes); | ||
| for (String jsonControlState : input.split("\0")) { | ||
| if (jsonControlState.contains("{")) { | ||
| ControlState state = controlStateReader.readValue(jsonControlState); | ||
| player.setControlState(state); | ||
| } | ||
| } | ||
| } catch (Exception ex) { | ||
| ex.printStackTrace(); | ||
| throw new RuntimeException(ex); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void sendGameState() { | ||
| if (socket.isClosed()) { | ||
| isConnected = false; | ||
| } | ||
| if (isConnected) { | ||
| try { | ||
| UpdateFooter header = new UpdateFooter(); | ||
| header.setYouAre(id); | ||
| String toSend = packetCreator.getPacket(header); | ||
| OutputStream os = socket.getOutputStream(); | ||
| os.write(toSend.getBytes()); | ||
| } catch (Exception ex) { | ||
| System.out.println("Caught exception while sending status to client: " + ex.getMessage()); | ||
| isConnected = false; | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,52 @@ | ||
| package server; | ||
|
|
||
| import java.net.ServerSocket; | ||
| import java.net.Socket; | ||
| import java.net.SocketTimeoutException; | ||
| import java.util.concurrent.ScheduledExecutorService; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| import org.codehaus.jackson.map.ObjectMapper; | ||
|
|
||
| import common.ControlState; | ||
|
|
||
| public class ConnectionManager { | ||
|
|
||
| private ObjectMapper mapper; | ||
| private Game game; | ||
| private ScheduledExecutorService executor; | ||
| private ServerSocket serverSocket; | ||
| private NetworkPacketCreator networkPacketCreator; | ||
|
|
||
| public ConnectionManager(ObjectMapper mapper, Game game, ScheduledExecutorService executor) { | ||
| this.mapper = mapper; | ||
| this.game = game; | ||
| this.executor = executor; | ||
| this.networkPacketCreator = new NetworkPacketCreator(mapper, game, executor); | ||
| } | ||
|
|
||
| public void beginAcceptingConnections() { | ||
|
|
||
| try { | ||
| serverSocket = new ServerSocket(50805); | ||
| executor.scheduleWithFixedDelay(() -> acceptPendingConnection(), 100, 100, TimeUnit.MILLISECONDS); | ||
| } catch (Exception ex) { | ||
| System.out.println("Exception during network initialization: " + ex.getMessage()); | ||
| throw new RuntimeException(ex); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| private void acceptPendingConnection() { | ||
| try { | ||
| Socket sock = serverSocket.accept(); | ||
| new Client(sock, game, executor, networkPacketCreator, mapper.reader(ControlState.class)); | ||
| } catch (SocketTimeoutException ex) { | ||
| System.out.println("Socket accept timed out"); | ||
| } catch (Exception ex) { | ||
| System.out.println("Caught exception accepting new client: " + ex.getMessage()); | ||
| ex.printStackTrace(); | ||
| } | ||
| } | ||
|
|
||
| } |
| @@ -0,0 +1,51 @@ | ||
| package server; | ||
|
|
||
| import java.util.List; | ||
| import java.util.concurrent.ScheduledExecutorService; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
| import org.codehaus.jackson.map.ObjectMapper; | ||
| import org.codehaus.jackson.map.ObjectWriter; | ||
|
|
||
| import common.Entity; | ||
| import common.networking.UpdateFooter; | ||
|
|
||
| public class NetworkPacketCreator { | ||
| private Game game; | ||
| private volatile String latestEntityTransmission = ""; | ||
| private ObjectWriter entityWriter; | ||
| private ObjectWriter footerWriter; | ||
|
|
||
| public NetworkPacketCreator(ObjectMapper mapper, Game game, ScheduledExecutorService executor) { | ||
| this.game = game; | ||
| this.entityWriter = mapper.writerWithType(Entity.class); | ||
| this.footerWriter = mapper.writerWithType(UpdateFooter.class); | ||
| executor.scheduleAtFixedRate(() -> updateEntityTransmissionString(), 100, 100, TimeUnit.MILLISECONDS); | ||
| } | ||
|
|
||
| public String getPacket(UpdateFooter header) { | ||
| String footerString; | ||
| try { | ||
| footerString = footerWriter.writeValueAsString(header); | ||
| } catch (Exception e) { | ||
| System.out.println("Exception caught in generation of transmission string"); | ||
| throw new RuntimeException(e); | ||
| } | ||
| return latestEntityTransmission + footerString; | ||
| } | ||
|
|
||
| private void updateEntityTransmissionString() { | ||
| List<Entity> entities = game.getEntities(); | ||
| StringBuilder sb = new StringBuilder(); | ||
| for (Entity entity : entities) { | ||
| try { | ||
| sb.append(entityWriter.writeValueAsString(entity)); | ||
| } catch (Exception e) { | ||
| System.out.println("Exception caught in generation of transmission string"); | ||
| throw new RuntimeException(e); | ||
| } | ||
| sb.append("\0"); | ||
| } | ||
| latestEntityTransmission = sb.toString(); | ||
| } | ||
| } |
| @@ -0,0 +1,37 @@ | ||
| package server; | ||
|
|
||
| import common.ControlState; | ||
| import common.Entity; | ||
|
|
||
| public class Player extends Entity { | ||
| private volatile ControlState controlState = new ControlState(); | ||
|
|
||
| public Player(long id) { | ||
| super( id, | ||
| Math.random() * 800, | ||
| Math.random() * 800, | ||
| 0, | ||
| 0, | ||
| 10, | ||
| (int) (Math.random() * 128 + 127), | ||
| (int) (Math.random() * 128 + 127), | ||
| (int) (Math.random() * 128 + 127), | ||
| EntityType.PLAYER); | ||
| } | ||
|
|
||
| public void update() { | ||
| double yScale = Math.sin(controlState.getDirection()); | ||
| double xScale = Math.cos(controlState.getDirection()); | ||
| double yChange = yScale * controlState.getMagnitude(); | ||
| double xChange = xScale * controlState.getMagnitude(); | ||
| yVelocity += yChange; | ||
| xVelocity += xChange; | ||
| yVelocity *= .8; | ||
| xVelocity *= .8; | ||
| super.update(); | ||
| } | ||
|
|
||
| public void setControlState(ControlState controlState) { | ||
| this.controlState = controlState; | ||
| } | ||
| } |