use of com.ixale.starparse.domain.CharacterDiscipline in project StarParse by Ixale.
the class Parser method processEventHealing.
public void processEventHealing(final Event e, final String effectiveValue) {
if (e.getThreat() != null) {
if (isAbilityFakeHeal(e)) {
// ignore
return;
}
// continue normally
} else if (!isEffectiveLogged) {
if (isAbilityNoThreat(e) && e.getSource() == e.getTarget()) {
// consider as fully effective
e.setEffectiveHeal(e.getValue());
} else {
// no effective, nothing to do
}
return;
}
// resolve effective healing
if (!actorStates.containsKey(e.getSource())) {
// setup healer
actorStates.put(e.getSource(), new ActorState());
}
// detect healer if possible
if (actorStates.get(e.getSource()).role == null) {
final CharacterDiscipline actorDiscipline = getDiscipline(e.getAbility().getGuid(), false);
if (actorDiscipline != null) {
actorStates.get(e.getSource()).role = actorDiscipline.getRole();
// if (logger.isDebugEnabled()) {
// logger.debug("Healing threat ratio set to " + actorDiscipline.getRole() + " for " + e.getSource() + " at " + e.getTs());
// }
}
}
if (isEffectiveLogged) {
if (effectiveValue != null && !effectiveValue.isEmpty()) {
e.setEffectiveHeal("0".equals(effectiveValue) || effectiveValue.startsWith("-") ? /* FIXME */
null : Integer.valueOf(effectiveValue));
} else {
e.setEffectiveHeal(e.getValue());
}
return;
}
// shortcuts
final boolean isGuarded = actorStates.get(e.getSource()).guarded > 0;
final boolean isHealer = actorStates.get(e.getSource()).role == null || CharacterRole.HEALER.equals(actorStates.get(e.getSource()).role);
final boolean isTank = !isHealer && CharacterRole.TANK.equals(actorStates.get(e.getSource()).role);
// calculate effective heal using the threat generated
int effectiveHeal = getEffectiveHeal(e.getThreat(), isHealer && !isAbilityNonreducedThreat(e), isGuarded, isTank);
// sanity check
if (effectiveHeal == e.getValue() || Math.abs(effectiveHeal - e.getValue()) <= HEALING_THREAT_TOLERANCE) {
// fully effective (possibly with rounding issue)
e.setEffectiveHeal(e.getValue());
return;
}
if (effectiveHeal < e.getValue()) {
// not fully effective
e.setEffectiveHeal(effectiveHeal);
if (!isGuarded) {
// try with guard on
effectiveHeal = getEffectiveHeal(e.getThreat(), isHealer && !isAbilityNonreducedThreat(e), true, isTank);
if (Math.abs(effectiveHeal - e.getValue()) <= HEALING_THREAT_TOLERANCE) {
// target is guarded, fix the flag
// if (logger.isDebugEnabled()) {
// logger.debug("Healing threat is reduced by guard, fixed for " + e.getSource() + " at " + e.getTs());
// }
actorStates.get(e.getSource()).guarded = 1;
e.setEffectiveHeal(e.getValue());
return;
}
}
// nothing to be done (e.g. unable to detect not fully effective heals from guarded healers)
return;
}
// value is too high - the ratios are off, try to detect the error ...
if (isHealer && !isAbilityNonreducedThreat(e)) {
// try without the 10% healing reduction
effectiveHeal = getEffectiveHeal(e.getThreat(), false, isGuarded, false);
if (effectiveHeal < (e.getValue() + HEALING_THREAT_TOLERANCE)) {
if (CharacterRole.HEALER.equals(actorStates.get(e.getSource()).role)) {
// we know for sure this is a healer, therefore 10% reduced, so assume
// it is actually the ability not being affected by it (true for many HOTs etc)
} else {
// healing threat reduction not active (probably a DPS class off-healing), reset
actorStates.get(e.getSource()).role = CharacterRole.DPS;
// if (logger.isDebugEnabled()) {
// logger.debug("Healing threat reduction removed for " + e.getSource() + " at " + e.getTs());
// }
}
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
return;
}
}
if (isGuarded) {
// try without the guard 25% reduction
effectiveHeal = getEffectiveHeal(e.getThreat(), isHealer && !isAbilityNonreducedThreat(e), false, isTank);
if (effectiveHeal <= (e.getValue() + HEALING_THREAT_TOLERANCE)) {
// supposedly guarded, but the threat is not reduced (possibly SWTOR bug) - reset the flag
actorStates.get(e.getSource()).guarded = 0;
// if (logger.isDebugEnabled()) {
// logger.debug("Healing threat is not reduced by guard, cancelled for " + e.getSource() + " at " + e.getTs());
// }
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
return;
}
}
if (isGuarded && isHealer && !isAbilityNonreducedThreat(e)) {
// both of the above combined (without 35% reduction)
effectiveHeal = getEffectiveHeal(e.getThreat(), false, false, false);
if (effectiveHeal <= (e.getValue() + HEALING_THREAT_TOLERANCE)) {
actorStates.get(e.getSource()).guarded = 0;
if (logger.isDebugEnabled()) {
logger.debug("Healing threat is not reduced by guard, cancelled for " + e.getSource() + " at " + e.getTs());
}
if (CharacterRole.HEALER.equals(actorStates.get(e.getSource()).role)) {
// we know for sure this is a healer, therefore 10% reduced, so assume
// it is actually the ability not being affected by it (true for many HOTs etc)
} else {
actorStates.get(e.getSource()).role = CharacterRole.DPS;
// if (logger.isDebugEnabled()) {
// logger.debug("Healing threat reduction removed for " + e.getSource() + " at " + e.getTs());
// }
}
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
return;
}
}
if (!isTank) {
// try with tanking 200% ratio (and without the reduction if any)
effectiveHeal = getEffectiveHeal(e.getThreat(), false, isGuarded, true);
if (effectiveHeal <= (e.getValue() + HEALING_THREAT_TOLERANCE)) {
actorStates.get(e.getSource()).role = CharacterRole.TANK;
if (logger.isDebugEnabled()) {
logger.debug("Healing threat ratio set to tank for " + e.getSource() + " at " + e.getTs());
}
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
return;
}
}
if (!isTank && isGuarded) {
// try again, this time even without a guard
effectiveHeal = getEffectiveHeal(e.getThreat(), false, false, true);
if (effectiveHeal <= (e.getValue() + HEALING_THREAT_TOLERANCE)) {
actorStates.get(e.getSource()).guarded = 0;
if (logger.isDebugEnabled()) {
logger.debug("Healing threat is not reduced by guard, cancelled for " + e.getSource() + " at " + e.getTs());
}
actorStates.get(e.getSource()).role = CharacterRole.TANK;
if (logger.isDebugEnabled()) {
logger.debug("Healing threat ratio set to tank for " + e.getSource() + " at " + e.getTs());
}
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
return;
}
}
e.setEffectiveHeal(Math.min(e.getValue(), effectiveHeal));
logger.warn("Unknown heal ratio for event: " + e);
// throw new ParserException("Unknown heal ratio for event: " + e);
}
use of com.ixale.starparse.domain.CharacterDiscipline in project StarParse by Ixale.
the class Parser method parseLogLine.
public boolean parseLogLine(final String line) throws ParserException {
if (line == null) {
logger.warn("Empty line, ignoring");
return false;
}
if (combatLog == null) {
throw new RuntimeException("Enclosing combat log not set");
}
// match the combat log line
Matcher baseMatcher;
if (context.getVersion() == null) {
baseMatcher = v7ZonePattern.matcher(line);
if (baseMatcher.matches()) {
final long timestamp = getTimestamp(baseMatcher);
context.setVersion(baseMatcher.group("Version"));
context.setServerId(baseMatcher.group("ServerId"));
setCharacterName(getSourceActor(baseMatcher, timestamp, null), timestamp);
if (baseMatcher.group("InstanceName") != null && !baseMatcher.group("InstanceName").isEmpty()) {
parseInstanceType(baseMatcher.group("InstanceName"), baseMatcher.group("InstanceGuid"), baseMatcher.group("InstanceType"), baseMatcher.group("InstanceTypeGuid"), timestamp);
}
} else {
// cropped?
for (final Pattern v7pattern : Arrays.asList(v7BasePattern, v7ZonePattern, v7DisciplinePattern)) {
baseMatcher = v7pattern.matcher(line);
if (baseMatcher.matches()) {
// tentative, inconclusive
return false;
}
}
}
if (context.getVersion() == null) {
// give up
// legacy - default
context.setVersion("6.0.0");
}
if (context.getVersion().startsWith("7")) {
basePattern = v7BasePattern;
combatPattern = null;
zonePattern = v7ZonePattern;
disciplinePattern = v7DisciplinePattern;
ignorePattern = null;
isEffectiveLogged = true;
gsfPattern = v7GsfPattern;
} else {
basePattern = legacyBasePattern;
combatPattern = legacyCombatPattern;
zonePattern = null;
disciplinePattern = null;
ignorePattern = null;
isEffectiveLogged = false;
gsfPattern = legacyGsfPattern;
}
if (baseMatcher.matches()) {
logger.info("Version detected as " + context.getVersion());
return false;
}
}
baseMatcher = basePattern.matcher(line);
if (!baseMatcher.matches()) {
if (combatPattern != null) {
// fallback to combat enter/exit
baseMatcher = combatPattern.matcher(line);
}
if (!baseMatcher.matches()) {
if (disciplinePattern != null) {
baseMatcher = disciplinePattern.matcher(line);
if (baseMatcher.matches()) {
final long timestamp = getTimestamp(baseMatcher);
final Actor a = getSourceActor(baseMatcher, timestamp, null);
final CharacterDiscipline newDiscipline = CharacterDiscipline.fromGuid(baseMatcher.group("DisciplineGuid"));
if (newDiscipline != null) {
if (!Objects.equals(newDiscipline, a.getDiscipline())) {
if (logger.isDebugEnabled()) {
logger.debug(a + ": Discipline set as [" + newDiscipline + "] (was " + a.getDiscipline() + ") at " + Event.formatTs(getTimestamp(baseMatcher)));
}
a.setDiscipline(newDiscipline);
if (Actor.Type.SELF.equals(a.getType())) {
clearHotsTracking();
}
}
if (actorStates.containsKey(a)) {
actorStates.get(a).discipline = a.getDiscipline();
actorStates.get(a).role = a.getDiscipline().getRole();
}
}
return false;
}
}
if (zonePattern != null) {
baseMatcher = zonePattern.matcher(line);
if (baseMatcher.matches()) {
final long timestamp = getTimestamp(baseMatcher);
if (baseMatcher.group("InstanceName") != null && !baseMatcher.group("InstanceName").isEmpty()) {
parseInstanceType(baseMatcher.group("InstanceName"), baseMatcher.group("InstanceGuid"), baseMatcher.group("InstanceType"), baseMatcher.group("InstanceTypeGuid"), timestamp);
}
return false;
}
}
if (gsfPattern.matcher(line).matches()) {
// GSF combat line, ignore for now
return false;
}
if (ignorePattern != null && ignorePattern.matcher(line).matches()) {
// intentionally ignored
return false;
}
throw new ParserException("Invalid line");
}
}
// setup event
final Event e = new Event(++eventId, combatLogId, getTimestamp(baseMatcher));
if (e.getEventId() == 1) {
// adjust combat log start from the very first event
combatLog.setTimeFrom(e.getTimestamp());
}
// auto detect name if not already (pre v7)
if (combatLog.getCharacterName() == null && baseMatcher.group("SourcePlayerName") != null && !baseMatcher.group("SourcePlayerName").isEmpty() && baseMatcher.group("SourcePlayerName").equals(baseMatcher.group("TargetPlayerName"))) {
// found, set
setCharacterName(getSourceActor(baseMatcher, e.getTimestamp(), null), e.getTimestamp());
}
// source
if (baseMatcher.group("Source") != null && !baseMatcher.group("Source").isEmpty()) {
e.setSource(getSourceActor(baseMatcher, e.getTimestamp(), baseMatcher.group("EffectGuid")));
} else {
e.setSource(context.getActor("Unknown", Actor.Type.NPC));
}
// target
if (baseMatcher.group("Target") != null && !baseMatcher.group("Target").isEmpty()) {
if ("=".equals(baseMatcher.group("Target"))) {
e.setTarget(e.getSource());
} else {
e.setTarget(getTargetActor(baseMatcher, e.getTimestamp(), baseMatcher.group("EffectGuid")));
}
} else {
if (isEffectiveLogged) {
e.setTarget(e.getSource());
} else {
e.setTarget(context.getActor("Unknown", Actor.Type.NPC));
}
}
if (e.getSource() != null && (Actor.Type.PLAYER.equals(e.getSource().getType()) || Actor.Type.SELF.equals(e.getSource().getType()))) {
ActorState ac = actorStates.get(e.getSource());
if (ac == null) {
ac = new ActorState();
if (e.getSource().getDiscipline() != null) {
// v7+
ac.discipline = e.getSource().getDiscipline();
ac.role = e.getSource().getDiscipline().getRole();
}
if (combat != null && (isEffectiveLogged || Actor.Type.SELF.equals(e.getSource().getType()))) {
context.addCombatPlayer(combat, e.getSource(), ac.discipline);
}
actorStates.put(e.getSource(), ac);
if (Actor.Type.SELF.equals(e.getSource().getType())) {
//
} else {
if (logger.isDebugEnabled()) {
logger.debug("Added group player " + e.getSource() + " at " + e.getTs());
}
}
} else if (combat != null) {
if (isEffectiveLogged || Actor.Type.SELF.equals(e.getSource().getType())) {
context.addCombatPlayer(combat, e.getSource(), ac.discipline);
}
}
}
if (zonePattern == null && baseMatcher.group("Value") != null && "836045448945489".equals(baseMatcher.group("EffectGuid"))) {
// EnterCombat
// enter, any ops details? // pre v7
parseInstanceType(null, null, baseMatcher.group("Value"), null, e.getTimestamp());
}
// ability
if (baseMatcher.group("Ability") != null && !baseMatcher.group("Ability").isEmpty()) {
e.setAbility(getEntity(baseMatcher.group("AbilityName"), baseMatcher.group("AbilityGuid")));
}
// action
e.setAction(getEntity(baseMatcher.group("ActionName"), baseMatcher.group("ActionGuid")));
// effect
e.setEffect(getEntity(baseMatcher.group("EffectName"), baseMatcher.group("EffectGuid")));
// value (healing / damage)
if (baseMatcher.group("Value") != null && !EntityGuid.EnterCombat.toString().equals(baseMatcher.group("EffectGuid")) && !EntityGuid.ExitCombat.toString().equals(baseMatcher.group("EffectGuid"))) {
e.setValue(Integer.parseInt(baseMatcher.group("Value")));
// critical hit?
e.setCrit(baseMatcher.group("IsCrit") != null);
// damage
if (baseMatcher.group("DamageType") != null && !baseMatcher.group("DamageTypeGuid").equals(EntityGuid.Charges.toString())) {
e.setDamage(getEntity(baseMatcher.group("DamageType"), baseMatcher.group("DamageTypeGuid")));
}
// reflect
if (baseMatcher.group("ReflectType") != null) {
e.setReflect(getEntity(baseMatcher.group("ReflectType"), baseMatcher.group("ReflectTypeGuid")));
}
// mitigation
if (baseMatcher.group("IsMitigation") != null) {
if (baseMatcher.group("MitigationType") != null) {
e.setMitigation(getEntity(baseMatcher.group("MitigationType"), baseMatcher.group("MitigationTypeGuid")));
// attack type (incoming attacks to known actors only)
if (combat != null && actorStates.containsKey(e.getTarget())) {
processAttackType(e);
}
} else {
// unknown mitigation
e.setMitigation(getEntity("unknown", "-1"));
}
}
// absorption
if (baseMatcher.group("AbsorbValue") != null) {
e.setAbsorption(getEntity(baseMatcher.group("AbsorbType"), baseMatcher.group("AbsorbTypeGuid")));
e.setAbsorbed(Integer.parseInt(baseMatcher.group("AbsorbValue")));
if (e.getValue() != null && e.getAbsorbed() != null && e.getAbsorbed() > e.getValue()) {
e.setAbsorbed(e.getValue());
}
if (isEffectiveLogged) {
final String s;
if (e.getSource() == e.getTarget()) {
// no TargetMaxHp for [=]
s = baseMatcher.group("SourceMaxHp");
} else {
s = baseMatcher.group("TargetMaxHp");
}
final Integer maxHp = s == null ? null : Integer.valueOf(s);
if (maxHp != null && maxHp < e.getAbsorbed()) {
// looking at you, Ciphas & Doom
e.setAbsorbed(maxHp);
}
}
}
}
// threat
if (baseMatcher.group("Threat") != null) {
e.setThreat(Long.parseLong(baseMatcher.group("Threat")));
}
// guard
if (actorStates.containsKey(e.getSource()) || actorStates.containsKey(e.getTarget())) {
processEventGuard(e);
}
// combat
final boolean wasInCombat = combat != null;
processEventCombat(e);
// healing
if (isEffectHeal(e)) {
processEventHealing(e, isEffectiveLogged ? baseMatcher.group("Effective") : null);
}
// effect
if (actorStates.containsKey(e.getSource()) || actorStates.containsKey(e.getTarget())) {
processEventEffect(e);
}
// absorption
processEventAbsorption(e, isEffectiveLogged ? baseMatcher.group("Effective") : null);
// instance swap?
if (isEffectEqual(e, EntityGuid.SafeLoginImmunity.getGuid()) && isActionApply(e)) {
if (zonePattern == null) {
instanceMode = null;
instanceSize = null;
}
isUsingMimCrystal = false;
if (logger.isDebugEnabled()) {
logger.debug("Instance reset at " + e.getTs());
}
clearHotsTracking();
// } else if (isEffectEqual(e, EntityGuid.Bolster.getGuid())) {
// instanceMode = Raid.Mode.SM;
} else if (isEffectEqual(e, 3638571739119616L) && isActionApply(e)) {
// Nightmare Fury
instanceMode = Raid.Mode.NiM;
if (logger.isDebugEnabled()) {
logger.debug("NiM crystal detected at " + e.getTs());
}
if (!isUsingMimCrystal && combat != null) {
// activated mid fight?
context.addCombatEvent(combat.getCombatId(), e.getSource(), Event.Type.NIM_CRYSTAL, e.getTimestamp());
}
isUsingMimCrystal = true;
}
// hots tracking
if (isSourceThisPlayer(e) && isTargetAnyPlayer(e) && (combat == null || actorStates.get(e.getSource()).discipline == null || CharacterRole.HEALER.equals(actorStates.get(e.getSource()).discipline.getRole()))) {
processEventHots(e, baseMatcher);
}
events.add(e);
return wasInCombat && combat == null;
}
use of com.ixale.starparse.domain.CharacterDiscipline in project StarParse by Ixale.
the class RankServiceImpl method getRanking.
private void getRanking(final RaidBoss boss, final RankType type, final CharacterDiscipline discipline, final Consumer<Ranking> callback) {
final String key = buildKey(boss, type, discipline);
if (!rankings.containsKey(key)) {
if (rankingExecutor == null) {
rankingExecutor = Executors.newSingleThreadExecutor(r -> {
final Thread worker = new Thread(r, "Ranking Worker");
worker.setDaemon(true);
return worker;
});
}
rankingExecutor.execute(() -> {
try {
// build remote URL
final URL url = buildUrl(boss, host, key);
// fetch from remote
final String content = FileDownloader.fetchFile(url);
// parse
final Ranking ranking = readRanking(content);
// cache
rankings.put(key, ranking);
Platform.runLater(() -> {
callback.accept(rankings.get(key));
});
if (logger.isDebugEnabled()) {
logger.debug("Ranking fetched from remote (" + boss + ", " + type + ", " + discipline + "): " + ranking);
}
} catch (Exception e) {
if (e.getMessage().equals("Read timed out") || e.getMessage().startsWith("Server returned non-OK status: 404")) {
// local issue, silently ignore
return;
}
logger.error("Failed to rank " + key + ": " + e.getMessage(), e);
}
});
return;
}
callback.accept(rankings.get(key));
}
use of com.ixale.starparse.domain.CharacterDiscipline in project StarParse by Ixale.
the class ParserTest method testDisciplines.
@Test
public void testDisciplines() throws Exception {
for (CharacterDiscipline discipline : CharacterDiscipline.values()) {
for (long guid : discipline.getAbilities()) {
final Parser p = createParser();
p.parseLogLine("[14:14:35.306] [@Ixayly] [@Ixayly] [] [Event {836045448945472}: EnterCombat {836045448945489}] ()");
assertNull(p.getActorStates().get(p.getContext().getActor("Ixayly", Actor.Type.SELF)).discipline);
p.parseLogLine("[21:30:14.981] [@SomeoneElse] [@Ixayly] [FooBar {" + guid + "}] [Event {836045448945472}: AbilityActivate {836045448945479}] ()");
assertNull(p.getActorStates().get(p.getContext().getActor("Ixayly", Actor.Type.SELF)).discipline);
p.parseLogLine("[21:30:14.981] [@SomeoneElse] [@SomeoneElse] [FooBar {" + guid + "}] [Event {836045448945472}: AbilityActivate {836045448945479}] ()");
assertNull(p.getActorStates().get(p.getContext().getActor("Ixayly", Actor.Type.SELF)).discipline);
p.parseLogLine("[21:30:14.981] [@SomeoneElse] [@SomeoneElse] [FooBar {" + guid + "}] [Event {836045448945472}: AbilityActivate {836045448945479}] ()");
assertNull(p.getActorStates().get(p.getContext().getActor("Ixayly", Actor.Type.SELF)).discipline);
if (CharacterClass.Sentinel.equals(discipline.getCharacterClass())) {
p.parseLogLine("[04:41:22.825] [@Ixayly] [@Ixayly] [Centering {2528580391141376}] [ApplyEffect {836045448945477}: Centering {2528580391141376}] ()");
}
if (CharacterClass.Marauder.equals(discipline.getCharacterClass())) {
p.parseLogLine("[04:41:22.825] [@Ixayly] [@Ixayly] [Fury {2515454971084800}] [ApplyEffect {836045448945477}: Fury {2515454971084800}] ()");
}
p.parseLogLine("[21:30:14.981] [@Ixayly] [@Ixayly] [FooBar {" + guid + "}] [Event {836045448945472}: AbilityActivate {836045448945479}] ()");
assertEquals("Failed to detect discipline", discipline, p.getActorStates().get(p.getContext().getActor("Ixayly", Actor.Type.SELF)).discipline);
}
}
}
use of com.ixale.starparse.domain.CharacterDiscipline in project StarParse by Ixale.
the class CombatDaoImpl method storeCombat.
private void storeCombat(final Combat c, boolean create, boolean close) throws Exception {
// resolve name
final String combatName = close ? getJdbcTemplate().query(SQL_GET_NAME, new Object[] { c.getEventIdFrom(), c.getEventIdTo() != null ? c.getEventIdTo() : Integer.MAX_VALUE }, rs -> rs.next() ? rs.getString("combat_name") : null) : null;
final Timestamp fromTs = new Timestamp(c.getTimeFrom());
Integer selfTick = null;
for (final Map.Entry<Actor, CharacterDiscipline> entry : context.getCombatInfo().get(c.getCombatId()).getCombatPlayers().entrySet()) {
// gather statistics
final CombatStats stats = getCombatStats(c, new CombatSelection(c.getEventIdFrom(), c.getEventIdTo(), null, null), entry.getKey().getName());
// insert or update (same structure)
final Timestamp toTs = new Timestamp(c.getTimeTo() != null ? c.getTimeTo() : c.getTimeFrom() + stats.getTick());
if (selfTick == null) {
// take first encountered (== this player)
selfTick = stats.getTick();
}
getJdbcTemplate().update(create ? SQL_INSERT_STATS : SQL_UPDATE_STATS, new Object[] { c.getEventIdFrom(), c.getEventIdTo(), fromTs, toTs, stats.getActions(), stats.getApm(), stats.getDamage(), stats.getDps(), stats.getHeal(), stats.getHps(), stats.getEffectiveHeal(), stats.getEhps(), stats.getEhpsPercent(), stats.getDamageTaken(), stats.getDtps(), stats.getAbsorbed(), stats.getAps(), stats.getHealTaken(), stats.getHpsTaken(), stats.getEhpsTaken(), stats.getEffectiveHealTakenTotal(), stats.getThreat(), stats.getThreatPositive(), stats.getTps(), entry.getValue() != null ? entry.getValue().name() : null, c.getCombatId(), entry.getKey().getName() });
}
getJdbcTemplate().update(create ? SQL_INSERT : SQL_UPDATE, new Object[] { c.getLogId(), c.getEventIdFrom(), c.getEventIdTo(), fromTs, new Timestamp(c.getTimeTo() != null ? c.getTimeTo() : c.getTimeFrom() + (selfTick == null ? 1000 : selfTick)), c.getBoss() != null ? c.getBoss().getRaid().getName() : null, c.getBoss() != null ? c.getBoss().toString() : null, combatName, c.isPvp() != null ? c.isPvp() : null, !close, c.getCombatId() });
}
Aggregations