Fixes exploit where players could get duplicate top ten entries

https://github.com/BentoBoxWorld/Level/issues/22

Requires 1.3.0 or later BentoBox because it listens for new events fired
by that version.
This commit is contained in:
tastybento 2019-02-02 20:44:15 -08:00
parent 708997237c
commit d4e1bbf0bd
4 changed files with 106 additions and 58 deletions

View File

@ -6,7 +6,7 @@
<groupId>world.bentobox</groupId>
<artifactId>level</artifactId>
<version>1.2-SNAPSHOT</version>
<version>1.2.1-SNAPSHOT</version>
<name>Level</name>
<description>Level is an add-on for BentoBox, an expandable Minecraft Bukkit plugin for island-type games like SkyBlock or AcidIsland.</description>
@ -86,7 +86,7 @@
<dependency>
<groupId>world.bentobox</groupId>
<artifactId>bentobox</artifactId>
<version>1.1-SNAPSHOT</version>
<version>1.3.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -16,7 +16,7 @@ import world.bentobox.level.commands.island.IslandLevelCommand;
import world.bentobox.level.commands.island.IslandTopCommand;
import world.bentobox.level.config.Settings;
import world.bentobox.level.listeners.JoinLeaveListener;
import world.bentobox.level.listeners.NewIslandListener;
import world.bentobox.level.listeners.IslandTeamListeners;
import world.bentobox.level.objects.LevelsData;
import world.bentobox.level.placeholders.LevelPlaceholder;
import world.bentobox.level.requests.LevelRequestHandler;
@ -133,7 +133,7 @@ public class Level extends Addon {
});
// Register new island listener
registerListener(new NewIslandListener(this));
registerListener(new IslandTeamListeners(this));
registerListener(new JoinLeaveListener(this));
// Register request handlers

View File

@ -0,0 +1,102 @@
package world.bentobox.level.listeners;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandCreatedEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandRegisteredEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandResettedEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandUnregisteredEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamJoinedEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamKickEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamLeaveEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.level.Level;
import world.bentobox.level.calculators.CalcIslandLevel;
/**
* Listens for new islands or ownership changes and sets the level to zero automatically
* @author tastybento
*
*/
public class IslandTeamListeners implements Listener {
private final Level addon;
private final Map<Island, CalcIslandLevel> cil;
/**
* @param addon - addon
*/
public IslandTeamListeners(Level addon) {
this.addon = addon;
cil = new HashMap<>();
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandCreatedEvent e) {
if (e.getIsland().getOwner() != null && e.getIsland().getWorld() != null) {
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandResettedEvent e) {
if (e.getIsland().getOwner() != null && e.getIsland().getWorld() != null) {
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIslandOwner(TeamSetownerEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getIsland().getOwner(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getIsland().getOwner());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamJoinedEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getPlayerUUID(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandUnregisteredEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getPlayerUUID(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(IslandRegisteredEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getPlayerUUID(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamLeaveEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getPlayerUUID(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getPlayerUUID());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onIsland(TeamKickEvent e) {
// Remove player from the top ten and level
addon.setIslandLevel(e.getIsland().getWorld(), e.getPlayerUUID(), 0);
addon.getTopTen().removeEntry(e.getIsland().getWorld(), e.getPlayerUUID());
}
private void zeroLevel(Island island) {
if (cil.containsKey(island)) {
addon.setInitialIslandLevel(island, cil.get(island).getResult().getLevel());
cil.remove(island);
}
}
}

View File

@ -1,54 +0,0 @@
package world.bentobox.level.listeners;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandCreatedEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandResettedEvent;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.level.Level;
import world.bentobox.level.calculators.CalcIslandLevel;
/**
* Listens for new islands and sets the level to zero automatically
* @author tastybento
*
*/
public class NewIslandListener implements Listener {
private final Level addon;
private final Map<Island, CalcIslandLevel> cil;
/**
* @param addon - addon
*/
public NewIslandListener(Level addon) {
this.addon = addon;
cil = new HashMap<>();
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandCreatedEvent e) {
if (e.getIsland().getOwner() != null && e.getIsland().getWorld() != null) {
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onNewIsland(IslandResettedEvent e) {
if (e.getIsland().getOwner() != null && e.getIsland().getWorld() != null) {
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
}
}
private void zeroLevel(Island island) {
if (cil.containsKey(island)) {
addon.setInitialIslandLevel(island, cil.get(island).getResult().getLevel());
cil.remove(island);
}
}
}