- Allows you to import a structure from a file
- Also fixed a bug with getting relative blocks in mirrored structures
- Also make /struct build default to false for mirrored
Turns out Bukkit has a really weird way of dispatching events
Fix EventListener not being able to listen to EntitySpawnEvent
Bug caused leading zeroes in decimals to be ignored
For structures that were both mirrored and rotated, Structure#getBlock would incorrectly return null sometimes
Fix bug with JSON parser leading to inaccurate parsing of negative decimals
JSON serialization now properly escapes backslashes
The new JSON parser is roughly twice as fast and should use somewhat less memory, dramatically improving the performance of the BlockDataManager.
Previously, BlockDataManager#loadAll would clear loaded DataBlocks but not load them back in properly, this has been fixed
- Caused by completed loading task not being removed somehow
Would previously have to manually create the config and put `devMode: true` to enable dev mode
- Can now define placeholders and custom regex to find them, and replace them easily when fetching a message
- Made formatter no longer run every time a message is fetched
- Since subclass converters were added, config post-init methods were not working as intended due to a mistake
- Enable asynchronous file writes to sql databases for BlockDataManager
- Should help avoid issues with protection plugins
CME would occur when saving on shutdown
- Should now properly work for all items
- Previously would not work for banners and some other complex items like bee hives with bees inside them
- Chunks flagged as modified would not be unflagged when saved
- This would cause modified chunks that were unloaded when saveAll is called to be deleted
- Previously would wait for a loading task to complete before unloading, this could cause severe lag in some cases
- Now cancels loading task instead
- NPE would occur when loading a chunk, then unloading it, then loading it again and attempting to interact with DataBlocks
- Add comments to config fields with the repeatable `@Comment` annotation
- Only supported in 1.18.1 and above, since there was no support for comments in spigot's config library prior to that
- Fix rare error which would happen when opening SQLite connections on some platforms
- Make DataBlocks remove keys mapped to null values
- Can now be backed by either PDC or SQLite
- Can now retrieve data asynchronously
- Can now automatically load data asynchronously as chunks are loaded
- To migrate from an old SQLite database, call BlockDataManager#migrate, only available for SQLite-backed managers
- Map<Double, V> would sometimes have issues if some keys in config were formatted like ints, this is now fixed
- Subclasses of config-mappable classes can now be converted by storing the type in config
- Base commands registered to the command map now correctly report their usage
- Removed old/deprecated config manager
- Post-argument subcommands can now be run with parent arguments that are quoted with multiple spaces
- Add ItemUtils.skull, used to generate a player skull
- Ignore exceptions for tab argument conversion
- Exception would be caused when trying to load a number from a config-mapped object inside a list
This required more internal restructuring than I would like to admit
- Added wrapper DataHolder to abstract away implementation details of storage from the converters
- Switch SQLCache to use synchronized maps, which can store null keys and values
- The old config manager, and the redempt.redlib.configmanager package, are now deprecated and will be removed at a later date
- New config manager is in redempt.redlib.config
- Now can deserialize to record types (ConfigMappable annotation not required)
- No longer uses ConfigValue, all fields are automatically deserialized unless marked transient
- No longer requires ConfigManager.map/list/collection, can natively serialize and deserialize regular collections and maps
- Major code cleanup, more extensible
- Can now only deserialize to static fields in the root of the config
- Can now reload config from disk
- New guide can be found at
https://github.com/Redempt/RedLib/wiki/Config-Manager
- New docs can be found at
https://redempt.dev/javadoc/com/github/Redempt/RedLib/redempt/redlib/config/package-summary.html
- Fix protection for hopper minecarts so a hopper minecart outside a protection can no longer remove items from an inventory inside a protection with the CONTAINER_ACCESS ProtectionType
- Add TRAMPLE to ProtectionType.DIRECT_PLAYERS
- Added ProtectionType.TRAMPLE
- ProtectionType.CONTAINER_ACCESS now properly prevents the opening of double chests
- Plugin is now versioned using the last commit date
NPE would happen when dispensing an item from a dispenser, but would not impact functionality
- ProtectionType.PLACE_BLOCK prevents multi blocks from being placed now
- Storage minecart access is now protected by CONTAINER_ACCESS and not INTERACT_ENTITY
- Dispenser protection types now also protect against placement of fish in buckets
- An ArrayIndexOutOfBoundsException would sometimes be thrown when running a subcommand with no arguments if it had no hook, this has been fixed
- Moved protection registrations to new helper class
- Added protection types to prevent use of dispensers with items that may place entities or blocks
- Added protection types to prevent messing with entities such as armor stands, boats, minecarts, and item frames
- The ENTITY_EXPLOSION protection type now also prevents item frames from being blown up
- Attempting to run a post-argument subcommand whose parent has invalid arguments will now only show the help menu for the subcommand, not all commands available from the parent
- Merged base commands will now discard null error messages if possible
- Breaking: All constraints defined prior to this version will need to be rewritten using the new constraint system
- Constraints are now parsed once when the command file is parsed and give a reusable predicate to lower computational cost of constraint checks
- Constraints can now dynamically generate error messages based on the sender, constraint conditions, and supplied value
- Refactored constraint definitions for default number types to avoid copying code
- Constraints for number types now show more specific error messages
- Added ArgType#getDefault to get a default ArgType by name
Jitpack builds now work properly again
- Commands with player-only parents that have hooks can now be run by console (unless they are also player-only, of course)
- Improved consistency of error reporting for commands when they are run incorrectly
- Fix NPE on error reporting for commands that have the wrong argument types in the method hook, and an optional argument that is not specified when the command is run
- Code cleanup to simplify logic
- Update gradle version to 7.3
- ProtectionType.CONTAINER_ACCESS now prevents hoppers from moving items into chests from outside a protected area
- Added static methods to ProtectionPolicy to register custom protections against multi-block and directional events
- Made methods on SQLCache synchronized
- Parsing for MID_VERSION was broken by the version string returned by spigot 1.18-pre5, now parses correctly again
- Can now pass null as the prompt to not show a prompt message to the player
- Can now pass a boolean to specify whether the cancel message should be shown to the player
- Bugfix for PaginationPanel#addSlots(int, int, int, int)
- Shift-clicked items will now enter an InventoryGUI into open slots in the order they were opened
- Added InventoryGUI#openSlots and InventoryGUI#closeSlots variants which fill a rectangular area with 2 x and y coordinates
- Constraints can now be applied to flags
- ArgTypes can now specify an error message to be shown when a constraint fails
- Command argument constraints allow you to apply additional filters per-argument with the same type
- You can specify your own constraint rules for your own argument types, but existing ones have been put in place for int, float, long, and double to specify min and max values
- Example is int<1,100>:num to limit from 1 to 100, or <,100> for up to 100, or <100,> for 100 or above
- Merged base commands now properly display help menus
- Merged base commands now properly display error messages when the command is misused
- Nested post-argument subcommands now display previous arguments in help menus properly
- Nested posted-argument subcommands followed by regular subcommands followed by more post-argument subcommands no longer break the command processor
- Does anyone other than me use these features?
- Made ProtectionType.INTERACT no longer prevent container access
- Fixed argument processing for nested post-argument subcommands
- Made SQLite connections enable foreign key constraints by default
- The lambdas passed to ArgType#tabStream and ArgType#setTab can now safely return null
- Fix NPE that would occur when a command with a post-argument subcommand that had no hook was run directly
- Added ProtectionType.STRUCTURE_GROWTH, for when a structure (like a tree) is grown
- Added ProtectionType.STRUCTURE_GROWTH_IN, for when a structure who location is outside a protected area would create blocks within a protected area
- ProtectionType.GROWTH no longer prevents fire spreading, and ProtectionType.FIRE does
- Added ProtectionType.FLOW_IN, which will only prevent liquids from flowing into protected regions, not from flowing within or flowing out of protected regions
- Added ProtectionType.PISTONS_IN, which will only prevent pistons from pushing or pulling blocks from outside of a protected region, not operating within one or pushing/pulling blocks outside
- ProtectionType.PISTONS is no longer included in ProtectionType.INDIRECT_PLAYERS, but PISTONS_IN is
- Will no longer create a new blank page when the last page fills up if there is not an element to be placed on the next page
- PaginationPanel#clear will now properly remove all elements from the inventory
- Fixed issue where PaginationPanel would never display the final element that was added
- Fixed issue where PaginationPanel#getMaxPage would divide by zero when no slots were added
- Added PaginationPanel#clear to remove all added elements
- Added methods to get all added ItemStacks and ItemButtons
- Users used to be able to tab-complete the names of base commands they didn't have permission for, this is no longer possible
- Added PaginationPanel#setPage, since you may sometimes need to skip to a specific page rather than moving one page at a time
- InventoryGUI can now be paginated using the PaginationPanel utility class
- ConfigManager#collection can now be used to wrap any collection type for saving and loading to config
- 'minecraft:' will no longer be included in front of block names (1.13+)
- Rewrote structure scanning method entirely
- Issue happened in 1.12, still not sure what cause was
- Structure scanning is now faster and less memory-intensive
- Skip classes which throw NoClassDefFoundError when finding subclasses at runtime
- WeightedRandom will no longer have biased RNG after removing an outcome (thanks for the PR, divios)
- Fix bug with command manager where messages would display as their name rather than their value
- Commands now implement PluginIdentifiableCommand, which should make them more reload-friendly
- ItemUtils now mutates items rather than returning clones
- ItemBuilder now no longer returns a new ItemBuilder object with each call, instead mutating and returning itself
- FormatUtils moved from RedLib to RedCommands
- FormatUtils#color now supports hex codes by default in the format &#FFFFFF
- You can now set custom formatter functions for Messages
- Messages now support hex codes by default in the same format as FormatUtils#color
- NPE would happen when trying to load a mapped object from config where no configuration section existed for the object
- This would only occur if the object was stored directly in a field rather than in a map or list, and saveDefaults was not called
- Added flag to specify tick minimum ms in /profiler monitor start
- Config options to start profilers on server startup are gone
- For some reason starting the profiler on startup crashes the server, and when I tried to attach to the server using VisualVM to see what caused it to crash, VisualVM crashed too
- Error when trying to run a command hook which has incorrect parameter types will now show the parameter types the command manager tried to pass
- Removed debug output leftover from the last update, sorry
- Fix issue with command manager loading a certain message
- Fix bug with loading floats in config manager
- It can be used as a plugin dependency or a shaded dependency
- If you use it as a shaded dependency, none of the developer commands or features will be available
- All messages are still configured in the RedLib plugin folder even if RedLib is not installed
- Removed profilers and associated commands, as they were causing issues
- BlockDataManager#getLoaded will now return an empty set again rather than null if the chunk is not loaded
- Removed unfinished CustomBiome and CustomWorldGenerator classes
- Command messages are now in command-format.txt
- For the sake of still allowing command messages to be globally configured, this messages file will always show up in the RedLib folder even for plugins which shade RedCommands
- Code can now be found at
https://github.com/Redempt/RedCommands
- Command manager is still shaded into RedLib, so your usage of RedLib will not need to change
- Updates to the command manager will still be made into releases of RedLib
- This is for people who want to use the command manager without having a plugin dependency for it
- Refactored command manager code in RedCommands
- Added support for combining single character boolean flags (flags like -a and -b can now be combined into -ab in command usage)
- Fixed formatting of multi-line help messages
RedLib now loads on startup instead of post-world, allowing other plugins which load earlier to interact with it in their onEnable
- ConfigManager will now implicitly convert enums using valueOf and name
- Minor optimization to EnchantRegistry (thanks, Shuaiouke)
@ConfigValue may now be used without specifying a path, the path will default to the name of the field it is annotating
- Due to an oversight, attempting to register a command with a non-java plugin would still error, this is now fixed
- '//' can now be used to indicate a comment in command files
- Added command feedback for `/struct tool` (thanks, UntouchedOdin0)
- Added variant of `CommandCollection#register` which takes the Plugin object explicitly, which is needed for non-java plugins (thanks, Jan Boerman)
- Fixed some logic in MultiBlockStructure#getAt
- Structures with strict mode set to false and ignoreAir set to true would not ignore air
- Added DataBlock#clear (thanks for the PR, Tacodude7729)
- Make ConfigSet extend LinkedHashSet instead of HashSet
- Make commands with no help messages show usage instead if they have no subcommands with help messages
- Fixed bug where optional arguments would sometimes not be considered properly if the input could be converted to its type
- Added WeightedRandom#fromCollection to more easily create WeightedRandom objects from collections using lambdas
Should prevent some unexpected behavior, I didn't realize BlockDataManager wasn't the only place I had done this
- BlockDataManager should now be more reliable
- Fixed hash collision causing some issues with BlockDataManager in general
- Fixed silly mistake causing other issues with BlockDataManager#getAll
- I think this should wrap up all the problems with BlockDataManager's reliability, but please report bugs if you find any
- Made some micro-optimizations to ProtectionPolicy
- Working on a fix for DataBlocks sometimes not loading properly from BlockDataManager
- Fix error with improperly detecting enchantments in EnchantRegistry
- PlayerChangedArmorEvent and PlayerChangedHeldItemEvent now both extend PlayerEvent instead of Event
- Added FormatUtils#lineWrap
- Added ItemUtils#addLore(ItemStack, Iterable<String>)
- Added ItemBuilder#addLore(Iterable<String>)
Previous changes to the JSON parser had broken it due to long/int type conversions
- Fixed type casting issue with JSON storage
- Fixed double-sending of help menu entries
- When a help menu for a subcommand is shown, help for any sibling subcommands with the same name will also be shown
- Fixed inconsistent formatting, commands with no arguments would have a space between their name and the colon in the help menu
- Remove debug output.
- Varargs would not be usable in post-argument subcommands, and would always throw an error. This is now fixed.
- Command hooks for subcommands of a post-argument command should still take the arguments of the parent of the post-argument subcommand, but this was not reflected when the command was determining how many arguments the method hook should have
- Subcommands with no arguments following a post-argument subcommand between an argument subtype and its parent argument are now ignored, allowing you to have more complex operations
Was a minor bug that would not interfere with functionality, but would still print an error to console
- Post-argument subcommands are subcommand which appear after the argument of their parent commands, and accept those arguments in their method hooks
- Internal rewrite to the tab completer code, since it was old and messy. It is now somewhat faster, much cleaner, and will suggest tab completion options with spaces in quotation marks even if you have not typed a quotation mark
- Added `postarg` tag to the command parser for defining post-argument subcommands
- Tore out and rewrote some old, messy code that was becoming hard to maintain (Command#processArgs)
- Fixed minor issue with CuboidRegion#overlaps being inclusive
- Added command argument subtypes, argument types which rely on the previous argument to resolve their value
Pistons pushing multiple blocks with only some of the blocks being data blocks would result in the data blocks not being moved
- BlockDataManager would sometimes move the same data block multiple times with a single piston event
- Rotator#rotateBlockFace would hang indefinitely
- Allow config mapped objects in plain fields rather than only in config maps, sets, and lists
- Add new events to be handled with BlockDataManager (byteful's PR)
- Add methods to rotate BlockFaces and Vectors to Rotator
Prevents having to get ItemMeta and add it the old fashioned way
- Wither breaking blocks on spawn is now a protection type, WITHER
- Add alternative method for getting vector from BlockFace for 1.8, and use it in parts of the library which previously used BlockFace#getDirection for compatibility
- Tab completion will no longer break after using a quoted argument with a space
- Arguments which take a consuming value will now be passed the entire value including quotation marks
- Remove check for if a SQL ResultSet object is already closed when attempting to close since it would throw an error on older servers
- Caused by an off-by-one error in the code which checks if a StructureBlock's coordinates would be within the bounds of the structure
- RegionEnterEvent is now fired when players respawn within a region
- RegionExitEvent is now fired when players die within a region
- Added Results#getColumnCount to SQLHelper
- Fix ClassCastException in MultiRegion#recalculate
- Would previously error when joining/leaving with custom enchanted armor
NPE would occur on players joining/leaving
- SpheroidRegion#surfaceContains will no longer throw an NPE
- Created FormatUtils#color as shorthand for ChatColor#translateAlternateColorCodes
- Created InventoryGUI#setOnDragOpenSlot
- SpheroidRegion#move will no longer throw a stack overflow
- UserCache will now properly cache new players who join
- Previously would throw an exception if running a command with an optional argument with a context default from console
- Now gives an error message saying the argument must be specified
- Same applies to flags with optional arguments, with its own message
- Added method to create custom block drops to CustomBlockType
- Added CustomBlockRegistry#getAllRegistries
- Fixed error with LocationUtils#delayedTeleport that would happen when changing worlds
- Code cleanup for command registration
- Commands ending with a vararg or consuming argument will now properly show error messages if there are too few arguments
- Fix NPE for LocationUtils which occurred when worlds with no waiting listeners loaded
- Line numbers for errors will now be correct instead of off by one
- Opening braces on the next line from command name/arguments is now supported
- CommandParser#setContextProviders no longer removes the default 'self' context provider
- Will no longer error when using a tag name as a command name, such as 'user'
Spheroids with large X and/or Z radii and a low Y radius would sometimes be missing blocks due to the way the surface is generated, this has been fixed
- SpheroidRegion#expand(BlockFace, double) is now properly implemented
- SpheroidRegion#getSurface and SpheroidRegion#surfaceContains now both generate/use a cached surface for the spheroid to make them agree
- Region#contains now accepts a Block as well as a Location
- Region renamed to CuboidRegion
- Abstract class Region created, which CuboidRegion and MultiRegion now extend
- Created SpheroidRegion for representing spheres and spheroids
- CommandParser now has 'nohelp' tag to get rid of the implied help subcommand
- Added Messages#getLoaded to get existing loaded messages for a specific plugin
- New alternate constructor for CommandParser takes a Messages object
- New command tag 'helpmsg' fetches the help message by its name from the Messages object
- Created UserCache for getting OfflinePlayers who have logged on before
- ConfigSet works exactly like ConfigList, but is a HashSet instead of an ArrayList
- Create one using ConfigManager#set
- The default player argument type now uses Bukkit#getPlayerExact instead of Bukkit#getPlayer, which is O(1) instead of O(n)
- New class, StructureData, represents a cross-version way to store block data for MultiBlockStructure
- MultiBlockStructure#create has been massively optimized to reduce string copying and useless string operations, and caches and reuses StructureData values where possible
- StructureData is now stored internally and kept instead of Strings
- Rotator#rotate now applies to BlockData rather than String
- Messages#load now preserves the order that the messages appeared in when writing defaults
- RedLib.midVersion has been made final and renamed to MID_VERSION
- Calls to Region#move and Region#expand will now make the Region return itself, making it easier to use it in a builder-style syntax
- Updated Spigot dependency to 1.16 and updated MockInventory to work with 1.16
- ConfigManager#map has a new variant which takes a ConversionType, allowing you to specify how the data will be converted
- ConfigManager#list also has a new variant with the same thing
- ProtectionPolicy now has methods to add and remove ProtectionTypes
- ArgType#map will now properly pass on tab completions
- CustomItem#item is now CustomItem#getDefaultItem, and CustomItem#getItem can be overridden
- CustomEnchants are no longer a parameterized type
- CustomEnchants no longer pass an EnchantTrigger in the constructor
- Added CustomEnchant#addTrigger for registering EnchantTriggers for a CustomEnchant
- CustomEnchants can now have multiple EnchantTriggers using this method
- EnchantTrigger is now an abstract class instead of an interface
- EnchantTrigger#register is now a no-arg void function
- Added EnchantTrigger#addListener to add listeners which get items related to events
- Removed NONE EnchantTrigger since it is no longer useful
- Multiple CustomEnchants using the same EnchantTrigger within the same plugin will no longer register multiple listeners
- This will break everything that currently uses the custom enchantments API, but should be fairly simple to port over
- Wiki will be updated soon
- Removed some redundancies in ConfigMap
- Removed bad practice/inefficient code in Command#splitArgs
- Added variants of ArgType#tab and ArgType#tabStream that give access to previous arguments
- Created /commandchain, alias /cchain, a command for dev mode which allows you to run multiple commands in sequence separated by semicolons, and has tab completion for commands you type into it
- Fixed bug with error messages not being displayed properly when a vararg command argument which is not optional is passed no values
- Fixed bug where old values were not cleared from ConfigMap and ConfigList when calling load
- ConfigMap can now be of any <K, V> by calling ConfigManager#map(Class, Class) and will convert the type for the keys if needed using converters
Related to previous update to command manager
- When executed improperly, commands will now try to tell you what went wrong rather than just sending the help page
- Running a subcommand improperly will now show the help for the subcommand, rather than the help for its parent
- As with everything else, these messages are configurable in RedLib's messages.txt file in its plugin folder
Simply adds materials to be treated as if strict mode is disabled rather than disabling it entirely
This class makes it easy to define and load custom items, and returns them in a handy-dandy map by name.
I've been overhauling and revamping various parts of the library, and the config manager was in need of some love. It had a lot of "magic" features, which made very little sense just looking at the code if you didn't have context. This overhaul is meant to make the code easier to understand and less convoluted. There are lots of breaking changes, any any plugin using the config manager will need to be adjusted and recompiled, so read carefully. I will do my best to update the wiki quickly.
- Major internal restructuring and code cleanup for ConfigManager
- Renamed ConfigHook to ConfigValue
- Moved config-related annotations to the redempt.redlib.configmanager.annotations package
- Config-mappable objects (previously just known as objects loaded through a ConfigMap) must now be annotated with @ConfigMappable
- Post-init methods for config-mappable objects must now be annotated with @ConfigPostInit
- Adding a ConfigValue annotation with the value "_section" will no longer work
- Adding @ConfigPath over a String variable will make it be populated with the name of the config section
- Adding @ConfigPath over a ConfigurationSection variable will make it be populated with the config section itself
- You no longer add `.*` to the end of a path loading config-mappable objects with a ConfigMap
- All config annotations are now inherited
- You can now register multiple objects/classes to store config values
- You can now use ConfigManager#list to create a list of config-mappable objects similarly to ConfigManager#map
- Code cleanup
- SQLHelper#getMatchingCaches and related methods will now also match the column they are caching
- FormatUtils#formatLargeInteger will no longer throw an exception when passed 0
- MultiBlockStructure#getAt is now considerably faster in certain cases
- Comparable to previous algorithm for case where the structure exists and the root corner is passed
- Several times faster than previous algorithm where the structure exists but the given location is far from the root corner
- Many times faster than previous algorithm where the structure is a close, but not exact, match
- Orders of magnitude faster than previous algorithm where structure is very clearly not present
- MultiRegion#recalculate safer against floating point errors
- Rotator now has setters for its fields
- Added variants of Region#expand which take doubles instead of ints
- Further optimized MultiRegion#recalculate. Previously execution time grew logarithmically with region sizes, it is now completely independent of region sizes
- MultiRegion#recalculate will now be more accurate, covering the same area down to .1 blocks instead of 1
- Added true and false as tab completions for the boolean ArgType
- Fixed potential NPE with ConfigMap
- Fixed IllegalArgumentException when building structures containing walls or redstone in 1.16 (thanks for reporting this, MaveCrit)
- Added ProtectionType for nether portal pairing
- Fixed RedLib#getCallingPlugin returning a disabled instance of the plugin if it has been reloaded previously
- Fixed issue where InventoryGUI would throw errors in 1.8
- Added variants of constructors for EventListener which will infer the plugin
- Added method to format large numbers with commas in FormatUtils
- Added constant array of BlockFace for all primary block faces in LocationUtils
- Added shorthand method to get the center of a block in LocationUtils
- Added variants of all methods to Task class which will infer the plugin
- Fixed edge case out-of-bounds error with WeightedRandom
- Tweaked NMSClass and NMSObject to support calling methods declared in a superclass
- Added method to main RedLib class which will get the plugin that called the calling method
- PlayerChangedArmorEvent is now fired more consistently
- Introduced PlayerChangedHeldItemEvent
- Added new enchant trigger KILL_ENTITY
- Added new enchant trigger HOLD_ITEM
- Fixed bug where enchants with a space in their name would not be included when calling EnchantRegistry#getEnchants(ItemStack)
- Added methods for Title Case and camelCase in FormatUtils
- Added method to get structure data block type from StructureBlock
- Made SQL queries by the BlockDataManager not sync to disk immediately for better performance
- Task async methods were public but not static, they are now static
- Created method MultiBlockStructure#getType, which is considerably cheaper to call than getData
- Fixed bug in InventoryGUI where players could double click an item in their inventory to collect to their cursor, taking items from the GUI
- BREAKING: Update references to SQLHelper before updating RedLib!
- Added method SQLHelper#setCommitInterval to commit periodically
- Rewrote ItemTrait#compare for ItemTrait.NAME and ItemTrait.LORE to make them not call ItemStack#getItemMeta on items which did not already have ItemMeta
- Created SQLCache, which allows you to easily cache values in a SQL database to avoid unnecessary SQL queries
BlockDataManager wasn't auto-saving before, so if your plugin didn't explicitly call save() every now and then, and only called saveAndClose() in the onDisable, the time to save would be very long if a lot of changes had been made / the server had been running for a very long time.
Oh well, it wasn't really useful anyways
- Breaking change: The ... to specify an argument is consuming must now go after the type, not the name
- Added support for [] after an argument type to indicate it is vararg
- Vararg works like consuming, but is parsed into multiple arguments and passed as an array rather than being passed to the converter as a single string
- This sounds confusing, but please check the wiki, where it is described with examples:
https://github.com/Redempt/RedLib/wiki/Command-Arguments
Flag aliases can be separated by commas, just like command aliases
Fixed bug with multiple spaces showing before arguments in help menu for commands with no flags
Also removed debug output
- player is now a default command argument type
- self is now a default context provider
- Minor optimizations and code cleanup for CommandParser
- Flags are now supported by the command manager, and are handled similarly to but separately from arguments
- Added ItemTrait enum for comparing individual traits of items
- Added ItemUtils#compare using ItemTraits for more fine-tune control of what is compared
- ItemUtils#compare with no ItemTraits will work the same as it did before
- Added LocationUtils#delayedTeleport
- Increased weight of distance to destination in heuristic
- LocationUtils#pathfind
- LocationUtils#directPathfind
- Not yet benchmarked but seems efficient, will likely optimize in the future
- BlockDataManager now properly unregisters its listeners when saveAndClose is called
- Added methods to query a long to SQLHelper because they get improperly cast to int
Haven't been doing as much work on RedLib recently as school has taken over a lot of my time. Should be back up and doing more soon though!
- Added toString and fromString
- Optimized to use binary search instead of linear search
Added BlockDataManager#getAllManagers
- DataBlock now supports transient properties, data values attached to the block that will not be saved
- ItemUtils#toString will now return null if the item is null instead of throwing an NPE
- Added support for longs to JSON parser and, subsequently, DataBlock
- Fixed issue with NoiseGenerator#noise returning the same value for coordinates 0 and 1 on all axes
- There is now a command to build the structure you have created with /struct create
- Added missing documentation to DataBlock
- Added DataBlock#move, to move all the data from one location to another
- Fixed no-op NPEs in BurstProfiler and PassiveProfiler
- When calling LocationUtils#fromString on a string which refers to a world which has not yet loaded, it will update the returned location with the correct world once it is loaded
- Moved Rotator to its own file and optimized it
- Removed BlockSetRegion
- Added Region#rotate
- CustomBlockPlaceEvent now has the item that was used to place the block
- CustomBlockType#initialize should no longer return null if CustomBlockType#getCustom is not overridden
- DataBlock#set will now remove a key if null is passed, fixing an NPE with saving in the BlockDataManager
- Added a common filler constant to InventoryGUI
- Fixed bug with JSON parser that caused booleans to always evaluate to false
- Created RegionUtils and added a basic method to find interior space within a region
ALL plugins which used either class must be recompiled to be compatible with this version.
I realize that this is the second breaking change in a row. After this, breaking changes will be largely avoided to ensure backwards compatibility. However, CommandArgumentType needed to be removed and put into a new file, ArgType. It was an internal class of Command, which extended the file to be much longer than it should have been. And CommandArgumentType is a very lengthy class name, hence the rename to ArgType. All documentation should be updated already, but let me know if I missed any. As RedLib grows, I want to make sure its older parts remain clean and maintainable, and I will be using better coding practices to ensure breaking changes can be avoided in the future.
Call this method in your onDisable instead of BlockDataManager#save
- Now uses SQLite and JSON instead of YAML
- No longer stores all values in memory, instead only stores values in explicitly loaded chunks
- Automatically unloads DataBlocks when their chunks are unloaded
- Commands can now have a "notab" tag to signify they should not be tab-completable
- You can now use maps in normal cases with ConfigManager (Map<String, ItemStack>)
- Introduced profiler and profiler commands
- Introduced ItemUtils#toString and ItemUtils#fromString
- Added JSON parser
- FormatUtils#formatTimeOffset can now truncate unwanted units
- Region#getChunks and Region#getLoadedChunks should be much less expensive
- ConfigMap#clear now works properly
- FormatUtils#formatTimeOffset now formats days
- MultiRegion#recalculate has been optimized even more and has had bugs fixed, and is now almost completely independent of region sizes
- Uses a binary search of a K-D tree instead of checking every point to see which regions have not been included yet
- Task is a shorthand way of scheduling tasks through the Bukkit scheduler
- MultiRegions will now properly recalculate subtracted regions
- Potentially breaking change: MultiRegion#getIntersection now returns a MultiRegion instead of a BlockSetRegion
- Introduced Region#getIntersection
- SelectionTools will now be unregistered when the plugin that created them is disabled
- You can now specify a block type to skip when scanning a structure, in case that type was used to select the corners
- You can now register custom events to be protected by a ProtectionPolicy using ProtectionPolicy#registerProtection and ProtectionPolicy#registerProtectionNonCancellable
- ConfigMap#postInit has been removed, as it was causing issues. Create a method called postInit with no arguments.
- ProtectionPolicies will now unregister themselves if the plugin which created them is disabled
- Region#getChunks and Region#getEntities have been optimized because World#getChunkAt is evidently an expensive operation. Chunks are now cached by Regions after one call, and Region#getEntities no longer loads chunks to check for entities unless specified to.
- Structure#getRegion now returns the correct region regardless of rotation
- LocationUtils#getNearestSafeLocation is now more accurate
- CustomBlockRegistry no longer throws an exception when breaking a custom block
- Commands registered through CommandManager will now be unregistered when the plugin that registered them is disabled
- InventoryGUI now cancels InventoryDragEvents which are in non-open slots in the GUI
- ItemUtils now has a utility method to clone an inventory (cannot be opened, but supports other operations)
Backwards compatibility is preserved, though it is deprecated and may be removed in the future.
Various other internals have also been reworked to ensure cross-version support.
Enchant triggers no longer ignore cancelled events; that can be decided by the enchant handling the event
InventoryGUI now has a method setOnDestroy which allows you to set an action to be performed before the inventory is destroyed
ProtectionPolicy should no longer send multiple messages if multiple policies are preventing the same action
CustomBiome and CustomWorldGenerator are still not ready for use, but they will be updated and improved with coming updates
World generation API other than perlin noise and octave generators is still WIP
BlockDataManager will no longer throw NPEs when attempting to load blocks from worlds that have not yet been loaded
NMSHelper will now find methods more smartly
You can now easily work with NMS classes and objects using RedLib
There is also now a built-in packet listener that allows you to easily listen to incoming and outgoing packets
Added documentation for CustomBlockType
Changed some abstract methods in CustomBlockType to take the CustomBlock instance instead of a DataBlock
You can now middle click custom blocks to get their item
General optimizations
The Custom Block API lets you easily define custom blocks and behavior for them. It leverages the previously-added persistent block data API.
Calling getObject on a ResultSet in a String column would return an Integer if the String could be parsed to an int, the String get variants are the workaround.
SQLHelper can now wrap a Connection and offer methods that make it much easier to work with SQL, reducing clutter and removing the need to surround everything in a try/catch.
BlockDataManager (the block data API) allows you to store persistent data attached to blocks which will be intuitively managed. If a block is broken, its data is removed, and if a block is pushed by pistons, its data is moved with it.
PlayerChangedArmorEvent is now called when armor breaks
ConfigHook priority allows you to define the order in which config fields will be loaded
- PlayerChangedArmorEvent is now called for a wider range of events wherein a player's armor changes
- Fixed error in interaction listener for ProtectionPolicy for 1.12 and below
BREAKING CHANGE:
Some classes have been moved from the package redempt.redlib.region to a new package, redempt.redlib.protection. Make sure that you fix any imports.
Protecting a region and enabling events (RegionEnterEvent and RegionExitEvent) are now more optimized for scale, meaning that there should be almost zero affect on performance even if there are thousands of regions with events enabled, or protected.
MultiRegion clustering helps to further optimize MultiRegions, especially for ones that have many sub-regions
The custom enchantments framework makes it easy to define your own custom enchantments and load them at runtime. I will be working on updating the RedLib wiki to explain how to use it more in-depth soon.
Would previously throw a NullPointerException if the given string or object was null when trying to convert
Added set(), remove(), and clone(), which can be used to help you modify the WeightedRandom without having to recreate it every time
Beforehand, nothing would happen, but calling put on a ConfigMap will now set this field in the object being put as the value
You can now schedule postInit tasks using ConfigManager#postInit, and an object being used for a ConfigMap can know its ConfigurationSection by having a field like this:
@ConfigHook("_section")
private ConfigurationSection section;
NPE happened when calling save() with a ConfigMap in one of the fields before calling another operation
Previously, it would just load from the same config it had in memory. Now it will load from file, so this is good for reload commands.
ConfigManager#saveDefaults() wasn't working correctly with ConfigMaps
Calling save() would actually load fields from config
BlockSetRegion is a faster version of a MultiRegion, but with considerably more memory overhead. Used for some intermediary operations in MultiRegion to make recalculation faster. BlockSetRegion has limited functionality.
- Added "assert" tag to command file parser, which acts similarly to "context" tag but doesn't pass the argument to the method hook. Useful for when you just need to assert that certain context is true or exists, but don't need the actual data beyond that.
- Created ArgType, which is the exact same as CommandArgumentType. CommandArgumentType can make your lines of code quite long, so ArgType just acts as an alias.
- Made CommandCollection coalesce multiple base commands with the same names/aliases into a single command which will attempt to run all of the commands until one is successful. This behavior is now consistent with how subcommands always worked, and simplifies command writing further.
Thanks to ambiguous method definitions in Spigot 1.8, EntityPersistor#persist doesn't work. I added an alternative, EntityPersistor#wrap, which returns an EntityPersistor<T>. You just call get() on it and it refreshes the instance if it's invalid, and returns it.
Minor optimizations to MultiRegion#recalculate, can no longer add Regions from different worlds to a MultiRegion
This protection type prevents players from using buckets
Holograms weren't persisting their Entity instances properly when created with getAt
EntityPersistor allows you to ensure the validity of an Entity instance even if the entity's chunk is unloaded and later loaded again. This update also uses EntityPersistor to fix persistence issues with Holograms.
ConfigList lets you store values in a config hook variable in a list of a type not supported for storage directly in YAML
ChatPrompt had a placeholder which wasn't properly being replaced
Optimizations and bugfixes
Methods are for adding ItemFlags and persistent data storage
ConfigManager allows you to load config values directly into variables in your code. For docs, go
here. For examples and more, go
here.
Thrown when a command with a hook name specified in the command file does not have a method hook
MultiRegion now has many more methods, and its existing methods have been optimized. It also now extends Region, and implements all of the same functionality, meaning you can now create a ProtectedRegion from it like you would a cuboid Region.