1 package cz.cuni.amis.pogamut.ut2004.teamcomm.bot;
2
3 import java.io.Serializable;
4 import java.net.InetSocketAddress;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import cz.cuni.amis.pogamut.base.agent.module.SensomotoricModule;
12 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
13 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
14 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
15 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectUpdatedEvent;
16 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
17 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
18 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BeginMessage;
19 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
20 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
21 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
22 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.TCMinaClient;
23 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.TCMinaClient.RequestFuture;
24 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.messages.TCRequestCreateChannel;
25 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.messages.TCRequestDestroyChannel;
26 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.messages.TCRequestGetStatus;
27 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.messages.TCRequestJoinChannel;
28 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.client.messages.TCRequestLeaveChannel;
29 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.messages.TCMessage;
30 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.messages.TCMessageData;
31 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.messages.TCRequestMessage;
32 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.model.TCChannel;
33 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.model.TCTeam;
34 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.TCMinaServer;
35 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.messages.TCInfoStatus;
36 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.messages.TCInfoTeamChannelBotJoined;
37 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.messages.TCInfoTeamChannelBotLeft;
38 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.messages.TCInfoTeamChannelCreated;
39 import cz.cuni.amis.pogamut.ut2004.teamcomm.mina.server.messages.TCInfoTeamChannelDestroyed;
40 import cz.cuni.amis.pogamut.ut2004.teamcomm.server.protocol.TCControlMessagesTranslator;
41 import cz.cuni.amis.pogamut.ut2004.teamcomm.server.protocol.messages.TCControlServerAlive;
42 import cz.cuni.amis.utils.exception.PogamutException;
43 import cz.cuni.amis.utils.flag.Flag;
44 import cz.cuni.amis.utils.future.FutureWithListeners;
45 import cz.cuni.amis.utils.maps.HashMapMap;
46 import cz.cuni.amis.utils.token.IToken;
47
48 public class UT2004TCClient extends SensomotoricModule<UT2004Bot> {
49
50 private UT2004Bot bot;
51
52 private IWorldView botWorldView;
53
54 private IWorldView teamWorldView;
55
56 private IWorldObjectEventListener<Self, WorldObjectUpdatedEvent<Self>> selfListener = new IWorldObjectEventListener<Self, WorldObjectUpdatedEvent<Self>>() {
57
58 @Override
59 public void notify(WorldObjectUpdatedEvent<Self> event) {
60 selfUpdate(event);
61 }
62 };
63
64 private IWorldEventListener<BeginMessage> beginMessageListener = new IWorldEventListener<BeginMessage>() {
65
66 @Override
67 public void notify(BeginMessage event) {
68 beginMessage(event);
69 }
70 };
71
72 private IWorldEventListener<EndMessage> endMessageListener = new IWorldEventListener<EndMessage>() {
73
74 @Override
75 public void notify(EndMessage event) {
76 endMessage(event);
77 }
78 };
79
80 private IWorldEventListener<TCMessage> tcMessageListener = new IWorldEventListener<TCMessage>() {
81
82 @Override
83 public void notify(TCMessage event) {
84 tcMessage(event);
85 }
86
87 };
88
89 private List<TCMessage> current = new ArrayList<TCMessage>();
90
91 private List<TCMessage> incoming = new ArrayList<TCMessage>();
92
93 private TCControlMessagesTranslator tcTranslator;
94
95 private TCEvents tcEvents;
96
97 private Self self;
98
99 private long simTime;
100
101 private TCMinaClient minaClient = null;
102
103 public UT2004TCClient(UT2004Bot bot, IWorldView teamWorldView) {
104 super(bot);
105
106 this.botWorldView = bot.getWorldView();
107 this.teamWorldView = teamWorldView;
108
109 tcTranslator = new TCControlMessagesTranslator(botWorldView, false);
110 tcTranslator.enable();
111
112 tcEvents = new TCEvents(agent.getWorldView()) {
113 @Override
114 public void tcControlServerAlive(TCControlServerAlive event) {
115 UT2004TCClient.this.tcControlServerAlive(event);
116 }
117 };
118 tcEvents.enableTCEvents();
119
120 bot.getWorldView().addObjectListener(Self.class, WorldObjectUpdatedEvent.class, selfListener);
121 bot.getWorldView().addEventListener(BeginMessage.class, beginMessageListener);
122 bot.getWorldView().addEventListener(EndMessage.class, endMessageListener);
123
124 this.teamWorldView.addEventListener(TCMessage.class, tcMessageListener);
125 }
126
127
128
129
130
131
132
133
134
135 public boolean isConnected() {
136 TCMinaClient mClient = minaClient;
137 if (mClient == null) return false;
138 return mClient.getConnected().getFlag();
139 }
140
141 public Flag<Boolean> getConnectedFlag() {
142 TCMinaClient mClient = minaClient;
143 if (mClient == null) return null;
144 return mClient.getConnected();
145 }
146
147 public boolean isConnected(UnrealId botId) {
148 TCMinaClient mClient = minaClient;
149 if (mClient == null) return false;
150 return mClient.isConnected(botId);
151 }
152
153 public boolean isConnected(Player bot) {
154 TCMinaClient mClient = minaClient;
155 if (mClient == null) return false;
156 return mClient.isConnected(bot);
157 }
158
159 public boolean isConnectedToMyTeam(UnrealId botId) {
160 TCMinaClient mClient = minaClient;
161 if (mClient == null) return false;
162 return mClient.isConnectedToMyTeam(botId);
163 }
164
165 public boolean isConnectedToMyTeam(Player bot) {
166 TCMinaClient mClient = minaClient;
167 if (mClient == null) return false;
168 return mClient.isConnectedToMyTeam(bot);
169 }
170
171 public boolean isConnectedToChannel(UnrealId botId, int channelId) {
172 TCMinaClient mClient = minaClient;
173 if (mClient == null) return false;
174 return mClient.isConnectedToChannel(botId, channelId);
175 }
176
177 public boolean isConnectedToChannel(Player bot, int channelId) {
178 TCMinaClient mClient = minaClient;
179 if (mClient == null) return false;
180 return mClient.isConnectedToChannel(bot, channelId);
181 }
182
183 public boolean isChannelExist(int channelId) {
184 TCMinaClient mClient = minaClient;
185 if (mClient == null) return false;
186 return mClient.isChannelExist(channelId);
187 }
188
189
190
191
192
193 public Set<UnrealId> getConnectedAllBots() {
194 TCMinaClient mClient = minaClient;
195 if (mClient == null) return new HashSet<UnrealId>();
196 return mClient.getConnectedAllBots();
197 }
198
199
200
201
202
203 public Set<UnrealId> getConnectedTeamBots() {
204 TCMinaClient mClient = minaClient;
205 if (mClient == null) return new HashSet<UnrealId>();
206 return mClient.getConnectedTeamBots();
207 }
208
209
210
211
212
213 public Set<UnrealId> getConnectedChannelBots(int channelId) {
214 TCMinaClient mClient = minaClient;
215 if (mClient == null) return new HashSet<UnrealId>();
216 return mClient.getConnectedChannelBots(channelId);
217 }
218
219
220
221
222
223
224
225
226 public TCTeam getTeam() {
227 TCMinaClient mClient = minaClient;
228 if (mClient == null) return null;
229 return mClient.getTeam();
230 }
231
232
233
234
235
236
237
238
239 public TCChannel getChannel(int channelId) {
240 TCMinaClient mClient = minaClient;
241 if (mClient == null) return null;
242 return mClient.getChannel(channelId);
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256 public RequestFuture<TCInfoTeamChannelCreated> requestCreateChannel() {
257 TCMinaClient mClient = minaClient;
258 if (mClient == null) return null;
259 return mClient.requestCreateChannel();
260 }
261
262
263
264
265
266
267 public RequestFuture<TCInfoTeamChannelDestroyed> requestDestroyChannel(int channelId) {
268 TCMinaClient mClient = minaClient;
269 if (mClient == null) return null;
270 return mClient.requestDestroyChannel(channelId);
271 }
272
273
274
275
276
277 public RequestFuture<TCInfoStatus> requestGetStatus() {
278 TCMinaClient mClient = minaClient;
279 if (mClient == null) return null;
280 return mClient.requestGetStatus();
281 }
282
283
284
285
286
287
288 public RequestFuture<TCInfoTeamChannelBotJoined> requestJoinChannel(int channelId) {
289 TCMinaClient mClient = minaClient;
290 if (mClient == null) return null;
291 return mClient.requestJoinChannel(channelId);
292 }
293
294
295
296
297
298
299 public RequestFuture<TCInfoTeamChannelBotLeft> requestLeaveChannel(int channelId) {
300 TCMinaClient mClient = minaClient;
301 if (mClient == null) return null;
302 return mClient.requestLeaveChannel(channelId);
303 }
304
305
306
307
308
309 public boolean sendToAll(IToken messageType, Serializable data) {
310 if (minaClient == null) {
311 log.warning("minaClient is NULL, cannot sendToAll: " + data);
312 return false;
313 }
314 if (!minaClient.getConnected().getFlag()) {
315 log.warning("minaClient is NOT connected, cannot sendToAll: " + data);
316 return false;
317 }
318 return minaClient.sendToAll(messageType, data);
319 }
320
321 public boolean sendToAll(TCMessageData data) {
322 data.setSimTime(getSimTime());
323 return sendToAll(data.getMessageType(), data);
324 }
325
326 public boolean sendToTeam(IToken messageType, Serializable data) {
327 if (minaClient == null) {
328 log.warning("minaClient is NULL, cannot sendToTeam: " + data);
329 return false;
330 }
331 if (!minaClient.getConnected().getFlag()) {
332 log.warning("minaClient is NOT connected, cannot sendToTeam: " + data);
333 return false;
334 }
335 return minaClient.sendToTeam(messageType, data);
336 }
337
338 public boolean sendToTeam(TCMessageData data) {
339 data.setSimTime(getSimTime());
340 return sendToTeam(data.getMessageType(), data);
341 }
342
343 public boolean sendToChannel(int channelId, IToken messageType, Serializable data) {
344 if (minaClient == null) {
345 log.warning("minaClient is NULL, cannot sendToChannel(" + channelId + "): " + data);
346 return false;
347 }
348 if (!minaClient.getConnected().getFlag()) {
349 log.warning("minaClient is NOT connected, cannot sendToChannel(" + channelId + "): " + data);
350 return false;
351 }
352 return minaClient.sendToChannel(channelId, messageType, data);
353 }
354
355 public boolean sendToChannel(int channelId, TCMessageData data) {
356 data.setSimTime(getSimTime());
357 return sendToChannel(channelId, data.getMessageType(), data);
358 }
359
360 public boolean sendToBot(UnrealId bot, IToken messageType, Serializable data) {
361 if (minaClient == null) {
362 log.warning("minaClient is NULL, cannot sendToBot(" + bot.getStringId() + "): " + data);
363 return false;
364 }
365 if (!minaClient.getConnected().getFlag()) {
366 log.warning("minaClient is NOT connected, cannot sendToBot(" + bot.getStringId() + "): " + data);
367 return false;
368 }
369 return minaClient.sendPrivate(bot, messageType, data);
370 }
371
372 public boolean sendToBot(UnrealId bot, TCMessageData data) {
373 data.setSimTime(getSimTime());
374 return sendToBot(bot, data.getMessageType(), data);
375 }
376
377
378
379
380
381
382
383
384 public List<TCMessage> getMessages() {
385 return this.current;
386 }
387
388
389
390
391
392 public UnrealId getBotId() {
393 if (self == null) {
394 throw new PogamutException("Could not retrieve BotId, self is NULL.", log, this);
395 }
396 return self.getBotId();
397 }
398
399 public int getBotTeam() {
400 if (self == null) {
401 throw new PogamutException("Could not retrieve bot Team, self is NULL.", log, this);
402 }
403 return self.getTeam();
404 }
405
406 public long getSimTime() {
407 return simTime;
408 }
409
410
411
412
413
414 protected void selfUpdate(WorldObjectUpdatedEvent<Self> event) {
415 this.self = event.getObject();
416 if (minaClient == null) return;
417 if (minaClient.getConnected().getFlag()) return;
418 if (minaClient.getConnecting().getFlag()) return;
419 minaClient.connect();
420 }
421
422 protected void beginMessage(BeginMessage event) {
423 this.simTime = event.getSimTime();
424 }
425
426 protected void endMessage(EndMessage event) {
427 this.current.clear();
428 List<TCMessage> temp = this.current;
429 this.current = incoming;
430 this.incoming = temp;
431 }
432
433 protected void tcControlServerAlive(TCControlServerAlive event) {
434 if (minaClient == null) {
435 if (this.self != null) {
436 minaClient = new TCMinaClient(this, new InetSocketAddress(event.getHost(), event.getPort()), teamWorldView, log);
437 if (minaClient.getConnected().getFlag()) return;
438 if (minaClient.getConnecting().getFlag()) return;
439 minaClient.connect();
440 }
441 } else {
442 if (!event.getHost().equals(minaClient.getHost()) || event.getPort() != minaClient.getPort()) {
443 log.warning("There are multiple TC server connected to the UT2004, currently using " + minaClient.getHost() + ":" + minaClient.getPort() + ", the other server is listening at " + event.getHost() + ":" + event.getPort());
444 return;
445 }
446 }
447 }
448
449 protected void tcMessage(TCMessage event) {
450 incoming.add(event);
451 }
452
453
454
455
456
457 @Override
458 protected void cleanUp() {
459 if (minaClient != null) {
460 minaClient.stop();
461 minaClient = null;
462 self = null;
463 simTime = -1;
464 }
465
466 super.cleanUp();
467
468 }
469
470
471
472 }