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.io.IOException;
22 import java.io.InputStream;
23
24 import net.sf.magicproject.action.MessagingAction;
25 import net.sf.magicproject.action.MoveCard;
26 import net.sf.magicproject.action.PayMana;
27 import net.sf.magicproject.clickable.ability.UserAbility;
28 import net.sf.magicproject.clickable.mana.ManaPool;
29 import net.sf.magicproject.clickable.targetable.card.MCard;
30 import net.sf.magicproject.clickable.targetable.card.TriggeredCard;
31 import net.sf.magicproject.clickable.targetable.card.TriggeredCardChoice;
32 import net.sf.magicproject.clickable.targetable.player.Player;
33 import net.sf.magicproject.stack.StackManager;
34 import net.sf.magicproject.tools.Log;
35 import net.sf.magicproject.tools.MToolKit;
36 import net.sf.magicproject.ui.MagicUIComponents;
37
38 /***
39 * This class is listening to the actions done by the opponent and apply the
40 * corresponding actions. These actions may be : click on cards, ability
41 * choosen, mana use and auto-options changment.
42 *
43 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
44 * @since 0.4
45 */
46 public final class MSocketListener extends Thread {
47
48 /***
49 * Private constructor used to create the unique instance of this class
50 */
51 private MSocketListener() {
52 super("SocketListener");
53 start();
54 }
55
56 /***
57 * Create a new instance of this class.
58 */
59 public static void init() {
60 instance = new MSocketListener();
61 }
62
63 /***
64 * The unique instance of this class.
65 */
66 private static MSocketListener instance;
67
68 /***
69 * Return the unique instance of this class.
70 *
71 * @return the unique instance of this class.
72 */
73 public static MSocketListener getInstance() {
74 return instance;
75 }
76
77 /***
78 * To read anew message
79 *
80 * @param in
81 * the input stram
82 * @throws IOException
83 */
84 public void newMessage(InputStream in) throws IOException {
85 virtualInput.newMessage(in);
86 }
87
88 /***
89 * run this thread
90 *
91 * @see IdMessages
92 */
93 @Override
94 public void run() {
95 try {
96 while (true) {
97 Synchronizer.SYNCHRONIZER.take();
98
99
100 synchronized (MBigPipe.LOCK) {
101 int read = virtualInput.read();
102 StackManager.noReplayToken.take();
103 switch (read) {
104 case IdMessages.MSG_CHOICE:
105 case IdMessages.COLOR_ANSWER:
106 case IdMessages.MSG_ANSWER:
107 case IdMessages.INTEGER_ANSWER:
108 case IdMessages.ZONE_ANSWER:
109 case IdMessages.PROPERTY_ANSWER:
110 final int optionAnswer = virtualInput.read();
111 MessagingAction.finishedMessage(optionAnswer, virtualInput.read(),
112 StackManager.getInstance().getAbilityContext(),
113 StackManager.currentAbility, StackManager.actionManager
114 .getActionContextNull());
115 break;
116 case IdMessages.MSG_SKIP:
117 Log.debug(" ...-> manual skip");
118 Player.unsetHandedPlayer();
119 StackManager.actionManager.manualSkip();
120 break;
121 case IdMessages.MSG_CLICK_CARD:
122 MCard.clickOn(virtualInput);
123 break;
124 case IdMessages.MSG_CLICK_ABILITY:
125 UserAbility.clickOn(virtualInput);
126 break;
127 case IdMessages.MSG_CLICK_PLAYER:
128 Player.clickOn(virtualInput);
129 break;
130 case IdMessages.MSG_CLICK_ACTION:
131 MagicUIComponents.choosenCostPanel.clickOn(virtualInput);
132 break;
133 case IdMessages.MSG_CLICK_MANA:
134 ManaPool.clickOn(virtualInput);
135 break;
136 case IdMessages.CLICK_MANA:
137 PayMana.clickOn(virtualInput);
138 break;
139 case IdMessages.MSG_CLICK_TRIGGERED_CARD:
140 TriggeredCard.clickOn(virtualInput);
141 break;
142 case -1:
143
144 ConnectionManager.notifyDisconnection();
145 ConnectionManager.closeConnexions();
146 break;
147 case IdMessages.MOVE_ORDER_ANSWER:
148 final int[] order = new int[virtualInput.read()];
149 for (int i = 0; i < order.length; i++) {
150 order[i] = virtualInput.read();
151 }
152 ((MoveCard) StackManager.actionManager.currentAction)
153 .receiveMoveOrder(order);
154 break;
155 case IdMessages.TRIGGERED_CARD_CHOICE:
156 TriggeredCardChoice.finishedMessage(virtualInput.read());
157 break;
158 default:
159 Log.debug("Unknown code " + read);
160 }
161 StackManager.noReplayToken.release();
162 }
163 }
164 } catch (IOException e) {
165 Log.debug(" **disconnection ** in socketlistener");
166 ConnectionManager.notifyDisconnection();
167 ConnectionManager.closeConnexions();
168 return;
169 } catch (Throwable e) {
170 Log.fatal("In SocketListener, occurred exception", e);
171 ConnectionManager.closeConnexions();
172 return;
173 } finally {
174 StackManager.noReplayToken.release();
175 virtualInput.reset();
176 }
177 }
178
179 /***
180 * Close connections.
181 */
182 public void closeConnections() {
183 virtualInput.reset();
184 }
185
186 /***
187 * Read and return replacement answer.
188 *
189 * @return the replacement answer.
190 */
191 public int readReplacementAnswer() {
192 try {
193 int read = virtualInput.read();
194 switch (read) {
195 case IdMessages.REPLACEMENT_ANSWER:
196 return MToolKit.readInt16(virtualInput);
197 case -1:
198
199 ConnectionManager.notifyDisconnection();
200 ConnectionManager.closeConnexions();
201 break;
202 default:
203 Log.debug("Unknown code for a Non-Block read " + read);
204 }
205 } catch (IOException e) {
206 Log.debug(" **disconnection ** in socketlistener");
207 ConnectionManager.notifyDisconnection();
208 ConnectionManager.closeConnexions();
209 } catch (Throwable e) {
210 Log.fatal("In SocketListener, occurred exception : ", e);
211 ConnectionManager.closeConnexions();
212 }
213 return -1;
214 }
215
216 private VirtualInputStream virtualInput = new VirtualInputStream();
217
218 }