1 package cz.cuni.amis.pogamut.ut2004.server.impl;
2
3 import java.util.Collection;
4 import java.util.List;
5 import java.util.logging.Level;
6 import java.util.logging.Logger;
7
8 import com.google.inject.Inject;
9
10 import cz.cuni.amis.pogamut.base.agent.IAgentId;
11 import cz.cuni.amis.pogamut.base.agent.state.impl.AgentStateStarting;
12 import cz.cuni.amis.pogamut.base.communication.command.IAct;
13 import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.SocketConnection;
14 import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.SocketConnectionAddress;
15 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
16 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
17 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
18 import cz.cuni.amis.pogamut.base.server.AbstractWorldServer;
19 import cz.cuni.amis.pogamut.base.utils.collections.adapters.WVObjectsSetAdapter;
20 import cz.cuni.amis.pogamut.base.utils.collections.adapters.WVVisibleObjectsSetAdapter;
21 import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
22 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
23 import cz.cuni.amis.pogamut.ut2004.bot.IUT2004Bot;
24 import cz.cuni.amis.pogamut.ut2004.bot.impl.NativeUT2004BotAdapter;
25 import cz.cuni.amis.pogamut.ut2004.bot.jmx.BotJMXProxy;
26 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.AddBot;
27 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.GetMaps;
28 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.PasswordReply;
29 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Ready;
30 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo;
31 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.MapList;
32 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Mutator;
33 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Password;
34 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
35 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.MapPointListObtained;
36 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.PlayerListObtained;
37 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.ReadyCommandRequest;
38 import cz.cuni.amis.pogamut.ut2004.communication.worldview.map.UT2004Map;
39 import cz.cuni.amis.pogamut.ut2004.server.IUT2004Server;
40 import cz.cuni.amis.utils.collections.ObservableCollection;
41 import cz.cuni.amis.utils.collections.TranslatedObservableCollection;
42 import cz.cuni.amis.utils.flag.Flag;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 @AgentScoped
67 public abstract class AbstractUT2004Server<WORLD_VIEW extends IWorldView, ACT extends IAct> extends AbstractWorldServer<WORLD_VIEW, ACT, IUT2004Bot> implements IUT2004Server {
68
69 ObservableCollection<Player> players = null;
70
71 List<Mutator> mutators = null;
72
73 Flag<Double> gameSpeed = new Flag<Double>();
74
75 List<MapList> maps = null;
76
77 Flag<String> mapName = new Flag<String>();
78
79 private UT2004Map map;
80
81 ObservableCollection<? extends NativeUT2004BotAdapter> nativeAgents = null;
82
83
84
85
86 ObservableCollection<IUT2004Bot> agents = null;
87
88
89
90
91
92 private String desiredPassword = null;
93
94 private IWorldEventListener<PlayerListObtained> playerListObtainedListener = new IWorldEventListener<PlayerListObtained>() {
95
96 @Override
97 public void notify(PlayerListObtained event) {
98 players.addAll(event.getPlayers());
99
100 }
101 };
102
103 private IWorldEventListener<MapPointListObtained> mapPointListObtainedListener = new IWorldEventListener<MapPointListObtained>() {
104
105 @Override
106 public void notify(MapPointListObtained event) {
107
108
109 getAct().act(new GetMaps());
110 }
111 };
112 private SocketConnection connection;
113
114 @Inject
115 public AbstractUT2004Server(IAgentId agentId, IAgentLogger agentLogger,
116 IComponentBus bus, SocketConnection connection,
117 WORLD_VIEW worldView, ACT act) {
118 super(agentId, agentLogger, bus, worldView, act);
119
120 this.connection = connection;
121
122 getWorldView().addEventListener(ReadyCommandRequest.class, readyCommandRequestListener);
123 getWorldView().addEventListener(Password.class, passwordRequestedListener);
124
125
126 getWorldView().addEventListener(PlayerListObtained.class, playerListObtainedListener);
127
128 getWorldView().addEventListener(MapPointListObtained.class, mapPointListObtainedListener);
129
130 players = new WVVisibleObjectsSetAdapter<Player>(Player.class, getWorldView());
131 }
132
133 public void setAddress(String host, int port) {
134 if (log.isLoggable(Level.WARNING)) log.warning("Setting address to: " + host + ":" + port);
135 this.connection.setAddress(new SocketConnectionAddress(host, port));
136 }
137
138
139
140
141
142
143 public void setPassword(String password) {
144 this.desiredPassword = password;
145 }
146
147
148
149
150
151
152
153
154
155
156
157 protected void readyCommandRequested() {
158 getAct().act(new Ready());
159 }
160
161
162
163
164
165
166 private IWorldEventListener<ReadyCommandRequest> readyCommandRequestListener = new IWorldEventListener<ReadyCommandRequest>() {
167
168 @Override
169 public void notify(ReadyCommandRequest event) {
170 setState(new AgentStateStarting("GameBots2004 greeted us, sending READY."));
171 readyCommandRequested();
172 setState(new AgentStateStarting("READY sent."));
173 }
174 };
175
176
177
178
179
180
181
182
183
184
185
186
187
188 private PasswordReply passwordReply = null;
189
190
191
192
193
194
195
196
197
198
199
200 public PasswordReply getPasswordReply() {
201 return passwordReply;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 protected PasswordReply createPasswordReply() {
223 return desiredPassword != null ? new PasswordReply(desiredPassword)
224 : null;
225 }
226
227
228
229
230
231 private IWorldEventListener<Password> passwordRequestedListener = new IWorldEventListener<Password>() {
232
233 @Override
234 public void notify(Password event) {
235 setState(new AgentStateStarting("Password requested by the world."));
236 passwordReply = createPasswordReply();
237 if (passwordReply == null) {
238 passwordReply = new PasswordReply("");
239 }
240 if (log.isLoggable(Level.INFO)) log.info("Password required for the world, replying with '"
241 + passwordReply.getPassword() + "'.");
242 getAct().act(passwordReply);
243 }
244 };
245
246
247
248
249
250
251
252
253 private GameInfo gameInfo = null;
254
255 public GameInfo getGameInfo() {
256 if (gameInfo == null) {
257 gameInfo = getWorldView().getSingle(GameInfo.class);
258 }
259 return gameInfo;
260 }
261
262 @Override
263 public WORLD_VIEW getWorldView() {
264 return super.getWorldView();
265 }
266
267 @Override
268 public Collection<MapList> getAvailableMaps() {
269 return maps;
270 }
271
272 @Override
273 public Flag<Double> getGameSpeedFlag() {
274 return gameSpeed;
275 }
276
277 @Override
278 public String getMapName() {
279 if (getGameInfo() == null) return null;
280 return getGameInfo().getLevel();
281 }
282
283 @Override
284 public ObservableCollection<Player> getPlayers() {
285 return players;
286 }
287
288 @Override
289 public List<Mutator> getMutators() {
290 return mutators;
291 }
292
293 @Override
294 public ObservableCollection<IUT2004Bot> getAgents() {
295 if (agents != null) {
296 return agents;
297 }
298
299 if (getPlayers() == null) {
300
301 return null;
302 } else {
303 agents = new TranslatedObservableCollection<IUT2004Bot, Player>(
304 getPlayers()) {
305
306 @Override
307 protected IUT2004Bot translate(Player obj) {
308 if (obj.getJmx() != null) {
309 try {
310
311 return new BotJMXProxy(obj.getJmx());
312 } catch (Exception ex) {
313
314 Logger.getLogger(
315 AbstractUT2004Server.class.getName()).log(
316 Level.SEVERE, "JMX error", ex);
317 throw new RuntimeException(ex);
318 }
319 } else {
320 return null;
321 }
322 }
323
324 @Override
325 protected Object getKeyForObj(Player elem) {
326 return elem.getId();
327 }
328 };
329 }
330 return agents;
331 }
332
333 @Override
334 public ObservableCollection<? extends NativeUT2004BotAdapter> getNativeAgents() {
335 if (nativeAgents != null) {
336 return nativeAgents;
337 }
338
339 if (getPlayers() == null) {
340
341 return null;
342 } else {
343
344 nativeAgents = new TranslatedObservableCollection<NativeUT2004BotAdapter, Player>(
345 getPlayers()) {
346
347 @Override
348 protected NativeUT2004BotAdapter translate(Player obj) {
349 if (obj.getJmx() == null) {
350 try {
351
352 return new NativeUT2004BotAdapter(obj,
353 AbstractUT2004Server.this, getAct(),
354 getWorldView());
355 } catch (Exception ex) {
356
357 Logger.getLogger(
358 AbstractUT2004Server.class.getName()).log(
359 Level.SEVERE, "JMX error", ex);
360 throw new RuntimeException(ex);
361 }
362 } else {
363 return null;
364 }
365 }
366
367 @Override
368 protected Object getKeyForObj(Player elem) {
369 return elem.getId();
370 }
371 };
372 }
373 return nativeAgents;
374
375 }
376
377 @Override
378 public void connectNativeBot(String botName, String botType, int team) {
379 getAct().act(new AddBot(botName, null, null, 3, team, botType));
380 }
381
382 @Override
383 public UT2004Map getMap() {
384 if (map == null) {
385 map = new UT2004Map(getWorldView());
386 }
387 return map;
388 }
389
390
391
392
393
394
395
396
397
398
399 protected void reset() {
400 map = null;
401 gameInfo = null;
402 if (players != null) players.clear();
403 if (mutators != null) mutators.clear();
404 if (maps != null) maps.clear();
405 if (nativeAgents != null) nativeAgents.clear();
406 if (agents != null) agents.clear();
407 }
408
409 @Override
410 protected void resetAgent() {
411 super.resetAgent();
412 reset();
413 }
414
415 @Override
416 protected void stopAgent() {
417 super.stopAgent();
418 reset();
419 }
420
421 @Override
422 protected void killAgent() {
423 super.killAgent();
424 reset();
425 }
426
427 @Override
428 protected void startAgent() {
429 super.startAgent();
430 }
431
432 @Override
433 protected void startPausedAgent() {
434 super.startPausedAgent();
435 }
436
437 }