1 package cz.cuni.amis.pogamut.ut2004.analyzer;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.logging.Level;
6
7 import com.google.inject.Inject;
8
9 import cz.cuni.amis.pogamut.base.agent.state.level1.IAgentStateUp;
10 import cz.cuni.amis.pogamut.base.communication.command.IAct;
11 import cz.cuni.amis.pogamut.base.communication.connection.impl.socket.SocketConnection;
12 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
14 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectListener;
15 import cz.cuni.amis.pogamut.base.communication.worldview.object.event.WorldObjectDestroyedEvent;
16 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus;
17 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
18 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
19 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
20 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PlayerJoinsGame;
21 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PlayerLeft;
22 import cz.cuni.amis.pogamut.ut2004.communication.worldview.UT2004WorldView;
23 import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004AnalyzerFactory;
24 import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ObserverFactory;
25 import cz.cuni.amis.pogamut.ut2004.observer.IUT2004Observer;
26 import cz.cuni.amis.pogamut.ut2004.server.impl.UT2004Server;
27 import cz.cuni.amis.pogamut.ut2004.utils.UT2004AnalyzerRunner;
28 import cz.cuni.amis.pogamut.ut2004.utils.UT2004ObserverRunner;
29 import cz.cuni.amis.utils.exception.PogamutInterruptedException;
30 import cz.cuni.amis.utils.listener.Listeners;
31
32
33
34
35
36
37
38
39 public class UT2004Analyzer extends UT2004Server implements IUT2004Analyzer {
40
41 private Object mutex = new Object();
42
43 private Listeners<IAnalyzerObserverListener> observerListeners = new Listeners<IAnalyzerObserverListener>();
44 private IAnalyzerObserverListener.ObserverAddedNotifier observerAddedNotifier = new IAnalyzerObserverListener.ObserverAddedNotifier();
45 private IAnalyzerObserverListener.ObserverRemovedNotifier observerRemovedNotifier = new IAnalyzerObserverListener.ObserverRemovedNotifier();
46
47 private void addObserver(UnrealId botId) {
48 synchronized(observers) {
49 if (observers.containsKey(botId)) return;
50 if (log.isLoggable(Level.INFO)) log.info("New bot has connected to the game, creating new observer for the bot with id '" + botId.getStringId() + "'.");
51 String fileName = getParams().getFileNames() != null ? getParams().getFileNames().get(botId) : null;
52 IUT2004AnalyzerObserver observer = getObserverRunner().startAgents(
53 new UT2004AnalyzerObserverParameters()
54 .setObservedAgentId(botId.getStringId())
55 .setOutputPath(getParams().getOutputPath())
56 .setWaitForMatchRestart(getParams().isWaitForMatchRestart())
57 .setFileName(fileName)
58 .setWorldAddress(getParams().getObserverAddress())
59 ).get(0);
60 observers.put(botId, observer);
61 observerAddedNotifier.setBotId(botId);
62 observerAddedNotifier.setObserver(observer);
63 observerListeners.notify(observerAddedNotifier);
64 }
65 }
66
67 private void removeObserver(UnrealId botId) {
68 synchronized(observers) {
69 IUT2004AnalyzerObserver observer = observers.get(botId);
70 if (log.isLoggable(Level.INFO)) log.info("Bot '" + botId.getStringId() + "' has left the game");
71 if (observer != null) {
72 if (log.isLoggable(Level.INFO)) log.info("Stopping observer for the bot.");
73 try {
74 Thread.sleep(50);
75 } catch (InterruptedException e) {
76 throw new PogamutInterruptedException(e, this);
77 }
78 if (observer.getState().getFlag() instanceof IAgentStateUp) {
79 try {
80 observer.stop();
81 } catch (Exception e) {
82 log.warning("Observer for the bot '" + observer.getObservedBotId().getStringId() + "' could not be stopped, killing...");
83 try {
84 observer.kill();
85 } catch (Exception e2) {
86 log.warning("Observer for the bot '" + observer.getObservedBotId().getStringId() + "' could not be killed: " + e2.getMessage());
87 }
88 }
89 }
90 observers.remove(botId);
91 observerRemovedNotifier.setBotId(botId);
92 observerRemovedNotifier.setObserver(observer);
93 observerListeners.notify(observerRemovedNotifier);
94 } else {
95 if (log.isLoggable(Level.WARNING)) log.warning("The bot '" + botId.getStringId() + "' has no observer attached, was not observer, probably because the analyzer has been started after the bot itself.");
96 }
97 }
98 }
99
100 private IWorldObjectListener<Player> playerListener = new IWorldObjectListener<Player>() {
101 @Override
102 public void notify(IWorldObjectEvent<Player> event) {
103 Player plr = event.getObject();
104 if (plr.getJmx() != null && plr.getJmx().length() > 0) {
105
106 if (event instanceof WorldObjectDestroyedEvent) {
107 removeObserver(plr.getId());
108 } else {
109 addObserver(plr.getId());
110 }
111 }
112 }
113 };
114
115 private IWorldEventListener<PlayerJoinsGame> playerJoinsGameListener = new IWorldEventListener<PlayerJoinsGame>() {
116 @Override
117 public void notify(PlayerJoinsGame event) {
118 addObserver(event.getId());
119 }
120 };
121
122 private IWorldEventListener<PlayerLeft> playerLeftListener = new IWorldEventListener<PlayerLeft>() {
123
124 @Override
125 public void notify(PlayerLeft event) {
126 removeObserver(event.getId());
127 }
128
129 };
130
131
132
133
134 private Map<UnrealId, IUT2004AnalyzerObserver> observers = new HashMap<UnrealId, IUT2004AnalyzerObserver>();
135
136
137
138
139 private UT2004ObserverRunner<IUT2004AnalyzerObserver, UT2004AnalyzerObserverParameters> observerRunner;
140
141 @Inject
142 public UT2004Analyzer(UT2004AnalyzerParameters params,
143 IAgentLogger agentLogger, IComponentBus bus,
144 SocketConnection connection, UT2004WorldView worldView, IAct act) {
145 super(params, agentLogger, bus, connection, worldView, act);
146
147 observerListeners.setLog(log, "ObserverListeners");
148
149
150 getWorldView().addEventListener(PlayerLeft.class, playerLeftListener);
151 getWorldView().addObjectListener(Player.class, playerListener);
152 }
153
154 private UT2004ObserverRunner<IUT2004AnalyzerObserver, UT2004AnalyzerObserverParameters> getObserverRunner() {
155 if (observerRunner == null) {
156 synchronized(mutex) {
157 if (observerRunner == null) observerRunner = new UT2004ObserverRunner(new UT2004ObserverFactory<IUT2004Observer, UT2004AnalyzerObserverParameters>(getParams().getObserverModule()));
158 }
159 }
160 return observerRunner;
161 }
162
163 @Override
164 public UT2004AnalyzerParameters getParams() {
165 return (UT2004AnalyzerParameters) super.getParams();
166 }
167
168 @Override
169 public Map<UnrealId, IUT2004AnalyzerObserver> getObservers() {
170 synchronized(observers) {
171 return new HashMap<UnrealId, IUT2004AnalyzerObserver>(observers);
172 }
173 }
174
175 @Override
176 protected void stopAgent() {
177 super.stopAgent();
178 cleanUp();
179 }
180
181 @Override
182 protected void killAgent() {
183 super.killAgent();
184 cleanUp();
185 }
186
187
188
189
190 protected void cleanUp() {
191 synchronized(observers) {
192 for (IUT2004AnalyzerObserver observer : observers.values()) {
193 if (observer.getState().getFlag() instanceof IAgentStateUp) {
194 try {
195 observer.stop();
196 } catch (Exception e) {
197 if (log.isLoggable(Level.WARNING)) log.warning("Observer for the bot '" + observer.getObservedBotId().getStringId() + "' could not be stopped, killing...");
198 try {
199 observer.kill();
200 } catch (Exception e2) {
201 if (log.isLoggable(Level.WARNING)) log.warning("Observer for the bot '" + observer.getObservedBotId().getStringId() + "' could not be killed: " + e2.getMessage());
202 }
203 }
204 }
205 }
206 }
207 }
208
209 public static void main(String[] args) {
210 UT2004AnalyzerRunner<IUT2004Analyzer, UT2004AnalyzerParameters> analyzerRunner = new UT2004AnalyzerRunner<IUT2004Analyzer, UT2004AnalyzerParameters>(
211 new UT2004AnalyzerFactory(
212 new UT2004AnalyzerModule()
213 )
214 );
215 analyzerRunner.setLogLevel(Level.INFO);
216 analyzerRunner.setMain(true).startAgent();
217 }
218
219 @Override
220 public void addListener(IAnalyzerObserverListener listener) {
221 observerListeners.addWeakListener(listener);
222 }
223
224 @Override
225 public boolean isListening(IAnalyzerObserverListener listener) {
226 return observerListeners.isListening(listener);
227 }
228
229 @Override
230 public void removeListener(IAnalyzerObserverListener listener) {
231 observerListeners.removeListener(listener);
232 }
233
234 }