10 Commits
Author SHA1 Message Date
caseload e635d42c9a update 1.3.2 2024-10-03 21:57:54 -05:00
caseload 7f42f824ed Add last adjustment check 2024-09-30 12:53:08 -05:00
caseload 97f8b47946 fix npe and cme 2024-09-30 12:51:24 -05:00
caseload 5966e7ca73 Update README.md 2024-09-27 17:34:09 -05:00
caseload 757a35e064 Update README.md 2024-09-27 17:32:44 -05:00
caseload cd779a9d91 Update README.md 2024-09-27 16:55:00 -05:00
caseload b21c31dd5e Update README.md 2024-09-24 16:10:15 -05:00
caseload ebfc3f4b22 Update README.md 2024-09-24 15:44:40 -05:00
caseload 70a37506f7 Update README.md 2024-09-24 15:44:03 -05:00
caseload 906498456d Create README.md 2024-09-24 15:32:08 -05:00
9 changed files with 51 additions and 32 deletions

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
Minecraft doesn’t factor in network latency when determining a player's actions on the server.
This causes the server to receive outdated information that doesn’t reflect the player's clientside position.
As a result, players take negative velocity when they're on the ground clientside, but not serverside.
This plugin handles knockback as if it were calculated clientside, ensuring that no player is at a disadvantage,
regardless of their own or their opponent’s connection.
## Frequently Asked Questions (FAQ)
### Does this change put high ping players at a disadvantage?
**It depends on the player.** Some may notice a difference if they're used to relying on high ping to reduce knockback. For others, it could actually be an advantage.
### How does this change benefit high ping players?
**Knockback control.** For example, it will be easier to escape crit chains and punish crit.
### Why was the configurability of ping offset removed?
**It promotes consistency across all servers.** Extensive testing with top players has shown that an offset of 20 provides a balanced experience for everyone.
### How do I change the ping offset?
**You must run a modified build of KnockbackSync.** The variable can be changed inside of the [PlayerData](src/main/java/me/caseload/knockbacksync/manager/PlayerData.java) class.
## License
GNU General Public License v3.0 or later
See [COPYING](COPYING) to see the full text.
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>me.caseload</groupId>
<artifactId>KnockbackSync</artifactId>
<version>1.3</version>
<version>1.3.2</version>
<packaging>jar</packaging>
<name>KnockbackSync</name>
@@ -22,6 +22,7 @@ public final class KnockbackSync extends JavaPlugin {
private boolean toggled;
private boolean runnable;
private boolean updateAvailable;
private boolean notifyUpdate;
private long runnableInterval;
private long combatTimer;
@@ -58,7 +59,8 @@ public final class KnockbackSync extends JavaPlugin {
runnable = getConfig().getBoolean("runnable.enabled", true);
runnableInterval = getConfig().getLong("runnable.interval", 5L);
combatTimer = getConfig().getLong("runnable.timer", 30L);
spikeThreshold = getConfig().getLong("spike_threshold", 25L);
spikeThreshold = getConfig().getLong("spike_threshold", 20L);
notifyUpdate = getConfig().getBoolean("notify_updates", true);
if (runnable)
new PingRunnable().runTaskTimerAsynchronously(this, 0L, runnableInterval);
@@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.UUID;
@@ -20,7 +19,7 @@ public class PlayerJoinQuitListener implements Listener {
Player player = event.getPlayer();
PlayerDataManager.addPlayerData(player.getUniqueId(), new PlayerData(player));
if (KnockbackSync.getInstance().isUpdateAvailable() && player.hasPermission("knockbacksync.update"))
if (KnockbackSync.getInstance().isUpdateAvailable() && KnockbackSync.getInstance().isNotifyUpdate() && player.hasPermission("knockbacksync.update"))
player.sendMessage(ChatColor.translateAlternateColorCodes(
'&',
"&6An updated version of &eKnockbackSync &6is now available for download at: &bhttps://github.com/CASELOAD7000/knockback-sync/releases/latest"
@@ -37,15 +36,4 @@ public class PlayerJoinQuitListener implements Listener {
PlayerDataManager.removePlayerData(uuid);
}
@EventHandler
public void onPlayerKick(PlayerKickEvent event) {
UUID uuid = event.getPlayer().getUniqueId();
PlayerData playerData = PlayerDataManager.getPlayerData(uuid);
if (playerData.isInCombat())
playerData.quitCombat(true);
PlayerDataManager.removePlayerData(uuid);
}
}
@@ -37,14 +37,18 @@ public class PlayerKnockbackListener implements Listener {
Vector velocity = victim.getVelocity();
Double verticalVelocity = playerData.getVerticalVelocity();
if (verticalVelocity == null || !playerData.isOnGround(velocity.getY()))
return;
Long lastAdjustment = playerData.getLastAdjustment();
if (lastAdjustment != null && System.currentTimeMillis() - lastAdjustment < 250)
return;
Vector adjustedVelocity = velocity.clone().setY(
verticalVelocity
);
victim.setVelocity(adjustedVelocity);
playerData.setLastAdjustment(System.currentTimeMillis());
}
}
@@ -2,17 +2,16 @@ package me.caseload.knockbacksync.manager;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class CombatManager {
private static final Set<UUID> combatPlayers = new HashSet<>();
private static final Set<UUID> combatPlayers = ConcurrentHashMap.newKeySet();
public static @NotNull Set<UUID> getPlayers() {
return Collections.unmodifiableSet(combatPlayers);
return combatPlayers;
}
public static void addPlayer(UUID uuid) {
@@ -8,6 +8,7 @@ import me.caseload.knockbacksync.KnockbackSync;
import me.caseload.knockbacksync.util.MathUtil;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@@ -28,7 +29,7 @@ public class PlayerData {
private final Player player;
// Please read the GitHub FAQ before adjusting.
private static final long PING_OFFSET = 20;
private static final long PING_OFFSET = 25;
@NotNull
private final Map<Integer, Long> timeline = new HashMap<>();
@@ -40,7 +41,7 @@ public class PlayerData {
private BukkitTask combatTask;
@Nullable @Setter
private Long ping, previousPing;
private Long ping, previousPing, lastAdjustment;
@Nullable @Setter
private Double verticalVelocity;
@@ -74,14 +75,10 @@ public class PlayerData {
}
/**
* Determines if the Player is on the ground, either serverside or clientside.
* Determines if the Player is on the ground clientside, but not serverside
* <p>
* Returns <code>ping ≥ (tMax + tFall)</code> and <code>gDist ≤ 1.3</code>
* <p>
* Returns <code>true</code> if:
* <ul>
* <li>Clientside: <code>ping ≥ (tMax + tFall)</code> and <code>gDist ≤ 1.3</code></li>
* <li>Serverside: <code>gDist ≤ 0</code></li>
* </ul>
*
* Where:
* <ul>
* <li><code>ping</code>: Estimated latency</li>
@@ -104,7 +101,7 @@ public class PlayerData {
double gDist = getDistanceToGround();
if (gDist <= 0)
return true;
return false; // prevent player from taking adjusted knockback when on ground serverside
int tMax = verticalVelocity > 0 ? MathUtil.calculateTimeToMaxVelocity(verticalVelocity) : 0;
double mH = verticalVelocity > 0 ? MathUtil.calculateDistanceTraveled(verticalVelocity, tMax) : 0;
@@ -172,6 +169,10 @@ public class PlayerData {
yAxis -= resistanceFactor;
}
// vertical velocity is always 0.4 when you have knockback level higher than 0
if (attacker.getInventory().getItemInMainHand().getEnchantmentLevel(Enchantment.KNOCKBACK) > 0)
yAxis = 0.4;
return yAxis;
}
+1 -1
View File
@@ -21,7 +21,7 @@ runnable:
# The minimum change in ping required for it to be considered a lag spike.
# If the difference between the latest and previous ping is greater than or equal to
# the threshold, the previous ping value is used to avoid calculation inaccuracies.
spike_threshold: 25
spike_threshold: 20
enable_message: "&aSuccessfully enabled KnockbackSync."
disable_message: "&cSuccessfully disabled KnockbackSync."
+1 -1
View File
@@ -1,5 +1,5 @@
name: KnockbackSync
version: '1.3'
version: '1.3.2'
main: me.caseload.knockbacksync.KnockbackSync
api-version: '1.18'
authors: [ Caseload ]