diff options
-rw-r--r-- | src/ch/epfl/xblast/server/Main.java | 5 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Server.java | 125 |
2 files changed, 128 insertions, 2 deletions
diff --git a/src/ch/epfl/xblast/server/Main.java b/src/ch/epfl/xblast/server/Main.java index 98bbb3d..aff499b 100644 --- a/src/ch/epfl/xblast/server/Main.java +++ b/src/ch/epfl/xblast/server/Main.java | |||
@@ -13,6 +13,11 @@ public final class Main { | |||
13 | // Static class | 13 | // Static class |
14 | } | 14 | } |
15 | 15 | ||
16 | /** | ||
17 | * Starts a new server. | ||
18 | * | ||
19 | * @param args arguments given to the server (i.e. number of players required for the game to start) | ||
20 | */ | ||
16 | public static void main(String[] args) { | 21 | public static void main(String[] args) { |
17 | Integer expectedClients = ArgumentChecker.parseIntOrNull(ArgumentChecker.getOrNull(args, 0)); | 22 | Integer expectedClients = ArgumentChecker.parseIntOrNull(ArgumentChecker.getOrNull(args, 0)); |
18 | String iface = ArgumentChecker.getOrNull(args, 1); | 23 | String iface = ArgumentChecker.getOrNull(args, 1); |
diff --git a/src/ch/epfl/xblast/server/Server.java b/src/ch/epfl/xblast/server/Server.java index 8a4b09b..015d771 100644 --- a/src/ch/epfl/xblast/server/Server.java +++ b/src/ch/epfl/xblast/server/Server.java | |||
@@ -21,14 +21,29 @@ import java.util.*; | |||
21 | */ | 21 | */ |
22 | public class Server { | 22 | public class Server { |
23 | 23 | ||
24 | public static final int DEFAULT_PORT = 2016; | 24 | /** |
25 | * Default parameters of the server. | ||
26 | */ | ||
25 | private static final long REFRESH_RATE = (long) (50 * 1E6); // nanosecond | 27 | private static final long REFRESH_RATE = (long) (50 * 1E6); // nanosecond |
26 | |||
27 | private static final int DEFAULT_EXPECTED_CLIENTS = PlayerID.values().length; | 28 | private static final int DEFAULT_EXPECTED_CLIENTS = PlayerID.values().length; |
29 | public static final int DEFAULT_PORT = 2016; | ||
30 | |||
31 | /** | ||
32 | * ID of an observer. | ||
33 | */ | ||
28 | public static final byte OBSERVER = -1; | 34 | public static final byte OBSERVER = -1; |
29 | 35 | ||
36 | /** | ||
37 | * A Channel. | ||
38 | */ | ||
30 | private static class Channel { | 39 | private static class Channel { |
31 | 40 | ||
41 | /** | ||
42 | * Transform a list of bytes to an array of bytes. | ||
43 | * | ||
44 | * @param l the given list of bytes | ||
45 | * @return the array built from the given list | ||
46 | */ | ||
32 | private static byte[] toByteArray(List<Byte> l) { | 47 | private static byte[] toByteArray(List<Byte> l) { |
33 | byte[] arr = new byte[l.size()]; | 48 | byte[] arr = new byte[l.size()]; |
34 | 49 | ||
@@ -38,6 +53,13 @@ public class Server { | |||
38 | return arr; | 53 | return arr; |
39 | } | 54 | } |
40 | 55 | ||
56 | /** | ||
57 | * Create the socket which will be listened. | ||
58 | * | ||
59 | * @param host hostname | ||
60 | * @param port port to be listened | ||
61 | * @return the socket build from the given params | ||
62 | */ | ||
41 | private static InetSocketAddress listeningInterface(String host, int port) { | 63 | private static InetSocketAddress listeningInterface(String host, int port) { |
42 | if (Objects.isNull(host)) | 64 | if (Objects.isNull(host)) |
43 | return new InetSocketAddress(port); | 65 | return new InetSocketAddress(port); |
@@ -45,6 +67,12 @@ public class Server { | |||
45 | return new InetSocketAddress(host, port); | 67 | return new InetSocketAddress(host, port); |
46 | } | 68 | } |
47 | 69 | ||
70 | /** | ||
71 | * Open a UDP channel. | ||
72 | * | ||
73 | * @param iface listened socket | ||
74 | * @return a UDP channel | ||
75 | */ | ||
48 | private static DatagramChannel openChannel(InetSocketAddress iface) { | 76 | private static DatagramChannel openChannel(InetSocketAddress iface) { |
49 | try { | 77 | try { |
50 | DatagramChannel chan = DatagramChannel.open(StandardProtocolFamily.INET); | 78 | DatagramChannel chan = DatagramChannel.open(StandardProtocolFamily.INET); |
@@ -57,16 +85,33 @@ public class Server { | |||
57 | } | 85 | } |
58 | } | 86 | } |
59 | 87 | ||
88 | /** | ||
89 | * The UDP communication channel. | ||
90 | */ | ||
60 | private final DatagramChannel channel; | 91 | private final DatagramChannel channel; |
61 | 92 | ||
93 | /** | ||
94 | * Instantiates a new Channel. | ||
95 | * | ||
96 | * @param iface listened socket | ||
97 | */ | ||
62 | Channel(InetSocketAddress iface) { | 98 | Channel(InetSocketAddress iface) { |
63 | this.channel = openChannel(iface); | 99 | this.channel = openChannel(iface); |
64 | } | 100 | } |
65 | 101 | ||
102 | /** | ||
103 | * Instantiates a new Channel. | ||
104 | * | ||
105 | * @param host hostname | ||
106 | * @param port port to be listened | ||
107 | */ | ||
66 | Channel(String host, Integer port) { | 108 | Channel(String host, Integer port) { |
67 | this(listeningInterface(host, Optional.ofNullable(port).orElse(DEFAULT_PORT))); | 109 | this(listeningInterface(host, Optional.ofNullable(port).orElse(DEFAULT_PORT))); |
68 | } | 110 | } |
69 | 111 | ||
112 | /** | ||
113 | * Close the channel. | ||
114 | */ | ||
70 | void closeChannel() { | 115 | void closeChannel() { |
71 | try { | 116 | try { |
72 | this.channel.close(); | 117 | this.channel.close(); |
@@ -75,6 +120,12 @@ public class Server { | |||
75 | } | 120 | } |
76 | } | 121 | } |
77 | 122 | ||
123 | /** | ||
124 | * Accept the registration of a new client. | ||
125 | * | ||
126 | * @param registrations | ||
127 | * @return a list of the clients. | ||
128 | */ | ||
78 | List<SocketAddress> acceptRegistrations(int registrations) { | 129 | List<SocketAddress> acceptRegistrations(int registrations) { |
79 | List<SocketAddress> clients = new ArrayList<>(registrations); | 130 | List<SocketAddress> clients = new ArrayList<>(registrations); |
80 | 131 | ||
@@ -87,6 +138,11 @@ public class Server { | |||
87 | return Collections.unmodifiableList(clients); | 138 | return Collections.unmodifiableList(clients); |
88 | } | 139 | } |
89 | 140 | ||
141 | /** | ||
142 | * Collect actions from the players. | ||
143 | * | ||
144 | * @return a list map containing the actions related to each player | ||
145 | */ | ||
90 | Map<SocketAddress, PlayerAction> collectActions() { | 146 | Map<SocketAddress, PlayerAction> collectActions() { |
91 | Map<SocketAddress, PlayerAction> actions = new HashMap<>(); | 147 | Map<SocketAddress, PlayerAction> actions = new HashMap<>(); |
92 | Optional<Map.Entry<SocketAddress, PlayerAction>> action; | 148 | Optional<Map.Entry<SocketAddress, PlayerAction>> action; |
@@ -100,6 +156,12 @@ public class Server { | |||
100 | return Collections.unmodifiableMap(actions); | 156 | return Collections.unmodifiableMap(actions); |
101 | } | 157 | } |
102 | 158 | ||
159 | /** | ||
160 | * Send data through the socket. | ||
161 | * | ||
162 | * @param content data to be send | ||
163 | * @param dst recepient of the data | ||
164 | */ | ||
103 | void send(List<Byte> content, SocketAddress dst) { | 165 | void send(List<Byte> content, SocketAddress dst) { |
104 | try { | 166 | try { |
105 | ByteBuffer buf = ByteBuffer.wrap(toByteArray(content)); | 167 | ByteBuffer buf = ByteBuffer.wrap(toByteArray(content)); |
@@ -109,6 +171,12 @@ public class Server { | |||
109 | } | 171 | } |
110 | } | 172 | } |
111 | 173 | ||
174 | /** | ||
175 | * Receive a Byte from the socket. | ||
176 | * | ||
177 | * @param block | ||
178 | * @return an Optional containing the received data | ||
179 | */ | ||
112 | private Optional<Map.Entry<SocketAddress, Byte>> receiveByte(boolean block) { | 180 | private Optional<Map.Entry<SocketAddress, Byte>> receiveByte(boolean block) { |
113 | try { | 181 | try { |
114 | ByteBuffer buf = ByteBuffer.allocate(1); | 182 | ByteBuffer buf = ByteBuffer.allocate(1); |
@@ -124,6 +192,12 @@ public class Server { | |||
124 | } | 192 | } |
125 | } | 193 | } |
126 | 194 | ||
195 | /** | ||
196 | * Receive a player action from the socket. | ||
197 | * | ||
198 | * @param block | ||
199 | * @return an Optional containing the received player action | ||
200 | */ | ||
127 | private Optional<Map.Entry<SocketAddress, PlayerAction>> receiveAction(boolean block) { | 201 | private Optional<Map.Entry<SocketAddress, PlayerAction>> receiveAction(boolean block) { |
128 | try { | 202 | try { |
129 | Map.Entry<SocketAddress, Byte> actionByte = this.receiveByte(block).get(); | 203 | Map.Entry<SocketAddress, Byte> actionByte = this.receiveByte(block).get(); |
@@ -134,6 +208,11 @@ public class Server { | |||
134 | } | 208 | } |
135 | } | 209 | } |
136 | 210 | ||
211 | /** | ||
212 | * Accept an action from the socket. | ||
213 | * | ||
214 | * @return the accepted action | ||
215 | */ | ||
137 | private Map.Entry<SocketAddress, PlayerAction> acceptAction() { | 216 | private Map.Entry<SocketAddress, PlayerAction> acceptAction() { |
138 | Optional<Map.Entry<SocketAddress, PlayerAction>> action; | 217 | Optional<Map.Entry<SocketAddress, PlayerAction>> action; |
139 | 218 | ||
@@ -144,6 +223,11 @@ public class Server { | |||
144 | return action.get(); | 223 | return action.get(); |
145 | } | 224 | } |
146 | 225 | ||
226 | /** | ||
227 | * Accept the registration of a player | ||
228 | * | ||
229 | * @return the address of the new player | ||
230 | */ | ||
147 | private SocketAddress acceptRegistration() { | 231 | private SocketAddress acceptRegistration() { |
148 | Map.Entry<SocketAddress, PlayerAction> clientAction; | 232 | Map.Entry<SocketAddress, PlayerAction> clientAction; |
149 | 233 | ||
@@ -156,29 +240,55 @@ public class Server { | |||
156 | 240 | ||
157 | } | 241 |