View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package net.sf.magicproject.network;
20  
21  import java.io.IOException;
22  import java.net.InetAddress;
23  import java.net.Socket;
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.token.IdZones;
36  import net.sf.magicproject.tools.Configuration;
37  import net.sf.magicproject.tools.Log;
38  import net.sf.magicproject.tools.MToolKit;
39  import net.sf.magicproject.ui.MagicUIComponents;
40  import net.sf.magicproject.ui.component.LoaderConsole;
41  import net.sf.magicproject.ui.i18n.LanguageManager;
42  
43  import org.apache.commons.io.IOUtils;
44  
45  /***
46   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
47   * @since 0.2c
48   */
49  public class Client extends NetworkActor implements IdMessages, IdZones {
50  
51  	/***
52  	 * create a new server for a specified port, play name, nickName and password
53  	 * required (null if none)
54  	 * 
55  	 * @param deck
56  	 *          the deck of this client
57  	 * @param passwd
58  	 *          is the password needed to connect to this play
59  	 */
60  	public Client(Deck deck, char[] passwd) {
61  		super(deck, passwd);
62  
63  		// Création de la socket de connexion
64  		LoaderConsole.beginTask(LanguageManager
65  				.getString("wiz_network.waitingforopponent"));
66  	}
67  
68  	@Override
69  	public void run() {
70  		String entree;
71  		LoaderConsole.beginTask(LanguageManager
72  				.getString("wiz_network.creatingconnection")
73  				+ "...", 2);
74  		InetAddress adr = null;
75  		try {
76  			// Connexion au serveur
77  			adr = InetAddress.getByName(Configuration.getString("ip"));
78  			clientSocket = new Socket(adr, port);
79  		} catch (IOException e) {
80  			// echec de la connexion au serveur
81  			JOptionPane.showMessageDialog(MagicUIComponents.magicForm,
82  					LanguageManager.getString("wiz_network.cannotconnectto", adr) + ", "
83  							+ LanguageManager.getString("wiz_network.port") + ":" + port
84  							+ ". \n" + LanguageManager.getString("wiz_network.port.invalid"),
85  					LanguageManager.getString("wiz_network.connectionpb"),
86  					JOptionPane.WARNING_MESSAGE);
87  			NetworkActor.cancelling = true;
88  			LoaderConsole.endTask();
89  		}
90  
91  		// stopping?
92  		if (cancelling) {
93  			cancelConnexion();
94  			return;
95  		}
96  		LoaderConsole.beginTask(
97  				LanguageManager.getString("wiz_network.connecting"), 5);
98  
99  		try {
100 			// Création des flots d'entrée/sortie
101 			outBin = clientSocket.getOutputStream();
102 			inBin = clientSocket.getInputStream();
103 
104 			// need password?
105 			entree = MToolKit.readString(inBin);
106 			if (STR_PASSWD.equals(entree)) {
107 				// a password is need by this server
108 				if (passwd == null) {
109 					// ... but we haven't any
110 					LoaderConsole.beginTask(LanguageManager
111 							.getString("wiz_network.password.missed"));
112 					MToolKit.writeString(outBin, STR_NOPASSWD);
113 					// close stream
114 					IOUtils.closeQuietly(inBin);
115 					IOUtils.closeQuietly(outBin);
116 					// free pointers
117 					outBin = null;
118 					inBin = null;
119 				} else {
120 					// send our password
121 					MToolKit.writeString(outBin, new String(passwd));
122 					entree = MToolKit.readString(inBin);
123 					if (STR_WRONGPASSWD.equals(entree)) {
124 						// wrong password
125 						LoaderConsole.beginTask(LanguageManager
126 								.getString("wiz_network.password.invalid"));
127 						// close stream
128 						IOUtils.closeQuietly(inBin);
129 						IOUtils.closeQuietly(outBin);
130 						// free pointers
131 						outBin = null;
132 						inBin = null;
133 					}
134 				}
135 			}
136 			if (outBin != null && !STR_OK.equals(entree)) {
137 				LoaderConsole.beginTask(LanguageManager
138 						.getString("wiz_network.unknowncommand")
139 						+ entree);
140 				// close stream
141 				IOUtils.closeQuietly(inBin);
142 				IOUtils.closeQuietly(outBin);
143 				// free pointers
144 				outBin = null;
145 				inBin = null;
146 			}
147 			if (outBin != null) {
148 				// send our version
149 				MToolKit.writeString(outBin, IdConst.VERSION);
150 				entree = MToolKit.readString(inBin);
151 				if (STR_WRONGVERSION.equals(entree)) {
152 					// wrong version
153 					LoaderConsole.beginTask(LanguageManager
154 							.getString("wiz_network.differentversionpb"));
155 					// close stream
156 					IOUtils.closeQuietly(inBin);
157 					IOUtils.closeQuietly(outBin);
158 					// free pointers
159 					outBin = null;
160 					inBin = null;
161 				}
162 			}
163 			if (outBin != null && !STR_OK.equals(entree)) {
164 				LoaderConsole.beginTask(LanguageManager
165 						.getString("wiz_network.unknowncommand")
166 						+ entree);
167 				// close stream
168 				IOUtils.closeQuietly(inBin);
169 				IOUtils.closeQuietly(outBin);
170 				// free pointers
171 				outBin = null;
172 				inBin = null;
173 			}
174 
175 			if (outBin != null) {
176 				/*
177 				 * client is connected to the server client/serveur I am ...
178 				 */
179 				MToolKit.writeString(outBin, nickName);
180 				// Opponent is ...
181 				String serverName = MToolKit.readString(inBin);
182 				LoaderConsole.beginTask(LanguageManager
183 						.getString("wiz_network.opponentis")
184 						+ serverName, 10);
185 
186 				// exchange shared string settings
187 				((Opponent) StackManager.PLAYERS[1]).readSettings(serverName, nickName,
188 						inBin);
189 				((You) StackManager.PLAYERS[0]).sendSettings(outBin);
190 
191 				// stopping?
192 				if (cancelling) {
193 					cancelConnexion();
194 					return;
195 				}
196 
197 				// receive, and set the random seed
198 				long seed = Long.parseLong(MToolKit.readString(inBin));
199 				MToolKit.random.setSeed(seed);
200 				Log.info("Seed = " + seed);
201 
202 				// read mana use option
203 				PayMana.useMana = Integer.parseInt(MToolKit.readString(inBin)) == 1;
204 
205 				// read opponent response option
206 				WaitActivatedChoice.opponentResponse = Integer.parseInt(MToolKit
207 						.readString(inBin)) == 1;
208 
209 				// Who starts?
210 				final StartingOption startingOption = StartingOption.values()[Integer
211 						.valueOf(MToolKit.readString(inBin)).intValue()];
212 				final boolean serverStarts;
213 				switch (startingOption) {
214 				case random:
215 				default:
216 					serverStarts = MToolKit.random.nextBoolean();
217 					break;
218 				case server:
219 					serverStarts = true;
220 					break;
221 				case client:
222 					serverStarts = false;
223 				}
224 
225 				if (serverStarts) {
226 					// server begins
227 					LoaderConsole.beginTask(LanguageManager
228 							.getString("wiz_network.opponentwillstart")
229 							+ " (mode=" + startingOption.getLocaleValue() + ")", 15);
230 					StackManager.idActivePlayer = 1;
231 					StackManager.idCurrentPlayer = 1;
232 				} else {
233 					// client begins
234 					LoaderConsole.beginTask(LanguageManager
235 							.getString("wiz_network.youwillstarts")
236 							+ " (mode=" + startingOption.getLocaleValue() + ")", 15);
237 					StackManager.idActivePlayer = 0;
238 					StackManager.idCurrentPlayer = 0;
239 				}
240 
241 				// load rules from the mdb file
242 				dbStream = MdbLoader.loadMDB(MToolKit.mdbFile,
243 						StackManager.idActivePlayer);
244 
245 				// send our deck
246 				LoaderConsole.beginTask(LanguageManager
247 						.getString("wiz_network.sendingdeck"), 25);
248 				deck.send(outBin);
249 				StackManager.PLAYERS[0].zoneManager.giveCards(deck, dbStream);
250 				MToolKit.writeString(outBin, "%EOF%");
251 				outBin.flush();
252 
253 				// stopping?
254 				if (cancelling) {
255 					cancelConnexion();
256 					return;
257 				}
258 
259 				// receive her/his deck
260 				LoaderConsole.beginTask(LanguageManager
261 						.getString("wiz_network.receivingdeck"), 55);
262 				readAndValidateOpponentDeck();
263 
264 				// free resources
265 				LoaderConsole.setTaskPercent(100);
266 
267 				// stopping?
268 				if (cancelling) {
269 					cancelConnexion();
270 					return;
271 				}
272 
273 				// stopping?
274 				if (cancelling) {
275 					cancelConnexion();
276 					return;
277 				}
278 
279 				initBigPipe();
280 				MagicUIComponents.magicForm.initGame();
281 			}
282 		} catch (Throwable e) {
283 			NetworkActor.cancelling = true;
284 			LoaderConsole.endTask();
285 			cancelConnexion();
286 			Log.error(e);
287 			throw new RuntimeException(LanguageManager.getString(
288 					"wiz_network.badconnection", adr), e);
289 		}
290 	}
291 }