Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.
/ StructureBlockLib Public archive

StructureBlockLib is a bukkit implementation for handling structures on spigot server.

License

Notifications You must be signed in to change notification settings

Shynixn/StructureBlockLib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Important

Final Notes: The NBT format has been reworked in Minecraft 1.20.5 and this library will not updated any further because it was not intended for that. The final version support range is Minecraft 1.9.0 - 1.20.4 and can still be used for that. The binaries stay available in Maven Central. Thank you for supporting StructureBlockLib all those years ♥️ .

StructureBlockLib Build Status GitHub license

branch status version download
master Build Status GitHub license Download latest release
development Build Status GitHub license Download snapshots

JavaDocs: https://shynixn.github.io/StructureBlockLib/apidocs/

Description

StructureBlockLib is a bukkit API and implementation for handling structures on spigot server.

Features

  • Bukkit API for the StructureBlock.
  • API to save or load structures without an actual structure block.
  • Asynchronous implementation and API.
  • Fluent API.
  • Version support 1.9.R1 - 1.20.R3
  • Java support 8 - Latest

Installation

  1. Include the dependency to StructureBlockLib

Maven

<dependency>
     <groupId>com.github.shynixn.structureblocklib</groupId>
     <artifactId>structureblocklib-bukkit-api</artifactId>
     <version>2.13.0</version>
     <scope>provided</scope>
</dependency>

Gradle

dependencies {
    compileOnly("com.github.shynixn.structureblocklib:structureblocklib-bukkit-api:2.13.0")
}

Jar File

StructureBlockLibBukkitApi.jar

Code Examples

  • If you need more information, check out the sample implementation of a plugin using StructureBlockLib in the structureblocklib-bukkit-sample folder.
  • All calls are not blocking and complete in the future.
Store a structure on your server to a target file
// Minimal configuration
Plugin plugin;
Path path = plugin.getDataFolder().toPath().resolve("mystructure.nbt");

StructureBlockLibApi.INSTANCE
    .saveStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .sizeX(32)
    .sizeY(5)
    .sizeZ(32)
    .saveToPath(path)
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to save structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Saved structure 'mystructure'."));
// Maximal configuration
Plugin plugin;
Path path = plugin.getDataFolder().toPath().resolve("mystructure.nbt");

StructureBlockLibApi.INSTANCE
    .saveStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .sizeX(32)
    .sizeY(5)
    .sizeZ(32)
    .includeEntities(false) // See JavaDoc for default values.
    .restriction(StructureRestriction.UNLIMITED)  // See JavaDoc for default values.
    .author("me")
    .saveToPath(path)
    .onProgress(c -> plugin.getLogger().log(Level.INFO, String.format("Percentage %.2f", c)))
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to save structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Saved structure 'mystructure'."));
Store a structure on your server to the default structure storage, so it can be used by ordinary StructureBlocks
// Minimal configuration
Plugin plugin;

StructureBlockLibApi.INSTANCE
    .saveStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .sizeX(32)
    .sizeY(5)
    .sizeZ(32)
    .saveToWorld("world", "me", "mystructure")
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to save structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Saved structure 'mystructure'."));
Load a structure on your server from a source file
// Minimal configuration
Plugin plugin;
Path path = plugin.getDataFolder().toPath().resolve("mystructure.nbt");

StructureBlockLibApi.INSTANCE
    .loadStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .loadFromPath(path)
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to load structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Loaded structure 'mystructure'."));
// Maximal configuration
Plugin plugin;
Path path = plugin.getDataFolder().toPath().resolve("mystructure.nbt");

StructureBlockLibApi.INSTANCE
    .loadStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .includeEntities(true) // See JavaDoc for default values.
    .seed(50L) // See JavaDoc for default values.
    .integrity(0.2F) // See JavaDoc for default values.
    .mirror(StructureMirror.FRONT_BACK) // See JavaDoc for default values.
    .rotation(StructureRotation.ROTATION_90) // See JavaDoc for default values.
    .loadFromPath(path)
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to load structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Loaded structure 'mystructure'."));
Load a structure on your server from the default structure storage, so you can use structures from ordinary StructureBlocks
// Minimal configuration
Plugin plugin;

StructureBlockLibApi.INSTANCE
    .loadStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .loadFromWorld("world", "me", "mystructure")
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to load structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Loaded structure 'mystructure'."));
Load a structure on your server and manipulate the blocks
// Minimal configuration
Plugin plugin;

StructureBlockLibApi.INSTANCE
    .loadStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .onProcessBlock(part -> {
      // onProcessBlock is called for every block before it is placed.  
      if (part.getSourceBlock().getBlockData().getMaterial() == Material.AIR) {
        // When the block in the structure file equals AIR, we do not want to place it -> return false.  
        return false;
      }
  
      // When the block in the structure file is something else, we do want to place it -> return true.
      return true;
    })
    .loadFromWorld("world", "me", "mystructure")
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to load structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Loaded structure 'mystructure'."));
Load a structure on your server and manipulate the entities
// Minimal configuration
Plugin plugin;

StructureBlockLibApi.INSTANCE
    .loadStructure(plugin)
    .at(new Location(Bukkit.getWorld("world"), 100, 100, 100))
    .includeEntities(true)
    .onProcessEntity(part -> {
      // onProcessEntity is called for every entity before it is placed.
      if (part.getEntity().isPresent()) {
        if (part.getEntity().get().getType() == EntityType.COW) {
          // When the entity in the structure file equals COW, we do not want to place it -> return false.
          return false;
        }
      }
  
      // When the entity in the structure file is something else, we do want to place it -> return true.
      return true;
    })
    .loadFromWorld("world", "me", "mystructure")
    .onException(e -> plugin.getLogger().log(Level.SEVERE, "Failed to load structure.", e))
    .onResult(e -> plugin.getLogger().log(Level.INFO, ChatColor.GREEN + "Loaded structure 'mystructure'."));
Load entities in memory and iterate them
List<StructureEntity<Entity, Location>> entities = new ArrayList<>();
StructureBlockLibApi.INSTANCE
  .loadStructure(plugin)
  .at(player.getLocation()) // We do need an existing world.
  .includeEntities(false) // Do not place entities.
  .includeBlocks(false)  // Do not place blocks.
  .onProcessEntity(entity -> {
      entities.add(entity);
      return false;
  })
  .loadFromWorld("world", "me", "mystructure")
  .onException(c -> c.printStackTrace())
  .onResult(e -> {
      for (StructureEntity<Entity, Location> structureEntity : entities) {
          // Do something with the entities
          structureEntity.spawnEntity(player.getLocation().add(-3, 0, 0));
      }
  });
Load blocks in memory and iterate them
List<StructurePlacePart<Block, World>> blocks = new ArrayList<>();
StructureBlockLibApi.INSTANCE
  .loadStructure(plugin)
  .at(player.getLocation()) // We do need an existing world.
  .includeEntities(false) // Do not place entities.
  .includeBlocks(false)  // Do not place blocks.
  .onProcessBlock(part -> {
    blocks.add(part);
    return false;
  })
  .loadFromWorld("world", "me", "mystructure")
  .onException(c -> c.printStackTrace())
  .onResult(e -> {
    for (StructurePlacePart<Block, World> structureBlock : blocks) {
      // Do something with the blocks
      System.out.println(structureBlock.getSourceBlock().getType());
    }
  });
Modify and use an existing structure block
Plugin plugin;
Location location = new Location(Bukkit.getWorld("world"), 100, 100, 100);
location.getBlock().setType(Material.STRUCTURE_BLOCK);

StructureBlockSave structureBlock = StructureBlockLibApi.INSTANCE.getStructureBlockAt(location, plugin);
structureBlock.setStructureMode(StructureMode.SAVE);
structureBlock.setSaveName("sample_save");
structureBlock.setSizeX(31);
structureBlock.setSizeY(15);
structureBlock.setSizeZ(12);
structureBlock.update();

Shipping and Running

  • In order to use the StructureBlockLib Api on your server, you need to put the implementation of the Api on your server.

For version >= 1.17

  • Add the dependencies to the libraries tag

plugin.yml

libraries:
  - com.github.shynixn.structureblocklib:structureblocklib-bukkit-api:2.13.0
  - com.github.shynixn.structureblocklib:structureblocklib-bukkit-core:2.13.0

For version < 1.17

Installing the StructureBlockLib.jar

Shipping the implementation with your plugin

  • Include both dependencies and shade them in your plugin jar file. If you do not know how to do that, you should go with the option above instead. There are several tutorials on spigotmc.org.

Maven

<dependency>
     <groupId>com.github.shynixn.structureblocklib</groupId>
     <artifactId>structureblocklib-bukkit-api</artifactId>
     <version>2.13.0</version>
     <scope>compile</scope>
</dependency>
<dependency>
     <groupId>com.github.shynixn.structureblocklib</groupId>
     <artifactId>structureblocklib-bukkit-core</artifactId>
     <version>2.13.0</version>
     <scope>compile</scope>
</dependency>

Gradle

dependencies {
    implementation("com.github.shynixn.structureblocklib:structureblocklib-bukkit-api:2.13.0")
    implementation("com.github.shynixn.structureblocklib:structureblocklib-bukkit-core:2.13.0")
}

Contributing

Setting up development environment

  • Install Java 17 or higher
  • Fork the StructureBlockLib project on github and clone it to your local environment.
  • StructureBlockLib requires spigot server implementations from 1.9.4 to 1.20.2 to be correctly installed in your local Maven cache. As this requires multiple java version to build different versions, a Dockerfile is provided to build these dependencies in a docker container and then copy it to your local Maven cache.

Note: If using Windows, execute the commands using Git Bash.

mkdir -p ~/.m2/repository/org/spigotmc/
docker build --target dependencies-jdk8 -t structureblocklib-dependencies-jdk8 .
docker create --name structureblocklib-dependencies-jdk8 structureblocklib-dependencies-jdk8 bash
docker cp structureblocklib-dependencies-jdk8:/root/.m2/repository/org/spigotmc ~/.m2/repository/org/
docker rm -f structureblocklib-dependencies-jdk8
docker build --target dependencies-jdk17 -t structureblocklib-dependencies-jdk17 .
docker create --name structureblocklib-dependencies-jdk17 structureblocklib-dependencies-jdk17 bash
docker cp structureblocklib-dependencies-jdk17:/root/.m2/repository/org/spigotmc ~/.m2/repository/org/
docker rm -f structureblocklib-dependencies-jdk17
  • Open the project with an IDE, gradle sync for dependencies.

Testing

Option 1

  • Setup your own minecraft server
  • Change // val destinationDir = File("C:/temp/plugins") to your plugins folder in the structureblocklib-bukkit-sample/build.gradle.kts file.
  • Run the pluginJar task to generate a plugin.jar file.
  • Run your minecraft server

Option 2 🐳

  • Run the provided docker file.
  • The source code is copied to a new docker container and built to a plugin.
  • This plugin is installed on a new minecraft server which is accessible on the host machine on the default port on localhost.
docker build -t structureblocklib .
docker run --name=structureblocklib -p 25565:25565 -p 5005:5005 structureblocklib

Licence

The source code is licensed under the MIT license.