├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── build
└── pom.xml
├── bukkit
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── net
│ │ └── labymod
│ │ └── serverapi
│ │ └── bukkit
│ │ ├── BukkitLabyModConfig.java
│ │ ├── LabyModPlugin.java
│ │ ├── event
│ │ ├── LabyModPlayerJoinEvent.java
│ │ ├── MessageReceiveEvent.java
│ │ ├── MessageSendEvent.java
│ │ └── PermissionsSendEvent.java
│ │ ├── listener
│ │ └── PlayerJoinListener.java
│ │ └── utils
│ │ └── PacketUtils.java
│ └── resources
│ └── plugin.yml
├── bungeecord
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── net
│ │ └── labymod
│ │ └── serverapi
│ │ └── bungee
│ │ ├── BungeecordLabyModConfig.java
│ │ ├── LabyModPlugin.java
│ │ ├── event
│ │ ├── LabyModPlayerJoinEvent.java
│ │ ├── MessageReceiveEvent.java
│ │ ├── MessageSendEvent.java
│ │ └── PermissionsSendEvent.java
│ │ └── listener
│ │ ├── PlayerJoinListener.java
│ │ └── PluginMessageListener.java
│ └── resources
│ └── bungee.yml
├── common
├── pom.xml
└── src
│ └── main
│ └── java
│ └── net
│ └── labymod
│ └── serverapi
│ ├── Addon.java
│ ├── LabyModAPI.java
│ ├── LabyModConfig.java
│ └── Permission.java
└── pom.xml
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | | Q | A
2 | | ---------------- | -----
3 | | Bug report? | yes/no
4 | | Feature request? | yes/no
5 | | BC Break report? | yes/no
6 | | RFC? | yes/no
7 |
8 |
13 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | | Q | A
2 | | ------------- | ---
3 | | Bug fix? | yes/no
4 | | New feature? | yes/no
5 | | BC breaks? | no
6 | | Deprecations? | yes/no
7 | | Fixed tickets | #...
8 |
9 |
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .idea/
3 | target/
4 | dependency-reduced-pom.xml
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Server-API
2 |
3 | ## Bug Reports & Feature Requests
4 |
5 | * [Open an issue](https://github.com/labymod/labymod-server-api/issues) here on GitHub.
6 | If you can, **please provide a fix and create a pull request (PR) instead**; this will automatically create an issue for you.
7 | * Please be patient as not all items will be tested immediately - remember, LabyMod is developed by normal people like you. They have to work or go to school and LabyMod is only a product of their leisure time
8 | * Occasionally we'll close issues if they appear stale or are too vague - please don't take this personally!
9 | Please feel free to re-open issues we've closed if there's something we've missed and they still need to be addressed.
10 |
11 | ## Contributing Pull Requests
12 | PR's are even better than issues.
13 | We gladly accept community pull requests.
14 | There are a few necessary steps before we can accept a pull request:
15 |
16 | * [Open an issue](https://github.com/labymod/labymod-server-api/issues) describing the problem that you are looking to solve in
17 | your PR (if one is not already open), and your approach to solving it (no necessary for bug fixes - only feature contributions).
18 | * [Sign the CLA](https://cla-assistant.io/labymod/labymod-server-api) - see also below.
19 | * [Send a pull request](https://help.github.com/articles/using-pull-requests/) from your fork’s branch to our `master` branch.
20 |
21 | ## Contributor License Agreement
22 | The following terms are used throughout this agreement:
23 |
24 | * **You** - the person or legal entity including its affiliates asked to accept this agreement. An affiliate is any
25 | entity that controls or is controlled by the legal entity, or is under common control with it.
26 |
27 | * **Project** - is an umbrella term that refers to any and all LabyMod open source projects.
28 |
29 | * **Contribution** - any type of work that is submitted to a Project, including any modifications or additions to
30 | existing work.
31 |
32 | * **Submitted** - conveyed to a Project via a pull request, commit, issue, or any form of electronic, written, or
33 | verbal communication with LabyMod, contributors or maintainers.
34 |
35 | #### 1. Grant of Copyright License.
36 | Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers, contributors, users and
37 | to LabyMod a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce,
38 | prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your contributions and such
39 | derivative works. Except for this license, You reserve all rights, title, and interest in your contributions.
40 |
41 | #### 2. Grant of Patent License.
42 | Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers, contributors, users and
43 | to LabyMod a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section)
44 | patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer your contributions, where
45 | such license applies only to those patent claims licensable by you that are necessarily infringed by your contribution
46 | or by combination of your contribution with the project to which this contribution was submitted.
47 |
48 | If any entity institutes patent litigation - including cross-claim or counterclaim in a lawsuit - against You alleging
49 | that your contribution or any project it was submitted to constitutes or is responsible for direct or contributory
50 | patent infringement, then any patent licenses granted to that entity under this agreement shall terminate as of the
51 | date such litigation is filed.
52 |
53 | #### 3. Source of Contribution.
54 | Your contribution is either your original creation, based upon previous work that, to the best of your knowledge, is
55 | covered under an appropriate open source license and you have the right under that license to submit that work with
56 | modifications, whether created in whole or in part by you, or you have clearly identified the source of the contribution
57 | and any license or other restriction (like related patents, trademarks, and license agreements) of which you are
58 | personally aware.
59 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 LabyMedia GmbH
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LabyMod Server API
2 | [](https://scrutinizer-ci.com/g/LabyMod/labymod-server-api/?branch=master)
3 | [](https://labymod.net/dc/dev)
4 | [](https://cla-assistant.io/LabyMod/labymod-server-api)
5 |
6 | Our new Server API allows you to communicate between the LabyMod client and the server by using simple JSON messages. It also allows you to enable or disable LabyMod features.
7 | If you want to find out how our API works, visit https://docs.labymod.net/pages/server/introduction/
8 |
--------------------------------------------------------------------------------
/build/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | serverapi
7 | net.labymod
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | net.labymod.serverapi
13 | build
14 |
15 |
16 |
17 |
18 | org.apache.maven.plugins
19 | maven-shade-plugin
20 | 2.4.3
21 |
22 |
23 | package
24 |
25 | shade
26 |
27 |
28 |
29 |
30 |
31 |
32 | net.labymod.serverapi:common
33 | net.labymod.serverapi:bukkit
34 | net.labymod.serverapi:bungeecord
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | net.labymod.serverapi
46 | bukkit
47 | 1.0-SNAPSHOT
48 |
49 |
50 |
51 |
52 | net.labymod.serverapi
53 | bungeecord
54 | 1.0-SNAPSHOT
55 |
56 |
57 |
58 |
59 | net.labymod.serverapi
60 | common
61 | 1.0-SNAPSHOT
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/bukkit/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | serverapi
9 | net.labymod
10 | 1.0-SNAPSHOT
11 |
12 |
13 | net.labymod.serverapi
14 | bukkit
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 | org.spigotmc
21 | spigot-api
22 | 1.8.8-R0.1-SNAPSHOT
23 | provided
24 |
25 |
26 |
27 |
28 | org.bukkit
29 | bukkit
30 | 1.8.8-R0.1-SNAPSHOT
31 | provided
32 |
33 |
34 |
35 |
36 | net.labymod.serverapi
37 | common
38 | 1.0-SNAPSHOT
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/BukkitLabyModConfig.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit;
2 |
3 | import net.labymod.serverapi.LabyModConfig;
4 | import org.bukkit.configuration.file.FileConfiguration;
5 | import org.bukkit.configuration.file.YamlConfiguration;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 |
10 | /**
11 | * Class created by qlow | Jan
12 | */
13 | public class BukkitLabyModConfig extends LabyModConfig {
14 |
15 | private FileConfiguration fileConfiguration;
16 |
17 | public BukkitLabyModConfig( File file ) {
18 | super( file );
19 |
20 | // Creating the file if it doesn't exist
21 | if ( !file.exists() )
22 | try {
23 | file.createNewFile();
24 | } catch ( IOException e ) {
25 | e.printStackTrace();
26 | }
27 |
28 | // Loading the config
29 | this.fileConfiguration = YamlConfiguration.loadConfiguration( file );
30 |
31 | // Initializing the config
32 | init( file );
33 | }
34 |
35 | @Override
36 | public void init( File file ) {
37 | // Applying options to the config
38 | fileConfiguration.options().copyDefaults( true );
39 |
40 | // Adding the defaults
41 | addDefaults();
42 |
43 | // Saving the config after adding the defaults
44 | saveConfig();
45 |
46 | // Loading the values
47 | loadValues();
48 | }
49 |
50 | @Override
51 | public Object getValue( String key ) {
52 | return fileConfiguration.get( key );
53 | }
54 |
55 | @Override
56 | public void addDefault( String key, Object value ) {
57 | fileConfiguration.addDefault( key, value );
58 | }
59 |
60 | @Override
61 | public void saveConfig() {
62 | try {
63 | fileConfiguration.save( file );
64 | } catch ( IOException e ) {
65 | e.printStackTrace();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/LabyModPlugin.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import com.google.gson.JsonParseException;
6 | import com.google.gson.JsonParser;
7 | import io.netty.buffer.ByteBuf;
8 | import io.netty.buffer.Unpooled;
9 | import lombok.Getter;
10 | import net.labymod.serverapi.Addon;
11 | import net.labymod.serverapi.LabyModAPI;
12 | import net.labymod.serverapi.LabyModConfig;
13 | import net.labymod.serverapi.Permission;
14 | import net.labymod.serverapi.bukkit.event.LabyModPlayerJoinEvent;
15 | import net.labymod.serverapi.bukkit.event.MessageReceiveEvent;
16 | import net.labymod.serverapi.bukkit.event.MessageSendEvent;
17 | import net.labymod.serverapi.bukkit.event.PermissionsSendEvent;
18 | import net.labymod.serverapi.bukkit.listener.PlayerJoinListener;
19 | import net.labymod.serverapi.bukkit.utils.PacketUtils;
20 | import org.bukkit.Bukkit;
21 | import org.bukkit.entity.Player;
22 | import org.bukkit.plugin.java.JavaPlugin;
23 | import org.bukkit.plugin.messaging.PluginMessageListener;
24 |
25 | import java.io.File;
26 | import java.util.ArrayList;
27 | import java.util.HashMap;
28 | import java.util.Map;
29 |
30 | /**
31 | * Class created by qlow | Jan
32 | */
33 | public class LabyModPlugin extends JavaPlugin {
34 |
35 | @Getter
36 | private static LabyModPlugin instance;
37 |
38 | private static final JsonParser JSON_PARSER = new JsonParser();
39 |
40 | @Getter
41 | private LabyModConfig labyModConfig;
42 |
43 | @Getter
44 | private LabyModAPI api = new LabyModAPI();
45 |
46 | @Getter
47 | private PacketUtils packetUtils;
48 |
49 | @Override
50 | public void onEnable() {
51 | instance = this;
52 |
53 | // Initializing packet utils
54 | this.packetUtils = new PacketUtils();
55 |
56 | // Creating the data folder
57 | if ( !getDataFolder().exists() )
58 | getDataFolder().mkdir();
59 |
60 | // Initializing the config
61 | this.labyModConfig = new BukkitLabyModConfig( new File( getDataFolder(), "config.yml" ) );
62 |
63 | // Registering the listeners
64 | Bukkit.getPluginManager().registerEvents( new PlayerJoinListener(), this );
65 |
66 | // The LABYMOD plugin channel is higly deprecated and shouldn't be used - we just listen to it to retrieve old labymod clients.
67 | // Registering the incoming plugin messages listeners
68 | getServer().getMessenger().registerIncomingPluginChannel( this, "LABYMOD", new PluginMessageListener() {
69 | @Override
70 | public void onPluginMessageReceived( String channel, final Player player, byte[] bytes ) {
71 | // Converting the byte array into a byte buffer
72 | ByteBuf buf = Unpooled.wrappedBuffer( bytes );
73 |
74 | try {
75 | // Reading the version from the buffer
76 | final String version = api.readString( buf, Short.MAX_VALUE );
77 |
78 | // Calling the event synchronously
79 | Bukkit.getScheduler().runTask( LabyModPlugin.this, new Runnable() {
80 | @Override
81 | public void run() {
82 | // Checking whether the player is still online
83 | if ( !player.isOnline() )
84 | return;
85 |
86 | // Calling the LabyModPlayerJoinEvent
87 | Bukkit.getPluginManager().callEvent( new LabyModPlayerJoinEvent( player, version, false, 0, new ArrayList() ) );
88 | }
89 | } );
90 | } catch ( RuntimeException ex ) {
91 | }
92 | }
93 | } );
94 |
95 | getServer().getMessenger().registerIncomingPluginChannel( this, "LMC", new PluginMessageListener() {
96 | @Override
97 | public void onPluginMessageReceived( String channel, final Player player, byte[] bytes ) {
98 | // Converting the byte array into a byte buffer
99 | ByteBuf buf = Unpooled.wrappedBuffer( bytes );
100 |
101 | try {
102 | // Reading the message key
103 | final String messageKey = api.readString( buf, Short.MAX_VALUE );
104 | final String messageContents = api.readString( buf, Short.MAX_VALUE );
105 | final JsonElement jsonMessage = JSON_PARSER.parse( messageContents );
106 |
107 | // Calling the event synchronously
108 | Bukkit.getScheduler().runTask( LabyModPlugin.this, new Runnable() {
109 | @Override
110 | public void run() {
111 | // Checking whether the player is still online
112 | if ( !player.isOnline() )
113 | return;
114 |
115 | // Listening to the INFO (join) message
116 | if ( messageKey.equals( "INFO" ) && jsonMessage.isJsonObject() ) {
117 | JsonObject jsonObject = jsonMessage.getAsJsonObject();
118 | String version = jsonObject.has( "version" )
119 | && jsonObject.get( "version" ).isJsonPrimitive()
120 | && jsonObject.get( "version" ).getAsJsonPrimitive().isString() ? jsonObject.get( "version" ).getAsString() : "Unknown";
121 |
122 | boolean chunkCachingEnabled = false;
123 | int chunkCachingVersion = 0;
124 |
125 | if ( jsonObject.has( "ccp" ) && jsonObject.get( "ccp" ).isJsonObject() ) {
126 | JsonObject chunkCachingObject = jsonObject.get( "ccp" ).getAsJsonObject();
127 |
128 | if ( chunkCachingObject.has( "enabled" ) )
129 | chunkCachingEnabled = chunkCachingObject.get( "enabled" ).getAsBoolean();
130 |
131 | if ( chunkCachingObject.has( "version" ) )
132 | chunkCachingVersion = chunkCachingObject.get( "version" ).getAsInt();
133 | }
134 |
135 | Bukkit.getPluginManager().callEvent( new LabyModPlayerJoinEvent( player, version,
136 | chunkCachingEnabled, chunkCachingVersion, Addon.getAddons( jsonObject ) ) );
137 | return;
138 | }
139 |
140 | // Calling the MessageReceiveEvent
141 | Bukkit.getPluginManager().callEvent( new MessageReceiveEvent( player, messageKey, jsonMessage ) );
142 | }
143 | } );
144 | } catch ( RuntimeException ignored ) {
145 | }
146 | }
147 | } );
148 | }
149 |
150 | @Override
151 | public void onDisable() {
152 | // Unregistering the plugin-message listeners
153 | getServer().getMessenger().unregisterIncomingPluginChannel( this, "LABYMOD" );
154 | getServer().getMessenger().unregisterIncomingPluginChannel( this, "LMC" );
155 | }
156 |
157 | /**
158 | * Sends the modified permissions to the given player
159 | *
160 | * @param player the player the permissions should be sent to
161 | */
162 | public void sendPermissions( Player player ) {
163 | Map modifiedPermissions = new HashMap<>( labyModConfig.getPermissions() );
164 |
165 | // Calling the Bukkit event
166 | PermissionsSendEvent sendEvent = new PermissionsSendEvent( player, modifiedPermissions, false );
167 | Bukkit.getPluginManager().callEvent( sendEvent );
168 |
169 | // Sending the packet
170 | if ( !sendEvent.isCancelled() && sendEvent.getPermissions().size() > 0 )
171 | packetUtils.sendPacket( player, packetUtils.getPluginMessagePacket( "LMC", api.getBytesToSend( modifiedPermissions ) ) );
172 | }
173 |
174 | /**
175 | * Sends a JSON server-message to the player
176 | *
177 | * @param player the player the message should be sent to
178 | * @param messageKey the message's key
179 | * @param messageContents the message's contents
180 | */
181 | public void sendServerMessage( Player player, String messageKey, JsonElement messageContents ) {
182 | messageContents = cloneJson( messageContents );
183 |
184 | // Calling the Bukkit event
185 | MessageSendEvent sendEvent = new MessageSendEvent( player, messageKey, messageContents, false );
186 | Bukkit.getPluginManager().callEvent( sendEvent );
187 |
188 | // Sending the packet
189 | if ( !sendEvent.isCancelled() )
190 | packetUtils.sendPacket( player, packetUtils.getPluginMessagePacket( "LMC", api.getBytesToSend( messageKey, messageContents.toString() ) ) );
191 | }
192 |
193 | /**
194 | * Clones a JsonElement
195 | *
196 | * @param cloneElement the element that should be cloned
197 | * @return the cloned element
198 | */
199 | public JsonElement cloneJson( JsonElement cloneElement ) {
200 | try {
201 | return JSON_PARSER.parse( cloneElement.toString() );
202 | } catch ( JsonParseException ex ) {
203 | ex.printStackTrace();
204 | return null;
205 | }
206 | }
207 |
208 | }
209 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/event/LabyModPlayerJoinEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import net.labymod.serverapi.Addon;
6 | import org.bukkit.entity.Player;
7 | import org.bukkit.event.Event;
8 | import org.bukkit.event.HandlerList;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Class created by qlow | Jan
14 | */
15 | @AllArgsConstructor
16 | @Getter
17 | public class LabyModPlayerJoinEvent extends Event {
18 |
19 | @Getter
20 | private final static HandlerList handlerList = new HandlerList();
21 |
22 | private Player player;
23 | private String modVersion;
24 | private boolean chunkCachingEnabled;
25 | private int chunkCachingVersion;
26 | private List addons;
27 |
28 | @Override
29 | public HandlerList getHandlers() {
30 | return handlerList;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/event/MessageReceiveEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.event;
2 |
3 | import com.google.gson.JsonElement;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import org.bukkit.entity.Player;
7 | import org.bukkit.event.Event;
8 | import org.bukkit.event.HandlerList;
9 |
10 | /**
11 | * Class created by qlow | Jan
12 | */
13 | @AllArgsConstructor
14 | @Getter
15 | public class MessageReceiveEvent extends Event {
16 |
17 | @Getter
18 | private final static HandlerList handlerList = new HandlerList();
19 |
20 | private Player player;
21 | private String messageKey;
22 | private JsonElement jsonElement;
23 |
24 | @Override
25 | public HandlerList getHandlers() {
26 | return handlerList;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/event/MessageSendEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.event;
2 |
3 | import com.google.gson.JsonElement;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.Setter;
7 | import org.bukkit.entity.Player;
8 | import org.bukkit.event.Cancellable;
9 | import org.bukkit.event.Event;
10 | import org.bukkit.event.HandlerList;
11 |
12 | /**
13 | * Class created by qlow | Jan
14 | */
15 | @AllArgsConstructor
16 | @Getter
17 | public class MessageSendEvent extends Event implements Cancellable {
18 |
19 | @Getter
20 | private final static HandlerList handlerList = new HandlerList();
21 |
22 | private Player player;
23 | private String messageKey;
24 | private JsonElement jsonElement;
25 | @Setter
26 | private boolean cancelled;
27 |
28 | @Override
29 | public HandlerList getHandlers() {
30 | return handlerList;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/event/PermissionsSendEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import net.labymod.serverapi.Permission;
7 | import org.bukkit.entity.Player;
8 | import org.bukkit.event.Cancellable;
9 | import org.bukkit.event.Event;
10 | import org.bukkit.event.HandlerList;
11 |
12 | import java.util.EnumMap;
13 | import java.util.Map;
14 |
15 | /**
16 | * Class created by qlow | Jan
17 | */
18 | @AllArgsConstructor
19 | @Getter
20 | public class PermissionsSendEvent extends Event implements Cancellable {
21 |
22 | @Getter
23 | private final static HandlerList handlerList = new HandlerList();
24 |
25 | private Player player;
26 | private Map permissions = new EnumMap<>( Permission.class );
27 | @Setter
28 | private boolean cancelled;
29 |
30 | @Override
31 | public HandlerList getHandlers() {
32 | return handlerList;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/listener/PlayerJoinListener.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.listener;
2 |
3 | import net.labymod.serverapi.bukkit.LabyModPlugin;
4 | import org.bukkit.entity.Player;
5 | import org.bukkit.event.EventHandler;
6 | import org.bukkit.event.Listener;
7 | import org.bukkit.event.player.PlayerJoinEvent;
8 |
9 | /**
10 | * Class created by qlow | Jan
11 | */
12 | public class PlayerJoinListener implements Listener {
13 |
14 | @EventHandler
15 | public void onJoin( PlayerJoinEvent event ) {
16 | Player player = event.getPlayer();
17 |
18 | // Sending the permissions
19 | LabyModPlugin.getInstance().sendPermissions( player );
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/labymod/serverapi/bukkit/utils/PacketUtils.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bukkit.utils;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.Unpooled;
5 | import lombok.Getter;
6 | import net.labymod.serverapi.bukkit.LabyModPlugin;
7 | import org.bukkit.Bukkit;
8 | import org.bukkit.entity.Player;
9 |
10 | import java.lang.reflect.Constructor;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.InvocationTargetException;
13 | import java.lang.reflect.Method;
14 |
15 | /**
16 | * Class created by qlow | Jan
17 | */
18 | public class PacketUtils {
19 |
20 | private String version;
21 |
22 | private Class> packetClass;
23 |
24 | private Class> packetPlayOutCustomPayloadClass;
25 | private Constructor> customPayloadConstructor;
26 | private boolean customPayloadHasBytes;
27 |
28 | private Class> packetDataSerializerClass;
29 | private Constructor> packetDataSerializerConstructor;
30 |
31 | private Method getHandleMethod;
32 | private Field playerConnectionField;
33 | @Getter
34 | private Field networkManagerField;
35 |
36 | public PacketUtils() {
37 | this.version = Bukkit.getServer().getClass().getPackage().getName().replace( ".", "," ).split( "," )[3];
38 |
39 | try {
40 | this.packetClass = getNmsClass( "Packet" );
41 | this.packetPlayOutCustomPayloadClass = getNmsClass( "PacketPlayOutCustomPayload" );
42 | this.networkManagerField = getNmsClass( "PlayerConnection" ).getDeclaredField( "networkManager" );
43 | } catch ( ClassNotFoundException | NoSuchFieldException e ) {
44 | e.printStackTrace();
45 | }
46 |
47 | if ( this.packetPlayOutCustomPayloadClass != null ) {
48 | for ( Constructor> constructors : packetPlayOutCustomPayloadClass.getDeclaredConstructors() ) {
49 | if ( constructors.getParameterTypes().length == 2 && constructors.getParameterTypes()[1] == byte[].class ) {
50 | customPayloadHasBytes = true;
51 | customPayloadConstructor = constructors;
52 | } else if ( constructors.getParameterTypes().length == 2 && constructors.getParameterTypes()[1].getSimpleName().equals( "PacketDataSerializer" ) ) {
53 | customPayloadConstructor = constructors;
54 | }
55 | }
56 |
57 | if ( !customPayloadHasBytes ) {
58 | try {
59 | packetDataSerializerClass = getNmsClass( "PacketDataSerializer" );
60 | packetDataSerializerConstructor = packetDataSerializerClass.getDeclaredConstructor( ByteBuf.class );
61 | } catch ( Exception ex ) {
62 | ex.printStackTrace();
63 | LabyModPlugin.getInstance().getLogger().severe( "Couldn't find a valid constructor for PacketPlayOutCustomPayload. Disabling the plugin." );
64 | Bukkit.getPluginManager().disablePlugin( LabyModPlugin.getInstance() );
65 | }
66 | }
67 | }
68 | }
69 |
70 | /**
71 | * Gets the player's nms-handle
72 | *
73 | * @param player the bukkit-player
74 | * @return the nms-handle
75 | */
76 | public Object getPlayerHandle( Player player ) {
77 | try {
78 | if ( getHandleMethod == null )
79 | getHandleMethod = player.getClass().getMethod( "getHandle" );
80 |
81 | // Getting the player's nms-handle
82 | return getHandleMethod.invoke( player );
83 | } catch ( Exception ex ) {
84 | ex.printStackTrace();
85 | }
86 |
87 | return null;
88 | }
89 |
90 | /**
91 | * Gets the player's connection
92 | *
93 | * @param nmsPlayer the player's nms-handle
94 | * @return the player-connection
95 | */
96 | public Object getPlayerConnection( Object nmsPlayer ) {
97 | try {
98 | if ( playerConnectionField == null )
99 | playerConnectionField = nmsPlayer.getClass().getField( "playerConnection" );
100 |
101 | // Getting the player's connection
102 | return playerConnectionField.get( nmsPlayer );
103 | } catch ( IllegalAccessException | NoSuchFieldException e ) {
104 | e.printStackTrace();
105 | }
106 |
107 | return null;
108 | }
109 |
110 | /**
111 | * Sends a packet to the given player
112 | *
113 | * @param player the player the packet should be sent to
114 | * @param packet the packet that should be sent to the player
115 | */
116 | public void sendPacket( Player player, Object packet ) {
117 | try {
118 | // Getting the player's nms-handle
119 | Object nmsPlayer = getPlayerHandle( player );
120 |
121 | // Getting the player's connection
122 | Object playerConnection = getPlayerConnection( nmsPlayer );
123 |
124 | // Sending the packet
125 | playerConnection.getClass().getMethod( "sendPacket", packetClass ).invoke( playerConnection, packet );
126 | } catch ( Exception ex ) {
127 | ex.printStackTrace();
128 | }
129 | }
130 |
131 | /**
132 | * Gets a constructed plugin message packet
133 | *
134 | * @param channel the channel-name
135 | * @param bytes the bytes that should be sent with the packet
136 | * @return a plugin-message packet
137 | */
138 | public Object getPluginMessagePacket( String channel, byte[] bytes ) {
139 | try {
140 | return customPayloadConstructor.newInstance( channel, customPayloadHasBytes ? bytes : packetDataSerializerConstructor.newInstance( Unpooled.wrappedBuffer( bytes ) ) );
141 | } catch ( NullPointerException | InstantiationException | IllegalAccessException | InvocationTargetException e ) {
142 | LabyModPlugin.getInstance().getLogger().severe( "Couldn't construct a custom-payload packet (Channel: " + channel + "):" );
143 | e.printStackTrace();
144 | }
145 |
146 | return null;
147 | }
148 |
149 | /**
150 | * Gets a nms-class
151 | *
152 | * @param nmsClassName the nms-class name
153 | * @return the multi-version compatible name of the class including the package
154 | * @throws ClassNotFoundException if the class wasn't found
155 | */
156 | public Class> getNmsClass( String nmsClassName ) throws ClassNotFoundException {
157 | return Class.forName( "net.minecraft.server." + version + "." + nmsClassName );
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/bukkit/src/main/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: LabyModAPI
2 | author: LabyMedia
3 | version: 1.1
4 | main: net.labymod.serverapi.bukkit.LabyModPlugin
--------------------------------------------------------------------------------
/bungeecord/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | serverapi
7 | net.labymod
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | net.labymod.serverapi
13 | bungeecord
14 |
15 |
16 |
17 | bungeecord-repo
18 | https://oss.sonatype.org/content/repositories/snapshots
19 |
20 |
21 |
22 |
23 |
24 |
25 | net.md-5
26 | bungeecord-api
27 | 1.12-SNAPSHOT
28 | jar
29 | provided
30 |
31 |
32 |
33 |
34 | net.md-5
35 | bungeecord-api
36 | 1.12-SNAPSHOT
37 | javadoc
38 | provided
39 |
40 |
41 |
42 |
43 | net.labymod.serverapi
44 | common
45 | 1.0-SNAPSHOT
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/BungeecordLabyModConfig.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee;
2 |
3 | import net.labymod.serverapi.LabyModConfig;
4 | import net.md_5.bungee.config.Configuration;
5 | import net.md_5.bungee.config.ConfigurationProvider;
6 | import net.md_5.bungee.config.YamlConfiguration;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 |
11 | /**
12 | * Class created by qlow | Jan
13 | */
14 | public class BungeecordLabyModConfig extends LabyModConfig {
15 |
16 | private Configuration configuration;
17 |
18 | public BungeecordLabyModConfig( File file ) {
19 | super( file );
20 |
21 | // Creating the file if it doesn't exist
22 | if ( !file.exists() )
23 | try {
24 | file.createNewFile();
25 | } catch ( IOException e ) {
26 | e.printStackTrace();
27 | }
28 |
29 | // Initializing the config
30 | init( file );
31 | }
32 |
33 | @Override
34 | public void init( File file ) {
35 | // Loading the config
36 | try {
37 | this.configuration = ConfigurationProvider.getProvider( YamlConfiguration.class ).load( file );
38 | } catch ( IOException e ) {
39 | e.printStackTrace();
40 | }
41 |
42 | // Adding the defaults
43 | addDefaults();
44 |
45 | // Saving the config after adding the defaults
46 | saveConfig();
47 |
48 | // Loading the values
49 | loadValues();
50 | }
51 |
52 | @Override
53 | public Object getValue( String key ) {
54 | return configuration.get( key );
55 | }
56 |
57 | @Override
58 | public void addDefault( String key, Object value ) {
59 | if ( !configuration.contains( key ) )
60 | configuration.set( key, value );
61 | }
62 |
63 | @Override
64 | public void saveConfig() {
65 | try {
66 | ConfigurationProvider.getProvider( YamlConfiguration.class ).save( configuration, file );
67 | } catch ( IOException e ) {
68 | e.printStackTrace();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/LabyModPlugin.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonParseException;
5 | import com.google.gson.JsonParser;
6 | import lombok.Getter;
7 | import net.labymod.serverapi.LabyModAPI;
8 | import net.labymod.serverapi.LabyModConfig;
9 | import net.labymod.serverapi.Permission;
10 | import net.labymod.serverapi.bungee.event.MessageSendEvent;
11 | import net.labymod.serverapi.bungee.event.PermissionsSendEvent;
12 | import net.labymod.serverapi.bungee.listener.PlayerJoinListener;
13 | import net.labymod.serverapi.bungee.listener.PluginMessageListener;
14 | import net.md_5.bungee.api.connection.ProxiedPlayer;
15 | import net.md_5.bungee.api.plugin.Plugin;
16 | import net.md_5.bungee.protocol.packet.PluginMessage;
17 |
18 | import java.io.File;
19 | import java.util.HashMap;
20 | import java.util.Map;
21 |
22 | /**
23 | * Class created by qlow | Jan
24 | */
25 | public class LabyModPlugin extends Plugin {
26 |
27 | @Getter
28 | private static LabyModPlugin instance;
29 |
30 | private static final JsonParser JSON_PARSER = new JsonParser();
31 |
32 | @Getter
33 | private LabyModConfig labyModConfig;
34 |
35 | @Getter
36 | private LabyModAPI api = new LabyModAPI();
37 |
38 | @Override
39 | public void onEnable() {
40 | instance = this;
41 |
42 | // Creating the data folder
43 | if ( !getDataFolder().exists() )
44 | getDataFolder().mkdir();
45 |
46 | // Initializing the config
47 | this.labyModConfig = new BungeecordLabyModConfig( new File( getDataFolder(), "config.yml" ) );
48 |
49 | // Registering the listeners
50 | getProxy().getPluginManager().registerListener( this, new PlayerJoinListener() );
51 | getProxy().getPluginManager().registerListener( this, new PluginMessageListener() );
52 | }
53 |
54 | /**
55 | * Sends the modified permissions to the given player
56 | *
57 | * @param player the player the permissions should be sent to
58 | */
59 | public void sendPermissions( ProxiedPlayer player ) {
60 | Map modifiedPermissions = new HashMap<>( labyModConfig.getPermissions() );
61 |
62 | // Calling the Bukkit event
63 | PermissionsSendEvent sendEvent = new PermissionsSendEvent( player, modifiedPermissions, false );
64 | getProxy().getPluginManager().callEvent( sendEvent );
65 |
66 | // Sending the packet
67 | if ( !sendEvent.isCancelled() )
68 | player.unsafe().sendPacket( new PluginMessage( "LMC", api.getBytesToSend( modifiedPermissions ), false ) );
69 | }
70 |
71 | /**
72 | * Sends a JSON server-message to the player
73 | *
74 | * @param player the player the message should be sent to
75 | * @param messageKey the message's key
76 | * @param messageContents the message's contents
77 | */
78 | public void sendServerMessage( ProxiedPlayer player, String messageKey, JsonElement messageContents ) {
79 | messageContents = cloneJson( messageContents );
80 |
81 | // Calling the Bukkit event
82 | MessageSendEvent sendEvent = new MessageSendEvent( player, messageKey, messageContents, false );
83 | getProxy().getPluginManager().callEvent( sendEvent );
84 |
85 | // Sending the packet
86 | if ( !sendEvent.isCancelled() )
87 | player.unsafe().sendPacket( new PluginMessage( "LMC", api.getBytesToSend( messageKey, messageContents.toString() ), false ) );
88 | }
89 |
90 | /**
91 | * Clones a JsonElement
92 | *
93 | * @param cloneElement the element that should be cloned
94 | * @return the cloned element
95 | */
96 | public JsonElement cloneJson( JsonElement cloneElement ) {
97 | try {
98 | return JSON_PARSER.parse( cloneElement.toString() );
99 | } catch ( JsonParseException ex ) {
100 | ex.printStackTrace();
101 | return null;
102 | }
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/event/LabyModPlayerJoinEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import net.labymod.serverapi.Addon;
7 | import net.md_5.bungee.api.connection.ProxiedPlayer;
8 | import net.md_5.bungee.api.plugin.Event;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Class created by qlow | Jan
14 | */
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @Getter
18 | public class LabyModPlayerJoinEvent extends Event {
19 |
20 | private ProxiedPlayer player;
21 | private String modVersion;
22 | private boolean chunkCachingEnabled;
23 | private int chunkCachingVersion;
24 | private List addons;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/event/MessageReceiveEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.event;
2 |
3 | import com.google.gson.JsonElement;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import net.md_5.bungee.api.connection.ProxiedPlayer;
8 | import net.md_5.bungee.api.plugin.Event;
9 |
10 | /**
11 | * Class created by qlow | Jan
12 | */
13 | @AllArgsConstructor
14 | @NoArgsConstructor
15 | @Getter
16 | public class MessageReceiveEvent extends Event {
17 |
18 | private ProxiedPlayer player;
19 | private String messageKey;
20 | private JsonElement jsonElement;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/event/MessageSendEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.event;
2 |
3 | import com.google.gson.JsonElement;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Setter;
8 | import net.md_5.bungee.api.connection.ProxiedPlayer;
9 | import net.md_5.bungee.api.plugin.Event;
10 |
11 | /**
12 | * Class created by qlow | Jan
13 | */
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | @Getter
17 | public class MessageSendEvent extends Event {
18 |
19 | private ProxiedPlayer player;
20 | private String messageKey;
21 | private JsonElement jsonElement;
22 | @Setter
23 | private boolean cancelled;
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/event/PermissionsSendEvent.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.event;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import lombok.Setter;
7 | import net.labymod.serverapi.Permission;
8 | import net.md_5.bungee.api.connection.ProxiedPlayer;
9 | import net.md_5.bungee.api.plugin.Cancellable;
10 | import net.md_5.bungee.api.plugin.Event;
11 |
12 | import java.util.EnumMap;
13 | import java.util.Map;
14 |
15 | /**
16 | * Class created by qlow | Jan
17 | */
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | @Getter
21 | public class PermissionsSendEvent extends Event implements Cancellable {
22 |
23 | private ProxiedPlayer player;
24 | private Map permissions = new EnumMap<>( Permission.class );
25 | @Setter
26 | private boolean cancelled;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/listener/PlayerJoinListener.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.listener;
2 |
3 | import net.labymod.serverapi.bungee.LabyModPlugin;
4 | import net.md_5.bungee.api.event.PostLoginEvent;
5 | import net.md_5.bungee.api.plugin.Listener;
6 | import net.md_5.bungee.event.EventHandler;
7 |
8 | /**
9 | * Class created by qlow | Jan
10 | */
11 | public class PlayerJoinListener implements Listener {
12 |
13 | @EventHandler
14 | public void onJoin( PostLoginEvent event ) {
15 | // Sending the permissions
16 | LabyModPlugin.getInstance().sendPermissions( event.getPlayer() );
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/bungeecord/src/main/java/net/labymod/serverapi/bungee/listener/PluginMessageListener.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi.bungee.listener;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import com.google.gson.JsonParser;
6 | import io.netty.buffer.ByteBuf;
7 | import io.netty.buffer.Unpooled;
8 | import lombok.Getter;
9 | import net.labymod.serverapi.Addon;
10 | import net.labymod.serverapi.bungee.LabyModPlugin;
11 | import net.labymod.serverapi.bungee.event.LabyModPlayerJoinEvent;
12 | import net.labymod.serverapi.bungee.event.MessageReceiveEvent;
13 | import net.md_5.bungee.api.ProxyServer;
14 | import net.md_5.bungee.api.connection.ProxiedPlayer;
15 | import net.md_5.bungee.api.event.PluginMessageEvent;
16 | import net.md_5.bungee.api.plugin.Listener;
17 | import net.md_5.bungee.event.EventHandler;
18 |
19 | import java.util.ArrayList;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | /**
23 | * Class created by qlow | Jan
24 | */
25 | public class PluginMessageListener implements Listener {
26 |
27 | @Getter
28 | private final static JsonParser jsonParser = new JsonParser();
29 |
30 | @EventHandler
31 | public void onPluginMessage( PluginMessageEvent event ) {
32 | if ( !(event.getSender() instanceof ProxiedPlayer) )
33 | return;
34 |
35 | final ProxiedPlayer player = ( ProxiedPlayer ) event.getSender();
36 |
37 | // The LABYMOD plugin channel is higly deprecated and shouldn't be used - we just listen to it to retrieve old labymod clients.
38 | if ( event.getTag().equals( "LABYMOD" ) ) {
39 | // Converting the byte array into a byte buffer
40 | ByteBuf buf = Unpooled.wrappedBuffer( event.getData() );
41 |
42 | try {
43 | // Reading the version from the buffer
44 | final String version = LabyModPlugin.getInstance().getApi().readString( buf, Short.MAX_VALUE );
45 |
46 | // Calling the event synchronously
47 | ProxyServer.getInstance().getScheduler().schedule( LabyModPlugin.getInstance(), new Runnable() {
48 | @Override
49 | public void run() {
50 | // Calling the LabyModPlayerJoinEvent
51 | ProxyServer.getInstance().getPluginManager().callEvent( new LabyModPlayerJoinEvent( player, version, false, 0, new ArrayList() ) );
52 | }
53 | }, 0L, TimeUnit.SECONDS );
54 | } catch ( RuntimeException ex ) {
55 | ex.printStackTrace();
56 | }
57 | }
58 |
59 | if ( event.getTag().equals( "LMC" ) ) {
60 | // Converting the byte array into a byte buffer
61 | ByteBuf buf = Unpooled.wrappedBuffer( event.getData() );
62 |
63 | try {
64 | // Reading the message key
65 | final String messageKey = LabyModPlugin.getInstance().getApi().readString( buf, Short.MAX_VALUE );
66 | final String messageContents = LabyModPlugin.getInstance().getApi().readString( buf, Short.MAX_VALUE );
67 | final JsonElement jsonMessage = jsonParser.parse( messageContents );
68 |
69 | // Calling the event synchronously
70 | ProxyServer.getInstance().getScheduler().schedule( LabyModPlugin.getInstance(), new Runnable() {
71 | @Override
72 | public void run() {
73 | // Listening to the INFO (join) message
74 | if ( messageKey.equals( "INFO" ) && jsonMessage.isJsonObject() ) {
75 | JsonObject jsonObject = jsonMessage.getAsJsonObject();
76 | String version = jsonObject.has( "version" )
77 | && jsonObject.get( "version" ).isJsonPrimitive()
78 | && jsonObject.get( "version" ).getAsJsonPrimitive().isString() ? jsonObject.get( "version" ).getAsString() : "Unknown";
79 |
80 | boolean chunkCachingEnabled = false;
81 | int chunkCachingVersion = 0;
82 |
83 | if ( jsonObject.has( "ccp" ) && jsonObject.get( "ccp" ).isJsonObject() ) {
84 | JsonObject chunkCachingObject = jsonObject.get( "ccp" ).getAsJsonObject();
85 |
86 | if ( chunkCachingObject.has( "enabled" ) )
87 | chunkCachingEnabled = chunkCachingObject.get( "enabled" ).getAsBoolean();
88 |
89 | if ( chunkCachingObject.has( "version" ) )
90 | chunkCachingVersion = chunkCachingObject.get( "version" ).getAsInt();
91 | }
92 |
93 | ProxyServer.getInstance().getPluginManager().callEvent( new LabyModPlayerJoinEvent( player, version,
94 | chunkCachingEnabled, chunkCachingVersion, Addon.getAddons( jsonObject ) ) );
95 | return;
96 | }
97 |
98 | // Calling the LabyModPlayerJoinEvent
99 | ProxyServer.getInstance().getPluginManager().callEvent( new MessageReceiveEvent( player, messageKey, jsonMessage ) );
100 | }
101 | }, 0L, TimeUnit.SECONDS );
102 | } catch ( RuntimeException ex ) {
103 | ex.printStackTrace();
104 | }
105 | }
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/bungeecord/src/main/resources/bungee.yml:
--------------------------------------------------------------------------------
1 | name: LabyModAPI
2 | author: LabyMedia
3 | version: 1.1
4 | main: net.labymod.serverapi.bungee.LabyModPlugin
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | serverapi
9 | net.labymod
10 | 1.0-SNAPSHOT
11 |
12 |
13 | net.labymod.serverapi
14 | common
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 | io.netty
21 | netty-all
22 | 4.1.42.Final
23 |
24 |
25 |
26 |
27 | com.google.code.gson
28 | gson
29 | 2.2.4
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/common/src/main/java/net/labymod/serverapi/Addon.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Getter;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.UUID;
11 |
12 | /**
13 | * An Addon represents a player's addon
14 | * The addons are being sent when a user joins the server
15 | * You can retrieve them by using LabyModPlayerJoinEvent#getAddons()
16 | *
17 | * @author Jan
18 | */
19 | @AllArgsConstructor
20 | @Getter
21 | public class Addon {
22 |
23 | private UUID uuid;
24 | private String name;
25 |
26 | /**
27 | * Parses the addons from the INFO plugin message
28 | *
29 | * @param jsonObject the json object of the message
30 | * @return a list containing the message's addons
31 | */
32 | public static List getAddons( JsonObject jsonObject ) {
33 | if ( !jsonObject.has( "addons" ) || !jsonObject.get( "addons" ).isJsonArray() )
34 | return new ArrayList<>();
35 |
36 | List addons = new ArrayList<>();
37 |
38 | for ( JsonElement arrayElement : jsonObject.get( "addons" ).getAsJsonArray() ) {
39 | if ( !arrayElement.isJsonObject() )
40 | continue;
41 |
42 | JsonObject arrayObject = arrayElement.getAsJsonObject();
43 |
44 | if ( !arrayObject.has( "uuid" ) || !arrayObject.get( "uuid" ).isJsonPrimitive() || !arrayObject.get( "uuid" ).getAsJsonPrimitive().isString()
45 | || !arrayObject.has( "name" ) || !arrayObject.get( "name" ).isJsonPrimitive() || !arrayObject.get( "name" ).getAsJsonPrimitive().isString() )
46 | continue;
47 |
48 | UUID uuid = null;
49 |
50 | try {
51 | uuid = UUID.fromString( arrayObject.get( "uuid" ).getAsString() );
52 | } catch ( IllegalArgumentException ex ) {
53 | continue;
54 | }
55 |
56 | addons.add( new Addon( uuid, arrayObject.get( "name" ).getAsString() ) );
57 | }
58 |
59 | return addons;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/common/src/main/java/net/labymod/serverapi/LabyModAPI.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi;
2 |
3 | import com.google.gson.JsonObject;
4 | import io.netty.buffer.ByteBuf;
5 | import io.netty.buffer.Unpooled;
6 | import io.netty.handler.codec.DecoderException;
7 | import io.netty.handler.codec.EncoderException;
8 |
9 | import java.nio.charset.Charset;
10 | import java.util.Map;
11 |
12 | /**
13 | * Class created by qlow | Jan
14 | */
15 | public class LabyModAPI {
16 |
17 | /**
18 | * Gets the bytes we should send to a player to update the permissions
19 | *
20 | * @param permissions a map containing the permissions
21 | * @return the byte array that should be the payload
22 | */
23 | public byte[] getBytesToSend( Map permissions ) {
24 | // Creating a json object we will put the permissions in
25 | JsonObject object = new JsonObject();
26 |
27 | // Adding the permissions to the json object
28 | for ( Map.Entry permissionEntry : permissions.entrySet() ) {
29 | object.addProperty( permissionEntry.getKey().name(), permissionEntry.getValue() );
30 | }
31 |
32 | // Returning the byte array
33 | return getBytesToSend( "PERMISSIONS", object.toString() );
34 | }
35 |
36 | /**
37 | * Gets the bytes that are required to send the given message
38 | *
39 | * @param messageKey the message's key
40 | * @param messageContents the message's contents
41 | * @return the byte array that should be the payload
42 | */
43 | public byte[] getBytesToSend( String messageKey, String messageContents ) {
44 | // Getting an empty buffer
45 | ByteBuf byteBuf = Unpooled.buffer();
46 |
47 | // Writing the message-key to the buffer
48 | writeString( byteBuf, messageKey );
49 |
50 | // Writing the contents to the buffer
51 | writeString( byteBuf, messageContents );
52 |
53 | // Copying the buffer's bytes to the byte array
54 | byte[] bytes = new byte[byteBuf.readableBytes()];
55 | byteBuf.readBytes( bytes );
56 |
57 | // Returning the byte array
58 | return bytes;
59 | }
60 |
61 | /**
62 | * Writes a varint to the given byte buffer
63 | *
64 | * @param buf the byte buffer the int should be written to
65 | * @param input the int that should be written to the buffer
66 | */
67 | private void writeVarIntToBuffer( ByteBuf buf, int input ) {
68 | while ( (input & -128) != 0 ) {
69 | buf.writeByte( input & 127 | 128 );
70 | input >>>= 7;
71 | }
72 |
73 | buf.writeByte( input );
74 | }
75 |
76 | /**
77 | * Writes a string to the given byte buffer
78 | *
79 | * @param buf the byte buffer the string should be written to
80 | * @param string the string that should be written to the buffer
81 | */
82 | private void writeString( ByteBuf buf, String string ) {
83 | byte[] abyte = string.getBytes( Charset.forName( "UTF-8" ) );
84 |
85 | if ( abyte.length > Short.MAX_VALUE ) {
86 | throw new EncoderException( "String too big (was " + string.length() + " bytes encoded, max " + Short.MAX_VALUE + ")" );
87 | } else {
88 | writeVarIntToBuffer( buf, abyte.length );
89 | buf.writeBytes( abyte );
90 | }
91 | }
92 |
93 | /**
94 | * Reads a varint from the given byte buffer
95 | *
96 | * @param buf the byte buffer the varint should be read from
97 | * @return the int read
98 | */
99 | public int readVarIntFromBuffer( ByteBuf buf ) {
100 | int i = 0;
101 | int j = 0;
102 |
103 | byte b0;
104 | do {
105 | b0 = buf.readByte();
106 | i |= (b0 & 127) << j++ * 7;
107 | if ( j > 5 ) {
108 | throw new RuntimeException( "VarInt too big" );
109 | }
110 | } while ( (b0 & 128) == 128 );
111 |
112 | return i;
113 | }
114 |
115 | /**
116 | * Reads a string from the given byte buffer
117 | *
118 | * @param buf the byte buffer the string should be read from
119 | * @param maxLength the string's max-length
120 | * @return the string read
121 | */
122 | public String readString( ByteBuf buf, int maxLength ) {
123 | int i = this.readVarIntFromBuffer( buf );
124 |
125 | if ( i > maxLength * 4 ) {
126 | throw new DecoderException( "The received encoded string buffer length is longer than maximum allowed (" + i + " > " + maxLength * 4 + ")" );
127 | } else if ( i < 0 ) {
128 | throw new DecoderException( "The received encoded string buffer length is less than zero! Weird string!" );
129 | } else {
130 | byte[] bytes = new byte[i];
131 | buf.readBytes( bytes );
132 |
133 | String s = new String( bytes, Charset.forName( "UTF-8" ) );
134 | if ( s.length() > maxLength ) {
135 | throw new DecoderException( "The received string length is longer than maximum allowed (" + i + " > " + maxLength + ")" );
136 | } else {
137 | return s;
138 | }
139 | }
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/common/src/main/java/net/labymod/serverapi/LabyModConfig.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi;
2 |
3 | import lombok.Getter;
4 |
5 | import java.io.File;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | /**
10 | * Class created by qlow | Jan
11 | */
12 | public abstract class LabyModConfig {
13 |
14 | protected File file;
15 |
16 | @Getter
17 | private Map permissions = new HashMap<>();
18 |
19 | public LabyModConfig( File file ) {
20 | this.file = file;
21 | }
22 |
23 | /**
24 | * Called once to initialize the config
25 | *
26 | * @param file the config-file
27 | */
28 | public abstract void init( File file );
29 |
30 | /**
31 | * Gets a key's value
32 | *
33 | * @param key the key the value should be resolved from
34 | * @return the value according to this key or null
if there is no value according to this key
35 | */
36 | public abstract Object getValue( String key );
37 |
38 | /**
39 | * Adds a default to the config
40 | *
41 | * @param key the key
42 | * @param value the default value
43 | */
44 | public abstract void addDefault( String key, Object value );
45 |
46 | /**
47 | * Saves the config
48 | */
49 | public abstract void saveConfig();
50 |
51 | /**
52 | * Adds the config's defaults
53 | */
54 | public void addDefaults() {
55 | // Iterating through all permissions
56 | for ( Permission permission : Permission.values() ) {
57 | // Putting the default value in
58 | addDefault( "permissions." + permission.name(), permission.isDefaultEnabled() );
59 | }
60 | }
61 |
62 | /**
63 | * Loads the config values after adding the defaults
64 | */
65 | public void loadValues() {
66 | // Iterating through all permissions
67 | for ( Permission permission : Permission.values() ) {
68 | Object value = getValue( "permissions." + permission.name() );
69 |
70 | // Checking whether there is a value according to this permission
71 | if ( value != null && value instanceof Boolean ) {
72 | // Checking whether the permission value was modified
73 | permissions.put( permission, ( Boolean ) value );
74 | } else {
75 | permissions.put( permission, permission.isDefaultEnabled() );
76 | }
77 | }
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/common/src/main/java/net/labymod/serverapi/Permission.java:
--------------------------------------------------------------------------------
1 | package net.labymod.serverapi;
2 |
3 | /**
4 | * Class created by qlow | Jan
5 | */
6 | public enum Permission {
7 |
8 | // Permissions that are disabled by default
9 | IMPROVED_LAVA( "Improved Lava", false ),
10 | CROSSHAIR_SYNC( "Crosshair sync", false ),
11 | REFILL_FIX( "Refill fix", false ),
12 |
13 | // GUI permissions
14 | GUI_ALL( "LabyMod GUI", true ),
15 | GUI_POTION_EFFECTS( "Potion Effects", true ),
16 | GUI_ARMOR_HUD( "Armor HUD", true ),
17 | GUI_ITEM_HUD( "Item HUD", true ),
18 |
19 | // Permissions that are enabled by default
20 | BLOCKBUILD( "Blockbuild", true ),
21 | TAGS( "Tags", true ),
22 | CHAT( "Chat features", true ),
23 | ANIMATIONS( "Animations", true ),
24 | SATURATION_BAR( "Saturation bar", true );
25 |
26 | private String displayName;
27 | private boolean defaultEnabled;
28 |
29 | /**
30 | * @param displayName the permission's display-name
31 | * @param defaultEnabled whether or not this permission is enabled/activated by default
32 | */
33 | Permission( String displayName, boolean defaultEnabled ) {
34 | this.displayName = displayName;
35 | this.defaultEnabled = defaultEnabled;
36 | }
37 |
38 | public String getDisplayName() {
39 | return displayName;
40 | }
41 |
42 | public boolean isDefaultEnabled() {
43 | return defaultEnabled;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | net.labymod
8 | serverapi
9 | pom
10 | 1.0-SNAPSHOT
11 |
12 | common
13 | bukkit
14 | bungeecord
15 | build
16 |
17 |
18 |
19 |
20 | spigot-repo
21 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/
22 |
23 |
24 |
25 |
26 |
27 |
28 | org.projectlombok
29 | lombok
30 | 1.18.6
31 | provided
32 |
33 |
34 |
35 |
36 |
37 |
38 | org.apache.maven.plugins
39 | maven-compiler-plugin
40 | 3.6.1
41 |
42 | 1.7
43 | 1.7
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------