From ff03812ce4ccdfb09fd5ac464ff1d993ccc16cb0 Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Wed, 11 May 2016 13:41:49 +0200 Subject: Implement server client registration --- src/ch/epfl/xblast/server/Server.java | 83 +++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/src/ch/epfl/xblast/server/Server.java b/src/ch/epfl/xblast/server/Server.java index 76f332e..10d5a85 100644 --- a/src/ch/epfl/xblast/server/Server.java +++ b/src/ch/epfl/xblast/server/Server.java @@ -1,9 +1,16 @@ package ch.epfl.xblast.server; +import ch.epfl.xblast.Lists; +import ch.epfl.xblast.PlayerAction; import ch.epfl.xblast.PlayerID; +import java.io.IOException; import java.net.InetSocketAddress; -import java.util.Optional; +import java.net.SocketAddress; +import java.net.StandardProtocolFamily; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; +import java.util.*; /** * The Server class. @@ -13,18 +20,86 @@ import java.util.Optional; public class Server { public static final int DEFAULT_PORT = 2016; - public static final int DEFAULT_EXPECTED_CLIENTS = PlayerID.values().length; + private static final int DEFAULT_EXPECTED_CLIENTS = PlayerID.values().length; + + private static InetSocketAddress listeningInterface(String host, int port) { + if (Objects.isNull(host)) + return new InetSocketAddress(port); + else + return new InetSocketAddress(host, port); + } + + private static DatagramChannel openChannel(InetSocketAddress iface) { + try { + DatagramChannel chan = DatagramChannel.open(StandardProtocolFamily.INET); + chan.bind(iface); + return chan; + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + return null; + } + } + + private static Optional> receiveAction(DatagramChannel chan, boolean block) { + try { + ByteBuffer buf = ByteBuffer.allocate(1); + chan.configureBlocking(block); + SocketAddress client = chan.receive(buf); + PlayerAction action = PlayerAction.fromByte(buf.get(0)); + return Optional.of(new AbstractMap.SimpleImmutableEntry<>(client, action)); + } catch (IOException | IllegalArgumentException e) { + return Optional.empty(); + } + } + + private static Map.Entry acceptAction(DatagramChannel chan) { + Optional> action; + + do { + action = receiveAction(chan, true); + } while (!action.isPresent()); + + return action.get(); + } + + private static SocketAddress acceptRegistration(DatagramChannel chan) { + Map.Entry clientAction; + + do { + clientAction = acceptAction(chan); + } while (clientAction.getValue() != PlayerAction.JOIN_GAME); + + return clientAction.getKey(); + } + + private static List acceptRegistrations(DatagramChannel chan, int registrations) { + List clients = new ArrayList<>(registrations); + + while (clients.size() < registrations) { + SocketAddress client = acceptRegistration(chan); + if (!clients.contains(client)) + clients.add(client); + } + + return Collections.unmodifiableList(clients); + } private final InetSocketAddress iface; private final int expectedClients; + private Map registeredClients; public Server(String iface, Integer port, Integer expectedClients) { - this.iface = new InetSocketAddress(iface, Optional.ofNullable(port).orElse(DEFAULT_PORT)); + this.iface = listeningInterface(iface, Optional.ofNullable(port).orElse(DEFAULT_PORT)); this.expectedClients = Optional.ofNullable(expectedClients).orElse(DEFAULT_EXPECTED_CLIENTS); } public void run() { - // TODO + DatagramChannel chan = openChannel(this.iface); + List clients = acceptRegistrations(chan, this.expectedClients); + this.registeredClients = Lists.linearAdjustedMap(clients, Arrays.asList(PlayerID.values())); + + System.out.println(this.registeredClients); } } -- cgit v1.2.3