1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.magicproject.network;
20
21 import java.net.ServerSocket;
22 import java.net.SocketException;
23 import java.net.SocketTimeoutException;
24
25 import javax.swing.JOptionPane;
26
27 import net.sf.magicproject.action.PayMana;
28 import net.sf.magicproject.action.WaitActivatedChoice;
29 import net.sf.magicproject.clickable.targetable.player.Opponent;
30 import net.sf.magicproject.clickable.targetable.player.You;
31 import net.sf.magicproject.deckbuilder.Deck;
32 import net.sf.magicproject.deckbuilder.MdbLoader;
33 import net.sf.magicproject.stack.StackManager;
34 import net.sf.magicproject.token.IdConst;
35 import net.sf.magicproject.tools.Configuration;
36 import net.sf.magicproject.tools.Log;
37 import net.sf.magicproject.tools.MToolKit;
38 import net.sf.magicproject.ui.MagicUIComponents;
39 import net.sf.magicproject.ui.component.LoaderConsole;
40 import net.sf.magicproject.ui.i18n.LanguageManager;
41
42 import org.apache.commons.io.IOUtils;
43
44 /***
45 * a multi-client server
46 *
47 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
48 * @since 0.2c
49 */
50 public class Server extends NetworkActor implements IdMessages {
51
52 /***
53 * create a new server for a specified port, play name, nickName and password
54 * required (null if none)
55 *
56 * @param deck
57 * the deck of this server
58 * @param passwd
59 * is the password needed to connect to this play
60 */
61 public Server(Deck deck, char[] passwd) {
62 super(deck, passwd);
63 LoaderConsole.beginTask(LanguageManager
64 .getString("wiz_network.waitingforopponent"));
65 }
66
67 /***
68 * If this thread was constructed using a separate <code>Runnable</code> run
69 * object, then that <code>Runnable</code> object's <code>run</code>
70 * method is called; otherwise, this method does nothing and returns.
71 * <p>
72 * Subclasses of <code>Thread</code> should override this method.
73 *
74 * @see java.lang.Thread#start()
75 * @see java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
76 * java.lang.String)
77 * @see java.lang.Runnable#run()
78 */
79 @Override
80 public void run() {
81
82 try {
83 serverSocket = new ServerSocket(port, 1);
84
85 serverSocket.setSoTimeout(2000);
86
87
88 clientSocket = null;
89 LoaderConsole.beginTask(LanguageManager
90 .getString("wiz_network.creatingconnection"), 2);
91 while (clientSocket == null && !cancelling) {
92 try {
93 clientSocket = serverSocket.accept();
94 } catch (SocketException timeout) {
95 if (!"socket closed".equals(timeout.getMessage())) {
96 throw timeout;
97 }
98 } catch (SocketTimeoutException timeout) {
99
100
101
102
103 }
104 }
105
106
107 if (cancelling) {
108 Log.info(LanguageManager.getString("wiz_network.canceledcreation"));
109 cancelConnexion();
110 return;
111 }
112
113
114
115 LoaderConsole.beginTask(LanguageManager
116 .getString("wiz_network.incomming")
117 + " : " + clientSocket.getInetAddress().toString(), 5);
118
119
120 outBin = clientSocket.getOutputStream();
121 inBin = clientSocket.getInputStream();
122
123
124 if (passwd != null && passwd.length > 0) {
125
126 MToolKit.writeString(outBin, STR_PASSWD);
127 if (MToolKit.readString(inBin).equals(passwd)) {
128 MToolKit.writeString(outBin, STR_OK);
129 } else {
130
131 MToolKit.writeString(outBin, STR_WRONGPASSWD);
132
133 IOUtils.closeQuietly(inBin);
134 IOUtils.closeQuietly(outBin);
135
136 outBin = null;
137 inBin = null;
138 }
139 } else {
140 MToolKit.writeString(outBin, STR_OK);
141 }
142
143
144 String clientVersion = MToolKit.readString(inBin);
145 if (IdConst.VERSION.equals(clientVersion)) {
146 MToolKit.writeString(outBin, STR_OK);
147 } else {
148
149 MToolKit.writeString(outBin, STR_WRONGVERSION);
150 LoaderConsole.beginTask(LanguageManager
151 .getString("wiz_network.differentversionClientpb")
152 + " (" + clientVersion + ")", 10);
153 IOUtils.closeQuietly(inBin);
154 IOUtils.closeQuietly(outBin);
155
156 outBin = null;
157 inBin = null;
158 }
159
160 if (outBin != null) {
161
162
163
164 String clientName = MToolKit.readString(inBin);
165 LoaderConsole.beginTask(LanguageManager
166 .getString("wiz_network.opponentis")
167 + clientName, 10);
168
169 MToolKit.writeString(outBin, nickName);
170
171
172 ((You) StackManager.PLAYERS[0]).sendSettings(outBin);
173 ((Opponent) StackManager.PLAYERS[1]).readSettings(clientName, nickName,
174 inBin);
175
176
177 if (cancelling) {
178 cancelConnexion();
179 return;
180 }
181
182
183 long seed = MToolKit.random.nextLong();
184 MToolKit.random.setSeed(seed);
185 MToolKit.writeString(outBin, Long.toString(seed));
186 Log.info("Seed = " + seed);
187
188
189 PayMana.useMana = Configuration.getBoolean("useMana", true);
190 MToolKit.writeString(outBin, PayMana.useMana ? "1" : "0");
191
192
193 WaitActivatedChoice.opponentResponse = Configuration.getBoolean(
194 "opponnentresponse", true);
195 MToolKit.writeString(outBin, WaitActivatedChoice.opponentResponse ? "1"
196 : "0");
197
198
199 final StartingOption startingOption = StartingOption.values()[Configuration
200 .getInt("whoStarts", StartingOption.random.ordinal())];
201 MToolKit.writeString(outBin, String.valueOf(Configuration.getInt(
202 "whoStarts", 0)));
203 final boolean serverStarts;
204 switch (startingOption) {
205 case random:
206 default:
207 serverStarts = MToolKit.random.nextBoolean();
208 break;
209 case server:
210 serverStarts = true;
211 break;
212 case client:
213 serverStarts = false;
214 }
215
216 if (serverStarts) {
217
218 LoaderConsole.beginTask(LanguageManager
219 .getString("wiz_network.youwillstarts")
220 + " (mode=" + startingOption.getLocaleValue() + ")", 15);
221 StackManager.idActivePlayer = 0;
222 StackManager.idCurrentPlayer = 0;
223 } else {
224
225 LoaderConsole.beginTask(LanguageManager
226 .getString("wiz_network.opponentwillstart")
227 + " (mode=" + startingOption.getLocaleValue() + ")", 15);
228 StackManager.idActivePlayer = 1;
229 StackManager.idCurrentPlayer = 1;
230 }
231
232
233 dbStream = MdbLoader.loadMDB(MToolKit.mdbFile,
234 StackManager.idActivePlayer);
235
236
237 LoaderConsole.beginTask(LanguageManager
238 .getString("wiz_network.receivingdeck"), 25);
239 readAndValidateOpponentDeck();
240
241
242 if (cancelling) {
243 cancelConnexion();
244 return;
245 }
246
247
248 LoaderConsole.beginTask(LanguageManager
249 .getString("wiz_network.sendingdeck"), 55);
250 deck.send(outBin);
251 StackManager.PLAYERS[0].zoneManager.giveCards(deck, dbStream);
252
253
254 if (cancelling) {
255 cancelConnexion();
256 return;
257 }
258
259 MToolKit.writeString(outBin, "%EOF%");
260
261
262 outBin.flush();
263
264
265 if (cancelling) {
266 cancelConnexion();
267 return;
268 }
269
270 initBigPipe();
271 MagicUIComponents.magicForm.initGame();
272 }
273 } catch (Throwable e) {
274 NetworkActor.cancelling = true;
275 LoaderConsole.endTask();
276 cancelConnexion();
277 JOptionPane.showMessageDialog(MagicUIComponents.magicForm,
278 LanguageManager.getString("wiz_server.error") + " : "
279 + e.getMessage(), LanguageManager.getString("error"),
280 JOptionPane.WARNING_MESSAGE);
281 Log.error(e);
282 return;
283 }
284 }
285
286 @Override
287 public void closeConnexion() {
288 super.closeConnexion();
289
290 if (serverSocket != null) {
291 try {
292 serverSocket.close();
293 } catch (Exception e) {
294
295 }
296 }
297 }
298
299 /***
300 * the server's socket of this connexion
301 */
302 public ServerSocket serverSocket;
303
304 }