1 /* 2 Copyright (c) 2008 Robin Vobruba <hoijui.quaero@gmail.com> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package nulloojavaai; 19 20 21 import com.springrts.ai.AI; 22 import com.springrts.ai.oo.AIFloat3; 23 import com.springrts.ai.oo.OOAI; 24 import com.springrts.ai.oo.clb.*; 25 26 import java.text.DateFormat; 27 import java.text.SimpleDateFormat; 28 import java.util.Date; 29 import java.util.Properties; 30 import java.util.List; 31 import java.util.logging.*; 32 33 /** 34 * Serves as Interface for a Java Skirmish AIs for the Spring engine. 35 * 36 * @author hoijui 37 */ 38 public class NullOOJavaAI extends OOAI implements AI { 39 40 private static class MyCustomLogFormatter extends Formatter { 41 42 private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSS dd.MM.yyyy"); 43 format(LogRecord record)44 public String format(LogRecord record) { 45 46 // Create a StringBuffer to contain the formatted record 47 // start with the date. 48 StringBuffer sb = new StringBuffer(); 49 50 // Get the date from the LogRecord and add it to the buffer 51 Date date = new Date(record.getMillis()); 52 sb.append(dateFormat.format(date)); 53 sb.append(" "); 54 55 // Get the level name and add it to the buffer 56 sb.append(record.getLevel().getName()); 57 sb.append(": "); 58 59 // Get the formatted message (includes localization 60 // and substitution of paramters) and add it to the buffer 61 sb.append(formatMessage(record)); 62 sb.append("\n"); 63 64 return sb.toString(); 65 } 66 } 67 logProperties(Logger log, Level level, Properties props)68 private static void logProperties(Logger log, Level level, Properties props) { 69 70 log.log(level, "properties (items: " + props.size() + "):"); 71 for (String key : props.stringPropertyNames()) { 72 log.log(level, key + " = " + props.getProperty(key)); 73 } 74 } 75 76 private int skirmishAIId = -1; 77 private int teamId = -1; 78 private Properties info = null; 79 private Properties optionValues = null; 80 private OOAICallback clb = null; 81 private String myLogFile = null; 82 private Logger log = null; 83 84 private static final int DEFAULT_ZONE = 0; 85 86 NullOOJavaAI()87 public NullOOJavaAI() {} 88 sendTextMsg(String msg)89 private int sendTextMsg(String msg) { 90 91 try { 92 clb.getGame().sendTextMessage(msg, DEFAULT_ZONE); 93 } catch (Exception ex) { 94 ex.printStackTrace(); 95 return 1; 96 } 97 98 return 0; 99 } isDebugging()100 public boolean isDebugging() { 101 return true; 102 } 103 104 @Override init(int skirmishAIId, OOAICallback callback)105 public int init(int skirmishAIId, OOAICallback callback) { 106 107 int ret = -1; 108 109 this.skirmishAIId = skirmishAIId; 110 this.clb = callback; 111 112 this.teamId = clb.getSkirmishAI().getTeamId(); 113 114 info = new Properties(); 115 Info inf = clb.getSkirmishAI().getInfo(); 116 int numInfo = inf.getSize(); 117 for (int i = 0; i < numInfo; i++) { 118 String key = inf.getKey(i); 119 String value = inf.getValue(i); 120 info.setProperty(key, value); 121 } 122 123 optionValues = new Properties(); 124 OptionValues opVals = clb.getSkirmishAI().getOptionValues(); 125 int numOpVals = opVals.getSize(); 126 for (int i = 0; i < numOpVals; i++) { 127 String key = opVals.getKey(i); 128 String value = opVals.getValue(i); 129 optionValues.setProperty(key, value); 130 } 131 132 // initialize the log 133 try { 134 myLogFile = callback.getDataDirs().allocatePath("log-team-" + teamId + ".txt", true, true, false, false); 135 FileHandler fileLogger = new FileHandler(myLogFile, false); 136 fileLogger.setFormatter(new MyCustomLogFormatter()); 137 fileLogger.setLevel(Level.ALL); 138 log = Logger.getLogger("nulloojavaai"); 139 log.addHandler(fileLogger); 140 if (isDebugging()) { 141 log.setLevel(Level.ALL); 142 } else { 143 log.setLevel(Level.INFO); 144 } 145 } catch (Exception ex) { 146 System.out.println("NullOOJavaAI: Failed initializing the logger!"); 147 ex.printStackTrace(); 148 ret = -2; 149 } 150 151 try { 152 log.info("initializing team " + teamId); 153 154 log.log(Level.FINE, "info:"); 155 logProperties(log, Level.FINE, info); 156 157 log.log(Level.FINE, "options:"); 158 logProperties(log, Level.FINE, optionValues); 159 160 ret = 0; 161 } catch (Exception ex) { 162 log.log(Level.SEVERE, "Failed initializing", ex); 163 ret = -3; 164 } 165 166 return ret; 167 } 168 169 @Override release(int reason)170 public int release(int reason) { 171 return 0; // signaling: OK 172 } 173 174 @Override update(int frame)175 public int update(int frame) { 176 177 if (frame % 300 == 0) { 178 sendTextMsg("listing resources ..."); 179 List<Resource> resources = clb.getResources(); 180 for (Resource resource : resources) { 181 sendTextMsg("Resource " + resource.getName() + " optimum: " 182 + resource.getOptimum()); 183 sendTextMsg("Resource " + resource.getName() + " current: " 184 + clb.getEconomy().getCurrent(resource)); 185 sendTextMsg("Resource " + resource.getName() + " income: " 186 + clb.getEconomy().getIncome(resource)); 187 sendTextMsg("Resource " + resource.getName() + " storage: " 188 + clb.getEconomy().getStorage(resource)); 189 sendTextMsg("Resource " + resource.getName() + " usage: " 190 + clb.getEconomy().getUsage(resource)); 191 } 192 } 193 194 return 0; // signaling: OK 195 } 196 197 @Override message(int player, String message)198 public int message(int player, String message) { 199 return 0; // signaling: OK 200 } 201 202 @Override unitCreated(Unit unit, Unit builder)203 public int unitCreated(Unit unit, Unit builder) { 204 205 int ret = sendTextMsg("unitCreated: " + unit.toString()); 206 sendTextMsg("unitCreated def: " + unit.getDef().getName()); 207 List<UnitDef> buildOptions = unit.getDef().getBuildOptions(); 208 for (UnitDef unitDef : buildOptions) { 209 sendTextMsg("\tbuildOption x: " + unitDef.getName() + "\t" + unitDef.getHumanName() + "\t" + unitDef.toString() + "\t" + unitDef.hashCode()); 210 } 211 212 return ret; 213 } 214 215 @Override unitFinished(Unit unit)216 public int unitFinished(Unit unit) { 217 return 0; // signaling: OK 218 } 219 220 @Override unitIdle(Unit unit)221 public int unitIdle(Unit unit) { 222 return 0; // signaling: OK 223 } 224 225 @Override unitMoveFailed(Unit unit)226 public int unitMoveFailed(Unit unit) { 227 return 0; // signaling: OK 228 } 229 230 @Override unitDamaged(Unit unit, Unit attacker, float damage, AIFloat3 dir, WeaponDef weaponDef, boolean paralyzed)231 public int unitDamaged(Unit unit, Unit attacker, float damage, AIFloat3 dir, WeaponDef weaponDef, boolean paralyzed) { 232 return 0; // signaling: OK 233 } 234 235 @Override unitDestroyed(Unit unit, Unit attacker)236 public int unitDestroyed(Unit unit, Unit attacker) { 237 return 0; // signaling: OK 238 } 239 240 @Override unitGiven(Unit unit, int oldTeamId, int newTeamId)241 public int unitGiven(Unit unit, int oldTeamId, int newTeamId) { 242 return 0; // signaling: OK 243 } 244 245 @Override unitCaptured(Unit unit, int oldTeamId, int newTeamId)246 public int unitCaptured(Unit unit, int oldTeamId, int newTeamId) { 247 return 0; // signaling: OK 248 } 249 250 @Override enemyEnterLOS(Unit enemy)251 public int enemyEnterLOS(Unit enemy) { 252 return 0; // signaling: OK 253 } 254 255 @Override enemyLeaveLOS(Unit enemy)256 public int enemyLeaveLOS(Unit enemy) { 257 return 0; // signaling: OK 258 } 259 260 @Override enemyEnterRadar(Unit enemy)261 public int enemyEnterRadar(Unit enemy) { 262 return 0; // signaling: OK 263 } 264 265 @Override enemyLeaveRadar(Unit enemy)266 public int enemyLeaveRadar(Unit enemy) { 267 return 0; // signaling: OK 268 } 269 270 @Override enemyDamaged(Unit enemy, Unit attacker, float damage, AIFloat3 dir, WeaponDef weaponDef, boolean paralyzed)271 public int enemyDamaged(Unit enemy, Unit attacker, float damage, AIFloat3 dir, WeaponDef weaponDef, boolean paralyzed) { 272 return 0; // signaling: OK 273 } 274 275 @Override enemyDestroyed(Unit enemy, Unit attacker)276 public int enemyDestroyed(Unit enemy, Unit attacker) { 277 return 0; // signaling: OK 278 } 279 280 @Override weaponFired(Unit unit, WeaponDef weaponDef)281 public int weaponFired(Unit unit, WeaponDef weaponDef) { 282 return 0; // signaling: OK 283 } 284 285 @Override playerCommand(java.util.List<Unit> units, int commandTopicId, int playerId)286 public int playerCommand(java.util.List<Unit> units, int commandTopicId, int playerId) { 287 return 0; // signaling: OK 288 } 289 290 @Override commandFinished(Unit unit, int commandId, int commandTopicId)291 public int commandFinished(Unit unit, int commandId, int commandTopicId) { 292 return 0; // signaling: OK 293 } 294 295 @Override seismicPing(AIFloat3 pos, float strength)296 public int seismicPing(AIFloat3 pos, float strength) { 297 return 0; // signaling: OK 298 } 299 300 @Override load(String file)301 public int load(String file) { 302 return 0; // signaling: OK 303 } 304 305 @Override save(String file)306 public int save(String file) { 307 return 0; // signaling: OK 308 } 309 310 @Override enemyCreated(Unit enemy)311 public int enemyCreated(Unit enemy) { 312 return 0; // signaling: OK 313 } 314 315 @Override enemyFinished(Unit enemy)316 public int enemyFinished(Unit enemy) { 317 return 0; // signaling: OK 318 } 319 320 } 321