GithubHelp home page GithubHelp logo

elytra-server / elytra Goto Github PK

View Code? Open in Web Editor NEW
51.0 10.0 6.0 11.4 MB

A Cleanroom minecraft server API in kotlin

License: MIT License

Kotlin 99.03% Python 0.97%
minecraft-server minecraft kotlin elytra

elytra's Introduction

Elytra

Elytra

Discord GitHub stars GitHub issues GitHub last commit MIT License Open Source Love

Elytra is a multi-threaded Minecraft server implementation and plugin API. It serves as an alternative and improvement on the single-threaded nature of the official server and Bukkit/Spigot APIs, which build upon it.

To follow news and get involved with the project, join our Discord.

Contents:

Compilation

Elytra is written in Kotlin and utilizes Gradle 2 as build management tool. To compile it from the source, perform the following steps:

  1. Make sure to have Git and Gradle 2 installed
  2. Clone the repository with git clone https://github.com/Elytra-Server/Elytra
  3. Build the project with gradle clean build shadowJar

Credits

  • Protocol Wiki community for providing extensive information on the most up-to-date protocol
  • MCP for proving client-side code and documentation to help with the protocol flow

Contributors


Wiljafor1

๐Ÿ’ป

Lucas

๐Ÿ’ป

Tomas Almeida

๐Ÿ’ป

chico ferreira

๐Ÿ’ป

Bruno Martins

๐Ÿ’ป ๐Ÿ“–

Jailson Pereira

๐Ÿ’ป

Joรฃo Victor G. Cruz

๐Ÿ’ป ๐Ÿ“– ๐Ÿ“ ๐Ÿ’ฌ

Sponsors

YourKit

We are proudly using the YourKit Java Profiler to improve the performance and find high memory usage. Thank you for this amazing tool and we can fully recommend it to all Java developers!

YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications. YourKit is the creator of YourKit Java Profiler, YourKit .NET Profiler, and YourKit YouMonitor.

Donate

Buy Me A Coffee

elytra's People

Contributors

allcontributors[bot] avatar chicoferreira avatar heroslender avatar jailson-lima avatar tommyalmeida avatar wiljafor1 avatar winx64 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elytra's Issues

Gamemode command not working

Describe the bug
When someone tries to change gamemode with /gamemode he gets kicked with an DecoderException error.

To Reproduce
Steps to reproduce the behavior:

  1. Open chat with T (default key)
  2. Type /gamemode something

Expected behavior
The players should have their gamemode changed to the input gamemode.

Screenshots
image

Add suport to ANSI Colors and a more verbose initialization

My suggestion is to add a support to ANSI to colorize a little bit of the terminal when printing the informations.

Jansi is a lib with this purpose.

By now the INB isn't printing much. It will be good if a more verbose info gets printed, like the version/versions supported, the host:port where the server was bound to and so on, to help the user knows what is happening.

Add NBT

Description
Add NBT out of the box

Shoulds:

  • All primitive types should be supported
  • Blocks should also support NBT in order to remove complex code from user plugins

More about NBT

Game profile cache

Make a system that caches the player's gameprofile when he enters without having to make unnecessary consultation

Simultaneous premium/cracked support

A brief contextualization

As we all know, the vanilla server has two modes of user authentication: Offline and Online. In offline mode, the server will skip this verification and let anyone connect. In online mode, the client/server will both make validations with Mojang's session server to ensure that the user connecting is who it's claiming to be, essentially limiting access to the server to those who bought the game.

In a simplified manner, the process of authentication first starts with the client positing a request to the session server with its access token (received from logging in with their original accounts), selected profile and the hashed id of the server (composed of its public key and symmetric encryption key used by the client/server) it's trying to connect to. After that, the server sends a request with the user's name and same hashed id to verify that the user is specifically trying to connect to it, and not another server. If all goes well, the client is allowed to log-in. Moreover, this process also enables point-to-point encryption between client and server, further securing the connection.

The current problem

In the vanilla implementation, the client will automatically disconnect from the server during the process if it sends an invalid request to the session server. This factor ends the authentication process early, and prevents it from continuing in the case the player's session is not valid. While not a problem by itself, it makes impossible to servers to allow both cracked and premium members to connect, while still being able to differentiate between the two.
image

Numerous attempts on a solution for this problem exist, but most of them end up introducing some kind of inconvenience for the player connecting.

One could perform the authentication process normally, kick players with an invalid session, but allow them to connect on the next attempt while marking them as cracked. While this seems a good solution, it not only makes so that cracked players have to login twice, it also prevents premium accounts from successfully joining in case they tried to log in with an invalid session previously.

The proposed solution

Considering that, when coming from a single point of entry, it is impossible to classify clients as premium/cracked while still letting them connect at the same time, a solution using multiple points of entry is proposed. The server would have two points of entry, one for clients desiring to join with premium accounts, and one for users with cracked accounts.

While there're several ways to create these points of entry, such as two physical server sockets, the proposed solutions makes use of the Server Address field in the Handshake packet. When connecting to a server, the client will send the unresolved address of the server in the handshake packet, which the server can use to make all sorts of decisions. In our case, it will be deciding whether the player wants to log in with a premium account or a cracked one, creating our two entry points.

The server would be configurable to allow the selection of the authentication method based on the address used to connect (e.g.: premium.myserver.com for normal authentication, and cracked.myserver.com for cracked accounts). The premium route would follow the normal authentication method, with only users with valid sessions being able to connect, while the cracked route would simply allow anyone to join, no questions asked. Using the same mechanism that the vanilla server uses, users would be differentiated by the version of their UUIDs, with premium players having version 4 ones returned by the session server, and cracked players having version 3 ones hashed from their names.

This system would of course, be completely optional, with server owners being able to choose between it, and the common online/offline operation modes.

Issues to be addressed

Even though each player would be uniquely identifiable by their UUID, some problems arise when users with identical names are both connected (one premium and one cracked).

Name clash

Even in the most recent versions, some of the game mechanics are not structured to allow duplicate entries, such as scoreboards.

Identification by name

To avoid confusion and misidentifying players, a way to differentiate between them would be necessary for text based mechanisms (Chat, Commands, etc).

Achievements and Statistics

Description
Implement achievements and statistics, found on minecraft settings, to keep track of the player goals.
That SHOULD BE DONE in a separated module and not incorporated in the player object, so it can be easily disabled for servers that do not need it.

Checklist

  • Achievements
  • Statistics

Command Aliases

Is your feature request related to a problem? Please describe.
I'm always frustrated when I try to type /gm and it doesn't work. So I think an alias to the gamemode command will be perfect.

Describe the solution you'd like
Add aliases list to command.

Additional context
@Aliases in CommandSpec

.elytra file format for world compression

Description
In order to be effective to save world data or backup it we decided that we are gonna create a .elytra file format instead of using the old .region file format.

Why?
Region files add unecessary data to the files that takes a lot of bytes filling up the space very quickly and difficulting operations in bulk.

Must use zstd instead of the zlib

Block Populators

Description
Add block populators to complement the world generator, so generated worlds can have basic structures (trees, dungeons, villages).

Effective PvP Combat

Description
Nowadays PvP combats depends alot of latency and in order to have a good pvp we need to be effective and somehow create a system that doesn't only depends on wheter the player hitted or not. We should have in count variables like: Packet Loss, Latency, Variance.

Placeholder not working

Describe the bug
Placeholders are not working as expected in gamemode command.

To Reproduce
Steps to reproduce the behavior:

  1. Type /gamemode <non_existing_gamemode>

Expected behavior
Should show the argument that the user typed.

Screenshots
image

Add multi-platform

Is your feature request related to a problem? Please describe.
Currently is pretty damn boring creating plugins for different minecraft editions and using different apis, this is a big problem.

Describe the solution you'd like
VertX is the way to go because allow us to have different verticles, this meaning servers can be single unit expanding vertically without having to override each other.

Additional context

Command API

Description
Add a command api and some basic commands.

Player head not showing on players list

Issue
When clicking on tab the player head is not displayed on the server players list

Expected
Player head to be displayed on players lists (if non-premium set head to steve).

Validate inbound packets

About
Packet validation is important to mantain a barrier for forbidden entities like bots

Expected
The packet validation should check if the packet exists on the netty pipeline in order to exclude/pushback the connection of the entity sending the unknown packet.

World Chunk

Description
Add world chunks so players can do something.

Checklist

  • Chunk
  • Chunk manager
  • Block entities

Command completion not working

Describe the bug
Tab-complete for commands isn't working, shows as if the server had no commands.

To Reproduce
Steps to reproduce the behavior:

  1. Open the chat and enter /
  2. Type any command

Expected behavior
It was exepected to show the available commands matching the typed text in chat.

Screenshots
Screenshot

I18n Support

Description
I18n should be supported with a resource bundle file.

Should

  • The developer can choose the pattern style
  • The developer can create as many resource bundles for the translations as he please
  • The resource bundles should respect the .properties style
  • Should be provided a DSL to simplify the i18n usage
  • Should be unit tested

Possible chunk data improvements

Contextualization
Recent versions of the game have completely revamped the method for storing block information in chunks. Instead of an array directly holding block ids, chunks now utilize a palette mapping mechanism.

Each chunk section is comprised of a block palette and a data array. The palette holds the block state id of each block present in the section, while the array holds the index (in the local palette) of each block in the chunk. As this palette contains considerably less elements than the global palette, less bits are needed to represent the indexes in the data array. The number of bits needed grows with the number of blocks in the chunk section palette, following a rounded-up base 2 log rule.

This technique helps to reduce the size of chunks with a lesser diversity of block types, and by consequence, the amount of data needed to be sent to the client.

The (possible) problem
As of now, the game follows some fixed rules on the number of bits needed to encode the palette indexes. The first one is that the minimum size is set to 4, a possible strategy to give a good interval (16 blocks) and avoid needing to constantly recalculate the data array for chunks with few block types.

The second one is that, after a certain number of bits, the game will stop mapping indexes from the local palette, and use the global one instead. This is most likely used to avoid the number of elements growing too much in size due to the large number of bits needed to encode the indexes (along with the data array itself). Currently, the game starts mapping from the global palette at 9 bits, up to 14 (the current maximum).

However, calculations show that it should only start at 11 bits instead. Chunk sections mapped using the Global palette have a constant size of 7168 bytes. If the palette is mapped using the maximum of 8 bits, as in Vanilla, the chunk size will only go up to 4610 bytes before changing to the global palette scheme.

The (possible) solution
If we consider 10 bits, however, it will be able to go up to 7120 bytes before changing schemes.
Comparison
As such, the current suggestion is to utilize 11 as the limit, in order to reduce the final chunk data packet sizes even further. However, tests need to be conducted to verify how the client will behave to this. How will it react upon receiving a chunk data packet with a number of bits set to 9? Will it adjust the data received, or refuse the packet entirely?

In the case that it accepts and adjusts it, other points that need further research include if having de-synced palette configurations between client and server will affect any other aspect. As of now, its confirmed that this won't cause block mismatches, since all block related packets (block change, multi block change, etc.), aside from the chunk data one itself, utilize ids from the global palette.

World entities

Implement an efficient and easy way to manipulate minecraft entities.

Server Configuration

Description
To be able to make a configuration system that can change from the most basic option to world settings, how to make the world read-only

Checklist

  • World
  • Entity
  • Common

Full JSON Chat API support

Several years ago, a new json-based chat text system was introduced to the game. While the old system, using a formatting character (ยง) and specific codes ([0-9a-f]), allowed for custom color and formatting, the new one provided extra features, such as click and hover events.

As stated in the change-logs for the most recent snapshot (20w17a), text will no longer be limited to the 16 default colors, but will now allow the use of the full RGB spectrum. While the client still parses text from the legacy system correctly, the new color system is only available through the new one.

Considering the above facts, a sensible suggestion at this point, would be to provide full-fledged API support to the new chat system in every game mechanic that utilizes it (Chat, Scoreboard, Books, to name a few).

Plugin Api

Description
Plugin API will give the ability to developers who want to extend the gameability on their servers.

Should

  • Identify the .jar on the plugins folder
  • Identify the @plugin annotation on the class inheriting ElytraPlugin
  • Load the plugin via a startup order (bootstrap, load, enable, disable)

Bidirectional UUID mapping for cracked accounts

Contextualization

Following issue #45, it is now more important than ever to raise awareness to future users of the API to save player-related data using unique ids, instead of player names.

Names are not only variable since premium accounts can change them, they're also no longer unique as well, since players with the same name (but different account type) can join the server simultaneously.

Problem

Linking data to the unique id is the safest option, and it can be easily queried by converting the unique id to the corresponding name.

For original accounts, this is easily done by consulting Mojang's API.

For pirated accounts, however, that feat is impossible. Unique ids for pirated accounts are generated from the hashed MD5 string OfflinePlayer:<name>, and so, are unidirectional functions, easily allowing the calculation of a unique id based on a name, but making the opposite impossible.

Suggestion

A new unique id mapping is suggested, allowing for bidirectional calculation. Below are two suggested implementations, each one having its advantages and disadvantages.

Implementation 1

Unique ids are composed of 128 bits, with 6 of them being reserved (4 for the version and 2 for the variant), resulting in 122 usable bits of data. By padding the user's name with null characters to the left, we can encode each of the 16 letters using the same amount of bits, or 7 (7.625 rounded down) per letter in this case. With 7 bits per letter, it is possible to represent every possible character in the ASCII table, accounting as well for every valid character ([0-9A-Za-z_]).

  • Advantage: Flexibility in case new valid characters are added in the future.
  • Disadvantage: No flexibility in case the maximum length of names is increased.

Implementation 2

There's a total of 63 possible options for each letter in a valid name (52 letters (uppercase and lowercase), 10 number and _), 64 if we consider null characters used for padding names shorter than 16 characters. By using this fact, each possible letter can be mapped to its index, and unique ids can be calculated incrementally.

  • Advantages: Flexibility in case the maximum length for names is increased in the future.
  • Disadvantages: No flexibility in case new valid characters are added in the future.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.