Skip to content

Commit 8caa2c2

Browse files
committed
Fix untag/death inconsistencies
1 parent fe23253 commit 8caa2c2

6 files changed

Lines changed: 50 additions & 13 deletions

File tree

pvpmanager/src/main/java/me/chancesd/pvpmanager/command/Tag.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public void execute(final CommandSender sender, final String label, final List<C
4949
final CommandArgument targetArg = getArgument(args, ARG_TARGET);
5050
final CommandArgument timeArg = getArgument(args, ARG_TIME);
5151
final long timeInMs = timeArg.getAsInt() * 1000L;
52+
53+
if (timeInMs <= 0) {
54+
ChatUtils.send(sender, Lang.PREFIX + " &#FF5555Combat time must be positive (greater than 0)");
55+
return;
56+
}
5257

5358
if (targetArg.isWildcard()) {
5459
tagAll(sender, timeInMs);

pvpmanager/src/main/java/me/chancesd/pvpmanager/player/CombatPlayer.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public class CombatPlayer extends EcoPlayer {
4545
private boolean lastDeathWasPvP;
4646
private long toggleTime;
4747
private long respawnTime;
48-
private long taggedTime;
49-
private long totalTagTime;
48+
private volatile long taggedTime;
49+
private volatile long totalTagTime;
5050
private long lastKillCommandTime;
5151
private NewbieTask newbieTask;
5252
private CombatPlayer enemy;
@@ -100,6 +100,7 @@ public boolean isEnemyOf(final CombatPlayer enemyPlayer) {
100100
public void addEnemy(final CombatPlayer enemyPlayer) {
101101
if (enemyPlayer == this)
102102
return;
103+
this.enemy = enemyPlayer;
103104
this.lastHitters.add(enemyPlayer);
104105
}
105106

@@ -157,11 +158,11 @@ public final void tag(final boolean isAttacker, final CombatPlayer other, final
157158
}
158159

159160
this.taggedTime = System.currentTimeMillis();
160-
this.enemy = other;
161161
addEnemy(other);
162162

163-
if (tagged)
163+
if (tagged) {
164164
return;
165+
}
165166

166167
this.totalTagTime = timeMiliseconds;
167168

@@ -207,6 +208,10 @@ public final void tag(final boolean isAttacker, final CombatPlayer other) {
207208
* Takes the player out of combat
208209
*/
209210
public final void untag(final UntagReason reason) {
211+
if (!isInCombat()) {
212+
Log.debug("Not untagging " + getName() + " because player is not tagged.");
213+
return;
214+
}
210215
final PlayerUntagEvent event = new PlayerUntagEvent(getPlayer(), this, reason);
211216
ScheduleUtils.ensureMainThread(() -> {
212217
Bukkit.getPluginManager().callEvent(event);

pvpmanager/src/main/java/me/chancesd/pvpmanager/setting/LogFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public final void logCombatLog(final CombatPlayer player) {
6363
locationInfo = " | Location:Unknown";
6464
}
6565

66-
final String data = player.getName() + " tried to escape combat! (" + player.getTagTimeLeft() / 1000 + "s left)"
66+
final String data = player.getName() + " tried to escape combat! (" + String.format("%.3f", player.getTagTimeLeft() / 1000.0) + "s left)"
6767
+ " | In combat with: " + player.getEnemies().stream().map(CombatPlayer::getName).toList() + locationInfo;
6868
write(format.format(new Date()) + data);
6969
}

pvpmanager/src/main/java/me/chancesd/pvpmanager/tasks/NewbieTask.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ private void startBossBarDisplay() {
7676
final TimeProgressSource timeProgressSource = new TimeProgressSource() {
7777
@Override
7878
public long getGoal() {
79-
return getDuration() / 1000;
79+
return getDuration();
8080
}
8181

8282
@Override
83-
public double getProgress() {
84-
return (getDuration() - getTimeleft()) / 1000.0;
83+
public long getProgress() {
84+
return getDuration() - getTimeleft();
8585
}
8686
};
8787

pvpmanager/src/main/java/me/chancesd/pvpmanager/tasks/TagTask.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ private final void startTracking(final CombatPlayer combatPlayer) {
6363
final TimeProgressSource timeProgressSource = new TimeProgressSource() {
6464
@Override
6565
public long getGoal() {
66-
return combatPlayer.getTotalTagTime() / 1000;
66+
return combatPlayer.getTotalTagTime();
6767
}
6868

6969
@Override
70-
public double getProgress() {
71-
return (System.currentTimeMillis() - combatPlayer.getTaggedTime()) / 1000D;
70+
public long getProgress() {
71+
return System.currentTimeMillis() - combatPlayer.getTaggedTime();
7272
}
7373
};
7474

@@ -82,13 +82,16 @@ public double getProgress() {
8282
}
8383
if (Conf.BOSS_BAR_ENABLED.asBool()) {
8484
builder.withBossBar(bossBar.build(), timeSource -> {
85+
final double secondsRemaining = (timeSource.getGoal() - timeSource.getProgress()) / 1000.0;
8586
final String message = Conf.BOSS_BAR_MESSAGE.asString().replace("<time>",
86-
Double.toString(Utils.roundTo1Decimal(timeSource.getGoal() - timeSource.getProgress())));
87+
Double.toString(Utils.roundTo1Decimal(secondsRemaining)));
8788
return CombatUtils.processPlaceholders(combatPlayer.getPlayer(), message);
8889
});
8990
}
9091
final CountdownData countdownData = builder.withTimeSource(timeProgressSource)
91-
.onFinish(() -> combatPlayer.untag(UntagReason.TIME_EXPIRED))
92+
.onFinish(() -> {
93+
combatPlayer.untag(UntagReason.TIME_EXPIRED);
94+
})
9295
.build(combatPlayer.getPlayer());
9396

9497
display.createCountdown(combatPlayer.getPlayer(), countdownData);

pvpmanager/src/test/java/me/chancesd/pvpmanager/listener/PlayerListenerTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,22 @@ final void regularDeath() {
120120

121121
@Test
122122
final void inCombatDeath() {
123+
// Test 1: Default config (UNTAG_ON_KILL=false, SELF_TAG=false)
123124
tagPlayer(combatDefender, combatAttacker);
124125
tagPlayer(combatAttacker, combatDefender);
125126
listener.onPlayerDeath(createDeathEvent(defender));
126127
assertFalse(combatDefender.isInCombat());
127128
assertTrue(combatAttacker.isInCombat());
128129

130+
// Test 2: UNTAG_ON_KILL=true
129131
Conf.UNTAG_ON_KILL.set(true);
130132
tagPlayer(combatDefender, combatAttacker);
131133
tagPlayer(combatAttacker, combatDefender);
132134
listener.onPlayerDeath(createDeathEvent(defender));
133135
assertFalse(combatDefender.isInCombat());
134136
assertFalse(combatAttacker.isInCombat());
135137

138+
// Test 3: SELF_TAG=true
136139
Conf.SELF_TAG.set(true);
137140
tagPlayer(combatAttacker, combatAttacker);
138141
tagPlayer(combatDefender, combatAttacker);
@@ -142,4 +145,25 @@ final void inCombatDeath() {
142145
assertFalse(combatAttacker.isInCombat());
143146
}
144147

148+
@Test
149+
final void deathEdgeCases() {
150+
Conf.SELF_TAG.set(false);
151+
tagPlayer(combatDefender, combatAttacker);
152+
PlayerDeathEvent event = mock(PlayerDeathEvent.class);
153+
when(event.getEntity()).thenReturn(defender);
154+
when(defender.getKiller()).thenReturn(defender);
155+
156+
listener.onPlayerDeath(event);
157+
assertFalse(combatDefender.isInCombat(), "Player should be untagged after self-kill");
158+
159+
// Test 2: Environmental death (killer = null)
160+
tagPlayer(combatDefender, combatAttacker);
161+
event = mock(PlayerDeathEvent.class);
162+
when(event.getEntity()).thenReturn(defender);
163+
when(defender.getKiller()).thenReturn(null);
164+
165+
listener.onPlayerDeath(event);
166+
assertFalse(combatDefender.isInCombat(), "Player should be untagged after environmental death");
167+
}
168+
145169
}

0 commit comments

Comments
 (0)