This changelog is out of date! For the latest changes, look at the Git history.
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Fixed weather ticking exiting early, causing the profiler to not get fully popped before it exits
- Fixed non-existent chunks throwing errors when trying to cast the heightmaps to
LongArrayBinaryTag
s - Fixed world save all not calling
get
to join the future, resulting on data not being saved properly and getting corrupted on shut down
- Chunk streaming for players (they are now updated as you move)
- Asynchronous world loading using a cached thread pool executor
- Every reference of
java.io.File
has been removed and replaced with the newer and much betterjava.nio.file.Path
. This includes in the API. - All chunk loading has been moved out of
KryptonWorldManager
and moved in toChunkManager
, which is also now where chunks are cached. This is to improve multi-world support, and also to better abide by the single responsibility principle (SRP) - Worlds now store a reference to the folder and server they were loaded from and by.
- GS4 status query handler
- Default values to all of the configuration options
- Packet handling has been separated into multiple per-session handlers rather than a single handler
Player
now implementsHoverEventSource
, meaning you can use it as a hover event sourceHand
has been fully moved to the API, and no longer exists in both the API and the server- Tab completion now uses
StringReader
to avoid having to add one to the start when we send the packet (and also because it's the way you're meant to do it) - Fixed server's address never getting instantiated
PacketHandler
(the god object) is finally gone and has been divided up into separate packet handlers for each state in the protocol
- Internal vars in
KryptonServer
have been madeprivate set
, to avoid them being updated outside of the server class. - Moved done message to the bottom (so it actually prints when the server is fully done, rather than after plugin loading is done)
- Moved shutdown logic into its own function called
stop
, for readability
- Asynchronous plugin loading with
PluginScope
, as it was unnecessary
- Optional
force-default-gamemode
setting (allows you to force all players and world gamemodes to the gamemode set in the config)
- Fixed abilities being read from the config (meaning they never change)
- Fixed block breaking not returning if the player can't build
- Fixed inbound abilities packet using some logic that was not what we wanted
- Fixed NBT compounds not reading properly due to not resetting the reader index if the tag type isn't an end tag
- Inventories are now better than they were and exposed properly to the API
- Implemented inventories on the backend
- Inventories are now properly persisted, along with your currently held item
- Added block placement support (currently with a few limitations, like no placing blocks in non existent chunk sections, and you can't place blocks that aren't in this current palette)
saveAll
message is now dependent on whether the save was an autosave or not.- Player data is now directly applied to a
KryptonPlayer
, rather than using aPlayerData
object and applying the values inSessionManager
- Fixed player data not being applied when there is no file for the player, resulting in lateinit properties not being initialised
- Fixed NBT reading
- Fixed index out of bounds when populating a player's inventory
- Registries are no longer required to be dependency injected, as
RegistryManager
is gone andRegistries
is now an object
- The useless, stupid
PlayerData
object is now gone
- Fixed error handling so the disconnect packet varies based on the session's current state
- Fixed plugin message handling (again) because I was reading bytes wrong (using
readerIndex()
as the destination index instead of 0) - Cleaned up some code that was repeated unnecessarily in bytebufs.kt
- Renamed
PacketOutDisconnect
(login) toPacketOutLoginDisconnect
andPacketOutPlayDisconnect
(play) toPacketOutDisconnect
, as the latter is used much more often. - Made
Session
'sdisconnect
function take the reason rather than having it sent manually.
- Fixed fastutil exclusions, cutting JAR size down by ~3 MB
- Fixed permission check dispatching having
has
hard coded to true, meaning permission checks would never fail for non-null permissions. https://tenor.com/bggaL.gif
- Moved player data persistence into its own
PlayerDataManager
- Fixed issues with join messages
- Replaced imperative
for
each loops with the superior declarativeforEach
operation - Probably a premature optimisation, but avoided instantiation of
NamespacedKey
in places where it is constant - Skin metadata is now properly updated when the client sends a client settings packet
PacketState
's ID field is gone, and its references (literally none) have been replaced with the enum's ordinal
- Player data persistence (now uses .dat files to save and load player data)
- Console now has three simple registered translation keys, to allow sending join, leave and chat messages to the
console without extra work (
TranslationRegister
) - Rain ticking (now checks if there is rain time and counts it down every tick, and stops raining when the counter reaches 0)
- World data persistence (now also saves data to level.dat as well as loading it)
- Autosaves, just like vanilla, now happen every 5 minutes
- Region data persistence, using a system that is very similar to how vanilla handles region data persistence. This includes support for MCC (files used when chunks are more than 1 MB in size) files and all compression types.
ChunkPosition
, as I was getting fed up with having to do double to int conversions all the time when usingVector
, and also to save wasted space from the Y always being 0- Inhabited time (chunks) is now updated every tick (increments by the amount of players currently in that chunk)
- Fixed
LegacyQueryHandler
's copiedByteBuf
sometimes not getting released before it was garbage collected - Rotation update packets now actually update the player's stored position, rather than just sending it to the other players
start
inKryptonServer
is nowinternal
(for obvious reasons)PacketOutJoinGame
now accepts a previous gamemode and a dimension key from the player's data, instead of using previously hard coded -1 and overworld values respectively- Scoreboard functions now (mostly) do what they are supposed to
- Unused registry entries are now commented out, to avoid us storing way more data than we need to
- Bumped Adventure version to 4.7.0 and made it a shared constant in the server (Netty's version is now also a shared constant)
- Terminal console now uses
server.isRunning
to determine if the server is running, rather than a hard codedtrue
- Log4J now no longer shuts down before we finish logging, resulting in logging messages not getting sent.
Item
class (internally, left over from when I thought you needed a class per item)teleportId
property fromSession
(no need to store it, as we only read it once)
- Players now have a
World
, which is the world they are currently in.
- Fixed time update packets not filtering by world, meaning worlds could send time packets to players in other worlds
- Moved packet state change below world and location initialisation to avoid the chance that the variable could not be initialised when we access it in the ticking mechanism.
- Time ticking (the server now sends out a time update packet every second, and the time is updated every tick). This is the start of ticking for Krypton.
- Watchdog thread, to make sure the tick thread doesn't die. The threshold for what this thread considers "death" is configurable in the main configuration
- Suggestion support (tab completion)
- Warning when memory is 512 MB or below (vanilla threshold)
- Built-in stop command to stop the server.
- Vanilla's two uncaught exception handlers, to catch and log exceptions from threads that throw exceptions in execution.
- Updated
CommandManager
'sregister
functions that take Brigadier types to accept nodes instead of builders Sender
is now identified (extendsIdentified
, meaning it has anIdentity
, or a UUID)WorldBorder
now has aWorld
property again.- Overrode permission checks for the console to force them to always succeed, as we are god and permission checks are for peasants :)
- Added
unregisterAll
function to the event bus, to allow - Properly disconnect all connected players when the server stops.
- Fixed Krypton JAR not working properly due to the
Log4J2Plugins.dat
file not being merged from Log4J 2 and Minecrell's TerminalConsoleAppender (see here) - Changed log level of world loading to INFO to allow it to be seen in production (not that Krypton is production ready yet though)
- Support for more of Adventure's
Audience
methods, such assendActionBar
,sendPlayerListHeaderAndFooter
,showTitle
,clearTitle
andresetTitle
- Better documentation for some of the
data class
es in the API by using@param
to describe their constructor parameters - Default parameter for
title
in thePacketOutTitle
packet to allow us to send action bars without having to provide an empty title ourselves (the title isn't sent anyway if we use the set action barTitleAction
)
- Fixed issue with player joining loading so many chunks that you would find over 50,000 sections and around 7-10
million
Long
s being allocated on the heap by only having the server load the chunks required by the client. - Config file format is now HOCON instead of TOML.
- Errors with plugin loading and instantiation are now better handled and better described.
PacketOutAbilities
now uses the APIAbilities
class rather than the internal one.- The metadata writing functions now have a shared constant for the ending index
0xFF
- Cleaned up the
KryptonEventBus
to remove an unnecessarydo while
and replace it with afor
, also cleaned up a few things that were remnants of messy Java code. - Switched to Gradle's Kotlin DSL.
- Removed
id
properties from enums where their values were the same as theordinal
, to preserve very minor memory space (micro optimisation I know) - Removed internal
Abilities
class (replaced with API one)
- Terminal console appender, to add support for legacy section formatting codes in the console
- Serialisers for all of Brigadier's argument type parsers
- Fixed issue with arguments not being registered in the Brigadier argument builders when commands were registered, and so commands with more than just the initial command were not being parsed.
- Permission check event only firing when a command performs a permission check when it needs to be fired every
time
hasPermission
is called - Better handling of
CommandSyntaxException
s from Brigadier, meaning you now better see what is actually wrong with the command you typed. - Fixed issues with the scheduler not shutting down properly (causing the plugin manager to never be able to shut down
plugins either) due to a
ConcurrentModificationException
as I was not using aConcurrentHashMap
andKeySetView
(ConcurrentHashMap.newKeySet()
) for storing tasks.
- Made locale a nullable var rather than a lateinit var to avoid issues where it would not be set and a plugin would attempt to access it, resulting in an error.
- Console's sender object is now exposed to the API
- Ability to manipulate permission checks (change the result of them)
- Quit event (no, it can't be cancelled)
- Permission check event, which is fired every time a permission check is made.
- Permissions are now mapped to boolean values, to allow for them to be tristate (true, false or unset).
- Priority values are now bytes to avoid confusion because the event bus ignores any values outside the range of a byte
- Priorities are now in the correct order (MAXIMUM first, NONE last)
- Calling of the PluginMessageEvent and MoveEvent
- Optional reason for cancellation for the login and join events (defaults to the Mojang default)
- Latency update packet to the login sequence, as denoted in https://wiki.vg/Protocol_FAQ#What.27s_the_normal_login_sequence_for_a_client.3F
- For now, MoveEvent is no longer cancellable, as I do not want to cause any issues.
- Simple scheduling using an executor service.
- Support for appending URLs to plugins' class loaders at runtime.
- Cancellable event support using a BungeeCord-style event bus.
- Some basic events.
- Plugin scope, for executing the
initialize
method asynchronously.
- Command scope now uses the same amount of threads as available processors on the CPU.
- Command errors are now appropriately handled.
- Reactive event manager :(
- Logging to files (creates a directory called logs and generates log files just like vanilla)
- Console input handling (you can now type commands into the console)
- Command handling! Typing commands in chat will now actually have them function as commands!
- Shutdown hook, so the server shuts down correctly.
- Plugin loading! Plugins will now be loaded if their JARs are placed inside the
plugins
folder!
- Brand new Krypton API! Still a work in progress, but the core of it is there!
- Support for reading boss bars from world files (
CustomBossEvents
)
RegionManager
has now been merged intoKryptonWorldManager
- Due to the new API, all classes that are implementations of their API counterparts have been renamed to now be
prefixed with
Krypton
(e.g.KryptonServer
,KryptonWorldManager
, etc.) - The project has now been split into two modules: api and server.
Position
,BlockPosition
andChunkPosition
have all been removed and replaced withVector
.
- Player swing arm animation
- Entity actions (start/stop sneaking, start/stop sprinting, leave bed and start flying with elytra currently usable)
- Support for scoreboards, titles, action bars and tablist header & footer. You can't do anything with them yet, but they will be more usable in future versions. Also currently untested.
- Sessions are now better managed by the
SessionManager
, which handles a lot of the packet sending and encryption & compression setup for sessions, instead of sessions handling that themselves (removal of god objects) - Authentication is now entirely handled by
SessionService
, instead of it just wrapping theMojangSessionService
andRetrofit
PacketHandler
has been reduced to a, well, packet handler, instead of distributing packets and authenticating users itself, further reducing god objects- The second declare recipes packet that was being sent is now unlock recipes (like it should be), and unlock recipes is now working how it should.
Location
is now world bound, meaning it requires a world. This further separates it fromPosition
, which is not world bound and doesn't allow for decimals in its coordinates, andVector
, which isn't world bound.
- Added some actual checking into namespaced key conversions
- Fixed issue with keys in join game containing invalid values, and added the worlds that should have been there
- Some basic world generation configuration support
- Join game now correctly specifies the hashed seed of the world, and the status (is debug/flat world)
- Chunk data's primary bit mask is finally no longer hard-coded, which means that now all worlds should be supported
- Basic TOML configuration file - you can now configure various options in the config.toml file, which will generate inside of the file that the JAR file is placed in.
- Support for reading the dimension codec from customly converted JSON files (found under registries/custom in resources, converted from the original SNBT files, which can be found here)
- Adventure! We have now fully switched to Adventure! See more here
- Fixed issue with dimension codec only sending one biome, thus making biomes invalid
- Continued cleaning things up.
- No more system properties! Say goodbye to configuring worlds in system properties! You can now just specify the world name in the config and Krypton will find a world with that folder name
- Downgraded to Netty 4.1.59.Final from 5.0.0.Alpha2 due to issues with Epoll and KQueue, general stability, and that 5 has been discontinued by Netty
readAllAvailableBytes
(ByteBuf
extension function) now checks if the buffer has a backing array, and copies the bytes into an array if it doesn't (to avoid issues with direct buffers not having backing arrays)
- Legacy server list ping support
- Exception handling for connections
- Localisation support for join and leave messages
- Per-player gamemodes (W.I.P, is currently set to the world's default)
- Handshake handling is now done in
PacketHandler
- Disconnect handling - the disconnection packet now has to be sent separately before the connection is closed
PacketInfo
is now a data class- Packet categorisation - Packets are now better categorised into their appropriate packages
- Packet sending - Packets sent to other connected players are now no longer instantiated for each individual connected player
- Some more hard-coded values, such as the world's gamemode