99 lines
3.9 KiB
Java
99 lines
3.9 KiB
Java
package tc.oc.pgm.timelimit;
|
|
|
|
import java.time.Duration;
|
|
import java.util.Optional;
|
|
import java.util.logging.Logger;
|
|
import javax.annotation.Nullable;
|
|
import javax.inject.Inject;
|
|
import javax.inject.Provider;
|
|
|
|
import org.jdom2.Document;
|
|
import org.jdom2.Element;
|
|
import tc.oc.commons.core.util.Comparables;
|
|
import tc.oc.pgm.map.MapModule;
|
|
import tc.oc.pgm.map.MapModuleContext;
|
|
import tc.oc.pgm.map.MapModuleFactory;
|
|
import tc.oc.pgm.map.ProtoVersions;
|
|
import tc.oc.pgm.match.Match;
|
|
import tc.oc.pgm.match.MatchModuleFactory;
|
|
import tc.oc.pgm.module.ModuleDescription;
|
|
import tc.oc.pgm.utils.XMLUtils;
|
|
import tc.oc.pgm.victory.DefaultResult;
|
|
import tc.oc.pgm.victory.MatchResult;
|
|
import tc.oc.pgm.victory.VictoryResultParser;
|
|
import tc.oc.pgm.xml.InvalidXMLException;
|
|
import tc.oc.pgm.xml.Node;
|
|
|
|
import static tc.oc.commons.core.exception.LambdaExceptionUtils.rethrowFunction;
|
|
|
|
@ModuleDescription(name = "Time Limit")
|
|
public class TimeLimitModule implements MapModule, MatchModuleFactory<TimeLimitMatchModule> {
|
|
private final @Nullable TimeLimitDefinition timeLimit;
|
|
|
|
public TimeLimitModule(@Nullable TimeLimitDefinition limit) {
|
|
this.timeLimit = limit;
|
|
}
|
|
|
|
@Override
|
|
public TimeLimitMatchModule createMatchModule(Match match) {
|
|
return new TimeLimitMatchModule(match, this.timeLimit);
|
|
}
|
|
|
|
// ---------------------
|
|
// ---- XML Parsing ----
|
|
// ---------------------
|
|
|
|
public static class Factory extends MapModuleFactory<TimeLimitModule> {
|
|
|
|
@Inject private Provider<VictoryResultParser> victoryResultParser;
|
|
|
|
@Override
|
|
public TimeLimitModule parse(MapModuleContext context, Logger logger, Document doc) throws InvalidXMLException {
|
|
TimeLimitDefinition timeLimit = parseTimeLimit(doc.getRootElement());
|
|
timeLimit = parseLegacyTimeLimit(context, doc.getRootElement(), "score", timeLimit);
|
|
timeLimit = parseLegacyTimeLimit(context, doc.getRootElement(), "blitz", timeLimit);
|
|
|
|
// TimeLimitModule always loads
|
|
return new TimeLimitModule(timeLimit);
|
|
}
|
|
|
|
private @Nullable TimeLimitDefinition parseLegacyTimeLimit(MapModuleContext context, Element el, String legacyTag, TimeLimitDefinition oldTimeLimit) throws InvalidXMLException {
|
|
el = el.getChild(legacyTag);
|
|
if(el != null) {
|
|
TimeLimitDefinition newTimeLimit = parseTimeLimit(el);
|
|
if(newTimeLimit != null) {
|
|
if(context.getProto().isNoOlderThan(ProtoVersions.REMOVE_SCORE_TIME_LIMIT)) {
|
|
throw new InvalidXMLException("<time> inside <" + legacyTag + "> is no longer supported, use root <time> instead", el);
|
|
}
|
|
if(oldTimeLimit != null) {
|
|
throw new InvalidXMLException("Time limit conflicts with another one that is already defined", el);
|
|
}
|
|
return newTimeLimit;
|
|
}
|
|
}
|
|
|
|
return oldTimeLimit;
|
|
}
|
|
|
|
private @Nullable TimeLimitDefinition parseTimeLimit(Element el) throws InvalidXMLException {
|
|
el = el.getChild("time");
|
|
if(el == null) return null;
|
|
|
|
final Duration duration = XMLUtils.parseDuration(Node.of(el));
|
|
if(Comparables.greaterThan(duration, TimeLimit.MAX_DURATION)) {
|
|
throw new InvalidXMLException("Time limit cannot exceed " + TimeLimit.MAX_DURATION.toDays() + " days", el);
|
|
}
|
|
|
|
return new TimeLimitDefinition(
|
|
duration,
|
|
parseVictoryCondition(Node.tryAttr(el, "result")),
|
|
XMLUtils.parseBoolean(el.getAttribute("show"), true)
|
|
);
|
|
}
|
|
|
|
private MatchResult parseVictoryCondition(Optional<Node> node) throws InvalidXMLException {
|
|
return node.map(rethrowFunction(n -> victoryResultParser.get().parse(n)))
|
|
.orElseGet(DefaultResult::new);
|
|
}
|
|
}
|
|
} |