1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.magicproject.network;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.PrintWriter;
28
29 /***
30 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
31 * @since 0.3
32 */
33 public class MBigPipe extends Thread implements IdMessages {
34
35 MBigPipe(InputStream mainIn, OutputStream mainOut, MChat chat) {
36 this.mainIn = mainIn;
37 this.mainOut = mainOut;
38 this.chat = chat;
39 MSocketListener.init();
40 ready = new MMiniPipe();
41 ready.take();
42 pipeOut = new MMiniPipe();
43 pipeInSync = new MMiniPipe();
44 pipeInSync.take();
45 instance = this;
46 }
47
48 /***
49 * Semaphore to indicate a ready stream
50 */
51 public MMiniPipe ready;
52
53 /***
54 * send a byte sized message to opponent. This message si not displayed in the
55 * chat window, but is destined to play triggers.
56 *
57 * @param msg
58 * is the message to send
59 */
60 public void sendGameMessage(int... msg) {
61 pipeOut.take();
62 try {
63 synchronized (LOCK) {
64 mainOut.write(BEGIN_GAME_DATA);
65 mainOut.write(msg.length);
66 for (int i : msg) {
67 mainOut.write(i);
68 }
69 mainOut.flush();
70 }
71 } catch (IOException e) {
72 ConnectionManager.notifyDisconnection();
73 ConnectionManager.closeConnexions();
74 throw new InternalError("disconnected in sendGameMessage");
75 } finally {
76 pipeOut.release();
77 }
78 }
79
80 /***
81 * send a STRING message to opponent. This message will be displayed in the
82 * chat window.
83 *
84 * @param msg
85 * is the message to send
86 */
87 public void sendChatMessage(String msg) {
88 pipeOut.take();
89 try {
90 synchronized (LOCK) {
91 mainOut.write(BEGIN_MESSAGE_DATA);
92 mainOut.flush();
93 PrintWriter printer = new PrintWriter(mainOut);
94 printer.println(msg);
95 printer.flush();
96 }
97 } catch (IOException e) {
98 throw new InternalError("disconnected in sendChatMessage");
99 } finally {
100 pipeOut.release();
101 }
102 }
103
104 /***
105 * The main loop allowing to mix 2 data types : the first is the data
106 * corresponding to player's action, and the second is the message of chat
107 * speaking.
108 *
109 * @see IdMessages#BEGIN_GAME_DATA
110 * @see IdMessages#BEGIN_MESSAGE_DATA
111 */
112 @Override
113 public void run() {
114 try {
115 while (true) {
116 int idHead = mainIn.read();
117 switch (idHead) {
118 case BEGIN_GAME_DATA:
119 MSocketListener.getInstance().newMessage(mainIn);
120 break;
121 case BEGIN_MESSAGE_DATA:
122 chat.newMessage(mainIn);
123 break;
124 default:
125 ConnectionManager.notifyDisconnection();
126
127 ConnectionManager.closeConnexions();
128 MSocketListener.getInstance().newMessage(mainIn);
129 System.out.println(" **disconnected **");
130 return;
131 }
132 }
133 } catch (IOException e) {
134 System.out.println(" **disconnected **");
135 ConnectionManager.notifyDisconnection();
136
137 ConnectionManager.closeConnexions();
138 return;
139 }
140 }
141
142 /***
143 * monitors
144 */
145 private MMiniPipe pipeOut;
146
147 private MMiniPipe pipeInSync;
148
149 /***
150 * Token to split stream for play message and chat message
151 */
152 public static final Object LOCK = new Object();
153
154 private MChat chat;
155
156 /***
157 * main input stream
158 */
159 private InputStream mainIn;
160
161 /***
162 * main output stream
163 */
164 private OutputStream mainOut;
165
166 /***
167 * The unique instance
168 */
169 public static MBigPipe instance;
170 }