View Javadoc

1   /*
2    *   Firemox 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.firemox.network;
20  
21  import java.io.FileInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.net.Socket;
26  
27  import net.sf.firemox.deckbuilder.Deck;
28  import net.sf.firemox.deckbuilder.DeckReader;
29  import net.sf.firemox.network.message.CoreMessage;
30  import net.sf.firemox.stack.StackManager;
31  import net.sf.firemox.tools.Configuration;
32  import net.sf.firemox.ui.MagicUIComponents;
33  import net.sf.firemox.ui.component.LoaderConsole;
34  
35  import org.apache.commons.io.IOUtils;
36  
37  /***
38   * This class is representing a client or a server, so contains nickname,
39   * connection's port and streams of opened socket.
40   * 
41   * @since 0.2d
42   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
43   */
44  public abstract class NetworkActor extends Thread {
45  
46  	/***
47  	 * Creates a new instance of NetworkActor <br>
48  	 * 
49  	 * @param deck
50  	 *          the deck of this network component.
51  	 * @param passwd
52  	 *          is the password needed to connect to this play
53  	 */
54  	protected NetworkActor(Deck deck, char[] passwd) {
55  		this.nickName = StackManager.PLAYERS[0].getNickName();
56  		this.deck = deck;
57  		this.passwd = passwd;
58  		this.port = Configuration.getInt("port", 1299);
59  		ConnectionManager.enableConnectingTools(true);
60  		bigPipe = null;
61  		cancelling = false;
62  		freePlaces();
63  	}
64  
65  	/***
66  	 * Initialize the pipe.
67  	 */
68  	protected void initBigPipe() {
69  		if (bigPipe != null) {
70  			// is already running!
71  			return;
72  		}
73  		bigPipe = new MBigPipe(inBin, outBin);
74  		bigPipe.start();
75  	}
76  
77  	/***
78  	 * end this server, close all connections with connected clients
79  	 */
80  	public void closeConnexion() {
81  		MagicUIComponents.timer.stop();
82  		cancelling = true;
83  		try {
84  			// close stream
85  			if (clientSocket != null) {
86  				clientSocket.close();
87  			}
88  			IOUtils.closeQuietly(outBin);
89  			IOUtils.closeQuietly(inBin);
90  			// free pointers
91  		} catch (Exception e) {
92  			// Nothing to do
93  		}
94  		outBin = null;
95  		inBin = null;
96  	}
97  
98  	/***
99  	 * flush the buffer or the current OutputStream
100 	 */
101 	public void flush() {
102 		try {
103 			outBin.flush();
104 		} catch (IOException e) {
105 			throw new InternalError("when flush outBin stream");
106 		}
107 	}
108 
109 	/***
110 	 * Send the specified message to the opponent.
111 	 * 
112 	 * @param message
113 	 *          is the message to send
114 	 */
115 	public void send(CoreMessage message) {
116 		bigPipe.send(message);
117 	}
118 
119 	/***
120 	 * cancel the join/create action, close current connections and set the main
121 	 * frame visible.
122 	 */
123 	public void cancelConnexion() {
124 		closeConnexion();
125 		freePlaces();
126 		LoaderConsole.endTask();
127 	}
128 
129 	/***
130 	 * Remove from all places the existing components and set to zero the mana
131 	 * pools.
132 	 */
133 	private void freePlaces() {
134 		StackManager.PLAYERS[0].zoneManager.reset();
135 		StackManager.PLAYERS[1].zoneManager.reset();
136 	}
137 
138 	/***
139 	 * Read and validate the opponent's deck.
140 	 * 
141 	 * @return <code>true</code> when the opponent's deck is valid.
142 	 * @throws IOException
143 	 *           If some other I/O error occurs
144 	 */
145 	protected boolean readAndValidateOpponentDeck() throws IOException {
146 		Deck opponentDeck = DeckReader.getDeck(new MInputStream(inBin));
147 		if (!DeckReader.validateDeck(MagicUIComponents.magicForm, opponentDeck,
148 				deck.getConstraint().getName())) {
149 			cancelling = true;
150 			return false;
151 		}
152 		StackManager.PLAYERS[1].zoneManager.giveCards(opponentDeck, dbStream);
153 		return true;
154 	}
155 
156 	/***
157 	 * the password needed to be connected
158 	 */
159 	protected final char[] passwd;
160 
161 	/***
162 	 * The nickname of this actor (client or server)
163 	 */
164 	protected final String nickName;
165 
166 	/***
167 	 * the socket of this connection
168 	 */
169 	protected Socket clientSocket;
170 
171 	/***
172 	 * Port number
173 	 */
174 	protected final int port;
175 
176 	/***
177 	 * Deck.
178 	 */
179 	protected Deck deck;
180 
181 	/***
182 	 * The optional OutputStream of deck.
183 	 */
184 	protected OutputStream outBin;
185 
186 	/***
187 	 * InputStream of deck. May be remote deck.
188 	 */
189 	protected InputStream inBin;
190 
191 	/***
192 	 * The opened stream of MDB.
193 	 */
194 	protected FileInputStream dbStream;
195 
196 	private MBigPipe bigPipe;
197 
198 	/***
199 	 * Is canceling?
200 	 */
201 	public static boolean cancelling;
202 }