Compare commits
5 Commits
master
...
island-exp
| Author | SHA1 | Date |
|---|---|---|
|
|
bc92a70025 | 1 week ago |
|
|
0b55d67829 | 2 weeks ago |
|
|
8002ad6ec8 | 2 weeks ago |
|
|
33fe586033 | 3 weeks ago |
|
|
67d0ec7def | 3 weeks ago |
33 changed files with 2068 additions and 134 deletions
@ -0,0 +1,34 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
@DatabaseTable(tableName = "active_servers") |
||||
public class ActiveServer { |
||||
@DatabaseField(unique = true, id = true) |
||||
private String name; |
||||
|
||||
public ActiveServer(){ |
||||
|
||||
} |
||||
|
||||
public ActiveServer(String name){ |
||||
this.name = name; |
||||
} |
||||
|
||||
public void save() throws SQLException { |
||||
DaoRegistry.getActiveServerDao().createIfNotExists(this); |
||||
} |
||||
|
||||
public void delete() throws SQLException { |
||||
DaoRegistry.getActiveServerDao().delete(this); |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
} |
||||
@ -0,0 +1,165 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
import com.j256.ormlite.dao.ForeignCollection; |
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.field.ForeignCollectionField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
|
||||
@DatabaseTable(tableName = "regions") |
||||
public class Region { |
||||
|
||||
public static final HashMap<String, List<Region>> cache = new HashMap<>(); |
||||
|
||||
@DatabaseField(generatedId = true) |
||||
private int id; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private String island; |
||||
|
||||
@DatabaseField(columnName = "region_type", canBeNull = false) |
||||
private int regionType; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int x1; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int y1; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int x2; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private int y2; |
||||
|
||||
@ForeignCollectionField(eager = true) |
||||
private ForeignCollection<RegionMember> regionMembers; |
||||
|
||||
@DatabaseField() |
||||
private Integer value; |
||||
|
||||
public Region() { |
||||
|
||||
} |
||||
|
||||
public Region(String island, int regionType, int x1, int y1, int x2, int y2) { |
||||
this.island = island; |
||||
this.regionType = regionType; |
||||
this.x1 = Math.min(x1, x2); |
||||
this.y1 = Math.min(y1, y2); |
||||
this.x2 = Math.max(x1, x2) ; |
||||
this.y2 = Math.max(y1, y2); |
||||
|
||||
} |
||||
|
||||
public int getRegionType() { |
||||
return regionType; |
||||
} |
||||
|
||||
public int getX1() { |
||||
return x1; |
||||
} |
||||
|
||||
public int getY1() { |
||||
return y1; |
||||
} |
||||
|
||||
public int getX2() { |
||||
return x2; |
||||
} |
||||
|
||||
public int getY2() { |
||||
return y2; |
||||
} |
||||
|
||||
public ForeignCollection<RegionMember> getRegionMembers() { |
||||
return regionMembers; |
||||
} |
||||
|
||||
public Integer getValue() { |
||||
return value; |
||||
} |
||||
|
||||
public String getIsland() { |
||||
return island; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setRegionType(int regionType) { |
||||
this.regionType = regionType; |
||||
} |
||||
|
||||
public void setValue(Integer value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public void save(){ |
||||
try { |
||||
DaoRegistry.getRegionDao().createOrUpdate(this); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
public void addRegionMember(String memberType, String member, String membershipType){ |
||||
RegionMember regionMember = new RegionMember(this, memberType, member, membershipType); |
||||
regionMember.save(); |
||||
} |
||||
|
||||
public boolean isInside(int x, int y) { |
||||
return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2; |
||||
} |
||||
|
||||
public static Region findById(int id) { |
||||
try { |
||||
return DaoRegistry.getRegionDao().queryForId(id); |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public static void cacheRegions(String island) { |
||||
try { |
||||
List<Region> regions = DaoRegistry.getRegionDao().queryBuilder() |
||||
.where() |
||||
.eq("island", island) |
||||
.query(); |
||||
cache.put(island, regions); |
||||
} catch (Exception e) { |
||||
|
||||
} |
||||
} |
||||
|
||||
public static Region findRegion(int x, int y, String island) { |
||||
|
||||
Region region = null; |
||||
int highestType = -1; |
||||
|
||||
if (!cache.containsKey(island)) { |
||||
cacheRegions(island); |
||||
} |
||||
|
||||
for (Region cachedRegion : cache.get(island)) { |
||||
if (!cachedRegion.isInside(x, y)) { |
||||
continue; |
||||
} |
||||
if (highestType >= cachedRegion.getRegionType()){ |
||||
continue; |
||||
} |
||||
region = cachedRegion; |
||||
} |
||||
|
||||
return region; |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
@ -0,0 +1,65 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
@DatabaseTable(tableName = "region_members") |
||||
public class RegionMember { |
||||
|
||||
@DatabaseField(generatedId = true) |
||||
private int id; |
||||
|
||||
@DatabaseField(foreign = true, foreignAutoRefresh = true) |
||||
private Region region; |
||||
|
||||
@DatabaseField(columnName = "member_type", canBeNull = false) |
||||
private String membertype; |
||||
|
||||
@DatabaseField(columnName = "member_name", canBeNull = false) |
||||
private String memberName; |
||||
|
||||
@DatabaseField(columnName = "membership_type", canBeNull = false) |
||||
private String membershipType; |
||||
|
||||
public RegionMember(){ |
||||
|
||||
} |
||||
|
||||
public RegionMember(Region region, String membertype, String memberName, String membershipType){ |
||||
this.region = region; |
||||
this.membertype = membertype; |
||||
this.memberName = memberName; |
||||
this.membershipType = membershipType; |
||||
} |
||||
|
||||
public Region getRegion() { |
||||
return region; |
||||
} |
||||
|
||||
public String getMembertype() { |
||||
return membertype; |
||||
} |
||||
|
||||
public String getName() { |
||||
return memberName; |
||||
} |
||||
|
||||
public String getMembershipType() { |
||||
return membershipType; |
||||
} |
||||
|
||||
public void setMembershipType(String membershipType) { |
||||
this.membershipType = membershipType; |
||||
} |
||||
|
||||
public void save(){ |
||||
try { |
||||
DaoRegistry.getRegionMemberDao().createOrUpdate(this); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,96 @@ |
||||
package xyz.soukup.ecoCraftCore.database.objects; |
||||
|
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
import org.bukkit.Location; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
@DatabaseTable(tableName = "teleport_requests") |
||||
public class TeleportRequest { |
||||
|
||||
@DatabaseField(unique = true, id = true) |
||||
private String player; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private String server; |
||||
|
||||
@DatabaseField(canBeNull = false) |
||||
private String world; |
||||
|
||||
@DatabaseField |
||||
private Integer x; |
||||
|
||||
@DatabaseField |
||||
private Integer y; |
||||
|
||||
@DatabaseField |
||||
private Integer z; |
||||
|
||||
@DatabaseField |
||||
private Float yaw; |
||||
|
||||
@DatabaseField |
||||
private Float pitch; |
||||
|
||||
public TeleportRequest() { |
||||
} |
||||
|
||||
public TeleportRequest(String player, String server, String world) { |
||||
this.player = player; |
||||
this.server = server; |
||||
this.world = world; |
||||
} |
||||
|
||||
public TeleportRequest(String player, String server, String world, Integer x, Integer y, Integer z, Float yaw, Float pitch) { |
||||
this.player = player; |
||||
this.server = server; |
||||
this.world = world; |
||||
this.x = x; |
||||
this.y = y; |
||||
this.z = z; |
||||
this.yaw = yaw; |
||||
this.pitch = pitch; |
||||
} |
||||
|
||||
public String getServer() { |
||||
return server; |
||||
} |
||||
|
||||
public String getWorld() { |
||||
return world; |
||||
} |
||||
|
||||
public String getPlayer() { |
||||
return player; |
||||
} |
||||
|
||||
public Integer getX() { |
||||
return x; |
||||
} |
||||
|
||||
public Integer getY() { |
||||
return y; |
||||
} |
||||
|
||||
public Integer getZ() { |
||||
return z; |
||||
} |
||||
|
||||
public Float getYaw() { |
||||
return yaw; |
||||
} |
||||
|
||||
public Float getPitch() { |
||||
return pitch; |
||||
} |
||||
|
||||
public void save() throws SQLException { |
||||
DaoRegistry.getTeleportRequestsDao().createOrUpdate(this); |
||||
} |
||||
|
||||
public void delete() throws SQLException { |
||||
DaoRegistry.getTeleportRequestsDao().delete(this); |
||||
} |
||||
} |
||||
@ -0,0 +1,257 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
import com.github.retrooper.packetevents.event.PacketListener; |
||||
import com.github.retrooper.packetevents.event.PacketSendEvent; |
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.Column; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.LightData; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.TileEntity; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v_1_18.Chunk_v1_18; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.palette.DataPalette; |
||||
import com.github.retrooper.packetevents.protocol.world.chunk.palette.PaletteType; |
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkData; |
||||
import org.bukkit.Bukkit; |
||||
import org.bukkit.NamespacedKey; |
||||
import org.bukkit.World; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.persistence.PersistentDataContainer; |
||||
import org.bukkit.persistence.PersistentDataType; |
||||
import org.bukkit.plugin.java.JavaPlugin; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
import java.util.BitSet; |
||||
import java.util.Arrays; |
||||
import java.util.HashMap; |
||||
|
||||
public class ChunkModifier implements PacketListener { |
||||
|
||||
private final JavaPlugin plugin; |
||||
private final NamespacedKey keyX1, keyX2, keyZ1, keyZ2, keyType; |
||||
|
||||
HashMap<String, Integer> blockStates = new HashMap<>(); |
||||
|
||||
public ChunkModifier(JavaPlugin plugin) { |
||||
this.plugin = plugin; |
||||
this.keyX1 = new NamespacedKey(plugin, "borderx1"); |
||||
this.keyX2 = new NamespacedKey(plugin, "borderx2"); |
||||
this.keyZ1 = new NamespacedKey(plugin, "bordery1"); // Based on your spec
|
||||
this.keyZ2 = new NamespacedKey(plugin, "borderx2"); // Based on your spec
|
||||
this.keyType = new NamespacedKey(plugin, "island_type"); |
||||
} |
||||
|
||||
@Override |
||||
public void onPacketSend(PacketSendEvent event) { |
||||
if (event.getPacketType() != PacketType.Play.Server.CHUNK_DATA) return; |
||||
|
||||
Player bukkitPlayer = Bukkit.getPlayer(event.getUser().getUUID()); |
||||
if (bukkitPlayer == null) return; |
||||
|
||||
World world = bukkitPlayer.getWorld(); |
||||
PersistentDataContainer pdc = world.getPersistentDataContainer(); |
||||
|
||||
String type = pdc.get(keyType, PersistentDataType.STRING); |
||||
if (type == null) return; |
||||
|
||||
String block; |
||||
|
||||
switch (type){ |
||||
case "flat_grass": |
||||
case "flat_sand": |
||||
block = "WATER"; |
||||
break; |
||||
case "flat_hell": |
||||
block = "LAVA"; |
||||
break; |
||||
default: |
||||
return; |
||||
|
||||
} |
||||
|
||||
Integer x1 = pdc.get(keyX1, PersistentDataType.INTEGER); |
||||
Integer x2 = pdc.get(keyX2, PersistentDataType.INTEGER); |
||||
Integer z1 = pdc.get(keyZ1, PersistentDataType.INTEGER); |
||||
Integer z2 = pdc.get(keyZ2, PersistentDataType.INTEGER); |
||||
if (x1 == null || x2 == null || z1 == null || z2 == null) return; |
||||
|
||||
int minCX = Math.min(x1 >> 4, x2 >> 4) - 1; |
||||
int maxCX = Math.max(x1 >> 4, x2 >> 4) + 1; |
||||
int minCZ = Math.min(z1 >> 4, z2 >> 4) - 1; |
||||
int maxCZ = Math.max(z1 >> 4, z2 >> 4) + 1; |
||||
|
||||
WrapperPlayServerChunkData wrapper = new WrapperPlayServerChunkData(event); |
||||
|
||||
Column original = wrapper.getColumn(); |
||||
if (original == null) return; |
||||
|
||||
int chunkX = original.getX(); |
||||
int chunkZ = original.getZ(); |
||||
if (chunkX >= minCX && chunkX <= maxCX && chunkZ >= minCZ && chunkZ <= maxCZ) return; |
||||
|
||||
Column ghostColumn = createGhostColumn(world, original, resolveBlockStateID(block)); |
||||
if (ghostColumn == null) return; |
||||
|
||||
wrapper.setColumn(ghostColumn); |
||||
|
||||
wrapper.setLightData(buildFullBrightLightData(world)); |
||||
} |
||||
|
||||
private static LightData buildFullBrightLightData(World world) { |
||||
int sections = (world.getMaxHeight() - world.getMinHeight()) >> 4; |
||||
if (sections <= 0) sections = 24; |
||||
|
||||
int lightCount = sections + 2; |
||||
|
||||
byte[] fullSky = new byte[2048]; |
||||
Arrays.fill(fullSky, (byte) 0xFF); |
||||
|
||||
byte[] noBlock = new byte[2048]; |
||||
|
||||
|
||||
boolean hasSkyLight = world.getEnvironment() != World.Environment.NETHER |
||||
&& world.getEnvironment() != World.Environment.THE_END; // adjust if you have custom dims
|
||||
|
||||
BitSet skyMask = new BitSet(lightCount); |
||||
BitSet blockMask = new BitSet(lightCount); |
||||
BitSet emptySkyMask = new BitSet(lightCount); |
||||
BitSet emptyBlockMask = new BitSet(lightCount); |
||||
|
||||
byte[][] skyArray; |
||||
int skyCount; |
||||
if (hasSkyLight) { |
||||
skyMask.set(0, lightCount); |
||||
skyCount = lightCount; |
||||
skyArray = new byte[skyCount][]; |
||||
for (int i = 0; i < skyCount; i++) { |
||||
skyArray[i] = fullSky; |
||||
} |
||||
} else { |
||||
// no skylight dimension
|
||||
emptySkyMask.set(0, lightCount); |
||||
skyCount = 0; |
||||
skyArray = new byte[0][]; |
||||
} |
||||
|
||||
blockMask.set(0, lightCount); |
||||
int blockCount = lightCount; |
||||
byte[][] blockArray = new byte[blockCount][]; |
||||
for (int i = 0; i < blockCount; i++) { |
||||
blockArray[i] = noBlock; |
||||
} |
||||
|
||||
LightData ld = new LightData(); |
||||
ld.setTrustEdges(true); |
||||
ld.setSkyLightMask(skyMask); |
||||
ld.setBlockLightMask(blockMask); |
||||
ld.setEmptySkyLightMask(emptySkyMask); |
||||
ld.setEmptyBlockLightMask(emptyBlockMask); |
||||
ld.setSkyLightCount(skyCount); |
||||
ld.setBlockLightCount(blockCount); |
||||
ld.setSkyLightArray(skyArray); |
||||
ld.setBlockLightArray(blockArray); |
||||
return ld; |
||||
} |
||||
|
||||
private Column createGhostColumn(World world, Column original, int blockID) { |
||||
int sections = (world.getMaxHeight() - world.getMinHeight()) >> 4; |
||||
if (sections <= 0) sections = 24; |
||||
|
||||
BaseChunk[] originalChunks = original.getChunks(); |
||||
|
||||
// Find any existing biome palette from the original packet; we will reuse it.
|
||||
DataPalette fallbackBiomePalette = null; |
||||
if (originalChunks != null) { |
||||
for (BaseChunk bc : originalChunks) { |
||||
if (bc instanceof Chunk_v1_18 c) { |
||||
fallbackBiomePalette = c.getBiomeData(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
BaseChunk[] chunks = new BaseChunk[sections]; |
||||
|
||||
for (int sectionIndex = 0; sectionIndex < sections; sectionIndex++) { |
||||
DataPalette biomePalette = fallbackBiomePalette; |
||||
|
||||
if (originalChunks != null && sectionIndex < originalChunks.length && originalChunks[sectionIndex] instanceof Chunk_v1_18 c) { |
||||
// Prefer the matching section's biome palette if present
|
||||
biomePalette = c.getBiomeData(); |
||||
} |
||||
|
||||
DataPalette blockPalette = PaletteType.CHUNK.create(); |
||||
|
||||
Chunk_v1_18 section = new Chunk_v1_18(0, blockPalette, biomePalette); |
||||
section.set(0, 0, 0, 0); |
||||
|
||||
chunks[sectionIndex] = section; |
||||
} |
||||
|
||||
if (chunks[0] instanceof Chunk_v1_18 section0) { |
||||
for (int localY = 0; localY <= 1; localY++) { |
||||
for (int x = 0; x < 16; x++) { |
||||
for (int z = 0; z < 16; z++) { |
||||
section0.set(x, localY, z, blockID); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return new Column( |
||||
original.getX(), |
||||
original.getZ(), |
||||
true, |
||||
chunks, |
||||
new TileEntity[0], |
||||
original.getHeightMaps() |
||||
); |
||||
} |
||||
|
||||
private int resolveBlockStateID(String name) { |
||||
Integer stateID = blockStates.get(name); |
||||
if (stateID != null) return stateID; |
||||
|
||||
int resolved = 0; |
||||
|
||||
try { |
||||
Object blockState = resolveNmsBlockState(name); |
||||
if (blockState != null) { |
||||
Integer id = tryGetBlockStateIdViaBlockGetId(blockState); |
||||
if (id != null && id > 0) { |
||||
resolved = id; |
||||
} |
||||
} |
||||
} catch (ReflectiveOperationException ignored) { |
||||
|
||||
} |
||||
|
||||
blockStates.put(name, resolved); |
||||
return resolved; |
||||
} |
||||
|
||||
private static Object resolveNmsBlockState(String name) throws ReflectiveOperationException { |
||||
Class<?> blocksClass = Class.forName("net.minecraft.world.level.block.Blocks"); |
||||
Field waterField = blocksClass.getField(name); |
||||
Object waterBlock = waterField.get(null); |
||||
|
||||
Method defaultBlockState = waterBlock.getClass().getMethod("defaultBlockState"); |
||||
return defaultBlockState.invoke(waterBlock); |
||||
} |
||||
|
||||
private static Integer tryGetBlockStateIdViaBlockGetId(Object blockState) throws ReflectiveOperationException { |
||||
// Block.getId(BlockState) exists on many modern versions
|
||||
Class<?> blockClass = Class.forName("net.minecraft.world.level.block.Block"); |
||||
Class<?> blockStateClass = Class.forName("net.minecraft.world.level.block.state.BlockState"); |
||||
|
||||
try { |
||||
Method getId = blockClass.getMethod("getId", blockStateClass); |
||||
Object idObj = getId.invoke(null, blockState); |
||||
return (idObj instanceof Integer i) ? i : null; |
||||
} catch (NoSuchMethodException ignored) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,72 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
import com.infernalsuite.asp.api.exceptions.UnknownWorldException; |
||||
import com.infernalsuite.asp.api.loaders.SlimeLoader; |
||||
import xyz.soukup.ecoCraftCore.EcoCraftCore; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.nio.file.Files; |
||||
import java.nio.file.Path; |
||||
import java.util.Arrays; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.stream.Collectors; |
||||
|
||||
public class FileIslandLoader implements SlimeLoader { |
||||
|
||||
private final Path storagePath; |
||||
private static final String EXTENSION = ".slime"; |
||||
|
||||
public FileIslandLoader() { |
||||
// Creates a directory named 'islands' inside your plugin folder
|
||||
this.storagePath = EcoCraftCore.plugin.getDataFolder().toPath().resolve("island_templates"); |
||||
|
||||
if (!Files.exists(storagePath)) { |
||||
storagePath.toFile().mkdirs(); |
||||
} |
||||
} |
||||
|
||||
private Path getWorldPath(String worldName) { |
||||
return storagePath.resolve(worldName + EXTENSION); |
||||
} |
||||
|
||||
@Override |
||||
public byte[] readWorld(String worldName) throws UnknownWorldException, IOException { |
||||
Path path = getWorldPath(worldName); |
||||
if (!Files.exists(path)) { |
||||
throw new UnknownWorldException(worldName); |
||||
} |
||||
return Files.readAllBytes(path); |
||||
} |
||||
|
||||
@Override |
||||
public boolean worldExists(String worldName) throws IOException { |
||||
return Files.exists(getWorldPath(worldName)); |
||||
} |
||||
|
||||
@Override |
||||
public void saveWorld(String worldName, byte[] serializedWorld) throws IOException { |
||||
// Files.write will create or overwrite the file automatically
|
||||
Files.write(getWorldPath(worldName), serializedWorld); |
||||
} |
||||
|
||||
@Override |
||||
public void deleteWorld(String worldName) throws IOException { |
||||
Files.deleteIfExists(getWorldPath(worldName)); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> listWorlds() throws IOException { |
||||
File folder = storagePath.toFile(); |
||||
File[] files = folder.listFiles((dir, name) -> name.endsWith(EXTENSION)); |
||||
|
||||
if (files == null) { |
||||
return Collections.emptyList(); |
||||
} |
||||
|
||||
return Arrays.stream(files) |
||||
.map(file -> file.getName().replace(EXTENSION, "")) |
||||
.collect(Collectors.toList()); |
||||
} |
||||
} |
||||
@ -0,0 +1,324 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; |
||||
import com.infernalsuite.asp.api.world.SlimeWorld; |
||||
import com.j256.ormlite.stmt.QueryBuilder; |
||||
import com.mojang.brigadier.arguments.IntegerArgumentType; |
||||
import com.mojang.brigadier.arguments.StringArgumentType; |
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; |
||||
import com.mojang.brigadier.context.CommandContext; |
||||
import io.papermc.paper.command.brigadier.CommandSourceStack; |
||||
import io.papermc.paper.command.brigadier.Commands; |
||||
import org.bukkit.Location; |
||||
import org.bukkit.NamespacedKey; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.persistence.PersistentDataContainer; |
||||
import org.bukkit.persistence.PersistentDataType; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
import xyz.soukup.ecoCraftCore.database.objects.Island; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
|
||||
import java.io.IOException; |
||||
import java.sql.SQLException; |
||||
import java.util.List; |
||||
|
||||
import static xyz.soukup.ecoCraftCore.EcoCraftCore.config; |
||||
import static xyz.soukup.ecoCraftCore.EcoCraftCore.plugin; |
||||
|
||||
public class IslandAdminCommand { |
||||
private final AdvancedSlimePaperAPI asp = AdvancedSlimePaperAPI.instance(); |
||||
|
||||
|
||||
public static LiteralArgumentBuilder<CommandSourceStack> getCommand() { |
||||
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> tp = Commands.literal("tp") |
||||
.then(Commands.argument("uuid", StringArgumentType.word()) |
||||
.executes(IslandAdminCommand::teleport) |
||||
.suggests(((context, builder) -> { |
||||
try { |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("uuid"); |
||||
List<Island> islands = queryBuilder.query(); |
||||
for (Island island : islands) { |
||||
builder.suggest(island.getUuid()); |
||||
} |
||||
return builder.buildFuture(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
}))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> create = Commands.literal("create") |
||||
.then(Commands.argument("type", StringArgumentType.word()) |
||||
.suggests(((context, builder) -> { |
||||
try { |
||||
IslandManager islandManager = new IslandManager(); |
||||
FileIslandLoader fileLoader = islandManager.fileLoader; |
||||
for (String world: fileLoader.listWorlds()){ |
||||
builder.suggest(world); |
||||
} |
||||
} catch (IOException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
return builder.buildFuture(); |
||||
})) |
||||
.then(Commands.argument("display_name", StringArgumentType.string()) |
||||
.then(Commands.argument("description", StringArgumentType.greedyString()) |
||||
.executes(IslandAdminCommand::createWorld)))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> load = Commands.literal("load") |
||||
.then(Commands.argument("uuid", StringArgumentType.word()) |
||||
.suggests(((context, builder) -> { |
||||
try { |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("uuid"); |
||||
List<Island> islands = queryBuilder.query(); |
||||
for (Island island : islands) { |
||||
builder.suggest(island.getUuid()); |
||||
} |
||||
return builder.buildFuture(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
})) |
||||
.executes(IslandAdminCommand::loadWorld)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> loadTemplate = Commands.literal("loadTemplate") |
||||
.then(Commands.argument("name", StringArgumentType.word()) |
||||
.suggests(((context, builder) -> { |
||||
IslandManager islandManager = new IslandManager(); |
||||
FileIslandLoader fileLoader = islandManager.fileLoader; |
||||
|
||||
try { |
||||
for (String world: fileLoader.listWorlds()){ |
||||
builder.suggest(world); |
||||
} |
||||
} catch (IOException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
return builder.buildFuture(); |
||||
})) |
||||
.executes(IslandAdminCommand::loadTemplate)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> template = Commands.literal("template") |
||||
.then(Commands.argument("uuid", StringArgumentType.word()) |
||||
.suggests((context, builder) -> { |
||||
try { |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("uuid"); |
||||
List<Island> islands = queryBuilder.query(); |
||||
for (Island island : islands) { |
||||
builder.suggest(island.getUuid()); |
||||
} |
||||
return builder.buildFuture(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
}) |
||||
.then(Commands.argument("templateName", StringArgumentType.word()) |
||||
.executes(IslandAdminCommand::createTemplate))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> metadata = Commands.literal("metadata") |
||||
.then(Commands.argument("key", StringArgumentType.word()) |
||||
.then(Commands.argument("value", IntegerArgumentType.integer()) |
||||
.executes(IslandAdminCommand::setMetadata))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> metadataString = Commands.literal("metadataString") |
||||
.then(Commands.argument("key", StringArgumentType.word()) |
||||
.then(Commands.argument("value", StringArgumentType.string()) |
||||
.executes(IslandAdminCommand::setMetadataString))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> expand = Commands.literal("expand") |
||||
.then(Commands.argument("lenght", IntegerArgumentType.integer()) |
||||
.executes(IslandAdminCommand::expandIsland)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> listMetadata = Commands.literal("listMetadata") |
||||
.executes(IslandAdminCommand::readAllMetadata); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> spawn = Commands.literal("spawn") |
||||
.executes(IslandAdminCommand::setSpawn); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> enviroment = Commands.literal("environment") |
||||
.then(Commands.argument("environment", StringArgumentType.word()) |
||||
.executes(IslandAdminCommand::setEnvironment) |
||||
.suggests(((context, builder) -> { |
||||
builder.suggest("normal"); |
||||
builder.suggest("nether"); |
||||
builder.suggest("the_end"); |
||||
return builder.buildFuture(); |
||||
}))); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> setDefaultIsland = Commands.literal("setDefaultIsland") |
||||
.executes(IslandAdminCommand::setDefualtIsland); |
||||
|
||||
return Commands.literal("island-admin") |
||||
.requires(commandSourceStack -> commandSourceStack.getSender().isOp()) |
||||
.then(tp) |
||||
.then(create) |
||||
.then(load) |
||||
.then(template) |
||||
.then(metadata) |
||||
.then(metadataString) |
||||
.then(listMetadata) |
||||
.then(loadTemplate) |
||||
.then(spawn) |
||||
.then(enviroment) |
||||
.then(expand) |
||||
.then(setDefaultIsland); |
||||
|
||||
|
||||
|
||||
} |
||||
|
||||
private static int setDefualtIsland(CommandContext<CommandSourceStack> context){ |
||||
if (!(context.getSource().getSender() instanceof Player player)) return 0; |
||||
String uuid = player.getWorld().getName(); |
||||
config.set("islands.spawn", uuid); |
||||
plugin.saveConfig(); |
||||
player.sendMessage("done."); |
||||
return 0; |
||||
|
||||
} |
||||
|
||||
private static int setSpawn(CommandContext<CommandSourceStack> context) { |
||||
if (!(context.getSource().getSender() instanceof Player player)) return 0; |
||||
IslandManager islandManager = new IslandManager(); |
||||
Location spawn = player.getLocation(); |
||||
String uuid = player.getWorld().getName(); |
||||
islandManager.changeSpawn(spawn, uuid); |
||||
Messages.send(player, "island.setSpawn.success"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
private static int setEnvironment(CommandContext<CommandSourceStack> context) { |
||||
if (!(context.getSource().getSender() instanceof Player player)) return 0; |
||||
IslandManager islandManager = new IslandManager(); |
||||
String uuid = player.getWorld().getName(); |
||||
islandManager.changeEnviroment(context.getArgument("environment", String.class), uuid); |
||||
Messages.send(player, "island.setEnvironment.success"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
private static int teleport(CommandContext<CommandSourceStack> context) { |
||||
IslandManager islandManager = new IslandManager(); |
||||
try { |
||||
Integer status = islandManager.teleport((Player) context.getSource().getSender(), context.getArgument("uuid", String.class)); |
||||
context.getSource().getSender().sendMessage(String.valueOf(status)); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
private static int createWorld(CommandContext<CommandSourceStack> context) { |
||||
IslandManager islandManager = new IslandManager(); |
||||
String type = context.getArgument("type", String.class); |
||||
String displayName = context.getArgument("display_name", String.class); |
||||
String description = context.getArgument("description", String.class); |
||||
String owner = context.getSource().getSender().getName(); |
||||
String uuid = islandManager.createIsland(type, displayName, description, owner, "player"); |
||||
context.getSource().getSender().sendMessage("Created island: " + uuid); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
private static int loadWorld(CommandContext<CommandSourceStack> context) { |
||||
IslandManager islandManager = new IslandManager(); |
||||
islandManager.loadIsland(context.getArgument("uuid", String.class)); |
||||
context.getSource().getSender().sendMessage("done."); |
||||
return 0; |
||||
} |
||||
|
||||
private static int loadTemplate(CommandContext<CommandSourceStack> context) { |
||||
IslandManager islandManager = new IslandManager(); |
||||
islandManager.loadIslandTemplate(context.getArgument("name", String.class)); |
||||
context.getSource().getSender().sendMessage("done."); |
||||
return 0; |
||||
} |
||||
|
||||
private static int createTemplate(CommandContext<CommandSourceStack> context) { |
||||
IslandManager islandManager = new IslandManager(); |
||||
String uuid = StringArgumentType.getString(context, "uuid"); |
||||
String templateName = StringArgumentType.getString(context, "templateName"); |
||||
context.getSource().getSender().sendMessage("§aCreating template '" + templateName + "' from world '" + uuid + "'..."); |
||||
islandManager.createIslandTemplate(uuid, templateName); |
||||
context.getSource().getSender().sendMessage("§aTemplate created successfully!"); |
||||
return 1; |
||||
} |
||||
|
||||
private static int setMetadata(CommandContext<CommandSourceStack> context) { |
||||
if (!(context.getSource().getSender() instanceof Player player)) return 0; |
||||
|
||||
String keyName = StringArgumentType.getString(context, "key"); |
||||
Integer value = IntegerArgumentType.getInteger(context, "value"); |
||||
|
||||
player.getWorld().getPersistentDataContainer().set(new NamespacedKey(plugin, keyName), PersistentDataType.INTEGER, value); |
||||
context.getSource().getSender().sendMessage(keyName + " set to " + value); |
||||
return 1; |
||||
} |
||||
|
||||
private static int setMetadataString(CommandContext<CommandSourceStack> context) { |
||||
if (!(context.getSource().getSender() instanceof Player player)) return 0; |
||||
|
||||
String keyName = StringArgumentType.getString(context, "key"); |
||||
String value = StringArgumentType.getString(context, "value"); |
||||
|
||||
player.getWorld().getPersistentDataContainer().set(new NamespacedKey(plugin, keyName), PersistentDataType.STRING, value); |
||||
context.getSource().getSender().sendMessage(keyName + " set to " + value); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
private static int readAllMetadata(CommandContext<CommandSourceStack> context) { |
||||
if (!(context.getSource().getSender() instanceof Player player)) { |
||||
context.getSource().getSender().sendMessage("§cOnly players can use this."); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
PersistentDataContainer pdc = player.getWorld().getPersistentDataContainer(); |
||||
if (pdc.getKeys().isEmpty()) { |
||||
player.sendMessage("§eNo metadata found."); |
||||
return 1; |
||||
} |
||||
|
||||
player.sendMessage("§6--- World Metadata ---"); |
||||
for (NamespacedKey key : pdc.getKeys()) { |
||||
String val = "unknown"; |
||||
// Logic to determine type for display
|
||||
if (pdc.has(key, PersistentDataType.STRING)) val = pdc.get(key, PersistentDataType.STRING); |
||||
else if (pdc.has(key, PersistentDataType.INTEGER)) val = String.valueOf(pdc.get(key, PersistentDataType.INTEGER)); |
||||
|
||||
player.sendMessage("§b" + key.getKey() + "§7: §f" + val); |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
private static int expandIsland(CommandContext<CommandSourceStack> context){ |
||||
|
||||
Player player = (Player) context.getSource().getSender(); |
||||
float yaw = player.getLocation().getYaw(); |
||||
int lenght = IntegerArgumentType.getInteger(context, "lenght"); |
||||
String uuid = player.getWorld().getName(); |
||||
|
||||
IslandManager islandManager = new IslandManager(); |
||||
islandManager.expandIsland(yaw, lenght, uuid); |
||||
|
||||
|
||||
return 0; |
||||
} |
||||
|
||||
private static void saveSlimeWorld(SlimeWorld world, Player player, String key, String val) { |
||||
try { |
||||
AdvancedSlimePaperAPI.instance().saveWorld(world); |
||||
player.sendMessage("§aMetadata set: §f" + key + " §7= §f" + val); |
||||
} catch (IOException e) { |
||||
player.sendMessage("§cFailed to save world metadata!"); |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
@ -1,32 +0,0 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType; |
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; |
||||
import com.mojang.brigadier.context.CommandContext; |
||||
import io.papermc.paper.command.brigadier.CommandSourceStack; |
||||
import io.papermc.paper.command.brigadier.Commands; |
||||
|
||||
|
||||
public class IslandCommand { |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> tp = Commands.literal("tp") |
||||
.then(Commands.argument("uuid", StringArgumentType.word()) |
||||
.executes(IslandCommand::teleport)); |
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> create = Commands.literal("create") |
||||
.then(Commands.argument("name", StringArgumentType.word()) |
||||
.then(Commands.argument("display_name", StringArgumentType.string()))); |
||||
|
||||
private static int teleport(CommandContext<CommandSourceStack> context) { |
||||
return 0; |
||||
} |
||||
|
||||
private static int createWorld(CommandContext<CommandSourceStack> context) { |
||||
return 0; |
||||
} |
||||
|
||||
private static int loadWorld(CommandContext<CommandSourceStack> context) { |
||||
return 0; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,188 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
import com.github.stefvanschie.inventoryframework.gui.GuiItem; |
||||
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; |
||||
import com.github.stefvanschie.inventoryframework.gui.type.HopperGui; |
||||
import com.github.stefvanschie.inventoryframework.pane.OutlinePane; |
||||
import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; |
||||
import com.github.stefvanschie.inventoryframework.pane.component.PagingButtons; |
||||
import com.github.stefvanschie.inventoryframework.pane.util.Slot; |
||||
import com.j256.ormlite.stmt.QueryBuilder; |
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; |
||||
import com.mojang.brigadier.context.CommandContext; |
||||
import io.papermc.paper.command.brigadier.CommandSourceStack; |
||||
import io.papermc.paper.command.brigadier.Commands; |
||||
import net.kyori.adventure.text.Component; |
||||
import net.kyori.adventure.text.format.TextColor; |
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; |
||||
import org.bukkit.Material; |
||||
import org.bukkit.entity.Player; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
import xyz.soukup.ecoCraftCore.database.objects.Island; |
||||
import xyz.soukup.ecoCraftCore.database.objects.Region; |
||||
import xyz.soukup.ecoCraftCore.database.objects.RegionMember; |
||||
import xyz.soukup.ecoCraftCore.gui.GuiItemBuilder; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Objects; |
||||
|
||||
public class IslandSelectorCommand { |
||||
|
||||
public static LiteralArgumentBuilder<CommandSourceStack> getCommand(){ |
||||
return Commands.literal("is") |
||||
.executes(IslandSelectorCommand::displayIslandListSelectorGui); |
||||
} |
||||
|
||||
private static int displayIslandListSelectorGui(CommandContext<CommandSourceStack> context) { |
||||
String title = LegacyComponentSerializer.legacySection().serialize(Messages.get("menu.island-selector.title")); |
||||
HopperGui hopperGui = new HopperGui(title); |
||||
hopperGui.setOnGlobalClick(event -> event.setCancelled(true)); |
||||
|
||||
OutlinePane outlinePane = new OutlinePane(0, 0, 5, 1); |
||||
Player player = (Player) context.getSource().getSender(); |
||||
|
||||
outlinePane.addItem(selectorItem("menu.island-selector.my-islands", Material.GRASS_BLOCK, getMyIslands(player))); |
||||
outlinePane.addItem(selectorItem("menu.island-selector.shared-islands", Material.MOSS_BLOCK, getSharedIslands(player))); |
||||
outlinePane.addItem(selectorItem("menu.island-selector.public-islands", Material.SAND, getPublicIslands())); |
||||
|
||||
hopperGui.getSlotsComponent().addPane(outlinePane); |
||||
|
||||
if (player.isOp()){ |
||||
outlinePane.addItem(selectorItem("menu.island-selector.all-islands", Material.CRIMSON_NYLIUM, getAllIslands())); |
||||
} |
||||
|
||||
hopperGui.show(player); |
||||
return 0; |
||||
} |
||||
|
||||
private static List<Island> getAllIslands(){ |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("display_name", "uuid", "descritpion", "type"); |
||||
try { |
||||
return queryBuilder.query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
private static List<Island> getPublicIslands(){ |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("display_name", "uuid", "descritpion", "type"); |
||||
try { |
||||
queryBuilder.where().eq("is_public", true); |
||||
return queryBuilder.query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
private static List<Island> getMyIslands(Player player){ |
||||
QueryBuilder<Island, Integer> queryBuilder = DaoRegistry.getIslandDao().queryBuilder(); |
||||
queryBuilder.selectColumns("display_name", "uuid", "descritpion", "type"); |
||||
try { |
||||
queryBuilder.where().eq("owner", player.getName()).and().eq("owner_type", "player"); |
||||
return queryBuilder.query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
private static List<Island> getSharedIslands(Player player){ |
||||
QueryBuilder<RegionMember, Integer> memberQb = DaoRegistry.getRegionMemberDao().queryBuilder(); |
||||
memberQb.selectColumns("region_id"); |
||||
try { |
||||
memberQb.where().eq("member_name", player.getName()).and().eq("member_type", "player"); |
||||
|
||||
QueryBuilder<Region, Integer> regionQb = DaoRegistry.getRegionDao().queryBuilder(); |
||||
regionQb.selectColumns("island"); |
||||
regionQb.where().in("id", memberQb); |
||||
|
||||
return DaoRegistry.getIslandDao().queryBuilder() |
||||
.where() |
||||
.in("uuid", regionQb) |
||||
.query(); |
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
|
||||
} |
||||
|
||||
public static GuiItem selectorItem(String key, Material material, List<Island> islands){ |
||||
GuiItemBuilder guiItemBuilder = new GuiItemBuilder(material); |
||||
guiItemBuilder.setName(Messages.get(key)); |
||||
GuiItem guiItem = guiItemBuilder.build(); |
||||
guiItem.setAction(event -> openIslandListGui((Player) event.getWhoClicked(), islands)); |
||||
return guiItem; |
||||
} |
||||
|
||||
|
||||
private static void openIslandListGui(Player player, List<Island> islands){ |
||||
String title = LegacyComponentSerializer.legacySection().serialize(Messages.get("menu.island-selector.title")); |
||||
ChestGui chestGui = new ChestGui(4, title); |
||||
chestGui.setOnGlobalClick(event -> event.setCancelled(true)); |
||||
|
||||
PaginatedPane paginatedPane = new PaginatedPane(0, 0, 9, 3); |
||||
|
||||
paginatedPane.populateWithGuiItems(itemsFromIslands(player, islands)); |
||||
PagingButtons pagingButtons = new PagingButtons(Slot.fromXY(0, 3), 9, paginatedPane); |
||||
|
||||
chestGui.addPane(paginatedPane); |
||||
chestGui.addPane(pagingButtons); |
||||
|
||||
chestGui.show(player); |
||||
} |
||||
|
||||
|
||||
private static List<GuiItem> itemsFromIslands(Player player, List<Island> islands){ |
||||
List<GuiItem> guiItems = new ArrayList<>(); |
||||
IslandManager islandManager = new IslandManager(); |
||||
for (Island island : islands){ |
||||
Material material; |
||||
TextColor color; |
||||
|
||||
switch (island.getType()){ |
||||
case "flat_grass": |
||||
material = Material.GRASS_BLOCK; |
||||
color = TextColor.color(0x02bd02); |
||||
break; |
||||
case "flat_sand": |
||||
material = Material.SAND; |
||||
color = TextColor.color(0xfccf03); |
||||
break; |
||||
case "flat_hell": |
||||
material = Material.SOUL_SAND; |
||||
color = TextColor.color(0xf00707); |
||||
break; |
||||
case "void": |
||||
material = Material.GLASS; |
||||
color = TextColor.color(0xffffff); |
||||
break; |
||||
default: |
||||
material = Material.WHITE_WOOL; |
||||
color = TextColor.color(0xffffff); |
||||
break; |
||||
} |
||||
|
||||
|
||||
GuiItemBuilder guiItemBuilder = new GuiItemBuilder(material); |
||||
guiItemBuilder.setName(Component.text(island.getDisplayName(), color)); |
||||
guiItemBuilder.setRawLore(island.getDescritpion()); |
||||
|
||||
GuiItem guiItem = guiItemBuilder.build(); |
||||
guiItem.setAction(event -> { |
||||
try { |
||||
islandManager.teleport(player, island.getUuid()); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
}); |
||||
|
||||
guiItems.add(guiItem); |
||||
|
||||
} |
||||
return guiItems; |
||||
} |
||||
} |
||||
@ -1,4 +1,4 @@ |
||||
package xyz.soukup.ecoCraftCore.islands; |
||||
|
||||
public class UnloadWorld { |
||||
public class UnloadIsland { |
||||
} |
||||
@ -0,0 +1,27 @@ |
||||
package xyz.soukup.ecoCraftCore.player; |
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerPostRespawnEvent; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.event.EventHandler; |
||||
import org.bukkit.event.Listener; |
||||
import org.bukkit.event.entity.PlayerDeathEvent; |
||||
import org.bukkit.event.player.PlayerRespawnEvent; |
||||
import xyz.soukup.ecoCraftCore.islands.IslandManager; |
||||
|
||||
import static xyz.soukup.ecoCraftCore.EcoCraftCore.config; |
||||
|
||||
public class OnKill implements Listener { |
||||
@EventHandler |
||||
public void spawnTeleportOnKill(PlayerPostRespawnEvent event){ |
||||
Player player = event.getPlayer(); |
||||
|
||||
String uuid = config.getString("islands.spawn"); |
||||
|
||||
IslandManager islandManager = new IslandManager(); |
||||
try { |
||||
islandManager.teleport(player, uuid); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,50 @@ |
||||
package xyz.soukup.ecoCraftCore.player; |
||||
|
||||
import com.google.common.eventbus.DeadEvent; |
||||
import com.j256.ormlite.stmt.QueryBuilder; |
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.event.EventHandler; |
||||
import org.bukkit.event.Listener; |
||||
import org.bukkit.event.entity.PlayerDeathEvent; |
||||
import org.bukkit.event.player.PlayerJoinEvent; |
||||
import xyz.soukup.ecoCraftCore.database.DaoRegistry; |
||||
import xyz.soukup.ecoCraftCore.database.objects.TeleportRequest; |
||||
import xyz.soukup.ecoCraftCore.islands.IslandManager; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
import static xyz.soukup.ecoCraftCore.EcoCraftCore.config; |
||||
|
||||
public class TeleportRequestsHandler implements Listener { |
||||
|
||||
@EventHandler |
||||
public void teleportRequestHandler(PlayerJoinEvent event){ |
||||
try { |
||||
Player player = event.getPlayer(); |
||||
|
||||
QueryBuilder<TeleportRequest, Integer> queryBuilder = DaoRegistry.getTeleportRequestsDao().queryBuilder(); |
||||
queryBuilder.where().eq("player", player.getName()); |
||||
|
||||
TeleportRequest teleportRequest = queryBuilder.queryForFirst(); |
||||
|
||||
IslandManager islandManager = new IslandManager(); |
||||
|
||||
|
||||
if (teleportRequest == null){ |
||||
islandManager.teleport(player, config.getString("islands.spawn")); |
||||
return; |
||||
} |
||||
|
||||
|
||||
islandManager.teleportLocally(player, teleportRequest.getWorld(), teleportRequest.getX(), teleportRequest.getY(), teleportRequest.getY(), teleportRequest.getYaw(), teleportRequest.getPitch()); |
||||
|
||||
teleportRequest.delete(); |
||||
|
||||
} catch (SQLException e) { |
||||
throw new RuntimeException(e); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
package xyz.soukup.ecoCraftCore.regions; |
||||
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType; |
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder; |
||||
import com.mojang.brigadier.context.CommandContext; |
||||
import io.papermc.paper.command.brigadier.CommandSourceStack; |
||||
import io.papermc.paper.command.brigadier.Commands; |
||||
import org.bukkit.entity.Player; |
||||
import xyz.soukup.ecoCraftCore.messages.Messages; |
||||
|
||||
public class RegionAdminCommand { |
||||
public static LiteralArgumentBuilder<CommandSourceStack> createCommand() { |
||||
LiteralArgumentBuilder<CommandSourceStack> create = Commands.literal("create") |
||||
.then(Commands.argument("type", IntegerArgumentType.integer(0, 1))) |
||||
.executes(RegionAdminCommand::createRegion); |
||||
|
||||
return Commands.literal("region") |
||||
.then(create); |
||||
} |
||||
|
||||
private static int createRegion(CommandContext<CommandSourceStack> context) { |
||||
Integer type = context.getArgument("type", Integer.class); |
||||
if(!(context.getSource().getSender() instanceof Player player)){ |
||||
Messages.send(context.getSource().getSender(), "generic.error.not-player"); |
||||
return 0; |
||||
}; |
||||
|
||||
int status = RegionManager.createRegion(player, type, player.getName(), "player"); |
||||
|
||||
switch (status){ |
||||
case 0 -> Messages.send(player, "generic.success.created"); |
||||
case 1 -> Messages.send(player, "region.error.not-marked"); |
||||
case 2 -> Messages.send(player, "region.error.not-same-world"); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
} |
||||
@ -0,0 +1,36 @@ |
||||
package xyz.soukup.ecoCraftCore.regions; |
||||
|
||||
import org.bukkit.entity.Player; |
||||
import org.bukkit.event.EventHandler; |
||||
import org.bukkit.event.Listener; |
||||
import org.bukkit.event.player.PlayerInteractEvent; |
||||
import org.bukkit.event.player.PlayerJoinEvent; |
||||
import xyz.soukup.ecoCraftCore.database.objects.Region; |
||||
import xyz.soukup.ecoCraftCore.database.objects.RegionMember; |
||||
|
||||
public class RegionEvents implements Listener { |
||||
|
||||
@EventHandler |
||||
public void onPlayerInteract(PlayerInteractEvent event){ |
||||
event.setCancelled(!isRegionMember(event.getClickedBlock().getWorld().getName(), event.getPlayer(), event.getClickedBlock().getX(), event.getClickedBlock().getY())); |
||||
} |
||||
|
||||
|
||||
private boolean isRegionMember(String island, Player player, int x, int y){ |
||||
Region region = Region.findRegion(x, y, island); |
||||
|
||||
if (region == null){ |
||||
return false; |
||||
} |
||||
|
||||
String name = player.getName(); |
||||
|
||||
for (RegionMember regionMember : region.getRegionMembers()){ |
||||
if (regionMember.getMembertype().equals("player") && regionMember.getName().equals(name)){ |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
} |
||||
@ -0,0 +1,34 @@ |
||||
package xyz.soukup.ecoCraftCore.regions; |
||||
|
||||
import org.bukkit.Location; |
||||
import org.bukkit.entity.Player; |
||||
import xyz.soukup.ecoCraftCore.database.objects.Region; |
||||
import xyz.soukup.ecoCraftCore.positionMarker.MarkerEvent; |
||||
|
||||
public class RegionManager { |
||||
public static int createRegion(Player player, Integer type, String owner, String ownerType){ |
||||
Location primaryLocation = MarkerEvent.primaryLocations.get(player); |
||||
Location secondaryLocation = MarkerEvent.secondaryLocations.get(player); |
||||
|
||||
if (primaryLocation == null || secondaryLocation == null){ |
||||
return 1; |
||||
} |
||||
|
||||
if (primaryLocation.getWorld() != secondaryLocation.getWorld()){ |
||||
return 2; |
||||
} |
||||
|
||||
String worldName = primaryLocation.getWorld().getName(); |
||||
int x1 = primaryLocation.getBlockX(); |
||||
int y1 = primaryLocation.getBlockZ(); |
||||
int x2 = secondaryLocation.getBlockX(); |
||||
int y2 = secondaryLocation.getBlockZ(); |
||||
|
||||
Region region = new Region(worldName, type, x1, y1, x2, y2); |
||||
region.save(); |
||||
|
||||
region.addRegionMember(ownerType, owner, "owner"); |
||||
|
||||
return 0; |
||||
} |
||||
} |
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue