Fix score attribution and preserve custom scores

This commit is contained in:
2026-09-26 18:46:22 -07:00
parent 11c5c94839
commit 648e706c86
5 changed files with 45 additions and 21 deletions

23
.github/workflows/gradle.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Gradle Build
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
repository: headhunter45/ScoreKeeper
path: ScoreKeeper
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '25'
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew publishToMavenLocal
working-directory: ScoreKeeper
- run: ./gradlew test build

View File

@@ -23,7 +23,7 @@ ScoreTable:
Restart the server after editing the configuration. A configured value of `0` suppresses that entity from the score table shown to players when they join. Restart the server after editing the configuration. A configured value of `0` suppresses that entity from the score table shown to players when they join.
MobScores has no commands of its own. Current killer attribution is recorded for zombie entities directly damaged by a player; projectile and other mob attribution are not currently handled. Points are awarded through ScoreKeeper's existing player API and follow the player's UUID-backed score. MobScores has no commands of its own. It records credit for configured entity types damaged directly by a player or by a projectile fired by a player. Other mob attribution is not currently handled. Points are awarded through ScoreKeeper's existing player API and follow the player's UUID-backed score.
## Build ## Build

View File

@@ -17,7 +17,7 @@
| MS-13 | Done | Build the plugin with Gradle (./gradlew build) and test on a modern Paper server using the provided bash scripts. | MS-13 | Done | Build the plugin with Gradle (./gradlew build) and test on a modern Paper server using the provided bash scripts.
| MS-14 | Done | Address any bugs or incompatibilities found during testing on a modern server. | MS-14 | Done | Address any bugs or incompatibilities found during testing on a modern server.
| MS-15 | Done | Update README.md and CONTRIBUTING.md with new build, usage, and development instructions. _(Depends on: bugfixes)_ | MS-15 | Done | Update README.md and CONTRIBUTING.md with new build, usage, and development instructions. _(Depends on: bugfixes)_
| MS-16 | Ready | (Optional) Add new features, quality-of-life improvements, automated tests, or CI configuration. _(Depends on: docs update)_ | MS-16 | Done | (Optional) Add new features, quality-of-life improvements, automated tests, or CI configuration. _(Depends on: docs update)_
| MS-17 | Done | Update MobScores to depend on the latest version of the ScoreKeeper plugin (update dependency in build.gradle and plugin.yml as needed). | MS-17 | Done | Update MobScores to depend on the latest version of the ScoreKeeper plugin (update dependency in build.gradle and plugin.yml as needed).
| MS-18 | Ready | Test MobScores with the latest ScoreKeeper to ensure score tracking, awarding, and all integration points work as expected (including with players who have changed names). | MS-18 | Ready | Test MobScores with the latest ScoreKeeper to ensure score tracking, awarding, and all integration points work as expected (including with players who have changed names).
| MS-19 | Done | Refactor MobDeathListener and PlayerConnectListener to implement Listener interface and use @EventHandler annotations instead of extending EntityListener/PlayerListener. | MS-19 | Done | Refactor MobDeathListener and PlayerConnectListener to implement Listener interface and use @EventHandler annotations instead of extending EntityListener/PlayerListener.

View File

@@ -18,7 +18,6 @@ along with MobScores. If not, see <http://www.gnu.org/licenses/>.
package com.majinnaibu.minecraft.plugins.mobscores; package com.majinnaibu.minecraft.plugins.mobscores;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@@ -29,7 +28,6 @@ import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@@ -58,12 +56,9 @@ public class MobScoresPlugin extends JavaPlugin {
// Create the default config if it doesn't exist. // Create the default config if it doesn't exist.
saveDefaultConfig(); saveDefaultConfig();
getConfig().set("ScoreTable", serializeScoreTable(getDefaultScoreTable()));
saveConfig();
// Load our score table from config or set defaults. // Load our score table from config or set defaults.
if (getConfig().isConfigurationSection("ScoreTable")) { if (getConfig().isConfigurationSection("ScoreTable")) {
deserializeScoreTable(getConfig().getConfigurationSection("ScoreTable").getValues(false)); _scoreTable = deserializeScoreTable(getConfig().getConfigurationSection("ScoreTable").getValues(false));
} else { } else {
_scoreTable = getDefaultScoreTable(); _scoreTable = getDefaultScoreTable();
getConfig().set("ScoreTable", serializeScoreTable(_scoreTable)); getConfig().set("ScoreTable", serializeScoreTable(_scoreTable));
@@ -113,7 +108,7 @@ public class MobScoresPlugin extends JavaPlugin {
} }
public void claimMob(Entity entity, Player damager) { public void claimMob(Entity entity, Player damager) {
if(entity instanceof Zombie){ if (_scoreTable.containsKey(entity.getType())) {
_claimedMobs.put(entity.getUniqueId(), damager.getUniqueId()); _claimedMobs.put(entity.getUniqueId(), damager.getUniqueId());
} }
} }
@@ -137,14 +132,12 @@ public class MobScoresPlugin extends JavaPlugin {
} }
public void sendPlayerScoreTable(Player player) { public void sendPlayerScoreTable(Player player) {
Iterator<Map.Entry<EntityType, Integer>> i = _scoreTable.entrySet().iterator(); for (Map.Entry<EntityType, Integer> entry : _scoreTable.entrySet()) {
Map.Entry<EntityType, Integer> pair = null; if (entry.getValue() != 0) {
for(pair = i.next(); i.hasNext(); pair = i.next()){ EntityType type = entry.getKey();
if(pair.getValue() != 0){
EntityType type = pair.getKey();
Component message = Component.translatable(type.translationKey()) Component message = Component.translatable(type.translationKey())
.append(Component.text(" = ")) .append(Component.text(" = "))
.append(Component.text(String.valueOf(pair.getValue())) .append(Component.text(String.valueOf(entry.getValue()))
.color(NamedTextColor.GREEN)); .color(NamedTextColor.GREEN));
sendPlayerMessage(player, message); sendPlayerMessage(player, message);
} }

View File

@@ -19,6 +19,7 @@ package com.majinnaibu.minecraft.plugins.mobscores.listeners;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
@@ -37,12 +38,19 @@ public class MobDeathListener implements Listener {
@EventHandler @EventHandler
public void onEntityDamage(EntityDamageEvent event) { public void onEntityDamage(EntityDamageEvent event) {
if(event instanceof EntityDamageByEntityEvent){ if (!(event instanceof EntityDamageByEntityEvent damageEvent)) {
EntityDamageByEntityEvent ev = (EntityDamageByEntityEvent) event; return;
Entity damager = ev.getDamager(); }
if(damager instanceof Player){ Entity damager = damageEvent.getDamager();
_plugin.claimMob(ev.getEntity(), (Player)damager); Player creditedPlayer = null;
} if (damager instanceof Player directPlayer) {
creditedPlayer = directPlayer;
} else if (damager instanceof Projectile projectile
&& projectile.getShooter() instanceof Player projectileShooter) {
creditedPlayer = projectileShooter;
}
if (creditedPlayer != null) {
_plugin.claimMob(event.getEntity(), creditedPlayer);
} }
} }