001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.bukkit.listener; 020 021import com.plotsquared.core.PlotSquared; 022import com.plotsquared.core.plot.world.PlotAreaManager; 023import com.plotsquared.core.plot.world.SinglePlotArea; 024import com.plotsquared.core.plot.world.SinglePlotAreaManager; 025import com.plotsquared.core.util.ReflectionUtils; 026import org.bukkit.Chunk; 027import org.bukkit.World; 028import org.bukkit.event.EventHandler; 029import org.bukkit.event.EventPriority; 030import org.bukkit.event.Listener; 031import org.bukkit.event.world.ChunkEvent; 032import org.bukkit.event.world.ChunkLoadEvent; 033 034import java.lang.reflect.Method; 035 036import static com.plotsquared.core.util.ReflectionUtils.getRefClass; 037 038public class SingleWorldListener implements Listener { 039 040 private final Method methodSetUnsaved; 041 private Method methodGetHandleChunk; 042 private Object objChunkStatusFull = null; 043 044 public SingleWorldListener() throws Exception { 045 ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); 046 ReflectionUtils.RefClass classChunkAccess = getRefClass("net.minecraft.world.level.chunk.IChunkAccess"); 047 this.methodSetUnsaved = classChunkAccess.getMethod("a", boolean.class).getRealMethod(); 048 try { 049 this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod(); 050 } catch (NoSuchMethodException ignored) { 051 try { 052 String chunkStatus = PlotSquared.platform().serverVersion()[1] < 21 053 ? "net.minecraft.world.level.chunk" + ".ChunkStatus" 054 : "net.minecraft.world.level.chunk.status.ChunkStatus"; 055 ReflectionUtils.RefClass classChunkStatus = getRefClass(chunkStatus); 056 this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null); 057 this.methodGetHandleChunk = classCraftChunk 058 .getMethod("getHandle", classChunkStatus.getRealClass()) 059 .getRealMethod(); 060 } catch (NoSuchMethodException ex) { 061 throw new RuntimeException(ex); 062 } 063 } 064 } 065 066 public void markChunkAsClean(Chunk chunk) { 067 try { 068 Object nmsChunk = objChunkStatusFull != null 069 ? this.methodGetHandleChunk.invoke(chunk, objChunkStatusFull) 070 : this.methodGetHandleChunk.invoke(chunk); 071 methodSetUnsaved.invoke(nmsChunk, false); 072 } catch (Throwable e) { 073 e.printStackTrace(); 074 } 075 } 076 077 private void handle(ChunkEvent event) { 078 World world = event.getWorld(); 079 String name = world.getName(); 080 PlotAreaManager man = PlotSquared.get().getPlotAreaManager(); 081 if (!(man instanceof SinglePlotAreaManager)) { 082 return; 083 } 084 if (!SinglePlotArea.isSinglePlotWorld(name)) { 085 return; 086 } 087 int x = event.getChunk().getX(); 088 int z = event.getChunk().getZ(); 089 if (x < 16 && x > -16 && z < 16 && z > -16) { 090 // Allow spawn to generate 091 return; 092 } 093 markChunkAsClean(event.getChunk()); 094 } 095 096 // @EventHandler 097 // public void onPopulate(ChunkPopulateEvent event) { 098 // handle(event); 099 // } 100 101 @EventHandler(priority = EventPriority.LOWEST) 102 public void onChunkLoad(ChunkLoadEvent event) { 103 // disable this for now, should address https://github.com/IntellectualSites/PlotSquared/issues/4413 104 // handle(event); 105 } 106 107}