-
-
Notifications
You must be signed in to change notification settings - Fork 771
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Performance Improvement: high-requency listener (#4402)
* Adding new 'high-frequency-listener' setting * Moving high-frequency event listener in new class * Small typo
- Loading branch information
1 parent
c8e8eb9
commit f88ea94
Showing
4 changed files
with
210 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
201 changes: 201 additions & 0 deletions
201
Bukkit/src/main/java/com/plotsquared/bukkit/listener/HighFreqBlockEventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
/* | ||
* PlotSquared, a land and world management plugin for Minecraft. | ||
* Copyright (C) IntellectualSites <https://intellectualsites.com> | ||
* Copyright (C) IntellectualSites team and contributors | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
package com.plotsquared.bukkit.listener; | ||
|
||
import com.google.inject.Inject; | ||
import com.plotsquared.bukkit.player.BukkitPlayer; | ||
import com.plotsquared.bukkit.util.BukkitUtil; | ||
import com.plotsquared.core.PlotSquared; | ||
import com.plotsquared.core.configuration.Settings; | ||
import com.plotsquared.core.database.DBFunc; | ||
import com.plotsquared.core.location.Location; | ||
import com.plotsquared.core.player.PlotPlayer; | ||
import com.plotsquared.core.plot.Plot; | ||
import com.plotsquared.core.plot.PlotArea; | ||
import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag; | ||
import com.plotsquared.core.plot.flag.implementations.RedstoneFlag; | ||
import com.plotsquared.core.plot.world.PlotAreaManager; | ||
import com.plotsquared.core.util.PlotFlagUtil; | ||
import com.plotsquared.core.util.task.TaskManager; | ||
import com.plotsquared.core.util.task.TaskTime; | ||
import com.sk89q.worldedit.WorldEdit; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.Material; | ||
import org.bukkit.block.Block; | ||
import org.bukkit.block.BlockFace; | ||
import org.bukkit.block.data.BlockData; | ||
import org.bukkit.event.EventHandler; | ||
import org.bukkit.event.EventPriority; | ||
import org.bukkit.event.Listener; | ||
import org.bukkit.event.block.BlockPhysicsEvent; | ||
import org.bukkit.event.block.BlockRedstoneEvent; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
|
||
import java.util.Set; | ||
import java.util.UUID; | ||
|
||
@SuppressWarnings("unused") | ||
public class HighFreqBlockEventListener implements Listener { | ||
|
||
private static final Set<Material> PISTONS = Set.of( | ||
Material.PISTON, | ||
Material.STICKY_PISTON | ||
); | ||
private static final Set<Material> PHYSICS_BLOCKS = Set.of( | ||
Material.TURTLE_EGG, | ||
Material.TURTLE_SPAWN_EGG | ||
); | ||
|
||
private final PlotAreaManager plotAreaManager; | ||
private final WorldEdit worldEdit; | ||
|
||
@Inject | ||
public HighFreqBlockEventListener(final @NonNull PlotAreaManager plotAreaManager, final @NonNull WorldEdit worldEdit) { | ||
this.plotAreaManager = plotAreaManager; | ||
this.worldEdit = worldEdit; | ||
} | ||
|
||
public static void sendBlockChange(final org.bukkit.Location bloc, final BlockData data) { | ||
TaskManager.runTaskLater(() -> { | ||
String world = bloc.getWorld().getName(); | ||
int x = bloc.getBlockX(); | ||
int z = bloc.getBlockZ(); | ||
int distance = Bukkit.getViewDistance() * 16; | ||
|
||
for (final PlotPlayer<?> player : PlotSquared.platform().playerManager().getPlayers()) { | ||
Location location = player.getLocation(); | ||
if (location.getWorldName().equals(world)) { | ||
if (16 * Math.abs(location.getX() - x) / 16 > distance || 16 * Math.abs(location.getZ() - z) / 16 > distance) { | ||
continue; | ||
} | ||
((BukkitPlayer) player).player.sendBlockChange(bloc, data); | ||
} | ||
} | ||
}, TaskTime.ticks(3L)); | ||
} | ||
|
||
@EventHandler | ||
public void onRedstoneEvent(BlockRedstoneEvent event) { | ||
Block block = event.getBlock(); | ||
Location location = BukkitUtil.adapt(block.getLocation()); | ||
PlotArea area = location.getPlotArea(); | ||
if (area == null) { | ||
return; | ||
} | ||
Plot plot = location.getOwnedPlot(); | ||
if (plot == null) { | ||
if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, RedstoneFlag.class, false)) { | ||
event.setNewCurrent(0); | ||
} | ||
return; | ||
} | ||
if (!plot.getFlag(RedstoneFlag.class)) { | ||
event.setNewCurrent(0); | ||
plot.debug("Redstone event was cancelled because redstone = false"); | ||
return; | ||
} | ||
if (Settings.Redstone.DISABLE_OFFLINE) { | ||
boolean disable = false; | ||
if (!DBFunc.SERVER.equals(plot.getOwner())) { | ||
if (plot.isMerged()) { | ||
disable = true; | ||
for (UUID owner : plot.getOwners()) { | ||
if (PlotSquared.platform().playerManager().getPlayerIfExists(owner) != null) { | ||
disable = false; | ||
break; | ||
} | ||
} | ||
} else { | ||
disable = PlotSquared.platform().playerManager().getPlayerIfExists(plot.getOwnerAbs()) == null; | ||
} | ||
} | ||
if (disable) { | ||
for (UUID trusted : plot.getTrusted()) { | ||
if (PlotSquared.platform().playerManager().getPlayerIfExists(trusted) != null) { | ||
disable = false; | ||
break; | ||
} | ||
} | ||
if (disable) { | ||
event.setNewCurrent(0); | ||
plot.debug("Redstone event was cancelled because no trusted player was in the plot"); | ||
return; | ||
} | ||
} | ||
} | ||
if (Settings.Redstone.DISABLE_UNOCCUPIED) { | ||
for (final PlotPlayer<?> player : PlotSquared.platform().playerManager().getPlayers()) { | ||
if (plot.equals(player.getCurrentPlot())) { | ||
return; | ||
} | ||
} | ||
event.setNewCurrent(0); | ||
} | ||
} | ||
|
||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) | ||
public void onPhysicsEvent(BlockPhysicsEvent event) { | ||
Block block = event.getBlock(); | ||
Location location = BukkitUtil.adapt(block.getLocation()); | ||
PlotArea area = location.getPlotArea(); | ||
if (area == null) { | ||
return; | ||
} | ||
Plot plot = area.getOwnedPlotAbs(location); | ||
if (plot == null) { | ||
return; | ||
} | ||
if (event.getChangedType().hasGravity() && plot.getFlag(DisablePhysicsFlag.class)) { | ||
event.setCancelled(true); | ||
sendBlockChange(event.getBlock().getLocation(), event.getBlock().getBlockData()); | ||
plot.debug("Prevented block physics and resent block change because disable-physics = true"); | ||
return; | ||
} | ||
if (event.getChangedType() == Material.COMPARATOR) { | ||
if (!plot.getFlag(RedstoneFlag.class)) { | ||
event.setCancelled(true); | ||
plot.debug("Prevented comparator update because redstone = false"); | ||
} | ||
return; | ||
} | ||
if (PHYSICS_BLOCKS.contains(event.getChangedType())) { | ||
if (plot.getFlag(DisablePhysicsFlag.class)) { | ||
event.setCancelled(true); | ||
plot.debug("Prevented block physics because disable-physics = true"); | ||
} | ||
return; | ||
} | ||
if (Settings.Redstone.DETECT_INVALID_EDGE_PISTONS) { | ||
if (PISTONS.contains(block.getType())) { | ||
org.bukkit.block.data.Directional piston = (org.bukkit.block.data.Directional) block.getBlockData(); | ||
final BlockFace facing = piston.getFacing(); | ||
location = location.add(facing.getModX(), facing.getModY(), facing.getModZ()); | ||
Plot newPlot = area.getOwnedPlotAbs(location); | ||
if (plot.equals(newPlot)) { | ||
return; | ||
} | ||
if (!plot.isMerged() || !plot.getConnectedPlots().contains(newPlot)) { | ||
event.setCancelled(true); | ||
plot.debug("Prevented piston update because of invalid edge piston detection"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters