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<Permission, Boolean> 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<Permission, Boolean> 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
|
|
|
|