├── LICENSE ├── README.md ├── client-connect-api ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── client │ └── connect │ └── api │ ├── Connect.java │ ├── ConnectSettings.java │ ├── MessageEvent.java │ ├── MessageEventListener.java │ ├── RedirectEvent.java │ ├── RedirectEventListener.java │ ├── ServerAddEvent.java │ ├── ServerEventListener.java │ ├── event │ ├── Event.java │ ├── EventListener.java │ ├── MessageEvent.java │ ├── RedirectEvent.java │ ├── ServerAddEvent.java │ └── ServerRemoveEvent.java │ ├── request │ ├── Request.java │ ├── RequestException.java │ └── impl │ │ ├── AsProxyRequest.java │ │ ├── AsServerRequest.java │ │ ├── AuthenticateRequest.java │ │ ├── GetDetailsRequest.java │ │ ├── GetKeyRequest.java │ │ ├── GetPlayersRequest.java │ │ ├── GetWhoamiRequest.java │ │ ├── MessageRequest.java │ │ ├── NotifyPlayerRequest.java │ │ └── RedirectRequest.java │ ├── result │ ├── FutureResult.java │ ├── FutureResultListener.java │ ├── Result.java │ ├── StatusCode.java │ └── impl │ │ ├── AsProxyResult.java │ │ ├── AsServerResult.java │ │ ├── AuthenticateResult.java │ │ ├── GetDetailsResult.java │ │ ├── GetKeyResult.java │ │ ├── GetPlayersResult.java │ │ ├── GetWhoamiResult.java │ │ ├── MessageResult.java │ │ ├── NotifyPlayerResult.java │ │ └── RedirectResult.java │ └── util │ └── SecurityUtils.java ├── client-connect-lib ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── client │ └── connect │ └── lib │ ├── ConnectImpl.java │ ├── ConnectNetworkHandler.java │ ├── request │ ├── ConnectRequestEncoderRegistry.java │ ├── RequestEncoder.java │ ├── RequestEncoderRegistry.java │ └── impl │ │ ├── AsProxyRequestEncoder.java │ │ ├── AsServerRequestEncoder.java │ │ ├── AuthenticateRequestEncoder.java │ │ ├── GetDetailsRequestEncoder.java │ │ ├── GetKeyRequestEncoder.java │ │ ├── GetPlayersRequestEncoder.java │ │ ├── GetWhoamiRequestEncoder.java │ │ ├── MessageRequestEncoder.java │ │ ├── NotifyPlayerRequestEncoder.java │ │ └── RedirectRequestEncoder.java │ ├── result │ ├── ConnectResultDecoderRegistry.java │ ├── FutureResultImpl.java │ ├── ResultDecoder.java │ ├── ResultDecoderRegistry.java │ └── impl │ │ ├── AsProxyResultDecoder.java │ │ ├── AsServerResultDecoder.java │ │ ├── AuthenticateResultDecoder.java │ │ ├── GetDetailsResultDecoder.java │ │ ├── GetKeyResultDecoder.java │ │ ├── GetPlayersResultDecoder.java │ │ ├── GetWhoamiResultDecoder.java │ │ ├── MessageResultDecoder.java │ │ ├── NotifyPlayerResultDecoder.java │ │ └── RedirectResultDecoder.java │ └── util │ └── StringUtils.java ├── packet-common ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── packet │ └── common │ ├── Packet.java │ ├── PacketCodec.java │ ├── PacketCodecProvider.java │ ├── PacketCodecRegistry.java │ ├── PacketDecoder.java │ ├── PacketEncoder.java │ ├── VarIntFrameCodec.java │ └── util │ └── BufferUtils.java ├── packet-connect ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── packet │ └── connect │ ├── ConnectPacketCodecRegistry.java │ ├── ConnectPacketConstants.java │ └── impl │ ├── KeepalivePacket.java │ ├── KeepalivePacketCodec.java │ ├── MessagePacket.java │ ├── MessagePacketCodec.java │ ├── RedirectPacket.java │ ├── RedirectPacketCodec.java │ ├── RequestPacket.java │ ├── RequestPacketCodec.java │ ├── ResultPacket.java │ ├── ResultPacketCodec.java │ ├── ServerAddPacket.java │ ├── ServerPacket.java │ └── ServerPacketCodec.java ├── server-common ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── common │ ├── IAuthenticator.java │ ├── IPlayable.java │ ├── IPlayerCallback.java │ ├── IRedirectable.java │ ├── IServer.java │ ├── IServerSource.java │ ├── config │ ├── FileConfig.java │ ├── FileConfigGson.java │ └── IConfig.java │ ├── service │ ├── Service.java │ └── ServiceManager.java │ └── util │ ├── GsonUtils.java │ ├── SecurityUtils.java │ └── StringUtils.java ├── server-connect ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── connect │ ├── ConnectConfig.java │ ├── ConnectService.java │ ├── node │ ├── NodeHandler.java │ ├── NodeSession.java │ ├── NodeSessionKeepalive.java │ ├── NodeSessionMapper.java │ ├── NodeSessionRole.java │ └── ProxyCache.java │ └── query │ ├── NodeQueryLookupService.java │ ├── Query.java │ ├── QueryLookupService.java │ └── impl │ ├── AsProxyQuery.java │ ├── AsServerQuery.java │ ├── AuthenticateQuery.java │ ├── GetDetailsQuery.java │ ├── GetKeyQuery.java │ ├── GetPlayersQuery.java │ ├── GetWhoamiQuery.java │ ├── MessageQuery.java │ ├── NotifyPlayer.java │ └── RedirectQuery.java ├── server-proxy ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── proxy │ ├── ProxyConfig.java │ ├── ProxyService.java │ ├── net │ ├── AesCodec.java │ ├── LegacyPingDecoder.java │ ├── ProxyInboundHandler.java │ ├── ProxyOutboundHandler.java │ ├── ProxySession.java │ ├── ProxySessionMapper.java │ ├── ProxyState.java │ └── http │ │ ├── HttpGetClient.java │ │ ├── HttpGetClientListener.java │ │ └── impl │ │ ├── AsyncHttpGetClient.java │ │ ├── AsyncHttpGetClientHandler.java │ │ ├── DummyTrustManager.java │ │ └── SyncHttpGetClient.java │ ├── packet │ ├── GenericPacket.java │ ├── GenericPacketCodec.java │ ├── MinecraftPacketCodecRegistry.java │ ├── MinecraftPacketConstants.java │ ├── ProxyPacketCodecProvider.java │ ├── StatefulPacketCodecProviderPair.java │ ├── impl │ │ ├── HandshakePacket.java │ │ ├── HandshakePacketCodec.java │ │ ├── LoginDisconnectPacket.java │ │ ├── LoginDisconnectPacketCodec.java │ │ ├── LoginEncryptRequestPacket.java │ │ ├── LoginEncryptRequestPacketCodec.java │ │ ├── LoginEncryptResponsePacket.java │ │ ├── LoginEncryptResponsePacketCodec.java │ │ ├── LoginStartPacket.java │ │ ├── LoginStartPacketCodec.java │ │ ├── LoginSuccessPacket.java │ │ ├── LoginSuccessPacketCodec.java │ │ ├── PlayClientSettingsPacket.java │ │ ├── PlayClientSettingsPacketCodec.java │ │ ├── PlayDisconnectPacket.java │ │ ├── PlayDisconnectPacketCodec.java │ │ ├── PlayJoinGamePacket.java │ │ ├── PlayJoinGamePacketCodec.java │ │ ├── PlayPlayerListPacket.java │ │ ├── PlayPlayerListPacketCodec.java │ │ ├── PlayRespawnPacket.java │ │ ├── PlayRespawnPacketCodec.java │ │ ├── PlayScoreObjectivePacket.java │ │ ├── PlayScoreObjectivePacketCodec.java │ │ ├── PlayTeamPacket.java │ │ ├── PlayTeamPacketCodec.java │ │ ├── StatusPingPacket.java │ │ ├── StatusPingPacketCodec.java │ │ ├── StatusRequestPacket.java │ │ ├── StatusRequestPacketCodec.java │ │ ├── StatusResponsePacket.java │ │ └── StatusResponsePacketCodec.java │ └── state │ │ ├── HandshakeStateCodecProvider.java │ │ ├── LoginStateCodecProvider.java │ │ ├── PlayStateCodecProvider.java │ │ └── StatusStateCodecProvider.java │ └── util │ ├── CipherUtils.java │ └── MinecraftUtils.java ├── server-query ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── query │ ├── tcp │ ├── QueryTcpConfig.java │ ├── QueryTcpService.java │ └── net │ │ ├── GsonResponse.java │ │ └── QueryTcpHandler.java │ └── udp │ ├── QueryUdpConfig.java │ ├── QueryUdpService.java │ └── net │ ├── QueryUdpHandler.java │ └── QueryUdpIdentification.java ├── server-standalone-allinone ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── standalone │ └── allinone │ ├── AllInOne.java │ ├── AllInOneConfig.java │ └── Config.java ├── server-standalone-connect ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── standalone │ └── connect │ ├── Config.java │ ├── Connect.java │ ├── ConnectConfig.java │ └── ConnectPlayable.java ├── server-standalone-proxy ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── lilypad │ └── server │ └── standalone │ └── proxy │ ├── Config.java │ ├── ConnectPlayerCallback.java │ ├── ConnectServer.java │ ├── ConnectServerRedirect.java │ ├── ConnectServerSource.java │ ├── ConnectThread.java │ ├── Proxy.java │ └── ProxyConfig.java └── server-standalone-query ├── .gitignore ├── pom.xml └── src └── main └── java └── lilypad └── server └── standalone └── query ├── Config.java ├── Query.java ├── QueryCache.java ├── QueryCacheUpdater.java └── QueryConfig.java /README.md: -------------------------------------------------------------------------------- 1 | JLilyPad 2 | ============= 3 | 4 | An implementation of LilyPad in the popular programming language Java. 5 | 6 | More information can be found at http://www.lilypadmc.org :) 7 | -------------------------------------------------------------------------------- /client-connect-api/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | doc/* 34 | -------------------------------------------------------------------------------- /client-connect-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | lilypad.client.connect 5 | api 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | Client-Connect-API 10 | http://www.lilypadmc.org 11 | 12 | 13 | UTF-8 14 | Unknown 15 | 16 | 17 | 18 | ${project.name} 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | 2.5.1 24 | 25 | 1.6 26 | 1.6 27 | 28 | 29 | 30 | maven-assembly-plugin 31 | 2.2 32 | 33 | 34 | make-assembly 35 | package 36 | 37 | single 38 | 39 | 40 | 1.6 41 | 1.6 42 | false 43 | 44 | jar-with-dependencies 45 | 46 | 47 | false 48 | 49 | ${name} 50 | ${build.number} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/ConnectSettings.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | public interface ConnectSettings { 6 | 7 | /** 8 | * 9 | * @return the address of the remote network's server 10 | */ 11 | public InetSocketAddress getOutboundAddress(); 12 | 13 | /** 14 | * 15 | * @return the username to be authenticated with on the network 16 | */ 17 | public String getUsername(); 18 | 19 | /** 20 | * 21 | * @return the password to be authenticated with on the network 22 | */ 23 | public String getPassword(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/MessageEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | @Deprecated 4 | public class MessageEvent extends lilypad.client.connect.api.event.MessageEvent { 5 | 6 | /** 7 | * Create a legacy message event from a new message event. 8 | * 9 | * @param event 10 | */ 11 | public MessageEvent(lilypad.client.connect.api.event.MessageEvent event) { 12 | super(event.getSender(), event.getChannel(), event.getMessage()); 13 | } 14 | 15 | /** 16 | * 17 | * @param sender of the event 18 | * @param channel of the event 19 | * @param message of the event 20 | */ 21 | public MessageEvent(String sender, String channel, byte[] message) { 22 | super(sender, channel, message); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/MessageEventListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | @Deprecated 4 | public interface MessageEventListener { 5 | 6 | /** 7 | * Called when a message has been received by the session. 8 | * 9 | * @param connect session that the event belongs to 10 | * @param messageEvent 11 | */ 12 | public void onMessage(Connect connect, MessageEvent messageEvent); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/RedirectEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | @Deprecated 4 | public class RedirectEvent extends lilypad.client.connect.api.event.RedirectEvent { 5 | 6 | /** 7 | * Create a legacy redirect event from a new redirect event. 8 | * 9 | * @param event 10 | */ 11 | public RedirectEvent(lilypad.client.connect.api.event.RedirectEvent event) { 12 | super(event.getServer(), event.getPlayer()); 13 | } 14 | 15 | /** 16 | * 17 | * @param server the server to redirect to 18 | * @param player the player to be redirected 19 | */ 20 | public RedirectEvent(String server, String player) { 21 | super(server, player); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/RedirectEventListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | @Deprecated 4 | public interface RedirectEventListener { 5 | 6 | /** 7 | * Called when a player is to be redirected to a specified 8 | * server by the session when the session is the role of a proxy. 9 | * 10 | * @param connect session that the event belongs to 11 | * @param redirectEvent 12 | */ 13 | public void onRedirect(Connect connect, RedirectEvent redirectEvent); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/ServerAddEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | @Deprecated 6 | public class ServerAddEvent extends lilypad.client.connect.api.event.ServerAddEvent { 7 | 8 | /** 9 | * Create a legacy server add event from a new server add event. 10 | * 11 | * @param event 12 | */ 13 | public ServerAddEvent(lilypad.client.connect.api.event.ServerAddEvent event) { 14 | super(event.getServer(), event.getSecurityKey(), event.getAddress()); 15 | } 16 | 17 | /** 18 | * 19 | * @param server the server that has been added 20 | * @param securityKey the security key of the server 21 | * @param address the connection address of the server 22 | */ 23 | public ServerAddEvent(String server, String securityKey, InetSocketAddress address) { 24 | super(server, securityKey, address); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/ServerEventListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api; 2 | 3 | @Deprecated 4 | public interface ServerEventListener { 5 | 6 | /** 7 | * Called when a server has been added to the network 8 | * when the session is the role of a proxy. 9 | * 10 | * @param connect session that the event belongs to 11 | * @param event 12 | */ 13 | public void onServerAdd(Connect connect, ServerAddEvent event); 14 | 15 | /** 16 | * Called when a server has been removed from the network 17 | * when the session is the role of a proxy. 18 | * 19 | * @param connect session that the event belongs to 20 | * @param server that has been removed 21 | */ 22 | public void onServerRemove(Connect connect, String server); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/Event.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | /** 4 | * Super-class for events. 5 | */ 6 | public abstract class Event { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/EventListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Used to mark a method as an EventListener. 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface EventListener { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/MessageEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | 5 | /** 6 | * Called when a message has been received by the session. 7 | */ 8 | public class MessageEvent extends Event { 9 | 10 | private String sender; 11 | private String channel; 12 | private byte[] message; 13 | 14 | /** 15 | * 16 | * @param sender of the event 17 | * @param channel of the event 18 | * @param message of the event 19 | */ 20 | public MessageEvent(String sender, String channel, byte[] message) { 21 | this.sender = sender; 22 | this.channel = channel; 23 | this.message = message; 24 | } 25 | 26 | /** 27 | * 28 | * @return sender of the message 29 | */ 30 | public String getSender() { 31 | return this.sender; 32 | } 33 | 34 | /** 35 | * 36 | * @return channel to identify the message 37 | */ 38 | public String getChannel() { 39 | return this.channel; 40 | } 41 | 42 | /** 43 | * 44 | * @return message 45 | */ 46 | public byte[] getMessage() { 47 | return this.message; 48 | } 49 | 50 | /** 51 | * 52 | * @return message represented as a UTF-8 string 53 | * @throws UnsupportedEncodingException if the message can not be represented as a UTF-8 string 54 | */ 55 | public String getMessageAsString() throws UnsupportedEncodingException { 56 | return new String(this.message, "UTF-8"); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/RedirectEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | /** 4 | * Called when a player is to be redirected to a specified 5 | * server by the session when the session is the role of a proxy. 6 | */ 7 | public class RedirectEvent extends Event { 8 | 9 | private String server; 10 | private String player; 11 | 12 | /** 13 | * 14 | * @param server the server to redirect to 15 | * @param player the player to be redirected 16 | */ 17 | public RedirectEvent(String server, String player) { 18 | this.server = server; 19 | this.player = player; 20 | } 21 | 22 | /** 23 | * 24 | * @return the server to redirect to 25 | */ 26 | public String getServer() { 27 | return this.server; 28 | } 29 | 30 | /** 31 | * 32 | * @return the player to be redirected 33 | */ 34 | public String getPlayer() { 35 | return this.player; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/ServerAddEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | /** 6 | * Called when a server has been added to the network 7 | * when the session is the role of a proxy. 8 | */ 9 | public class ServerAddEvent extends Event { 10 | 11 | private String server; 12 | private String securityKey; 13 | private InetSocketAddress address; 14 | 15 | /** 16 | * 17 | * @param server the server that has been added 18 | * @param securityKey the security key of the server 19 | * @param address the connection address of the server 20 | */ 21 | public ServerAddEvent(String server, String securityKey, InetSocketAddress address) { 22 | this.server = server; 23 | this.securityKey = securityKey; 24 | this.address = address; 25 | } 26 | 27 | /** 28 | * 29 | * @return the server that has been added 30 | */ 31 | public String getServer() { 32 | return this.server; 33 | } 34 | 35 | /** 36 | * 37 | * @return the security key of the server 38 | */ 39 | public String getSecurityKey() { 40 | return this.securityKey; 41 | } 42 | 43 | /** 44 | * 45 | * @return the connection address of the server 46 | */ 47 | public InetSocketAddress getAddress() { 48 | return this.address; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/event/ServerRemoveEvent.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.event; 2 | 3 | /** 4 | * Called when a server has been removed from the network 5 | * when the session is the role of a proxy. 6 | */ 7 | public class ServerRemoveEvent extends Event { 8 | 9 | private String server; 10 | 11 | /** 12 | * 13 | * @param server the server removed from the network 14 | */ 15 | public ServerRemoveEvent(String server) { 16 | this.server = server; 17 | } 18 | 19 | /** 20 | * 21 | * @return the server removed from the network 22 | */ 23 | public String getServer() { 24 | return this.server; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/Request.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | 5 | public interface Request { 6 | 7 | /** 8 | * 9 | * @return accompanying result of the request 10 | */ 11 | public Class getResult(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/RequestException.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request; 2 | 3 | public class RequestException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | /** 8 | * Showing a request failed 9 | * 10 | * @param reason of the exception 11 | */ 12 | public RequestException(String reason) { 13 | super(reason); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/AsServerRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.AsServerResult; 5 | 6 | /** 7 | * Request to be assigned the role of a server on the network. 8 | */ 9 | public class AsServerRequest implements Request { 10 | 11 | private String ip; 12 | private int port; 13 | 14 | /** 15 | * Shortcut to dictate that the network should assume it's ip 16 | * address. 17 | * 18 | * @param port of the server 19 | */ 20 | public AsServerRequest(int port) { 21 | this(null, port); 22 | } 23 | 24 | /** 25 | * 26 | * @param ip of the server, null if the network should assume 27 | * it's ip address 28 | * @param port of the server 29 | */ 30 | public AsServerRequest(String ip, int port) { 31 | this.ip = ip; 32 | this.port = port; 33 | } 34 | 35 | /** 36 | * 37 | * @return accompanying result of the request 38 | */ 39 | public Class getResult() { 40 | return AsServerResult.class; 41 | } 42 | 43 | /** 44 | * 45 | * @return the ip address of the server, null if the network 46 | * should assume it's ip address 47 | */ 48 | public String getIp() { 49 | return this.ip; 50 | } 51 | 52 | /** 53 | * 54 | * @return the port number of the server 55 | */ 56 | public int getPort() { 57 | return this.port; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/AuthenticateRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.AuthenticateResult; 5 | import lilypad.client.connect.api.util.SecurityUtils; 6 | 7 | /** 8 | * Request to authenticate with the network. 9 | */ 10 | public class AuthenticateRequest implements Request { 11 | 12 | private String username; 13 | private String password; 14 | 15 | /** 16 | * 17 | * @param username to be authenticated with 18 | * @param password to be authenticated with 19 | * @param passwordKey salt to hash the password with 20 | */ 21 | public AuthenticateRequest(String username, String password, String passwordKey) { 22 | this.username = username; 23 | this.password = SecurityUtils.shaHex(SecurityUtils.shaHex(passwordKey) + SecurityUtils.shaHex(password)); 24 | } 25 | 26 | /** 27 | * 28 | * @return accompanying result of the request 29 | */ 30 | public Class getResult() { 31 | return AuthenticateResult.class; 32 | } 33 | 34 | /** 35 | * 36 | * @return username to be authenticated with 37 | */ 38 | public String getUsername() { 39 | return this.username; 40 | } 41 | 42 | /** 43 | * 44 | * @return password to be authenticated with 45 | */ 46 | public String getPassword() { 47 | return this.password; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/GetDetailsRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.GetDetailsResult; 5 | 6 | /** 7 | * Request to get the uniform connection details of the network, 8 | * not guaranteed to be an accurate representation. 9 | */ 10 | public class GetDetailsRequest implements Request { 11 | 12 | /** 13 | * 14 | * @return accompanying result of the request 15 | */ 16 | public Class getResult() { 17 | return GetDetailsResult.class; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/GetKeyRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.GetKeyResult; 5 | 6 | /** 7 | * Request to receive a shared salt to be used within the 8 | * authentication process. 9 | */ 10 | public class GetKeyRequest implements Request { 11 | 12 | /** 13 | * 14 | * @return accompanying result of the request 15 | */ 16 | public Class getResult() { 17 | return GetKeyResult.class; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/GetPlayersRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.GetPlayersResult; 5 | 6 | /** 7 | * Request to get an accurate representation of all players 8 | * on the network. 9 | */ 10 | public class GetPlayersRequest implements Request { 11 | 12 | private boolean asList; 13 | 14 | /** 15 | * Shortcut to dictate that we needn't a list of every 16 | * player. 17 | */ 18 | public GetPlayersRequest() { 19 | this(false); 20 | } 21 | 22 | /** 23 | * 24 | * @param asList if a list of every player is required 25 | */ 26 | public GetPlayersRequest(boolean asList) { 27 | this.asList = asList; 28 | } 29 | 30 | /** 31 | * 32 | * @return accompanying result of the request 33 | */ 34 | public Class getResult() { 35 | return GetPlayersResult.class; 36 | } 37 | 38 | /** 39 | * 40 | * @return if a list of every player is required 41 | */ 42 | public boolean getAsList() { 43 | return this.asList; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/GetWhoamiRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.GetWhoamiResult; 5 | 6 | /** 7 | * Request to get the current identification the network 8 | * recognizes your session as. 9 | */ 10 | public class GetWhoamiRequest implements Request { 11 | 12 | /** 13 | * 14 | * @return accompanying result of the request 15 | */ 16 | public Class getResult() { 17 | return GetWhoamiResult.class; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/NotifyPlayerRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.NotifyPlayerResult; 5 | 6 | /** 7 | * Request to notify the network that a player has been added 8 | * or removed from our proxy. 9 | */ 10 | public class NotifyPlayerRequest implements Request { 11 | 12 | private boolean addOrRemove; 13 | private String player; 14 | 15 | /** 16 | * 17 | * @param addOrRemove true if adding, false if removing 18 | * @param player in question 19 | */ 20 | public NotifyPlayerRequest(boolean addOrRemove, String player) { 21 | this.addOrRemove = addOrRemove; 22 | this.player = player; 23 | } 24 | 25 | /** 26 | * 27 | * @return accompanying result of the request 28 | */ 29 | public Class getResult() { 30 | return NotifyPlayerResult.class; 31 | } 32 | 33 | /** 34 | * 35 | * @return if this is a request to add 36 | */ 37 | public boolean isAdding() { 38 | return this.addOrRemove; 39 | } 40 | 41 | /** 42 | * 43 | * @return if this is a request to remove 44 | */ 45 | public boolean isRemoving() { 46 | return !this.addOrRemove; 47 | } 48 | 49 | /** 50 | * 51 | * @return the player in question 52 | */ 53 | public String getPlayer() { 54 | return this.player; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/request/impl/RedirectRequest.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.request.impl; 2 | 3 | import lilypad.client.connect.api.request.Request; 4 | import lilypad.client.connect.api.result.impl.RedirectResult; 5 | 6 | /** 7 | * Request asking the network to redirect a player to a specified 8 | * server. 9 | */ 10 | public class RedirectRequest implements Request { 11 | 12 | private String server; 13 | private String player; 14 | 15 | /** 16 | * 17 | * @param server to be redirected to 18 | * @param player to be redirected 19 | */ 20 | public RedirectRequest(String server, String player) { 21 | this.server = server; 22 | this.player = player; 23 | } 24 | 25 | /** 26 | * 27 | * @return accompanying result of the request 28 | */ 29 | public Class getResult() { 30 | return RedirectResult.class; 31 | } 32 | 33 | /** 34 | * 35 | * @return the server to be redirected to 36 | */ 37 | public String getServer() { 38 | return this.server; 39 | } 40 | 41 | /** 42 | * 43 | * @return the player to be redirected 44 | */ 45 | public String getPlayer() { 46 | return this.player; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/FutureResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result; 2 | 3 | public interface FutureResult { 4 | 5 | /** 6 | * Registers a listener to receive a callback when the future 7 | * has been completed. 8 | * 9 | * @param futureResultListener 10 | */ 11 | public void registerListener(FutureResultListener futureResultListener); 12 | 13 | /** 14 | * Unregisters a listener to exclude from receiving a callback 15 | * when the future has been completed. 16 | * 17 | * @param futureResultListener 18 | */ 19 | public void unregisterListener(FutureResultListener futureResultListener); 20 | 21 | /** 22 | * Awaits a result with no timeout. 23 | * 24 | * @return the result, null if cancelled 25 | * @throws InterruptedException 26 | */ 27 | public T await() throws InterruptedException; 28 | 29 | /** 30 | * Awaits a result with a timeout in milliseconds. 31 | * 32 | * @return the result, null if cancelled 33 | * @throws InterruptedException 34 | */ 35 | public T await(long timeout) throws InterruptedException; 36 | 37 | /** 38 | * Awaits a result uninterruptibly with no timeout. 39 | * 40 | * @return the result, null if cancelled 41 | */ 42 | public T awaitUninterruptibly(); 43 | 44 | /** 45 | * Awaits a result uninterruptibly with a timeout in milliseconds. 46 | * 47 | * @return the result, null if cancelled 48 | */ 49 | public T awaitUninterruptibly(long timeout); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/FutureResultListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result; 2 | 3 | public interface FutureResultListener { 4 | 5 | /** 6 | * Called when a result has been received for a registered 7 | * FutureResult. 8 | * 9 | * @param result of the request 10 | * @see FutureResult 11 | */ 12 | public void onResult(T result); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/Result.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result; 2 | 3 | public abstract class Result { 4 | 5 | private StatusCode statusCode; 6 | 7 | /** 8 | * 9 | * @param statusCode of the result 10 | */ 11 | public Result(StatusCode statusCode) { 12 | this.statusCode = statusCode; 13 | } 14 | 15 | /** 16 | * Showing how the request was handled by the network, namely 17 | * if it succeeded or failed. 18 | * 19 | * @return status code 20 | */ 21 | public StatusCode getStatusCode() { 22 | return this.statusCode; 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/StatusCode.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result; 2 | 3 | public enum StatusCode { 4 | 5 | /** 6 | * Failure of any reason relative to what the result 7 | * entitles. 8 | */ 9 | INVALID_GENERIC, 10 | /** 11 | * Failure due to the fact of the session not having 12 | * the required role to make the request. 13 | */ 14 | INVALID_ROLE, 15 | /** 16 | * Success. 17 | */ 18 | SUCCESS; 19 | } 20 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/AsProxyResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class AsProxyResult extends Result { 7 | 8 | /** 9 | * 10 | * @param statusCode of the result 11 | */ 12 | public AsProxyResult(StatusCode statusCode) { 13 | super(statusCode); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/AsServerResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class AsServerResult extends Result { 7 | 8 | private String securityKey; 9 | 10 | /** 11 | * Called only when the result is unsuccessful. 12 | * 13 | * @param statusCode of the result 14 | */ 15 | public AsServerResult(StatusCode statusCode) { 16 | super(statusCode); 17 | } 18 | 19 | /** 20 | * Showing the result was successful, passing the data 21 | * to accompany the result. 22 | * 23 | * @param securityKey of the result 24 | */ 25 | public AsServerResult(String securityKey) { 26 | super(StatusCode.SUCCESS); 27 | this.securityKey = securityKey; 28 | } 29 | 30 | /** 31 | * Secret used within the game login process for authorization. 32 | * 33 | * @return security key 34 | */ 35 | public String getSecurityKey() { 36 | return this.securityKey; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/AuthenticateResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class AuthenticateResult extends Result { 7 | 8 | /** 9 | * 10 | * @param statusCode of the result 11 | */ 12 | public AuthenticateResult(StatusCode statusCode) { 13 | super(statusCode); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/GetDetailsResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class GetDetailsResult extends Result { 7 | 8 | private String ip; 9 | private int port; 10 | private String motd; 11 | private String version; 12 | 13 | /** 14 | * Called only when the result is unsuccessful. 15 | * 16 | * @param statusCode of the result 17 | */ 18 | public GetDetailsResult(StatusCode statusCode) { 19 | super(statusCode); 20 | } 21 | 22 | /** 23 | * Showing the result was successful, passing the data 24 | * to accompany the result. 25 | * 26 | * @param ip of the result 27 | * @param port of the result 28 | * @param motd of the result 29 | * @param version of the result 30 | */ 31 | public GetDetailsResult(String ip, int port, String motd, String version) { 32 | super(StatusCode.SUCCESS); 33 | this.ip = ip; 34 | this.port = port; 35 | this.motd = motd; 36 | this.version = version; 37 | } 38 | 39 | /** 40 | * Uniform ip address decided by the network deriving from a single 41 | * proxy. There is no guarantee which proxy this ip address derives from. 42 | * 43 | * @return ip address 44 | */ 45 | public String getIp() { 46 | return this.ip; 47 | } 48 | 49 | /** 50 | * Uniform port number decided by the network deriving from a single 51 | * proxy. There is no guarantee which proxy this port number derives from. 52 | * 53 | * @return port number 54 | */ 55 | public int getPort() { 56 | return this.port; 57 | } 58 | 59 | /** 60 | * Uniform motd decided by the network deriving from a single proxy. 61 | * There is no guarantee which proxy this motd derives from. 62 | * 63 | * @return motd 64 | */ 65 | public String getMotd() { 66 | return this.motd; 67 | } 68 | 69 | /** 70 | * Uniform version decided by the network deriving from a single proxy. 71 | * There is no guarantee which proxy this version derives from. 72 | * 73 | * @return motd 74 | */ 75 | public String getVersion() { 76 | return this.version; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/GetKeyResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class GetKeyResult extends Result { 7 | 8 | private String key; 9 | 10 | /** 11 | * Called only when the result is unsuccessful. 12 | * 13 | * @param statusCode of the result 14 | */ 15 | public GetKeyResult(StatusCode statusCode) { 16 | super(statusCode); 17 | } 18 | 19 | /** 20 | * Showing the result was successful, passing the data 21 | * to accompany the result. 22 | * 23 | * @param key 24 | */ 25 | public GetKeyResult(String key) { 26 | this(StatusCode.SUCCESS); 27 | this.key = key; 28 | } 29 | 30 | /** 31 | * Shared salt used within the authentication process for the password. 32 | * 33 | * @return salt 34 | */ 35 | public String getKey() { 36 | return this.key; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/GetPlayersResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import java.util.Set; 4 | 5 | import lilypad.client.connect.api.result.Result; 6 | import lilypad.client.connect.api.result.StatusCode; 7 | 8 | public class GetPlayersResult extends Result { 9 | 10 | private int currentPlayers; 11 | private int maximumPlayers; 12 | private Set players; 13 | 14 | /** 15 | * Called only when the result is unsuccessful. 16 | * 17 | * @param statusCode of the result 18 | */ 19 | public GetPlayersResult(StatusCode statusCode) { 20 | super(statusCode); 21 | } 22 | 23 | /** 24 | * Showing the result was successful, passing the data 25 | * to accompany the result. 26 | * 27 | * @param currentPlayers 28 | * @param maximumPlayers 29 | * @param players 30 | */ 31 | public GetPlayersResult(int currentPlayers, int maximumPlayers, Set players) { 32 | super(StatusCode.SUCCESS); 33 | this.currentPlayers = currentPlayers; 34 | this.maximumPlayers = maximumPlayers; 35 | this.players = players; 36 | } 37 | 38 | /** 39 | * An accurate representation of the current player count 40 | * as reported by the network 41 | * 42 | * @return current players 43 | */ 44 | public int getCurrentPlayers() { 45 | return this.currentPlayers; 46 | } 47 | 48 | /** 49 | * The maximum players allowed on the network. This is normally 50 | * calculated through the sum of all proxies' maximum player count, 51 | * however when at least one proxies' player count is below 2, 52 | * it will return the single proxies' player count instead 53 | * 54 | * @return max players 55 | */ 56 | public int getMaximumPlayers() { 57 | return this.maximumPlayers; 58 | } 59 | 60 | /** 61 | * If the original request asked for the list of players, an accurate 62 | * representation of all players on the network will be returned. 63 | * Otherwise, it will return null. 64 | * 65 | * @return set of players 66 | */ 67 | public Set getPlayers() { 68 | return this.players; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/GetWhoamiResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class GetWhoamiResult extends Result { 7 | 8 | private String identification; 9 | 10 | /** 11 | * Called only when the result is unsuccessful. 12 | * 13 | * @param statusCode of the result 14 | */ 15 | public GetWhoamiResult(StatusCode statusCode) { 16 | super(statusCode); 17 | } 18 | 19 | /** 20 | * Showing the result was successful, passing the data 21 | * to accompany the result. 22 | * 23 | * @param identification 24 | */ 25 | public GetWhoamiResult(String identification) { 26 | super(StatusCode.SUCCESS); 27 | this.identification = identification; 28 | } 29 | 30 | /** 31 | * The network will identify you differently based on your state. 32 | * If you are unauthenticated, your identification will be blank, while if 33 | * you are authenticated, your identification will be [username].[uniqueInt], 34 | * and if you are either a server or a proxy, your identification will simply 35 | * be [username]. 36 | * 37 | * @return identification by the network 38 | */ 39 | public String getIdentification() { 40 | return this.identification; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/MessageResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class MessageResult extends Result { 7 | 8 | /** 9 | * 10 | * @param statusCode of the result 11 | */ 12 | public MessageResult(StatusCode statusCode) { 13 | super(statusCode); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/NotifyPlayerResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class NotifyPlayerResult extends Result { 7 | 8 | /** 9 | * 10 | * @param statusCode of the result 11 | */ 12 | public NotifyPlayerResult(StatusCode statusCode) { 13 | super(statusCode); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/result/impl/RedirectResult.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.result.impl; 2 | 3 | import lilypad.client.connect.api.result.Result; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | 6 | public class RedirectResult extends Result { 7 | 8 | /** 9 | * 10 | * @param statusCode of the result 11 | */ 12 | public RedirectResult(StatusCode statusCode) { 13 | super(statusCode); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /client-connect-api/src/main/java/lilypad/client/connect/api/util/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.api.util; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | 6 | public class SecurityUtils { 7 | 8 | /** 9 | * Calculates a SHA-1 Hex-Encoded Hash of a String's bytes given 10 | * the default system Charset. 11 | * 12 | * @param string input by which to derive the hash 13 | * @return SHA-1 Hex-Encoded Hash derived from the input 14 | */ 15 | public static String shaHex(String string) { 16 | return shaHex(string.getBytes()); 17 | } 18 | 19 | /** 20 | * Calculates a SHA-1 Hex-Encoded Hash of an input. 21 | * 22 | * @param bytesArray input by which to derive the hash 23 | * @return SHA-1 Hex-Encoded Hash derived from the input 24 | */ 25 | public static String shaHex(byte[]... bytesArray) { 26 | try { 27 | MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); 28 | for(byte[] bytes : bytesArray) { 29 | messageDigest.update(bytes); 30 | } 31 | String hash = new BigInteger(1, messageDigest.digest()).toString(16); 32 | if(hash.length() == 39) { 33 | hash = "0" + hash; 34 | } 35 | return hash; 36 | } catch(Exception exception) { 37 | exception.printStackTrace(); 38 | return null; 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /client-connect-lib/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/ConnectRequestEncoderRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request; 2 | 3 | import lilypad.client.connect.lib.request.impl.AsProxyRequestEncoder; 4 | import lilypad.client.connect.lib.request.impl.AsServerRequestEncoder; 5 | import lilypad.client.connect.lib.request.impl.AuthenticateRequestEncoder; 6 | import lilypad.client.connect.lib.request.impl.GetDetailsRequestEncoder; 7 | import lilypad.client.connect.lib.request.impl.GetKeyRequestEncoder; 8 | import lilypad.client.connect.lib.request.impl.GetPlayersRequestEncoder; 9 | import lilypad.client.connect.lib.request.impl.GetWhoamiRequestEncoder; 10 | import lilypad.client.connect.lib.request.impl.MessageRequestEncoder; 11 | import lilypad.client.connect.lib.request.impl.NotifyPlayerRequestEncoder; 12 | import lilypad.client.connect.lib.request.impl.RedirectRequestEncoder; 13 | 14 | public class ConnectRequestEncoderRegistry extends RequestEncoderRegistry { 15 | 16 | public static final ConnectRequestEncoderRegistry instance = new ConnectRequestEncoderRegistry(); 17 | 18 | private ConnectRequestEncoderRegistry() { 19 | this.submit(new AsProxyRequestEncoder()); 20 | this.submit(new AsServerRequestEncoder()); 21 | this.submit(new AuthenticateRequestEncoder()); 22 | this.submit(new GetDetailsRequestEncoder()); 23 | this.submit(new GetKeyRequestEncoder()); 24 | this.submit(new GetPlayersRequestEncoder()); 25 | this.submit(new GetWhoamiRequestEncoder()); 26 | this.submit(new MessageRequestEncoder()); 27 | this.submit(new NotifyPlayerRequestEncoder()); 28 | this.submit(new RedirectRequestEncoder()); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/RequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.Request; 5 | 6 | public interface RequestEncoder> { 7 | 8 | public void encode(T request, ByteBuf buffer); 9 | 10 | public int getId(); 11 | 12 | public Class getRequest(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/RequestEncoderRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import lilypad.client.connect.api.request.Request; 7 | 8 | public class RequestEncoderRegistry { 9 | 10 | private Map>, RequestEncoder> registryByRequest = new HashMap>, RequestEncoder>(); 11 | private RequestEncoder[] registryById = new RequestEncoder[256]; 12 | 13 | public void submit(RequestEncoder requestEncoder) { 14 | if(requestEncoder == null) { 15 | return; 16 | } 17 | this.registryByRequest.put(requestEncoder.getRequest(), requestEncoder); 18 | this.registryById[requestEncoder.getId()] = requestEncoder; 19 | } 20 | 21 | public RequestEncoder getById(int id) { 22 | return this.registryById[id]; 23 | } 24 | 25 | public RequestEncoder getByRequest(Class request) { 26 | return this.registryByRequest.get(request); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/AsProxyRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.AsProxyRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class AsProxyRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(AsProxyRequest request, ByteBuf buffer) { 12 | if(request.getIp() == null) { 13 | BufferUtils.writeVarInt(buffer, 0); 14 | } else { 15 | BufferUtils.writeString(buffer, request.getIp()); 16 | } 17 | buffer.writeShort(request.getPort()); 18 | BufferUtils.writeString(buffer, request.getMotd()); 19 | BufferUtils.writeString(buffer, request.getVersion()); 20 | buffer.writeShort(request.getMaximumPlayers()); 21 | } 22 | 23 | public int getId() { 24 | return ConnectPacketConstants.requestAsProxy; 25 | } 26 | 27 | public Class getRequest() { 28 | return AsProxyRequest.class; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/AsServerRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.AsServerRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class AsServerRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(AsServerRequest request, ByteBuf buffer) { 12 | if(request.getIp() == null) { 13 | BufferUtils.writeVarInt(buffer, 0); 14 | } else { 15 | BufferUtils.writeString(buffer, request.getIp()); 16 | } 17 | buffer.writeShort(request.getPort()); 18 | } 19 | 20 | public int getId() { 21 | return ConnectPacketConstants.requestAsServer; 22 | } 23 | 24 | public Class getRequest() { 25 | return AsServerRequest.class; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/AuthenticateRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.AuthenticateRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class AuthenticateRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(AuthenticateRequest request, ByteBuf buffer) { 12 | BufferUtils.writeString(buffer, request.getUsername()); 13 | BufferUtils.writeString(buffer, request.getPassword()); 14 | } 15 | 16 | public int getId() { 17 | return ConnectPacketConstants.requestAuthenticate; 18 | } 19 | 20 | public Class getRequest() { 21 | return AuthenticateRequest.class; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/GetDetailsRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.GetDetailsRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | 8 | public class GetDetailsRequestEncoder implements RequestEncoder { 9 | 10 | public void encode(GetDetailsRequest request, ByteBuf buffer) { 11 | // no payload 12 | } 13 | 14 | public int getId() { 15 | return ConnectPacketConstants.requestGetDetails; 16 | } 17 | 18 | public Class getRequest() { 19 | return GetDetailsRequest.class; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/GetKeyRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.GetKeyRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | 8 | public class GetKeyRequestEncoder implements RequestEncoder { 9 | 10 | public void encode(GetKeyRequest request, ByteBuf buffer) { 11 | // no payload 12 | } 13 | 14 | public int getId() { 15 | return ConnectPacketConstants.requestGetKey; 16 | } 17 | 18 | public Class getRequest() { 19 | return GetKeyRequest.class; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/GetPlayersRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.GetPlayersRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | 8 | public class GetPlayersRequestEncoder implements RequestEncoder { 9 | 10 | public void encode(GetPlayersRequest request, ByteBuf buffer) { 11 | buffer.writeBoolean(request.getAsList()); 12 | } 13 | 14 | public int getId() { 15 | return ConnectPacketConstants.requestGetPlayers; 16 | } 17 | 18 | public Class getRequest() { 19 | return GetPlayersRequest.class; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/GetWhoamiRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.GetWhoamiRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | 8 | public class GetWhoamiRequestEncoder implements RequestEncoder { 9 | 10 | public void encode(GetWhoamiRequest request, ByteBuf buffer) { 11 | // no payload 12 | } 13 | 14 | public int getId() { 15 | return ConnectPacketConstants.requestGetWhoami; 16 | } 17 | 18 | public Class getRequest() { 19 | return GetWhoamiRequest.class; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/MessageRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.MessageRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class MessageRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(MessageRequest request, ByteBuf buffer) { 12 | buffer.writeShort(request.getRecipients().size()); 13 | for(String username : request.getRecipients()) { 14 | BufferUtils.writeString(buffer, username); 15 | } 16 | BufferUtils.writeString(buffer, request.getChannel()); 17 | buffer.writeShort(request.getMessage().length); 18 | buffer.writeBytes(request.getMessage()); 19 | } 20 | 21 | public int getId() { 22 | return ConnectPacketConstants.requestMessage; 23 | } 24 | 25 | public Class getRequest() { 26 | return MessageRequest.class; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/NotifyPlayerRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.NotifyPlayerRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class NotifyPlayerRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(NotifyPlayerRequest request, ByteBuf buffer) { 12 | buffer.writeBoolean(request.isAdding()); 13 | BufferUtils.writeString(buffer, request.getPlayer()); 14 | } 15 | 16 | public int getId() { 17 | return ConnectPacketConstants.requestNotifyPlayer; 18 | } 19 | 20 | public Class getRequest() { 21 | return NotifyPlayerRequest.class; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/request/impl/RedirectRequestEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.request.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.request.impl.RedirectRequest; 5 | import lilypad.client.connect.lib.request.RequestEncoder; 6 | import lilypad.packet.common.util.BufferUtils; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class RedirectRequestEncoder implements RequestEncoder { 10 | 11 | public void encode(RedirectRequest request, ByteBuf buffer) { 12 | BufferUtils.writeString(buffer, request.getServer()); 13 | BufferUtils.writeString(buffer, request.getPlayer()); 14 | } 15 | 16 | public int getId() { 17 | return ConnectPacketConstants.requestRedirect; 18 | } 19 | 20 | public Class getRequest() { 21 | return RedirectRequest.class; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/ConnectResultDecoderRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result; 2 | 3 | import lilypad.client.connect.lib.result.impl.AsProxyResultDecoder; 4 | import lilypad.client.connect.lib.result.impl.AsServerResultDecoder; 5 | import lilypad.client.connect.lib.result.impl.AuthenticateResultDecoder; 6 | import lilypad.client.connect.lib.result.impl.GetDetailsResultDecoder; 7 | import lilypad.client.connect.lib.result.impl.GetKeyResultDecoder; 8 | import lilypad.client.connect.lib.result.impl.GetPlayersResultDecoder; 9 | import lilypad.client.connect.lib.result.impl.GetWhoamiResultDecoder; 10 | import lilypad.client.connect.lib.result.impl.MessageResultDecoder; 11 | import lilypad.client.connect.lib.result.impl.NotifyPlayerResultDecoder; 12 | import lilypad.client.connect.lib.result.impl.RedirectResultDecoder; 13 | 14 | public class ConnectResultDecoderRegistry extends ResultDecoderRegistry { 15 | 16 | public static final ConnectResultDecoderRegistry instance = new ConnectResultDecoderRegistry(); 17 | 18 | private ConnectResultDecoderRegistry() { 19 | this.submit(new AsProxyResultDecoder()); 20 | this.submit(new AsServerResultDecoder()); 21 | this.submit(new AuthenticateResultDecoder()); 22 | this.submit(new GetDetailsResultDecoder()); 23 | this.submit(new GetKeyResultDecoder()); 24 | this.submit(new GetPlayersResultDecoder()); 25 | this.submit(new GetWhoamiResultDecoder()); 26 | this.submit(new MessageResultDecoder()); 27 | this.submit(new NotifyPlayerResultDecoder()); 28 | this.submit(new RedirectResultDecoder()); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/ResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.Result; 5 | import lilypad.client.connect.api.result.StatusCode; 6 | 7 | public interface ResultDecoder { 8 | 9 | public T decode(StatusCode statusCode, ByteBuf buffer); 10 | 11 | public int getId(); 12 | 13 | public Class getResult(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/ResultDecoderRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import lilypad.client.connect.api.result.Result; 7 | 8 | public class ResultDecoderRegistry { 9 | 10 | private Map, ResultDecoder> registryByResult = new HashMap, ResultDecoder>(); 11 | private ResultDecoder[] registryById = new ResultDecoder[256]; 12 | 13 | public void submit(ResultDecoder resultDecoder) { 14 | if(resultDecoder == null) { 15 | return; 16 | } 17 | this.registryByResult.put(resultDecoder.getResult(), resultDecoder); 18 | this.registryById[resultDecoder.getId()] = resultDecoder; 19 | } 20 | 21 | public ResultDecoder getByResult(Class resultClass) { 22 | return this.registryByResult.get(resultClass); 23 | } 24 | 25 | public ResultDecoder getById(int id) { 26 | return this.registryById[id]; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/AsProxyResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.AsProxyResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class AsProxyResultDecoder implements ResultDecoder { 10 | 11 | public AsProxyResult decode(StatusCode statusCode, ByteBuf buffer) { 12 | return new AsProxyResult(statusCode); 13 | } 14 | 15 | public int getId() { 16 | return ConnectPacketConstants.requestAsProxy; 17 | } 18 | 19 | public Class getResult() { 20 | return AsProxyResult.class; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/AsServerResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.AsServerResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | 10 | public class AsServerResultDecoder implements ResultDecoder { 11 | 12 | public AsServerResult decode(StatusCode statusCode, ByteBuf buffer) { 13 | if(statusCode == StatusCode.SUCCESS) { 14 | return new AsServerResult(BufferUtils.readString(buffer)); 15 | } else { 16 | return new AsServerResult(statusCode); 17 | } 18 | } 19 | 20 | public int getId() { 21 | return ConnectPacketConstants.requestAsServer; 22 | } 23 | 24 | public Class getResult() { 25 | return AsServerResult.class; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/AuthenticateResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.AuthenticateResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class AuthenticateResultDecoder implements ResultDecoder { 10 | 11 | public AuthenticateResult decode(StatusCode statusCode, ByteBuf buffer) { 12 | return new AuthenticateResult(statusCode); 13 | } 14 | 15 | public int getId() { 16 | return ConnectPacketConstants.requestAuthenticate; 17 | } 18 | 19 | public Class getResult() { 20 | return AuthenticateResult.class; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/GetDetailsResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.GetDetailsResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | 10 | public class GetDetailsResultDecoder implements ResultDecoder { 11 | 12 | public GetDetailsResult decode(StatusCode statusCode, ByteBuf buffer) { 13 | if(statusCode == StatusCode.SUCCESS) { 14 | return new GetDetailsResult(BufferUtils.readString(buffer), buffer.readUnsignedShort(), BufferUtils.readString(buffer), BufferUtils.readString(buffer)); 15 | } else { 16 | return new GetDetailsResult(statusCode); 17 | } 18 | } 19 | 20 | public int getId() { 21 | return ConnectPacketConstants.requestGetDetails; 22 | } 23 | 24 | public Class getResult() { 25 | return GetDetailsResult.class; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/GetKeyResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.GetKeyResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | 10 | public class GetKeyResultDecoder implements ResultDecoder { 11 | 12 | public GetKeyResult decode(StatusCode statusCode, ByteBuf buffer) { 13 | if(statusCode == StatusCode.SUCCESS) { 14 | return new GetKeyResult(BufferUtils.readString(buffer)); 15 | } else { 16 | return new GetKeyResult(statusCode); 17 | } 18 | } 19 | 20 | public int getId() { 21 | return ConnectPacketConstants.requestGetKey; 22 | } 23 | 24 | public Class getResult() { 25 | return GetKeyResult.class; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/GetPlayersResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import lilypad.client.connect.api.result.StatusCode; 8 | import lilypad.client.connect.api.result.impl.GetPlayersResult; 9 | import lilypad.client.connect.lib.result.ResultDecoder; 10 | import lilypad.packet.common.util.BufferUtils; 11 | import lilypad.packet.connect.ConnectPacketConstants; 12 | 13 | public class GetPlayersResultDecoder implements ResultDecoder { 14 | 15 | public GetPlayersResult decode(StatusCode statusCode, ByteBuf buffer) { 16 | if(statusCode == StatusCode.SUCCESS) { 17 | boolean hasList = buffer.readBoolean(); 18 | int currentPlayers = buffer.readUnsignedShort(); 19 | int maximumPlayers = buffer.readUnsignedShort(); 20 | Set players = new HashSet(); 21 | if(hasList) { 22 | for(int i = 0; i < currentPlayers; i++) { 23 | players.add(BufferUtils.readString(buffer)); 24 | } 25 | } 26 | return new GetPlayersResult(currentPlayers, maximumPlayers, players); 27 | } else { 28 | return new GetPlayersResult(statusCode); 29 | } 30 | } 31 | 32 | public int getId() { 33 | return ConnectPacketConstants.requestGetPlayers; 34 | } 35 | 36 | public Class getResult() { 37 | return GetPlayersResult.class; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/GetWhoamiResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.GetWhoamiResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | 10 | public class GetWhoamiResultDecoder implements ResultDecoder { 11 | 12 | public GetWhoamiResult decode(StatusCode statusCode, ByteBuf buffer) { 13 | if(statusCode == StatusCode.SUCCESS) { 14 | return new GetWhoamiResult(BufferUtils.readString(buffer)); 15 | } else { 16 | return new GetWhoamiResult(statusCode); 17 | } 18 | } 19 | 20 | public int getId() { 21 | return ConnectPacketConstants.requestGetWhoami; 22 | } 23 | 24 | public Class getResult() { 25 | return GetWhoamiResult.class; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/MessageResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.MessageResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class MessageResultDecoder implements ResultDecoder { 10 | 11 | public MessageResult decode(StatusCode statusCode, ByteBuf buffer) { 12 | return new MessageResult(statusCode); 13 | } 14 | 15 | public int getId() { 16 | return ConnectPacketConstants.requestMessage; 17 | } 18 | 19 | public Class getResult() { 20 | return MessageResult.class; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/NotifyPlayerResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.NotifyPlayerResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class NotifyPlayerResultDecoder implements ResultDecoder { 10 | 11 | public NotifyPlayerResult decode(StatusCode statusCode, ByteBuf buffer) { 12 | return new NotifyPlayerResult(statusCode); 13 | } 14 | 15 | public int getId() { 16 | return ConnectPacketConstants.requestNotifyPlayer; 17 | } 18 | 19 | public Class getResult() { 20 | return NotifyPlayerResult.class; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/result/impl/RedirectResultDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.result.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.client.connect.api.result.StatusCode; 5 | import lilypad.client.connect.api.result.impl.RedirectResult; 6 | import lilypad.client.connect.lib.result.ResultDecoder; 7 | import lilypad.packet.connect.ConnectPacketConstants; 8 | 9 | public class RedirectResultDecoder implements ResultDecoder { 10 | 11 | public RedirectResult decode(StatusCode statusCode, ByteBuf buffer) { 12 | return new RedirectResult(statusCode); 13 | } 14 | 15 | public int getId() { 16 | return ConnectPacketConstants.requestRedirect; 17 | } 18 | 19 | public Class getResult() { 20 | return RedirectResult.class; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /client-connect-lib/src/main/java/lilypad/client/connect/lib/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.client.connect.lib.util; 2 | 3 | import java.util.List; 4 | 5 | public class StringUtils { 6 | 7 | public static String join(List args, String seperator) { 8 | return join(args.toArray(new String[0]), seperator); 9 | } 10 | 11 | public static String join(String[] args, String seperator) { 12 | StringBuilder builder = new StringBuilder(); 13 | for (int i = 0; i < args.length; i++) { 14 | if (i != 0) { 15 | builder.append(seperator); 16 | } 17 | builder.append(args[i]); 18 | } 19 | return builder.toString(); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /packet-common/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/Packet.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | public abstract class Packet { 4 | 5 | private int opcode; 6 | 7 | public Packet(int opcode) { 8 | this.opcode = opcode; 9 | } 10 | 11 | public int getOpcode() { 12 | return this.opcode; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/PacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | public abstract class PacketCodec { 6 | 7 | private int opcode; 8 | 9 | public PacketCodec(int opcode) { 10 | this.opcode = opcode; 11 | } 12 | 13 | public abstract T decode(ByteBuf buffer) throws Exception; 14 | 15 | public abstract void encode(T packet, ByteBuf buffer); 16 | 17 | @SuppressWarnings("unchecked") 18 | public final void encodePacket(Packet packet, ByteBuf buffer) { 19 | this.encode((T) packet, buffer); 20 | } 21 | 22 | public int getOpcode() { 23 | return this.opcode; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/PacketCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | public interface PacketCodecProvider { 4 | 5 | public PacketCodec getByOpcode(int opcode); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/PacketCodecRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | public class PacketCodecRegistry implements PacketCodecProvider { 4 | 5 | private PacketCodec[] packetCodecs = new PacketCodec[256]; 6 | 7 | public void register(PacketCodec packetCodec) { 8 | this.packetCodecs[packetCodec.getOpcode()] = packetCodec; 9 | } 10 | 11 | public PacketCodec getByOpcode(int opcode) { 12 | return this.packetCodecs[opcode]; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/PacketDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | import java.util.List; 4 | 5 | import lilypad.packet.common.util.BufferUtils; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.ByteToMessageDecoder; 9 | 10 | public class PacketDecoder extends ByteToMessageDecoder { 11 | 12 | private PacketCodecProvider packetCodecProvider; 13 | 14 | public PacketDecoder(PacketCodecProvider packetCodecProvider) { 15 | this.packetCodecProvider = packetCodecProvider; 16 | } 17 | 18 | @Override 19 | protected void decode(ChannelHandlerContext context, ByteBuf buffer, List out) throws Exception { 20 | if(!buffer.isReadable()) { 21 | return; 22 | } 23 | int opcode = BufferUtils.readVarInt(buffer); 24 | PacketCodec packetCodec = this.packetCodecProvider.getByOpcode(opcode); 25 | if(packetCodec == null) { 26 | context.close(); 27 | return; 28 | } 29 | out.add(packetCodec.decode(buffer)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/PacketEncoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | import lilypad.packet.common.util.BufferUtils; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.MessageToByteEncoder; 7 | 8 | public class PacketEncoder extends MessageToByteEncoder { 9 | 10 | private PacketCodecProvider packetCodecProvider; 11 | 12 | public PacketEncoder(PacketCodecProvider packetCodecProvider) { 13 | this.packetCodecProvider = packetCodecProvider; 14 | } 15 | 16 | @Override 17 | protected void encode(ChannelHandlerContext context, Packet packet, ByteBuf out) throws Exception { 18 | BufferUtils.writeVarInt(out, packet.getOpcode()); 19 | this.packetCodecProvider.getByOpcode(packet.getOpcode()).encodePacket(packet, out); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/VarIntFrameCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common; 2 | 3 | import java.util.List; 4 | 5 | import lilypad.packet.common.util.BufferUtils; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandler.Sharable; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import io.netty.handler.codec.ByteToMessageCodec; 10 | import io.netty.handler.codec.CorruptedFrameException; 11 | 12 | public class VarIntFrameCodec extends ByteToMessageCodec { 13 | 14 | protected void decode(ChannelHandlerContext context, ByteBuf in, List out) throws Exception { 15 | in.markReaderIndex(); 16 | for(int i = 0; i < 3; i++) { 17 | if(!in.isReadable(i + 1)) { 18 | in.resetReaderIndex(); 19 | return; 20 | } 21 | if(in.getByte(in.readerIndex() + i) < 0) { 22 | continue; 23 | } 24 | int size = BufferUtils.readVarInt(in); 25 | if(size > in.readableBytes()) { 26 | in.resetReaderIndex(); 27 | return; 28 | } 29 | out.add(in.readBytes(size)); 30 | return; 31 | } 32 | throw new CorruptedFrameException("VarInt size is longer than 21-bit"); 33 | } 34 | 35 | protected void encode(ChannelHandlerContext context, ByteBuf in, ByteBuf out) throws Exception { 36 | BufferUtils.writeVarInt(out, in.readableBytes()); 37 | out.writeBytes(in); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /packet-common/src/main/java/lilypad/packet/common/util/BufferUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.common.util; 2 | 3 | import java.security.KeyFactory; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.security.PublicKey; 6 | import java.security.spec.InvalidKeySpecException; 7 | import java.security.spec.X509EncodedKeySpec; 8 | 9 | import io.netty.buffer.ByteBuf; 10 | import io.netty.util.CharsetUtil; 11 | 12 | public class BufferUtils { 13 | 14 | public static int readVarInt(ByteBuf buffer) { 15 | int value = 0; 16 | int bytes = 0; 17 | byte in; 18 | while(true) { 19 | in = buffer.readByte(); 20 | value |= (in & 0x7F) << (bytes++ * 7); 21 | if(bytes > 32) { 22 | throw new IllegalArgumentException("VarInt is too long: " + bytes); 23 | } 24 | if((in & 0x80) == 0x80) { 25 | continue; 26 | } 27 | break; 28 | } 29 | return value; 30 | } 31 | 32 | public static void writeVarInt(ByteBuf buffer, int value) { 33 | byte in; 34 | while(true) { 35 | in = (byte) (value & 0x7F); 36 | value >>>= 7; 37 | if(value != 0) { 38 | in |= 0x80; 39 | } 40 | buffer.writeByte(in); 41 | if(value != 0) { 42 | continue; 43 | } 44 | break; 45 | } 46 | } 47 | 48 | public static String readString(ByteBuf buffer) { 49 | byte[] bytes = new byte[readVarInt(buffer)]; 50 | buffer.readBytes(bytes); 51 | return new String(bytes, CharsetUtil.UTF_8); 52 | } 53 | 54 | public static void writeString(ByteBuf buffer, String string) { 55 | byte[] bytes = string.getBytes(CharsetUtil.UTF_8); 56 | writeVarInt(buffer, bytes.length); 57 | buffer.writeBytes(bytes); 58 | } 59 | 60 | public static byte[] readBytes(ByteBuf from, int length) { 61 | byte[] data = new byte[length]; 62 | from.readBytes(data); 63 | return data; 64 | } 65 | 66 | public static PublicKey readPublicKey(ByteBuf buffer) { 67 | int size = buffer.readUnsignedShort(); 68 | try { 69 | X509EncodedKeySpec x509 = new X509EncodedKeySpec(buffer.readBytes(size).array()); 70 | KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 71 | return keyFactory.generatePublic(x509); 72 | } catch (NoSuchAlgorithmException exception) { 73 | exception.printStackTrace(); 74 | } catch (InvalidKeySpecException exception) { 75 | exception.printStackTrace(); 76 | } 77 | return null; 78 | } 79 | 80 | public static void writePublicKey(ByteBuf buffer, PublicKey publicKey) { 81 | byte[] encoded = publicKey.getEncoded(); 82 | buffer.writeShort(encoded.length); 83 | buffer.writeBytes(encoded); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /packet-connect/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /packet-connect/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | lilypad.packet 5 | connect 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | Packet-Connect 10 | http://www.lilypadmc.org 11 | 12 | 13 | UTF-8 14 | Unknown 15 | 16 | 17 | 18 | 19 | lilypad 20 | http://ci.lilypadmc.org/plugin/repository/everything 21 | 22 | 23 | 24 | 25 | 26 | lilypad.packet 27 | common 28 | 0.0.1-SNAPSHOT 29 | 30 | 31 | 32 | 33 | ${project.name} 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 2.5.1 39 | 40 | 1.6 41 | 1.6 42 | 43 | 44 | 45 | maven-assembly-plugin 46 | 2.2 47 | 48 | 49 | make-assembly 50 | package 51 | 52 | single 53 | 54 | 55 | 1.6 56 | 1.6 57 | 58 | jar-with-dependencies 59 | 60 | false 61 | 62 | false 63 | 64 | ${name} 65 | ${build.number} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/ConnectPacketCodecRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect; 2 | 3 | import lilypad.packet.common.PacketCodecRegistry; 4 | import lilypad.packet.connect.impl.KeepalivePacketCodec; 5 | import lilypad.packet.connect.impl.MessagePacketCodec; 6 | import lilypad.packet.connect.impl.RedirectPacketCodec; 7 | import lilypad.packet.connect.impl.RequestPacketCodec; 8 | import lilypad.packet.connect.impl.ResultPacketCodec; 9 | import lilypad.packet.connect.impl.ServerPacketCodec; 10 | 11 | public class ConnectPacketCodecRegistry extends PacketCodecRegistry { 12 | 13 | public static final ConnectPacketCodecRegistry instance = new ConnectPacketCodecRegistry(); 14 | 15 | public ConnectPacketCodecRegistry() { 16 | this.register(new KeepalivePacketCodec()); 17 | this.register(new RequestPacketCodec()); 18 | this.register(new ResultPacketCodec()); 19 | this.register(new MessagePacketCodec()); 20 | this.register(new RedirectPacketCodec()); 21 | this.register(new ServerPacketCodec()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/ConnectPacketConstants.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect; 2 | 3 | 4 | public class ConnectPacketConstants { 5 | 6 | public static final int statusInvalidRole = 0x02; 7 | public static final int statusInvalidGeneric = 0x01; 8 | public static final int statusSuccess = 0x00; 9 | 10 | public static final int requestAuthenticate = 0x00; 11 | public static final int requestAsServer = 0x01; 12 | public static final int requestAsProxy = 0x02; 13 | public static final int requestGetKey = 0x03; 14 | public static final int requestGetWhoami = 0x04; 15 | public static final int requestMessage = 0x10; 16 | public static final int requestRedirect = 0x11; 17 | public static final int requestGetPlayers = 0x20; 18 | public static final int requestNotifyPlayer = 0x21; 19 | public static final int requestGetDetails = 0x22; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/KeepalivePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class KeepalivePacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | private int random; 10 | 11 | public KeepalivePacket(int random) { 12 | super(opcode); 13 | this.random = random; 14 | } 15 | 16 | public int getRandom() { 17 | return this.random; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/KeepalivePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class KeepalivePacketCodec extends PacketCodec { 7 | 8 | public KeepalivePacketCodec() { 9 | super(KeepalivePacket.opcode); 10 | } 11 | 12 | public KeepalivePacket decode(ByteBuf buffer) throws Exception { 13 | int random = buffer.readInt(); 14 | return new KeepalivePacket(random); 15 | } 16 | 17 | public void encode(KeepalivePacket packet, ByteBuf buffer) { 18 | buffer.writeInt(packet.getRandom()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/MessagePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.Packet; 5 | 6 | public class MessagePacket extends Packet { 7 | 8 | public static final int opcode = 0x03; 9 | 10 | private String sender; 11 | private String channel; 12 | private ByteBuf payload; 13 | 14 | public MessagePacket(String sender, String channel, ByteBuf payload) { 15 | super(opcode); 16 | this.sender = sender; 17 | this.channel = channel; 18 | this.payload = payload; 19 | } 20 | 21 | public String getSender() { 22 | return this.sender; 23 | } 24 | 25 | public String getChannel() { 26 | return this.channel; 27 | } 28 | 29 | public ByteBuf getPayload() { 30 | return this.payload; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/MessagePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class MessagePacketCodec extends PacketCodec { 8 | 9 | public MessagePacketCodec() { 10 | super(MessagePacket.opcode); 11 | } 12 | 13 | public MessagePacket decode(ByteBuf buffer) throws Exception { 14 | String sender = BufferUtils.readString(buffer); 15 | String channel = BufferUtils.readString(buffer); 16 | ByteBuf payload = buffer.readBytes(buffer.readUnsignedShort()); 17 | return new MessagePacket(sender, channel, payload); 18 | } 19 | 20 | public void encode(MessagePacket packet, ByteBuf buffer) { 21 | BufferUtils.writeString(buffer, packet.getSender()); 22 | BufferUtils.writeString(buffer, packet.getChannel()); 23 | ByteBuf payload = packet.getPayload(); 24 | buffer.writeShort(payload.readableBytes()); 25 | buffer.writeBytes(payload, payload.readerIndex(), payload.readableBytes()); 26 | packet.getPayload().release(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/RedirectPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class RedirectPacket extends Packet { 6 | 7 | public static final int opcode = 0x04; 8 | 9 | private String server; 10 | private String player; 11 | 12 | public RedirectPacket(String server, String player) { 13 | super(opcode); 14 | this.server = server; 15 | this.player = player; 16 | } 17 | 18 | public String getServer() { 19 | return this.server; 20 | } 21 | 22 | public String getPlayer() { 23 | return this.player; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/RedirectPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class RedirectPacketCodec extends PacketCodec { 8 | 9 | public RedirectPacketCodec() { 10 | super(RedirectPacket.opcode); 11 | } 12 | 13 | public RedirectPacket decode(ByteBuf buffer) throws Exception { 14 | String server = BufferUtils.readString(buffer); 15 | String player = BufferUtils.readString(buffer); 16 | return new RedirectPacket(server, player); 17 | } 18 | 19 | public void encode(RedirectPacket packet, ByteBuf buffer) { 20 | BufferUtils.writeString(buffer, packet.getServer()); 21 | BufferUtils.writeString(buffer, packet.getPlayer()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/RequestPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.Packet; 5 | 6 | public class RequestPacket extends Packet { 7 | 8 | public static final int opcode = 0x01; 9 | 10 | private int id; 11 | private int operation; 12 | private ByteBuf payload; 13 | 14 | public RequestPacket(int id, int operation, ByteBuf payload) { 15 | super(opcode); 16 | this.id = id; 17 | this.operation = operation; 18 | this.payload = payload; 19 | } 20 | 21 | public int getId() { 22 | return this.id; 23 | } 24 | 25 | public int getOperation() { 26 | return this.operation; 27 | } 28 | 29 | public ByteBuf getPayload() { 30 | return this.payload; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/RequestPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class RequestPacketCodec extends PacketCodec { 7 | 8 | public RequestPacketCodec() { 9 | super(RequestPacket.opcode); 10 | } 11 | 12 | public RequestPacket decode(ByteBuf buffer) throws Exception { 13 | return new RequestPacket(buffer.readInt(), buffer.readUnsignedByte(), buffer.readBytes(buffer.readUnsignedShort())); 14 | } 15 | 16 | public void encode(RequestPacket packet, ByteBuf buffer) { 17 | buffer.writeInt(packet.getId()); 18 | buffer.writeByte(packet.getOperation()); 19 | ByteBuf payload = packet.getPayload(); 20 | buffer.writeShort(payload.readableBytes()); 21 | buffer.writeBytes(payload, payload.readerIndex(), payload.readableBytes()); 22 | packet.getPayload().release(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/ResultPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.Packet; 5 | import lilypad.packet.connect.ConnectPacketConstants; 6 | 7 | public class ResultPacket extends Packet { 8 | 9 | public static final int opcode = 0x02; 10 | 11 | private int id; 12 | private int statusCode; 13 | private ByteBuf payload; 14 | 15 | public ResultPacket(int id, int statusCode) { 16 | super(opcode); 17 | this.id = id; 18 | this.statusCode = statusCode; 19 | } 20 | 21 | public ResultPacket(int id, ByteBuf payload) { 22 | super(opcode); 23 | this.id = id; 24 | this.statusCode = ConnectPacketConstants.statusSuccess; 25 | this.payload = payload; 26 | } 27 | 28 | public int getId(){ 29 | return this.id; 30 | } 31 | 32 | public int getStatusCode() { 33 | return this.statusCode; 34 | } 35 | 36 | public ByteBuf getPayload() { 37 | return this.payload; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/ResultPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.connect.ConnectPacketConstants; 6 | 7 | public class ResultPacketCodec extends PacketCodec { 8 | 9 | public ResultPacketCodec() { 10 | super(ResultPacket.opcode); 11 | } 12 | 13 | public ResultPacket decode(ByteBuf buffer) throws Exception { 14 | int id = buffer.readInt(); 15 | int statusCode = buffer.readUnsignedByte(); 16 | if(statusCode == ConnectPacketConstants.statusSuccess) { 17 | return new ResultPacket(id, buffer.readBytes(buffer.readUnsignedShort())); 18 | } else { 19 | return new ResultPacket(id, statusCode); 20 | } 21 | } 22 | 23 | public void encode(ResultPacket packet, ByteBuf buffer) { 24 | buffer.writeInt(packet.getId()); 25 | buffer.writeByte(packet.getStatusCode()); 26 | ByteBuf payload = packet.getPayload(); 27 | if(payload != null) { 28 | buffer.writeShort(payload.readableBytes()); 29 | buffer.writeBytes(payload, payload.readerIndex(), payload.readableBytes()); 30 | packet.getPayload().release(); 31 | } else if(packet.getStatusCode() == ConnectPacketConstants.statusSuccess) { 32 | buffer.writeShort(0); 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/ServerAddPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | public class ServerAddPacket extends ServerPacket { 4 | 5 | private String securityKey; 6 | private String address; 7 | private int port; 8 | 9 | public ServerAddPacket(String server, String securityKey, String address, int port) { 10 | super(server); 11 | this.securityKey = securityKey; 12 | this.address = address; 13 | this.port = port; 14 | } 15 | 16 | @Override 17 | public boolean isAdding() { 18 | return true; 19 | } 20 | 21 | public String getSecurityKey() { 22 | return this.securityKey; 23 | } 24 | 25 | public String getAddress() { 26 | return this.address; 27 | } 28 | 29 | public int getPort() { 30 | return this.port; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/ServerPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class ServerPacket extends Packet { 6 | 7 | public static final int opcode = 0x05; 8 | 9 | private String server; 10 | 11 | public ServerPacket(String server) { 12 | super(opcode); 13 | this.server = server; 14 | } 15 | 16 | public boolean isAdding() { 17 | return false; 18 | } 19 | 20 | public String getServer() { 21 | return this.server; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /packet-connect/src/main/java/lilypad/packet/connect/impl/ServerPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.packet.connect.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class ServerPacketCodec extends PacketCodec { 8 | 9 | public ServerPacketCodec() { 10 | super(ServerPacket.opcode); 11 | } 12 | 13 | public ServerPacket decode(ByteBuf buffer) throws Exception { 14 | boolean addOrRemove = buffer.readBoolean(); 15 | String server = BufferUtils.readString(buffer); 16 | if(addOrRemove) { 17 | return new ServerAddPacket(server, BufferUtils.readString(buffer), BufferUtils.readString(buffer), buffer.readUnsignedShort()); 18 | } 19 | return new ServerPacket(server); 20 | } 21 | 22 | public void encode(ServerPacket packet, ByteBuf buffer) { 23 | boolean addOrRemove = packet.isAdding(); 24 | buffer.writeBoolean(addOrRemove); 25 | BufferUtils.writeString(buffer, packet.getServer()); 26 | if(addOrRemove) { 27 | ServerAddPacket addPacket = (ServerAddPacket) packet; 28 | BufferUtils.writeString(buffer, addPacket.getSecurityKey()); 29 | BufferUtils.writeString(buffer, addPacket.getAddress()); 30 | buffer.writeShort(addPacket.getPort()); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /server-common/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IAuthenticator.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | public interface IAuthenticator { 4 | 5 | public boolean authenticate(String username, String password, String authenticationKey); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IPlayable.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.Set; 5 | 6 | public interface IPlayable extends IRedirectable { 7 | 8 | public String getMotd(); 9 | 10 | public InetSocketAddress getBindAddress(); 11 | 12 | public Set getPlayers(); 13 | 14 | public int getPlayerMaximum(); 15 | 16 | public String getVersion(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IPlayerCallback.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | public interface IPlayerCallback { 4 | 5 | public int getPlayerCount(); 6 | 7 | public int getPlayerMaximum(); 8 | 9 | public int notifyPlayerJoin(String playerName); 10 | 11 | public void notifyPlayerLeave(String playerName); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IRedirectable.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | public interface IRedirectable { 4 | 5 | public boolean redirect(String name, IServer server); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IServer.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | public interface IServer { 6 | 7 | public String getIdentification(); 8 | 9 | public InetSocketAddress getInboundAddress(); 10 | 11 | public String getSecurityKey(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/IServerSource.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common; 2 | 3 | public interface IServerSource { 4 | 5 | public IServer getServerByName(String username); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/config/FileConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.config; 2 | 3 | public interface FileConfig { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/config/FileConfigGson.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.config; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.FileWriter; 7 | import java.io.IOException; 8 | 9 | import lilypad.server.common.util.GsonUtils; 10 | 11 | public class FileConfigGson { 12 | 13 | private String name; 14 | private File configFile; 15 | private Class configClass; 16 | 17 | private T config; 18 | 19 | public FileConfigGson(String name, Class configClass) throws InstantiationException, IllegalAccessException, IOException { 20 | this.name = name; 21 | this.configFile = new File(this.name + ".conf"); 22 | this.configFile.createNewFile(); 23 | this.configClass = configClass; 24 | this.config = this.configClass.newInstance(); 25 | } 26 | 27 | public boolean load() { 28 | FileReader fileReader = null; 29 | try { 30 | fileReader = new FileReader(this.configFile); 31 | T config = GsonUtils.prettyGson().fromJson(fileReader, this.configClass); 32 | if(config == null) { 33 | return false; 34 | } 35 | this.config = config; 36 | return true; 37 | } catch (FileNotFoundException exception) { 38 | exception.printStackTrace(); 39 | return false; 40 | } finally { 41 | if(fileReader != null) { 42 | try { 43 | fileReader.close(); 44 | } catch(IOException exception) { 45 | //ignore 46 | } 47 | } 48 | } 49 | } 50 | 51 | public boolean save() { 52 | FileWriter fileWriter = null; 53 | try { 54 | fileWriter = new FileWriter(this.configFile); 55 | GsonUtils.prettyGson().toJson(this.config, fileWriter); 56 | return true; 57 | } catch (IOException exception) { 58 | exception.printStackTrace(); 59 | return false; 60 | } finally { 61 | if(fileWriter != null) { 62 | try { 63 | fileWriter.close(); 64 | } catch (IOException exception) { 65 | //ignore 66 | } 67 | try { 68 | fileWriter.flush(); 69 | } catch (IOException exception) { 70 | //ignore 71 | } 72 | } 73 | } 74 | } 75 | 76 | public T getConfig() { 77 | return this.config; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/config/IConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.config; 2 | 3 | public interface IConfig { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/service/Service.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.service; 2 | 3 | import lilypad.server.common.config.IConfig; 4 | 5 | public abstract class Service { 6 | 7 | public abstract void enable(T config) throws Exception; 8 | 9 | public abstract void disable(); 10 | 11 | public abstract boolean isRunning(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/service/ServiceManager.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.service; 2 | 3 | import java.util.HashSet; 4 | import java.util.Iterator; 5 | import java.util.Set; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | import lilypad.server.common.config.IConfig; 9 | 10 | public class ServiceManager { 11 | 12 | private Set> services = new HashSet>(); 13 | private ReentrantLock servicesLock = new ReentrantLock(); 14 | 15 | public void enableService(Service service, T config) throws Exception { 16 | this.servicesLock.lock(); 17 | try { 18 | service.enable(config); 19 | this.services.add(service); 20 | } catch(Exception exception) { 21 | service.disable(); 22 | throw exception; 23 | } finally { 24 | this.servicesLock.unlock(); 25 | } 26 | } 27 | 28 | public void disableService(Service service) { 29 | this.servicesLock.lock(); 30 | try { 31 | if(service.isRunning()) { 32 | service.disable(); 33 | } 34 | this.services.remove(service); 35 | } finally { 36 | this.servicesLock.unlock(); 37 | } 38 | } 39 | 40 | public void disableAllServices() { 41 | this.servicesLock.lock(); 42 | try { 43 | Iterator> services = this.services.iterator(); 44 | Service service; 45 | while(services.hasNext()) { 46 | service = services.next(); 47 | if(service.isRunning()) { 48 | service.disable(); 49 | } 50 | services.remove(); 51 | } 52 | } finally { 53 | this.servicesLock.unlock(); 54 | } 55 | } 56 | 57 | public boolean hasService(Service service) { 58 | return this.services.contains(service); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/util/GsonUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | 6 | public class GsonUtils { 7 | 8 | private static final Gson gson = new Gson(); 9 | private static final Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); 10 | 11 | public static Gson gson() { 12 | return gson; 13 | } 14 | 15 | public static Gson prettyGson() { 16 | return prettyGson; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/util/SecurityUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.util; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | import java.security.SecureRandom; 6 | 7 | public class SecurityUtils { 8 | 9 | private static final SecureRandom secureRandom = new SecureRandom(); 10 | 11 | public static String randomHash() { 12 | long randomHash; 13 | synchronized(secureRandom) { 14 | randomHash = secureRandom.nextLong() & 0xFFFFFFFF; 15 | } 16 | return Long.toHexString(randomHash); 17 | } 18 | 19 | public static byte[] randomBytes(int size) { 20 | byte[] bytes = new byte[size]; 21 | synchronized(secureRandom) { 22 | secureRandom.nextBytes(bytes); 23 | } 24 | return bytes; 25 | } 26 | 27 | public static int randomInt(int size) { 28 | int i; 29 | synchronized(secureRandom) { 30 | i = secureRandom.nextInt(size); 31 | } 32 | return i; 33 | } 34 | 35 | public static String shaHex(String string) { 36 | return shaHex(string.getBytes()); 37 | } 38 | 39 | public static String shaHex(byte[]... bytesArray) { 40 | try { 41 | MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); 42 | for(byte[] bytes : bytesArray) { 43 | messageDigest.update(bytes); 44 | } 45 | String hash = new BigInteger(1, messageDigest.digest()).toString(16); 46 | if(hash.length() == 39) { 47 | hash = "0" + hash; 48 | } 49 | return hash; 50 | } catch(Exception exception) { 51 | exception.printStackTrace(); 52 | return null; 53 | } 54 | } 55 | 56 | public static String mojangShaHex(String string) { 57 | return mojangShaHex(string.getBytes()); 58 | } 59 | 60 | public static String mojangShaHex(byte[]... bytesArray) { 61 | try { 62 | MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); 63 | for(byte[] bytes : bytesArray) { 64 | messageDigest.update(bytes); 65 | } 66 | return new BigInteger(messageDigest.digest()).toString(16); 67 | } catch(Exception exception) { 68 | exception.printStackTrace(); 69 | return null; 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /server-common/src/main/java/lilypad/server/common/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.common.util; 2 | 3 | public class StringUtils { 4 | 5 | public static String concat(String[] args, String seperator) { 6 | StringBuilder stringBuilder = new StringBuilder(); 7 | for(int i = 0; i < args.length; i++) { 8 | if(i != 0) { 9 | stringBuilder.append(seperator); 10 | } 11 | stringBuilder.append(args[i]); 12 | } 13 | return stringBuilder.toString(); 14 | } 15 | 16 | public static String[] shift(String[] args, int count) { 17 | String[] result = new String[args.length - count]; 18 | for(int i = 0; i < result.length; i++) { 19 | result[i] = args[(i + count)]; 20 | } 21 | return result; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-connect/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-connect/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | lilypad.server 5 | connect 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | Server-Connect 10 | http://www.lilypadmc.org 11 | 12 | 13 | UTF-8 14 | Unknown 15 | 16 | 17 | 18 | 19 | lilypad 20 | http://ci.lilypadmc.org/plugin/repository/everything 21 | 22 | 23 | 24 | 25 | 26 | lilypad.server 27 | common 28 | 0.0.1-SNAPSHOT 29 | 30 | 31 | lilypad.packet 32 | connect 33 | 0.0.1-SNAPSHOT 34 | 35 | 36 | 37 | 38 | ${project.name} 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-compiler-plugin 43 | 2.5.1 44 | 45 | 1.6 46 | 1.6 47 | 48 | 49 | 50 | maven-assembly-plugin 51 | 2.2 52 | 53 | 54 | make-assembly 55 | package 56 | 57 | single 58 | 59 | 60 | 1.6 61 | 1.6 62 | 63 | jar-with-dependencies 64 | 65 | false 66 | 67 | false 68 | 69 | ${name} 70 | ${build.number} 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/ConnectConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import lilypad.server.common.IAuthenticator; 6 | import lilypad.server.common.IPlayable; 7 | import lilypad.server.common.config.IConfig; 8 | 9 | public interface ConnectConfig extends IConfig { 10 | 11 | public InetSocketAddress connect_getBindAddress(); 12 | 13 | public IAuthenticator connect_getAuthenticator(); 14 | 15 | public IPlayable connect_getPlayable(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/node/NodeSessionKeepalive.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.node; 2 | 3 | import java.util.Random; 4 | 5 | public class NodeSessionKeepalive implements Runnable { 6 | 7 | private NodeSessionMapper nodeSessionMapper; 8 | private Thread thread; 9 | 10 | public NodeSessionKeepalive(NodeSessionMapper nodeSessionMapper) { 11 | this.nodeSessionMapper = nodeSessionMapper; 12 | } 13 | 14 | public void start() { 15 | if(this.thread != null) { 16 | return; 17 | } 18 | this.thread = new Thread(this); 19 | this.thread.start(); 20 | } 21 | 22 | public void stop() { 23 | if(this.thread == null) { 24 | return; 25 | } 26 | this.thread.interrupt(); 27 | this.thread = null; 28 | } 29 | 30 | public void run() { 31 | try { 32 | Random random = new Random(); 33 | while(this.thread != null) { 34 | int randomInt; 35 | for(NodeSession nodeSession : this.nodeSessionMapper.getAuthenticated()) { 36 | do { 37 | randomInt = random.nextInt(); 38 | } while(randomInt == 0); 39 | nodeSession.ping(randomInt); 40 | } 41 | Thread.sleep(5000L); 42 | } 43 | } catch(InterruptedException exception) { 44 | // ignore 45 | } catch(Exception exception) { 46 | exception.printStackTrace(); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/node/NodeSessionMapper.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.node; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | public class NodeSessionMapper { 9 | 10 | private Map authenticatedByUsername = new ConcurrentHashMap(); 11 | private Map serversByUsername = new ConcurrentHashMap(); 12 | private Map proxiesByUsername = new ConcurrentHashMap(); 13 | 14 | public void markAuthenticated(NodeSession nodeSession) { 15 | this.authenticatedByUsername.put(nodeSession.getIdentification(), nodeSession); 16 | } 17 | 18 | public NodeSession getAuthenticatedByUsername(String username) { 19 | return this.authenticatedByUsername.get(username); 20 | } 21 | 22 | public Collection getAuthenticated() { 23 | return Collections.unmodifiableCollection(this.authenticatedByUsername.values()); 24 | } 25 | 26 | public void markServer(NodeSession nodeSession) { 27 | this.serversByUsername.put(nodeSession.getIdentification(), nodeSession); 28 | } 29 | 30 | public NodeSession getServerByUsername(String username) { 31 | return this.serversByUsername.get(username); 32 | } 33 | 34 | public Collection getServers() { 35 | return Collections.unmodifiableCollection(this.serversByUsername.values()); 36 | } 37 | 38 | public void markProxy(NodeSession nodeSession) { 39 | this.proxiesByUsername.put(nodeSession.getIdentification(), nodeSession); 40 | } 41 | 42 | public NodeSession getProxyByUsername(String username) { 43 | return this.proxiesByUsername.get(username); 44 | } 45 | 46 | public Collection getProxies() { 47 | return Collections.unmodifiableCollection(this.proxiesByUsername.values()); 48 | } 49 | 50 | public void remove(NodeSession nodeSession) { 51 | this.authenticatedByUsername.remove(nodeSession.getIdentification()); 52 | this.serversByUsername.remove(nodeSession.getIdentification()); 53 | this.proxiesByUsername.remove(nodeSession.getIdentification()); 54 | } 55 | 56 | public void clear() { 57 | this.authenticatedByUsername.clear(); 58 | this.serversByUsername.clear(); 59 | this.proxiesByUsername.clear(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/node/NodeSessionRole.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.node; 2 | 3 | public enum NodeSessionRole { 4 | 5 | UNAUTHENTICATED, 6 | AUTHENTICATED, 7 | SERVER, 8 | PROXY; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/NodeQueryLookupService.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query; 2 | 3 | import lilypad.server.connect.node.NodeSession; 4 | import lilypad.server.connect.query.impl.AsProxyQuery; 5 | import lilypad.server.connect.query.impl.AsServerQuery; 6 | import lilypad.server.connect.query.impl.AuthenticateQuery; 7 | import lilypad.server.connect.query.impl.GetDetailsQuery; 8 | import lilypad.server.connect.query.impl.GetKeyQuery; 9 | import lilypad.server.connect.query.impl.GetPlayersQuery; 10 | import lilypad.server.connect.query.impl.GetWhoamiQuery; 11 | import lilypad.server.connect.query.impl.MessageQuery; 12 | import lilypad.server.connect.query.impl.NotifyPlayer; 13 | import lilypad.server.connect.query.impl.RedirectQuery; 14 | 15 | public class NodeQueryLookupService extends QueryLookupService { 16 | 17 | public static final NodeQueryLookupService instance = new NodeQueryLookupService(); 18 | 19 | private NodeQueryLookupService() { 20 | this.submit(new AsProxyQuery()); 21 | this.submit(new AsServerQuery()); 22 | this.submit(new AuthenticateQuery()); 23 | this.submit(new GetDetailsQuery()); 24 | this.submit(new GetKeyQuery()); 25 | this.submit(new GetPlayersQuery()); 26 | this.submit(new GetWhoamiQuery()); 27 | this.submit(new MessageQuery()); 28 | this.submit(new NotifyPlayer()); 29 | this.submit(new RedirectQuery()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/Query.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query; 2 | 3 | import lilypad.packet.connect.impl.ResultPacket; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.buffer.ByteBufAllocator; 6 | 7 | public interface Query { 8 | 9 | public ResultPacket execute(T sender, int id, ByteBuf in, ByteBufAllocator alloc); 10 | 11 | public int getId(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/QueryLookupService.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query; 2 | 3 | public class QueryLookupService { 4 | 5 | @SuppressWarnings("unchecked") 6 | private Query[] queries = new Query[256]; 7 | 8 | public void submit(Query query) { 9 | this.queries[query.getId()] = query; 10 | } 11 | 12 | public Query getById(int id) { 13 | return this.queries[id]; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/AsProxyQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufAllocator; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | import lilypad.packet.connect.impl.ResultPacket; 10 | import lilypad.server.connect.node.NodeSession; 11 | import lilypad.server.connect.node.NodeSessionRole; 12 | import lilypad.server.connect.query.Query; 13 | 14 | public class AsProxyQuery implements Query { 15 | 16 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 17 | if(sender.getRole() != NodeSessionRole.AUTHENTICATED) { 18 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 19 | } 20 | String inboundIp = BufferUtils.readString(in); 21 | if(inboundIp.length() == 0) { 22 | inboundIp = sender.getAddress().getAddress().getHostAddress(); 23 | } 24 | if(!sender.markProxy(new InetSocketAddress(inboundIp, in.readUnsignedShort()), 25 | BufferUtils.readString(in), 26 | BufferUtils.readString(in), 27 | in.readUnsignedShort())) { 28 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 29 | } 30 | return new ResultPacket(id, ConnectPacketConstants.statusSuccess); 31 | } 32 | 33 | public int getId() { 34 | return ConnectPacketConstants.requestAsProxy; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/AsServerQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufAllocator; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | import lilypad.packet.connect.impl.ResultPacket; 10 | import lilypad.server.connect.node.NodeSession; 11 | import lilypad.server.connect.node.NodeSessionRole; 12 | import lilypad.server.connect.query.Query; 13 | 14 | public class AsServerQuery implements Query { 15 | 16 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 17 | if(sender.getRole() != NodeSessionRole.AUTHENTICATED) { 18 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 19 | } 20 | String ip = BufferUtils.readString(in); 21 | if(ip.length() == 0) { 22 | ip = sender.getAddress().getAddress().getHostAddress(); 23 | } 24 | if(!sender.markServer(new InetSocketAddress(ip, in.readUnsignedShort()))) { 25 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 26 | } 27 | ByteBuf out = alloc.buffer(); 28 | BufferUtils.writeString(out, sender.getSecurityKey()); 29 | return new ResultPacket(id, out); 30 | } 31 | 32 | public int getId() { 33 | return ConnectPacketConstants.requestAsServer; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/AuthenticateQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufAllocator; 5 | import lilypad.packet.common.util.BufferUtils; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | import lilypad.packet.connect.impl.ResultPacket; 8 | import lilypad.server.connect.node.NodeSession; 9 | import lilypad.server.connect.query.Query; 10 | 11 | public class AuthenticateQuery implements Query { 12 | 13 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 14 | if(sender.isAuthenticated()) { 15 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 16 | } 17 | String username = BufferUtils.readString(in); 18 | String password = BufferUtils.readString(in); 19 | if(!sender.getAuthenticator().authenticate(username, password, sender.getAuthenticationKey())) { 20 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 21 | } 22 | sender.markAuthenticated(username); 23 | return new ResultPacket(id, ConnectPacketConstants.statusSuccess); 24 | } 25 | 26 | public int getId() { 27 | return ConnectPacketConstants.requestAuthenticate; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/GetDetailsQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufAllocator; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | import lilypad.packet.connect.impl.ResultPacket; 10 | import lilypad.server.connect.node.NodeSession; 11 | import lilypad.server.connect.query.Query; 12 | 13 | public class GetDetailsQuery implements Query { 14 | 15 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 16 | if(!sender.isAuthenticated()) { 17 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 18 | } 19 | ByteBuf out = alloc.buffer(); 20 | InetSocketAddress bindAddress = sender.getPlayable().getBindAddress(); 21 | BufferUtils.writeString(out, bindAddress.getAddress().getHostAddress()); 22 | out.writeShort(bindAddress.getPort()); 23 | BufferUtils.writeString(out, sender.getPlayable().getMotd()); 24 | BufferUtils.writeString(out, sender.getPlayable().getVersion()); 25 | return new ResultPacket(id, out); 26 | 27 | } 28 | 29 | public int getId() { 30 | return ConnectPacketConstants.requestGetDetails; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/GetKeyQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufAllocator; 5 | import lilypad.packet.common.util.BufferUtils; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | import lilypad.packet.connect.impl.ResultPacket; 8 | import lilypad.server.connect.node.NodeSession; 9 | import lilypad.server.connect.query.Query; 10 | 11 | public class GetKeyQuery implements Query { 12 | 13 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 14 | if(sender.isAuthenticated()) { 15 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 16 | } 17 | ByteBuf out = alloc.buffer(); 18 | BufferUtils.writeString(out, sender.genAuthenticationKey()); 19 | return new ResultPacket(id, out); 20 | } 21 | 22 | public int getId() { 23 | return ConnectPacketConstants.requestGetKey; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/GetPlayersQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import java.util.Set; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufAllocator; 7 | import lilypad.packet.common.util.BufferUtils; 8 | import lilypad.packet.connect.ConnectPacketConstants; 9 | import lilypad.packet.connect.impl.ResultPacket; 10 | import lilypad.server.connect.node.NodeSession; 11 | import lilypad.server.connect.query.Query; 12 | 13 | public class GetPlayersQuery implements Query { 14 | 15 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 16 | if(!sender.isAuthenticated()) { 17 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 18 | } 19 | boolean asList = in.readBoolean(); 20 | Set players = sender.getPlayable().getPlayers(); 21 | ByteBuf out = alloc.buffer(); 22 | out.writeBoolean(asList); 23 | out.writeShort(players.size()); 24 | out.writeShort(sender.getPlayable().getPlayerMaximum()); 25 | if(asList) { 26 | for(String player : players) { 27 | BufferUtils.writeString(out, player); 28 | } 29 | } 30 | return new ResultPacket(id, out); 31 | } 32 | 33 | public int getId() { 34 | return ConnectPacketConstants.requestGetPlayers; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/GetWhoamiQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufAllocator; 5 | import lilypad.packet.common.util.BufferUtils; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | import lilypad.packet.connect.impl.ResultPacket; 8 | import lilypad.server.connect.node.NodeSession; 9 | import lilypad.server.connect.query.Query; 10 | 11 | public class GetWhoamiQuery implements Query { 12 | 13 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 14 | ByteBuf response = alloc.buffer(); 15 | BufferUtils.writeString(response, sender.getIdentification()); 16 | return new ResultPacket(id, response); 17 | } 18 | 19 | public int getId() { 20 | return ConnectPacketConstants.requestGetWhoami; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/MessageQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.buffer.ByteBufAllocator; 8 | import lilypad.packet.common.util.BufferUtils; 9 | import lilypad.packet.connect.ConnectPacketConstants; 10 | import lilypad.packet.connect.impl.MessagePacket; 11 | import lilypad.packet.connect.impl.ResultPacket; 12 | import lilypad.server.connect.node.NodeSession; 13 | import lilypad.server.connect.node.NodeSessionMapper; 14 | import lilypad.server.connect.query.Query; 15 | 16 | public class MessageQuery implements Query { 17 | 18 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 19 | if(!sender.isAuthenticated()) { 20 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 21 | } 22 | int recipientsCount = in.readUnsignedShort(); 23 | Set recipients = new HashSet(); 24 | while(recipientsCount-- != 0) { 25 | recipients.add(BufferUtils.readString(in)); 26 | } 27 | String senderId = sender.getIdentification(); 28 | String channel = BufferUtils.readString(in); 29 | ByteBuf payload = in.readBytes(in.readUnsignedShort()); 30 | boolean messageSent = false; 31 | if(recipients.isEmpty()) { 32 | messageSent = true; 33 | for(NodeSession otherSession : sender.getConnectService().getSessionMapper().getAuthenticated()) { 34 | otherSession.write(new MessagePacket(senderId, channel, payload.copy())); 35 | } 36 | } else { 37 | NodeSession otherSession; 38 | NodeSessionMapper sessionMapper = sender.getConnectService().getSessionMapper(); 39 | for(String recipient : recipients) { 40 | otherSession = sessionMapper.getAuthenticatedByUsername(recipient); 41 | if(otherSession == null) { 42 | continue; 43 | } 44 | otherSession.write(new MessagePacket(senderId, channel, payload.copy())); 45 | messageSent = true; 46 | } 47 | } 48 | if(messageSent) { 49 | return new ResultPacket(id, ConnectPacketConstants.statusSuccess); 50 | } else { 51 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 52 | } 53 | } 54 | 55 | public int getId() { 56 | return ConnectPacketConstants.requestMessage; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/NotifyPlayer.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufAllocator; 5 | import lilypad.packet.common.util.BufferUtils; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | import lilypad.packet.connect.impl.ResultPacket; 8 | import lilypad.server.connect.node.NodeSession; 9 | import lilypad.server.connect.node.NodeSessionRole; 10 | import lilypad.server.connect.query.Query; 11 | 12 | public class NotifyPlayer implements Query { 13 | 14 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 15 | if(sender.getRole() != NodeSessionRole.PROXY) { 16 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 17 | } 18 | boolean addOrRemove = in.readBoolean(); 19 | String player = BufferUtils.readString(in); 20 | if(addOrRemove) { 21 | if(!sender.addPlayer(player)) { 22 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 23 | } 24 | } else { 25 | sender.removePlayer(player); 26 | } 27 | return new ResultPacket(id, ConnectPacketConstants.statusSuccess); 28 | } 29 | 30 | public int getId() { 31 | return ConnectPacketConstants.requestNotifyPlayer; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /server-connect/src/main/java/lilypad/server/connect/query/impl/RedirectQuery.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.connect.query.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.buffer.ByteBufAllocator; 5 | import lilypad.packet.common.util.BufferUtils; 6 | import lilypad.packet.connect.ConnectPacketConstants; 7 | import lilypad.packet.connect.impl.ResultPacket; 8 | import lilypad.server.connect.node.NodeSession; 9 | import lilypad.server.connect.query.Query; 10 | 11 | public class RedirectQuery implements Query { 12 | 13 | public ResultPacket execute(NodeSession sender, int id, ByteBuf in, ByteBufAllocator alloc) { 14 | if(!sender.isAuthenticated()) { 15 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidRole); 16 | } 17 | String serverName = BufferUtils.readString(in); 18 | String playerName = BufferUtils.readString(in); 19 | NodeSession server = sender.getConnectService().getSessionMapper().getServerByUsername(serverName); 20 | if(server == null) { 21 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 22 | } 23 | if(!sender.getPlayable().redirect(playerName, server)) { 24 | return new ResultPacket(id, ConnectPacketConstants.statusInvalidGeneric); 25 | } 26 | return new ResultPacket(id, ConnectPacketConstants.statusSuccess); 27 | } 28 | 29 | public int getId() { 30 | return ConnectPacketConstants.requestRedirect; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server-proxy/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/ProxyConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.security.KeyPair; 5 | import java.util.Map; 6 | 7 | import lilypad.server.common.config.IConfig; 8 | import lilypad.server.common.IPlayerCallback; 9 | import lilypad.server.common.IServerSource; 10 | 11 | public interface ProxyConfig extends IConfig { 12 | 13 | public InetSocketAddress proxy_getBindAddress(); 14 | 15 | public InetSocketAddress proxy_getOutboundAddress(); 16 | 17 | public IPlayerCallback proxy_getPlayerCallback(); 18 | 19 | public KeyPair proxy_getKeyPair(); 20 | 21 | public String proxy_getPlayerMotd(); 22 | 23 | public String proxy_getPlayerFavicon(); 24 | 25 | public int proxy_getPlayerMaximum(); 26 | 27 | public long proxy_getPlayerThrottle(); 28 | 29 | public boolean proxy_isPlayerTab(); 30 | 31 | public boolean proxy_isPlayerAuthenticate(); 32 | 33 | public Map proxy_getDomains(); 34 | 35 | public IServerSource proxy_getServerSource(); 36 | 37 | public String proxy_getLocaleFull(); 38 | 39 | public String proxy_getLocaleOffline(); 40 | 41 | public String proxy_getLocaleLoggedIn(); 42 | 43 | public String proxy_getLocaleLostConn(); 44 | 45 | public String proxy_getLocaleShutdown(); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/LegacyPingDecoder.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net; 2 | 3 | import java.util.List; 4 | 5 | import lilypad.packet.common.VarIntFrameCodec; 6 | import lilypad.server.common.IPlayerCallback; 7 | import lilypad.server.proxy.ProxyConfig; 8 | import lilypad.server.proxy.packet.MinecraftPacketConstants; 9 | import io.netty.buffer.ByteBuf; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.handler.codec.ByteToMessageDecoder; 12 | 13 | public class LegacyPingDecoder extends ByteToMessageDecoder { 14 | 15 | private ProxyConfig config; 16 | private ProxySessionMapper sessionMapper; 17 | 18 | public LegacyPingDecoder(ProxyConfig config, ProxySessionMapper sessionMapper) { 19 | this.config = config; 20 | this.sessionMapper = sessionMapper; 21 | } 22 | 23 | protected void decode(ChannelHandlerContext context, ByteBuf in, List out) throws Exception { 24 | if(!in.isReadable()) { 25 | return; 26 | } 27 | in.markReaderIndex(); 28 | if(in.readUnsignedByte() != 0xFE) { 29 | in.resetReaderIndex(); 30 | context.pipeline().remove(this); 31 | return; 32 | } 33 | in.readerIndex(in.writerIndex()); 34 | in.markReaderIndex(); 35 | context.pipeline().remove(this); 36 | context.pipeline().remove(VarIntFrameCodec.class); 37 | IPlayerCallback playerCallback = this.config.proxy_getPlayerCallback(); 38 | int playerCount; 39 | int playerMaximum; 40 | if(playerCallback != null) { 41 | playerCount = playerCallback.getPlayerCount(); 42 | playerMaximum = playerCallback.getPlayerMaximum(); 43 | } else { 44 | playerCount = this.sessionMapper.getAuthenticatedSize(); 45 | playerMaximum = this.config.proxy_getPlayerMaximum(); 46 | } 47 | ByteBuf buffer = context.alloc().buffer(); 48 | buffer.writeByte(0xFF); 49 | char[] chars = (MinecraftPacketConstants.magic + "1\0" 50 | + MinecraftPacketConstants.protocolVersion + '\0' 51 | + MinecraftPacketConstants.minecraftVersion + '\0' 52 | + MinecraftPacketConstants.colorize(this.config.proxy_getPlayerMotd()) + '\0' 53 | + playerCount + '\0' 54 | + playerMaximum).toCharArray(); 55 | buffer.writeShort(chars.length); 56 | for(char c : chars) { 57 | buffer.writeShort((short) c); 58 | } 59 | context.writeAndFlush(buffer); 60 | context.close(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/ProxySessionMapper.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | import java.util.Set; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | public class ProxySessionMapper { 9 | 10 | private Map authenticatedByUsername = new ConcurrentHashMap(); 11 | 12 | public void markAuthenticated(ProxySession proxySession) { 13 | this.authenticatedByUsername.put(proxySession.getUsername(), proxySession); 14 | } 15 | 16 | public Set getAuthenticatedUsernames() { 17 | return Collections.unmodifiableSet(this.authenticatedByUsername.keySet()); 18 | } 19 | 20 | public boolean hasAuthenticatedByUsername(String string) { 21 | return this.authenticatedByUsername.containsKey(string); 22 | } 23 | 24 | public ProxySession getAuthenticatedByUsername(String string) { 25 | return this.authenticatedByUsername.get(string); 26 | } 27 | 28 | public int getAuthenticatedSize() { 29 | return this.authenticatedByUsername.size(); 30 | } 31 | 32 | public void disconnectAuthenticated(String reason) { 33 | for(ProxySession proxySession : this.authenticatedByUsername.values()) { 34 | proxySession.disconnect(reason); 35 | } 36 | } 37 | 38 | public void remove(ProxySession proxySession) { 39 | this.authenticatedByUsername.remove(proxySession.getUsername()); 40 | } 41 | 42 | public void clear() { 43 | this.authenticatedByUsername.clear(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/ProxyState.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net; 2 | 3 | public enum ProxyState { 4 | 5 | DISCONNECTED, 6 | STATUS, 7 | STATUS_PING, 8 | LOGIN, 9 | LOGIN_ENCRYPT, 10 | VERIFY, 11 | INIT, 12 | CONNECTED; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/http/HttpGetClient.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net.http; 2 | 3 | public interface HttpGetClient { 4 | 5 | public void run(); 6 | 7 | public boolean isRunning(); 8 | 9 | public void close(); 10 | 11 | public void registerListener(HttpGetClientListener listener); 12 | 13 | public void unregisterListener(HttpGetClientListener listener); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/http/HttpGetClientListener.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net.http; 2 | 3 | public interface HttpGetClientListener { 4 | 5 | public void httpResponse(HttpGetClient httpClient, String response); 6 | 7 | public void exceptionCaught(HttpGetClient httpClient, Throwable throwable); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/http/impl/AsyncHttpGetClientHandler.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net.http.impl; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.SimpleChannelInboundHandler; 6 | import io.netty.handler.codec.http.HttpContent; 7 | import io.netty.handler.codec.http.HttpObject; 8 | import io.netty.handler.codec.http.HttpResponse; 9 | import io.netty.handler.codec.http.HttpResponseStatus; 10 | import io.netty.handler.codec.http.LastHttpContent; 11 | import io.netty.util.CharsetUtil; 12 | 13 | public class AsyncHttpGetClientHandler extends SimpleChannelInboundHandler { 14 | 15 | private AsyncHttpGetClient httpGetClient; 16 | private StringBuilder response = new StringBuilder(); 17 | 18 | public AsyncHttpGetClientHandler(AsyncHttpGetClient httpGetClient) { 19 | this.httpGetClient = httpGetClient; 20 | } 21 | 22 | @Override 23 | protected void channelRead0(ChannelHandlerContext context, HttpObject httpObject) throws Exception { 24 | if (httpObject instanceof HttpResponse) { 25 | HttpResponse httpResponse = (HttpResponse) httpObject; 26 | int statusCode = httpResponse.getStatus().code(); 27 | if(statusCode == HttpResponseStatus.NO_CONTENT.code()) { 28 | try { 29 | this.httpGetClient.dispatchHttpResponse(""); 30 | } finally { 31 | context.close(); 32 | } 33 | return; 34 | } 35 | if(statusCode != HttpResponseStatus.OK.code()) { 36 | throw new IllegalStateException("Unexpected status code: " + statusCode); 37 | } 38 | } else if(httpObject instanceof HttpContent) { 39 | HttpContent httpContent = (HttpContent) httpObject; 40 | this.response.append(httpContent.content().toString(CharsetUtil.UTF_8)); 41 | if(httpObject instanceof LastHttpContent) { 42 | try { 43 | this.httpGetClient.dispatchHttpResponse(this.response.toString()); 44 | } finally { 45 | context.close(); 46 | } 47 | } 48 | } 49 | } 50 | 51 | @Override 52 | public void exceptionCaught(ChannelHandlerContext context, Throwable cause) throws Exception { 53 | Channel channel = context.channel(); 54 | if(channel.isOpen()) { 55 | channel.close(); 56 | } 57 | this.httpGetClient.dispatchExceptionCaught(cause); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/net/http/impl/DummyTrustManager.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.net.http.impl; 2 | 3 | import java.security.KeyManagementException; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.security.cert.X509Certificate; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | import javax.net.ssl.SSLContext; 9 | import javax.net.ssl.TrustManager; 10 | import javax.net.ssl.X509TrustManager; 11 | 12 | public class DummyTrustManager implements X509TrustManager { 13 | 14 | private static SSLContext dummySSLContext; 15 | private static ReentrantLock dummySSLContextLock = new ReentrantLock(); 16 | public static final DummyTrustManager instance = new DummyTrustManager(); 17 | 18 | public static SSLContext getDummySSLContext() { 19 | if(dummySSLContext != null) { 20 | return dummySSLContext; 21 | } 22 | dummySSLContextLock.lock(); 23 | try { 24 | if(dummySSLContext == null) { 25 | try { 26 | dummySSLContext = SSLContext.getInstance("TLS"); 27 | } catch (NoSuchAlgorithmException exception) { 28 | exception.printStackTrace(); 29 | return null; 30 | } 31 | try { 32 | dummySSLContext.init(null, new TrustManager[] { instance }, null); 33 | } catch (KeyManagementException exception) { 34 | exception.printStackTrace(); 35 | return null; 36 | } 37 | } 38 | } finally { 39 | dummySSLContextLock.unlock(); 40 | } 41 | return dummySSLContext; 42 | } 43 | 44 | private DummyTrustManager() { 45 | 46 | } 47 | 48 | public X509Certificate[] getAcceptedIssuers() { 49 | return new X509Certificate[0]; 50 | } 51 | 52 | public void checkClientTrusted(X509Certificate[] chain, String authType) { 53 | // blank 54 | } 55 | 56 | public void checkServerTrusted(X509Certificate[] chain, String authType) { 57 | // blank 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/GenericPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.Packet; 5 | 6 | public class GenericPacket extends Packet { 7 | 8 | private ByteBuf buffer; 9 | 10 | public GenericPacket(int opcode, ByteBuf buffer) { 11 | super(opcode); 12 | this.buffer = buffer; 13 | } 14 | 15 | public ByteBuf getBuffer() { 16 | return this.buffer; 17 | } 18 | 19 | public void swapEntityId(int a, int b) { 20 | if(a == b) { 21 | return; 22 | } 23 | int[] entityIdPositions = MinecraftPacketConstants.entityIdPositions[this.getOpcode()]; 24 | if(entityIdPositions != null) { 25 | int id; 26 | for(int position : entityIdPositions) { 27 | id = this.buffer.getInt(position); 28 | if(id == a) { 29 | this.buffer.setInt(position, b); 30 | } else if(id == b) { 31 | this.buffer.setInt(position, a); 32 | } 33 | } 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/GenericPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class GenericPacketCodec extends PacketCodec { 7 | 8 | public GenericPacketCodec(int opcode) { 9 | super(opcode); 10 | } 11 | 12 | public GenericPacket decode(ByteBuf buffer) throws Exception { 13 | return new GenericPacket(super.getOpcode(), buffer.readBytes(buffer.readableBytes())); 14 | } 15 | 16 | public void encode(GenericPacket packet, ByteBuf buffer) { 17 | buffer.writeBytes(packet.getBuffer()); 18 | packet.getBuffer().release(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/MinecraftPacketCodecRegistry.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | import lilypad.packet.common.PacketCodecRegistry; 4 | 5 | public class MinecraftPacketCodecRegistry extends PacketCodecRegistry { 6 | 7 | public MinecraftPacketCodecRegistry() { 8 | for(int i = 0; i < 256; i++) { 9 | super.register(new GenericPacketCodec(i)); 10 | } 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/MinecraftPacketConstants.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | public class MinecraftPacketConstants { 4 | 5 | public static final String minecraftVersion = "1.7.2"; 6 | public static final int protocolVersion = 4; 7 | public static final char magic = 167; 8 | public static final int[][] entityIdPositions = new int[256][]; 9 | static { 10 | entityIdPositions[0x0A] = new int[] {0}; 11 | entityIdPositions[0x0D] = new int[] {4}; 12 | entityIdPositions[0x12] = new int[] {0}; 13 | entityIdPositions[0x1B] = new int[] {0, 4}; 14 | entityIdPositions[0x1C] = new int[] {0}; 15 | entityIdPositions[0x1D] = new int[] {0}; 16 | entityIdPositions[0x1E] = new int[] {0}; 17 | entityIdPositions[0x20] = new int[] {0}; 18 | } 19 | 20 | public static String colorize(String string) { 21 | return string.replace("&n", "\n").replace('&', MinecraftPacketConstants.magic).replace(Character.toString(MinecraftPacketConstants.magic) + Character.toString(MinecraftPacketConstants.magic), "&"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/ProxyPacketCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | import lilypad.packet.common.PacketCodec; 4 | import lilypad.packet.common.PacketCodecProvider; 5 | 6 | public class ProxyPacketCodecProvider implements PacketCodecProvider { 7 | 8 | private PacketCodecProvider provider; 9 | 10 | public ProxyPacketCodecProvider(PacketCodecProvider provider) { 11 | this.provider = provider; 12 | } 13 | 14 | public PacketCodec getByOpcode(int opcode) { 15 | return this.provider.getByOpcode(opcode); 16 | } 17 | 18 | public PacketCodecProvider getProvider() { 19 | return this.provider; 20 | } 21 | 22 | public void setProvider(PacketCodecProvider provider) { 23 | this.provider = provider; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/StatefulPacketCodecProviderPair.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet; 2 | 3 | import io.netty.util.AttributeKey; 4 | import lilypad.packet.common.PacketCodecProvider; 5 | 6 | public class StatefulPacketCodecProviderPair { 7 | 8 | public static AttributeKey attributeKey = new AttributeKey("statuefulPacketCodecProviderPair"); 9 | 10 | public interface StateCodecProvider { 11 | public PacketCodecProvider getClientBound(); 12 | public PacketCodecProvider getServerBound(); 13 | } 14 | 15 | private StateCodecProvider state; 16 | private ProxyPacketCodecProvider clientBound; 17 | private ProxyPacketCodecProvider serverBound; 18 | 19 | public StatefulPacketCodecProviderPair(StateCodecProvider state) { 20 | this.state = state; 21 | this.clientBound = new ProxyPacketCodecProvider(state.getClientBound()); 22 | this.serverBound = new ProxyPacketCodecProvider(state.getServerBound()); 23 | } 24 | 25 | public PacketCodecProvider getClientBound() { 26 | return this.clientBound; 27 | } 28 | 29 | public PacketCodecProvider getServerBound() { 30 | return this.serverBound; 31 | } 32 | 33 | public StateCodecProvider getState() { 34 | return this.state; 35 | } 36 | 37 | public void setState(StateCodecProvider state) { 38 | this.state = state; 39 | this.clientBound.setProvider(state.getClientBound()); 40 | this.serverBound.setProvider(state.getServerBound()); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/HandshakePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class HandshakePacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | private int protocolVersion; 10 | private String serverAddress; 11 | private int serverPort; 12 | private int requestedState; 13 | 14 | public HandshakePacket(int protocolVersion, String serverAddress, int serverPort, int requestedState) { 15 | super(opcode); 16 | this.protocolVersion = protocolVersion; 17 | this.serverAddress = serverAddress; 18 | this.serverPort = serverPort; 19 | this.requestedState = requestedState; 20 | } 21 | 22 | public int getProtocolVersion() { 23 | return this.protocolVersion; 24 | } 25 | 26 | public String getServerAddress() { 27 | return this.serverAddress; 28 | } 29 | 30 | public int getServerPort() { 31 | return this.serverPort; 32 | } 33 | 34 | public int getRequestedState() { 35 | return this.requestedState; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/HandshakePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class HandshakePacketCodec extends PacketCodec { 8 | 9 | public HandshakePacketCodec() { 10 | super(HandshakePacket.opcode); 11 | } 12 | 13 | public HandshakePacket decode(ByteBuf buffer) throws Exception { 14 | return new HandshakePacket(BufferUtils.readVarInt(buffer), BufferUtils.readString(buffer), buffer.readUnsignedShort(), BufferUtils.readVarInt(buffer)); 15 | } 16 | 17 | public void encode(HandshakePacket packet, ByteBuf buffer) { 18 | BufferUtils.writeVarInt(buffer, packet.getProtocolVersion()); 19 | BufferUtils.writeString(buffer, packet.getServerAddress()); 20 | buffer.writeShort(packet.getServerPort()); 21 | BufferUtils.writeVarInt(buffer, packet.getRequestedState()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginDisconnectPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class LoginDisconnectPacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | private String json; 10 | 11 | public LoginDisconnectPacket(String json) { 12 | super(opcode); 13 | this.json = json; 14 | } 15 | 16 | public String getJson() { 17 | return this.json; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginDisconnectPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class LoginDisconnectPacketCodec extends PacketCodec { 8 | 9 | public LoginDisconnectPacketCodec() { 10 | super(LoginDisconnectPacket.opcode); 11 | } 12 | 13 | public LoginDisconnectPacket decode(ByteBuf buffer) throws Exception { 14 | return new LoginDisconnectPacket(BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(LoginDisconnectPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getJson()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginEncryptRequestPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import java.security.PublicKey; 4 | 5 | import lilypad.packet.common.Packet; 6 | 7 | public class LoginEncryptRequestPacket extends Packet { 8 | 9 | public static final int opcode = 0x01; 10 | 11 | private String serverId; 12 | private PublicKey publicKey; 13 | private byte[] verifyToken; 14 | 15 | public LoginEncryptRequestPacket(String serverId, PublicKey publicKey, byte[] verifyToken) { 16 | super(opcode); 17 | this.serverId = serverId; 18 | this.publicKey = publicKey; 19 | this.verifyToken = verifyToken; 20 | } 21 | 22 | public String getServerId() { 23 | return this.serverId; 24 | } 25 | 26 | public PublicKey getPublicKey() { 27 | return this.publicKey; 28 | } 29 | 30 | public byte[] getVerifyToken() { 31 | return this.verifyToken; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginEncryptRequestPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import java.security.PublicKey; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import lilypad.packet.common.PacketCodec; 7 | import lilypad.packet.common.util.BufferUtils; 8 | 9 | public class LoginEncryptRequestPacketCodec extends PacketCodec { 10 | 11 | public LoginEncryptRequestPacketCodec() { 12 | super(LoginEncryptRequestPacket.opcode); 13 | } 14 | 15 | public LoginEncryptRequestPacket decode(ByteBuf buffer) throws Exception { 16 | String serverId = BufferUtils.readString(buffer); 17 | PublicKey publicKey = BufferUtils.readPublicKey(buffer); 18 | byte[] verifyToken = new byte[buffer.readUnsignedShort()]; 19 | buffer.readBytes(verifyToken); 20 | return new LoginEncryptRequestPacket(serverId, publicKey, verifyToken); 21 | } 22 | 23 | public void encode(LoginEncryptRequestPacket packet, ByteBuf buffer) { 24 | BufferUtils.writeString(buffer, packet.getServerId()); 25 | BufferUtils.writePublicKey(buffer, packet.getPublicKey()); 26 | buffer.writeShort(packet.getVerifyToken().length); 27 | buffer.writeBytes(packet.getVerifyToken()); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginEncryptResponsePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class LoginEncryptResponsePacket extends Packet { 6 | 7 | public static final int opcode = 0x01; 8 | 9 | private byte[] sharedSecret; 10 | private byte[] verifyToken; 11 | 12 | public LoginEncryptResponsePacket(byte[] sharedSecret, byte[] verifyToken) { 13 | super(opcode); 14 | this.sharedSecret = sharedSecret; 15 | this.verifyToken = verifyToken; 16 | } 17 | 18 | public byte[] getSharedSecret() { 19 | return this.sharedSecret; 20 | } 21 | 22 | public byte[] getVerifyToken() { 23 | return this.verifyToken; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginEncryptResponsePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class LoginEncryptResponsePacketCodec extends PacketCodec { 7 | 8 | public LoginEncryptResponsePacketCodec() { 9 | super(LoginEncryptResponsePacket.opcode); 10 | } 11 | 12 | public LoginEncryptResponsePacket decode(ByteBuf buffer) throws Exception { 13 | byte[] sharedSecret = new byte[buffer.readUnsignedShort()]; 14 | buffer.readBytes(sharedSecret); 15 | byte[] verifyToken = new byte[buffer.readUnsignedShort()]; 16 | buffer.readBytes(verifyToken); 17 | return new LoginEncryptResponsePacket(sharedSecret, verifyToken); 18 | } 19 | 20 | public void encode(LoginEncryptResponsePacket packet, ByteBuf buffer) { 21 | buffer.writeShort(packet.getSharedSecret().length); 22 | buffer.writeBytes(packet.getSharedSecret()); 23 | buffer.writeShort(packet.getVerifyToken().length); 24 | buffer.writeBytes(packet.getVerifyToken()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginStartPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class LoginStartPacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | private String name; 10 | 11 | public LoginStartPacket(String name) { 12 | super(opcode); 13 | this.name = name; 14 | } 15 | 16 | public String getName() { 17 | return this.name; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginStartPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class LoginStartPacketCodec extends PacketCodec { 8 | 9 | public LoginStartPacketCodec() { 10 | super(LoginStartPacket.opcode); 11 | } 12 | 13 | public LoginStartPacket decode(ByteBuf buffer) throws Exception { 14 | return new LoginStartPacket(BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(LoginStartPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getName()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginSuccessPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class LoginSuccessPacket extends Packet { 6 | 7 | public static final int opcode = 0x02; 8 | 9 | private String uuid; 10 | private String username; 11 | 12 | public LoginSuccessPacket(String uuid, String username) { 13 | super(opcode); 14 | this.uuid = uuid; 15 | this.username = username; 16 | } 17 | 18 | public String getUuid() { 19 | return this.uuid; 20 | } 21 | 22 | public String getUsername() { 23 | return this.username; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/LoginSuccessPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class LoginSuccessPacketCodec extends PacketCodec { 8 | 9 | public LoginSuccessPacketCodec() { 10 | super(LoginSuccessPacket.opcode); 11 | } 12 | 13 | public LoginSuccessPacket decode(ByteBuf buffer) throws Exception { 14 | return new LoginSuccessPacket(BufferUtils.readString(buffer), BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(LoginSuccessPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getUuid()); 19 | BufferUtils.writeString(buffer, packet.getUsername()); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayClientSettingsPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayClientSettingsPacket extends Packet { 6 | 7 | public static final int opcode = 0x15; 8 | 9 | private String locale; 10 | private byte viewDistance; 11 | private byte chatFlags; 12 | private boolean unused; 13 | private byte difficulty; 14 | private boolean showCape; 15 | 16 | public PlayClientSettingsPacket(String locale, byte viewDistance, byte chatFlags, boolean unused, byte difficulty, boolean showCape) { 17 | super(opcode); 18 | this.locale = locale; 19 | this.viewDistance = viewDistance; 20 | this.chatFlags = chatFlags; 21 | this.unused = unused; 22 | this.difficulty = difficulty; 23 | this.showCape = showCape; 24 | } 25 | 26 | public String getLocale() { 27 | return this.locale; 28 | } 29 | 30 | public byte getViewDistance() { 31 | return this.viewDistance; 32 | } 33 | 34 | public byte getChatFlags() { 35 | return this.chatFlags; 36 | } 37 | 38 | public boolean isUnused() { 39 | return this.unused; 40 | } 41 | 42 | public byte getDifficulty() { 43 | return this.difficulty; 44 | } 45 | 46 | public boolean isShowCape() { 47 | return this.showCape; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayClientSettingsPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayClientSettingsPacketCodec extends PacketCodec { 8 | 9 | public PlayClientSettingsPacketCodec() { 10 | super(PlayClientSettingsPacket.opcode); 11 | } 12 | 13 | public PlayClientSettingsPacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayClientSettingsPacket(BufferUtils.readString(buffer), buffer.readByte(), buffer.readByte(), buffer.readBoolean(), buffer.readByte(), buffer.readBoolean()); 15 | } 16 | 17 | public void encode(PlayClientSettingsPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getLocale()); 19 | buffer.writeByte(packet.getViewDistance()); 20 | buffer.writeByte(packet.getChatFlags()); 21 | buffer.writeBoolean(packet.isUnused()); 22 | buffer.writeByte(packet.getDifficulty()); 23 | buffer.writeBoolean(packet.isShowCape()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayDisconnectPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayDisconnectPacket extends Packet { 6 | 7 | public static final int opcode = 0x40; 8 | 9 | private String json; 10 | 11 | public PlayDisconnectPacket(String json) { 12 | super(opcode); 13 | this.json = json; 14 | } 15 | 16 | public String getJson() { 17 | return this.json; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayDisconnectPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayDisconnectPacketCodec extends PacketCodec { 8 | 9 | public PlayDisconnectPacketCodec() { 10 | super(PlayDisconnectPacket.opcode); 11 | } 12 | 13 | public PlayDisconnectPacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayDisconnectPacket(BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(PlayDisconnectPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getJson()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayJoinGamePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayJoinGamePacket extends Packet { 6 | 7 | public static final int opcode = 0x01; 8 | 9 | private int entityId; 10 | private int gamemode; 11 | private int dimension; 12 | private int difficulty; 13 | private int maxPlayers; 14 | private String levelType; 15 | 16 | public PlayJoinGamePacket(int entityId, int gamemode, int dimension, int difficulty, int maxPlayers, String levelType) { 17 | super(opcode); 18 | this.entityId = entityId; 19 | this.gamemode = gamemode; 20 | this.dimension = dimension; 21 | this.difficulty = difficulty; 22 | this.maxPlayers = maxPlayers; 23 | this.levelType = levelType; 24 | } 25 | 26 | public int getEntityId() { 27 | return this.entityId; 28 | } 29 | 30 | public int getGamemode() { 31 | return this.gamemode; 32 | } 33 | 34 | public int getDimension() { 35 | return this.dimension; 36 | } 37 | 38 | public int getDifficulty() { 39 | return this.difficulty; 40 | } 41 | 42 | public int getMaxPlayers() { 43 | return this.maxPlayers; 44 | } 45 | 46 | public void setMaxPlayers(int maxPlayers) { 47 | this.maxPlayers = maxPlayers; 48 | } 49 | 50 | public String getLevelType() { 51 | return this.levelType; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayJoinGamePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayJoinGamePacketCodec extends PacketCodec { 8 | 9 | public PlayJoinGamePacketCodec() { 10 | super(PlayJoinGamePacket.opcode); 11 | } 12 | 13 | public PlayJoinGamePacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayJoinGamePacket(buffer.readInt(), buffer.readUnsignedByte(), buffer.readByte(), buffer.readUnsignedByte(), buffer.readUnsignedByte(), BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(PlayJoinGamePacket packet, ByteBuf buffer) { 18 | buffer.writeInt(packet.getEntityId()); 19 | buffer.writeByte(packet.getGamemode()); 20 | buffer.writeByte(packet.getDimension()); 21 | buffer.writeByte(packet.getDifficulty()); 22 | buffer.writeByte(packet.getMaxPlayers()); 23 | BufferUtils.writeString(buffer, packet.getLevelType()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayPlayerListPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayPlayerListPacket extends Packet { 6 | 7 | public static final int opcode = 0x38; 8 | 9 | private String name; 10 | private boolean online; 11 | private int ping; 12 | 13 | public PlayPlayerListPacket(String name, boolean online, int ping) { 14 | super(opcode); 15 | this.name = name; 16 | this.online = online; 17 | this.ping = ping; 18 | } 19 | 20 | public String getName() { 21 | return this.name; 22 | } 23 | 24 | public boolean isOnline() { 25 | return this.online; 26 | } 27 | 28 | public int getPing() { 29 | return this.ping; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayPlayerListPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayPlayerListPacketCodec extends PacketCodec { 8 | 9 | public PlayPlayerListPacketCodec() { 10 | super(PlayPlayerListPacket.opcode); 11 | } 12 | 13 | public PlayPlayerListPacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayPlayerListPacket(BufferUtils.readString(buffer), buffer.readBoolean(), buffer.readShort()); 15 | } 16 | 17 | public void encode(PlayPlayerListPacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getName()); 19 | buffer.writeBoolean(packet.isOnline()); 20 | buffer.writeShort(packet.getPing()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayRespawnPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayRespawnPacket extends Packet { 6 | 7 | public static final int opcode = 0x07; 8 | 9 | private int dimension; 10 | private int difficulty; 11 | private int gamemode; 12 | private String levelType; 13 | 14 | public PlayRespawnPacket(int dimension, int difficulty, int gamemode, String levelType) { 15 | super(opcode); 16 | this.dimension = dimension; 17 | this.difficulty = difficulty; 18 | this.gamemode = gamemode; 19 | this.levelType = levelType; 20 | } 21 | 22 | public int getDimension() { 23 | return this.dimension; 24 | } 25 | 26 | public int getDifficulty() { 27 | return this.difficulty; 28 | } 29 | 30 | public int getGamemode() { 31 | return this.gamemode; 32 | } 33 | 34 | public String getLevelType() { 35 | return this.levelType; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayRespawnPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayRespawnPacketCodec extends PacketCodec { 8 | 9 | public PlayRespawnPacketCodec() { 10 | super(PlayRespawnPacket.opcode); 11 | } 12 | 13 | public PlayRespawnPacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayRespawnPacket(buffer.readInt(), buffer.readUnsignedByte(), buffer.readUnsignedByte(), BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(PlayRespawnPacket packet, ByteBuf buffer) { 18 | buffer.writeInt(packet.getDimension()); 19 | buffer.writeByte(packet.getDifficulty()); 20 | buffer.writeByte(packet.getGamemode()); 21 | BufferUtils.writeString(buffer, packet.getLevelType()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayScoreObjectivePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayScoreObjectivePacket extends Packet { 6 | 7 | public static final int opcode = 0x3B; 8 | 9 | private String name; 10 | private String value; 11 | private int action; 12 | 13 | public PlayScoreObjectivePacket(String name, String value, int action) { 14 | super(opcode); 15 | this.name = name; 16 | this.value = value; 17 | this.action = action; 18 | } 19 | 20 | public String getName() { 21 | return this.name; 22 | } 23 | 24 | public String getValue() { 25 | return this.value; 26 | } 27 | 28 | public int getAction() { 29 | return this.action; 30 | } 31 | 32 | public boolean isCreating() { 33 | return this.action == 0; 34 | } 35 | 36 | public boolean isRemoving() { 37 | return this.action == 1; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayScoreObjectivePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayScoreObjectivePacketCodec extends PacketCodec { 8 | 9 | public PlayScoreObjectivePacketCodec() { 10 | super(PlayScoreObjectivePacket.opcode); 11 | } 12 | 13 | public PlayScoreObjectivePacket decode(ByteBuf buffer) throws Exception { 14 | return new PlayScoreObjectivePacket(BufferUtils.readString(buffer), BufferUtils.readString(buffer), buffer.readByte()); 15 | } 16 | 17 | public void encode(PlayScoreObjectivePacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getName()); 19 | BufferUtils.writeString(buffer, packet.getValue()); 20 | buffer.writeByte(packet.getAction()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayTeamPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class PlayTeamPacket extends Packet { 6 | 7 | public static final int opcode = 0x3E; 8 | 9 | private String name; 10 | private int mode; 11 | private String displayName; 12 | private String prefix; 13 | private String suffix; 14 | private int friendlyFire; 15 | private String[] players; 16 | 17 | public PlayTeamPacket(String name, int mode, String displayName, String prefix, String suffix, int friendlyFire, String[] players) { 18 | super(opcode); 19 | this.name = name; 20 | this.mode = mode; 21 | this.displayName = displayName; 22 | this.prefix = prefix; 23 | this.suffix = suffix; 24 | this.friendlyFire = friendlyFire; 25 | this.players = players; 26 | } 27 | 28 | public String getName() { 29 | return this.name; 30 | } 31 | 32 | public int getMode() { 33 | return this.mode; 34 | } 35 | 36 | public boolean isCreating() { 37 | return this.mode == 0; 38 | } 39 | 40 | public boolean isRemoving() { 41 | return this.mode == 1; 42 | } 43 | 44 | public String getDisplayName() { 45 | return this.displayName; 46 | } 47 | 48 | public String getPrefix() { 49 | return this.prefix; 50 | } 51 | 52 | public String getSuffix() { 53 | return this.suffix; 54 | } 55 | 56 | public int getFriendlyFire() { 57 | return this.friendlyFire; 58 | } 59 | 60 | public String[] getPlayers() { 61 | return this.players; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/PlayTeamPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class PlayTeamPacketCodec extends PacketCodec { 8 | 9 | public PlayTeamPacketCodec() { 10 | super(PlayTeamPacket.opcode); 11 | } 12 | 13 | public PlayTeamPacket decode(ByteBuf buffer) throws Exception { 14 | String name = BufferUtils.readString(buffer); 15 | int mode = buffer.readByte(); 16 | String displayName = null; 17 | String prefix = null; 18 | String suffix = null; 19 | int friendlyFire = 0; 20 | if(mode == 0 || mode == 2) { 21 | displayName = BufferUtils.readString(buffer); 22 | prefix = BufferUtils.readString(buffer); 23 | suffix = BufferUtils.readString(buffer); 24 | friendlyFire = buffer.readByte(); 25 | } 26 | String[] players = null; 27 | if(mode == 0 || mode == 3 || mode == 4) { 28 | players = new String[buffer.readShort()]; 29 | for(int i = 0; i < players.length; i++) { 30 | players[i] = BufferUtils.readString(buffer); 31 | } 32 | } 33 | return new PlayTeamPacket(name, mode, displayName, prefix, suffix, friendlyFire, players); 34 | } 35 | 36 | public void encode(PlayTeamPacket packet, ByteBuf buffer) { 37 | BufferUtils.writeString(buffer, packet.getName()); 38 | int mode = packet.getMode(); 39 | buffer.writeByte(mode); 40 | if(mode == 0 || mode == 2) { 41 | BufferUtils.writeString(buffer, packet.getDisplayName()); 42 | BufferUtils.writeString(buffer, packet.getPrefix()); 43 | BufferUtils.writeString(buffer, packet.getSuffix()); 44 | buffer.writeByte(packet.getFriendlyFire()); 45 | } 46 | if(mode == 0 || mode == 3 || mode == 4) { 47 | String[] players = packet.getPlayers(); 48 | buffer.writeShort(players.length); 49 | for(String player : players) { 50 | BufferUtils.writeString(buffer, player); 51 | } 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusPingPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class StatusPingPacket extends Packet { 6 | 7 | public static final int opcode = 0x01; 8 | 9 | private long time; 10 | 11 | public StatusPingPacket(long time) { 12 | super(opcode); 13 | this.time = time; 14 | } 15 | 16 | public long getTime() { 17 | return this.time; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusPingPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class StatusPingPacketCodec extends PacketCodec { 7 | 8 | public StatusPingPacketCodec() { 9 | super(StatusPingPacket.opcode); 10 | } 11 | 12 | public StatusPingPacket decode(ByteBuf buffer) throws Exception { 13 | return new StatusPingPacket(buffer.readLong()); 14 | } 15 | 16 | public void encode(StatusPingPacket packet, ByteBuf buffer) { 17 | buffer.writeLong(packet.getTime()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusRequestPacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class StatusRequestPacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | public StatusRequestPacket() { 10 | super(opcode); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusRequestPacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | 6 | public class StatusRequestPacketCodec extends PacketCodec { 7 | 8 | public StatusRequestPacketCodec() { 9 | super(StatusRequestPacket.opcode); 10 | } 11 | 12 | public StatusRequestPacket decode(ByteBuf buffer) throws Exception { 13 | return new StatusRequestPacket(); 14 | } 15 | 16 | public void encode(StatusRequestPacket packet, ByteBuf buffer) { 17 | // no payload 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusResponsePacket.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import lilypad.packet.common.Packet; 4 | 5 | public class StatusResponsePacket extends Packet { 6 | 7 | public static final int opcode = 0x00; 8 | 9 | private String json; 10 | 11 | public StatusResponsePacket(String json) { 12 | super(opcode); 13 | this.json = json; 14 | } 15 | 16 | public String getJson() { 17 | return this.json; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/impl/StatusResponsePacketCodec.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.impl; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import lilypad.packet.common.PacketCodec; 5 | import lilypad.packet.common.util.BufferUtils; 6 | 7 | public class StatusResponsePacketCodec extends PacketCodec { 8 | 9 | public StatusResponsePacketCodec() { 10 | super(StatusResponsePacket.opcode); 11 | } 12 | 13 | public StatusResponsePacket decode(ByteBuf buffer) throws Exception { 14 | return new StatusResponsePacket(BufferUtils.readString(buffer)); 15 | } 16 | 17 | public void encode(StatusResponsePacket packet, ByteBuf buffer) { 18 | BufferUtils.writeString(buffer, packet.getJson()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/state/HandshakeStateCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.state; 2 | 3 | import lilypad.packet.common.PacketCodecProvider; 4 | import lilypad.server.proxy.packet.MinecraftPacketCodecRegistry; 5 | import lilypad.server.proxy.packet.StatefulPacketCodecProviderPair.StateCodecProvider; 6 | import lilypad.server.proxy.packet.impl.HandshakePacketCodec; 7 | 8 | public class HandshakeStateCodecProvider implements StateCodecProvider { 9 | 10 | public static final HandshakeStateCodecProvider instance = new HandshakeStateCodecProvider(); 11 | 12 | private MinecraftPacketCodecRegistry clientBound = new MinecraftPacketCodecRegistry(); 13 | private MinecraftPacketCodecRegistry serverBound = new MinecraftPacketCodecRegistry(); 14 | 15 | private HandshakeStateCodecProvider() { 16 | this.serverBound.register(new HandshakePacketCodec()); 17 | } 18 | 19 | public PacketCodecProvider getClientBound() { 20 | return this.clientBound; 21 | } 22 | 23 | public PacketCodecProvider getServerBound() { 24 | return this.serverBound; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/state/LoginStateCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.state; 2 | 3 | import lilypad.packet.common.PacketCodecProvider; 4 | import lilypad.server.proxy.packet.MinecraftPacketCodecRegistry; 5 | import lilypad.server.proxy.packet.StatefulPacketCodecProviderPair.StateCodecProvider; 6 | import lilypad.server.proxy.packet.impl.LoginDisconnectPacketCodec; 7 | import lilypad.server.proxy.packet.impl.LoginEncryptRequestPacketCodec; 8 | import lilypad.server.proxy.packet.impl.LoginEncryptResponsePacketCodec; 9 | import lilypad.server.proxy.packet.impl.LoginStartPacketCodec; 10 | import lilypad.server.proxy.packet.impl.LoginSuccessPacketCodec; 11 | 12 | public class LoginStateCodecProvider implements StateCodecProvider { 13 | 14 | public static final LoginStateCodecProvider instance = new LoginStateCodecProvider(); 15 | 16 | private MinecraftPacketCodecRegistry clientBound = new MinecraftPacketCodecRegistry(); 17 | private MinecraftPacketCodecRegistry serverBound = new MinecraftPacketCodecRegistry(); 18 | 19 | private LoginStateCodecProvider() { 20 | this.clientBound.register(new LoginDisconnectPacketCodec()); 21 | this.clientBound.register(new LoginEncryptRequestPacketCodec()); 22 | this.clientBound.register(new LoginSuccessPacketCodec()); 23 | this.serverBound.register(new LoginStartPacketCodec()); 24 | this.serverBound.register(new LoginEncryptResponsePacketCodec()); 25 | } 26 | 27 | public PacketCodecProvider getClientBound() { 28 | return this.clientBound; 29 | } 30 | 31 | public PacketCodecProvider getServerBound() { 32 | return this.serverBound; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/state/PlayStateCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.state; 2 | 3 | import lilypad.packet.common.PacketCodecProvider; 4 | import lilypad.server.proxy.packet.MinecraftPacketCodecRegistry; 5 | import lilypad.server.proxy.packet.StatefulPacketCodecProviderPair.StateCodecProvider; 6 | import lilypad.server.proxy.packet.impl.PlayClientSettingsPacketCodec; 7 | import lilypad.server.proxy.packet.impl.PlayDisconnectPacketCodec; 8 | import lilypad.server.proxy.packet.impl.PlayJoinGamePacketCodec; 9 | import lilypad.server.proxy.packet.impl.PlayPlayerListPacketCodec; 10 | import lilypad.server.proxy.packet.impl.PlayRespawnPacketCodec; 11 | import lilypad.server.proxy.packet.impl.PlayScoreObjectivePacketCodec; 12 | import lilypad.server.proxy.packet.impl.PlayTeamPacketCodec; 13 | 14 | public class PlayStateCodecProvider implements StateCodecProvider { 15 | 16 | public static final PlayStateCodecProvider instance = new PlayStateCodecProvider(); 17 | 18 | private MinecraftPacketCodecRegistry clientBound = new MinecraftPacketCodecRegistry(); 19 | private MinecraftPacketCodecRegistry serverBound = new MinecraftPacketCodecRegistry(); 20 | 21 | private PlayStateCodecProvider() { 22 | this.clientBound.register(new PlayDisconnectPacketCodec()); 23 | this.clientBound.register(new PlayJoinGamePacketCodec()); 24 | this.clientBound.register(new PlayRespawnPacketCodec()); 25 | this.clientBound.register(new PlayPlayerListPacketCodec()); 26 | this.clientBound.register(new PlayScoreObjectivePacketCodec()); 27 | this.clientBound.register(new PlayTeamPacketCodec()); 28 | this.serverBound.register(new PlayClientSettingsPacketCodec()); 29 | } 30 | 31 | public PacketCodecProvider getClientBound() { 32 | return this.clientBound; 33 | } 34 | 35 | public PacketCodecProvider getServerBound() { 36 | return this.serverBound; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/packet/state/StatusStateCodecProvider.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.packet.state; 2 | 3 | import lilypad.packet.common.PacketCodecProvider; 4 | import lilypad.server.proxy.packet.MinecraftPacketCodecRegistry; 5 | import lilypad.server.proxy.packet.StatefulPacketCodecProviderPair.StateCodecProvider; 6 | import lilypad.server.proxy.packet.impl.StatusPingPacketCodec; 7 | import lilypad.server.proxy.packet.impl.StatusRequestPacketCodec; 8 | import lilypad.server.proxy.packet.impl.StatusResponsePacketCodec; 9 | 10 | public class StatusStateCodecProvider implements StateCodecProvider { 11 | 12 | public static final StatusStateCodecProvider instance = new StatusStateCodecProvider(); 13 | 14 | private MinecraftPacketCodecRegistry clientBound = new MinecraftPacketCodecRegistry(); 15 | private MinecraftPacketCodecRegistry serverBound = new MinecraftPacketCodecRegistry(); 16 | 17 | private StatusStateCodecProvider() { 18 | this.clientBound.register(new StatusPingPacketCodec()); 19 | this.clientBound.register(new StatusResponsePacketCodec()); 20 | this.serverBound.register(new StatusPingPacketCodec()); 21 | this.serverBound.register(new StatusRequestPacketCodec()); 22 | } 23 | 24 | public PacketCodecProvider getClientBound() { 25 | return this.clientBound; 26 | } 27 | 28 | public PacketCodecProvider getServerBound() { 29 | return this.serverBound; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/util/CipherUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.util; 2 | 3 | import java.security.KeyPair; 4 | import java.security.KeyPairGenerator; 5 | import java.security.Security; 6 | 7 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 8 | 9 | public class CipherUtils { 10 | 11 | static { 12 | Security.addProvider(new BouncyCastleProvider()); 13 | } 14 | 15 | public static KeyPair generateRSAKeyPair(int size) { 16 | try { 17 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 18 | keyPairGenerator.initialize(size); 19 | return keyPairGenerator.genKeyPair(); 20 | } catch(Exception exception) { 21 | exception.printStackTrace(); 22 | return null; 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /server-proxy/src/main/java/lilypad/server/proxy/util/MinecraftUtils.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.proxy.util; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URI; 5 | import java.net.URISyntaxException; 6 | import java.net.URLEncoder; 7 | 8 | public class MinecraftUtils { 9 | 10 | public static URI getSessionURI(String username, String serverKey, boolean ssl) { 11 | if(username == null || serverKey == null) { 12 | return null; 13 | } 14 | try { 15 | return new URI((ssl ? "https" : "http") + "://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + URLEncoder.encode(username, "UTF-8") + "&serverId=" + URLEncoder.encode(serverKey, "UTF-8")); 16 | } catch(UnsupportedEncodingException exception) { 17 | exception.printStackTrace(); 18 | } catch(URISyntaxException exception) { 19 | exception.printStackTrace(); 20 | } 21 | return null; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-query/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | lilypad.server 5 | query 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | Server-Query 10 | http://www.lilypadmc.org 11 | 12 | 13 | UTF-8 14 | Unknown 15 | 16 | 17 | 18 | 19 | lilypad 20 | http://ci.lilypadmc.org/plugin/repository/everything 21 | 22 | 23 | 24 | 25 | 26 | lilypad.server 27 | common 28 | 0.0.1-SNAPSHOT 29 | 30 | 31 | 32 | 33 | ${project.name} 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-compiler-plugin 38 | 2.5.1 39 | 40 | 1.6 41 | 1.6 42 | 43 | 44 | 45 | maven-assembly-plugin 46 | 2.2 47 | 48 | 49 | make-assembly 50 | package 51 | 52 | single 53 | 54 | 55 | 1.6 56 | 1.6 57 | 58 | jar-with-dependencies 59 | 60 | false 61 | 62 | false 63 | 64 | ${name} 65 | ${build.number} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /server-query/src/main/java/lilypad/server/query/tcp/QueryTcpConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.query.tcp; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import lilypad.server.common.config.IConfig; 6 | import lilypad.server.common.IPlayable; 7 | 8 | public interface QueryTcpConfig extends IConfig { 9 | 10 | public InetSocketAddress querytcp_getBindAddress(); 11 | 12 | public IPlayable querytcp_getPlayable(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /server-query/src/main/java/lilypad/server/query/tcp/net/GsonResponse.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.query.tcp.net; 2 | 3 | import java.util.Set; 4 | 5 | import lilypad.server.common.util.GsonUtils; 6 | 7 | import com.google.gson.Gson; 8 | 9 | @SuppressWarnings("unused") 10 | public class GsonResponse { 11 | 12 | private int serverPort; 13 | private int playerCount; 14 | private int maxPlayers; 15 | private Set playerList; 16 | 17 | public GsonResponse(int serverPort, int maxPlayers, Set players) { 18 | this.serverPort = serverPort; 19 | this.playerCount = players.size(); 20 | this.maxPlayers = maxPlayers; 21 | this.playerList = players; 22 | } 23 | 24 | public String toGson() { 25 | return GsonUtils.gson().toJson(this); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /server-query/src/main/java/lilypad/server/query/udp/QueryUdpConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.query.udp; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import lilypad.server.common.IPlayable; 6 | import lilypad.server.common.config.IConfig; 7 | 8 | public interface QueryUdpConfig extends IConfig { 9 | 10 | public InetSocketAddress queryudp_getBindAddress(); 11 | 12 | public IPlayable queryudp_getPlayable(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /server-query/src/main/java/lilypad/server/query/udp/QueryUdpService.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.query.udp; 2 | 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.nio.NioEventLoopGroup; 5 | import io.netty.channel.socket.nio.NioDatagramChannel; 6 | import lilypad.server.query.udp.net.QueryUdpHandler; 7 | import lilypad.server.common.service.Service; 8 | 9 | public class QueryUdpService extends Service { 10 | 11 | private NioEventLoopGroup eventGroup; 12 | private boolean running; 13 | 14 | public void enable(QueryUdpConfig config) throws Exception { 15 | Bootstrap bootstrap = new Bootstrap().group(this.eventGroup = new NioEventLoopGroup()) 16 | .channel(NioDatagramChannel.class) 17 | .localAddress(config.queryudp_getBindAddress()) 18 | .handler(new QueryUdpHandler(config.queryudp_getPlayable())); 19 | bootstrap.bind().sync(); 20 | this.running = true; 21 | } 22 | 23 | public void disable() { 24 | try { 25 | if (this.eventGroup != null) { 26 | this.eventGroup.shutdownGracefully(); 27 | } 28 | } catch (Exception exception) { 29 | exception.printStackTrace(); 30 | } finally { 31 | this.eventGroup = null; 32 | this.running = false; 33 | } 34 | } 35 | 36 | public boolean isRunning() { 37 | return this.running; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /server-query/src/main/java/lilypad/server/query/udp/net/QueryUdpIdentification.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.query.udp.net; 2 | 3 | import lilypad.server.common.util.SecurityUtils; 4 | 5 | public class QueryUdpIdentification { 6 | 7 | private long time; 8 | private int requestId; 9 | private int challenge; 10 | 11 | public QueryUdpIdentification(int requestId) { 12 | this.time = System.currentTimeMillis(); 13 | this.requestId = requestId; 14 | this.challenge = SecurityUtils.randomInt(16777216); 15 | } 16 | 17 | public void updateTime() { 18 | this.time = System.currentTimeMillis(); 19 | } 20 | 21 | public boolean hasExpired() { 22 | return System.currentTimeMillis() - this.time > 30000L; 23 | } 24 | 25 | public int getRequestId() { 26 | return this.requestId; 27 | } 28 | 29 | public int getChallenge() { 30 | return this.challenge; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /server-standalone-allinone/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-standalone-allinone/src/main/java/lilypad/server/standalone/allinone/AllInOne.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.allinone; 2 | 3 | import java.util.Scanner; 4 | 5 | import lilypad.server.common.config.FileConfigGson; 6 | import lilypad.server.common.service.ServiceManager; 7 | import lilypad.server.connect.ConnectService; 8 | import lilypad.server.proxy.ProxyService; 9 | import lilypad.server.proxy.util.CipherUtils; 10 | import lilypad.server.query.tcp.QueryTcpService; 11 | import lilypad.server.query.udp.QueryUdpService; 12 | 13 | public class AllInOne { 14 | 15 | public static final String build = AllInOne.class.getPackage().getImplementationVersion(); 16 | 17 | public static void main(String[] args) { 18 | System.out.println("[LilyPad] build " + build + " of AllInOne"); 19 | 20 | ConnectService connectService = new ConnectService(); 21 | QueryTcpService queryTcpService = new QueryTcpService(); 22 | QueryUdpService queryUdpService = new QueryUdpService(); 23 | ProxyService proxyService = new ProxyService(); 24 | 25 | FileConfigGson fileConfigJson; 26 | try { 27 | fileConfigJson = new FileConfigGson("allinone", AllInOneConfig.class); 28 | } catch(Exception exception) { 29 | System.out.println("[LilyPad] fatal error: config"); 30 | exception.printStackTrace(); 31 | return; 32 | } 33 | fileConfigJson.load(); 34 | fileConfigJson.save(); 35 | Config config = fileConfigJson.getConfig(); 36 | config.init(proxyService, connectService, CipherUtils.generateRSAKeyPair(1024)); 37 | 38 | ServiceManager serviceManager = new ServiceManager(); 39 | try { 40 | serviceManager.enableService(connectService, config); 41 | serviceManager.enableService(queryTcpService, config); 42 | serviceManager.enableService(queryUdpService, config); 43 | serviceManager.enableService(proxyService, config); 44 | Scanner scanner = new Scanner(System.in); 45 | try { 46 | String scannerLine; 47 | while((scannerLine = scanner.next()) != null) { 48 | if(scannerLine.equals("stop") || scannerLine.equals("halt")) { 49 | break; 50 | } 51 | } 52 | } finally { 53 | scanner.close(); 54 | } 55 | } catch(Exception exception) { 56 | System.out.println("[LilyPad] fatal error: services"); 57 | exception.printStackTrace(); 58 | return; 59 | } finally { 60 | serviceManager.disableAllServices(); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /server-standalone-allinone/src/main/java/lilypad/server/standalone/allinone/Config.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.allinone; 2 | 3 | import java.security.KeyPair; 4 | import java.util.Map; 5 | 6 | import lilypad.server.common.util.SecurityUtils; 7 | import lilypad.server.connect.ConnectConfig; 8 | import lilypad.server.proxy.ProxyConfig; 9 | import lilypad.server.query.tcp.QueryTcpConfig; 10 | import lilypad.server.query.udp.QueryUdpConfig; 11 | import lilypad.server.common.IAuthenticator; 12 | import lilypad.server.common.IPlayable; 13 | import lilypad.server.common.IPlayerCallback; 14 | import lilypad.server.common.IServerSource; 15 | 16 | public abstract class Config implements QueryTcpConfig, QueryUdpConfig, ConnectConfig, ProxyConfig, IAuthenticator { 17 | 18 | private transient IPlayable playable; 19 | private transient IServerSource serverSource; 20 | private transient KeyPair keyPair; 21 | 22 | public void init(IPlayable playable, IServerSource serverSource, KeyPair keyPair) { 23 | this.playable = playable; 24 | this.serverSource = serverSource; 25 | this.keyPair = keyPair; 26 | } 27 | 28 | public IPlayable querytcp_getPlayable() { 29 | return this.playable; 30 | } 31 | 32 | public IPlayable queryudp_getPlayable() { 33 | return this.playable; 34 | } 35 | 36 | public IAuthenticator connect_getAuthenticator() { 37 | return this; 38 | } 39 | 40 | public IPlayable connect_getPlayable() { 41 | return this.playable; 42 | } 43 | 44 | public abstract Map connect_getLogins(); 45 | 46 | public IPlayerCallback proxy_getPlayerCallback() { 47 | return null; 48 | } 49 | 50 | public KeyPair proxy_getKeyPair() { 51 | return this.keyPair; 52 | } 53 | 54 | public IServerSource proxy_getServerSource() { 55 | return this.serverSource; 56 | } 57 | 58 | public boolean authenticate(String username, String password, String authenticationKey) { 59 | Map logins = this.connect_getLogins(); 60 | if(!logins.containsKey(username)) { 61 | return false; 62 | } 63 | String realPassword = SecurityUtils.shaHex(SecurityUtils.shaHex(authenticationKey) + SecurityUtils.shaHex(logins.get(username))); 64 | if(!realPassword.equals(password)) { 65 | return false; 66 | } 67 | return true; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /server-standalone-connect/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-standalone-connect/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | lilypad.server.standalone 5 | connect 6 | 0.0.1-SNAPSHOT 7 | jar 8 | 9 | Server-Standalone-Connect 10 | http://www.lilypadmc.org 11 | 12 | 13 | UTF-8 14 | Unknown 15 | 16 | 17 | 18 | lilypad 19 | http://ci.lilypadmc.org/plugin/repository/everything 20 | 21 | 22 | 23 | 24 | 25 | lilypad.server 26 | connect 27 | 0.0.1-SNAPSHOT 28 | 29 | 30 | 31 | 32 | ${project.name} 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-compiler-plugin 37 | 2.5.1 38 | 39 | 1.6 40 | 1.6 41 | 42 | 43 | 44 | maven-assembly-plugin 45 | 2.2 46 | 47 | 48 | make-assembly 49 | package 50 | 51 | single 52 | 53 | 54 | 1.6 55 | 1.6 56 | 57 | jar-with-dependencies 58 | 59 | false 60 | 61 | false 62 | 63 | lilypad.server.standalone.connect.Connect 64 | ${name} 65 | ${build.number} 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /server-standalone-connect/src/main/java/lilypad/server/standalone/connect/Config.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.connect; 2 | 3 | import java.util.Map; 4 | 5 | import lilypad.server.common.util.SecurityUtils; 6 | import lilypad.server.connect.ConnectConfig; 7 | import lilypad.server.common.IAuthenticator; 8 | import lilypad.server.common.IPlayable; 9 | 10 | public abstract class Config implements ConnectConfig, IAuthenticator { 11 | 12 | private transient IPlayable playable; 13 | 14 | public void init(IPlayable playable) { 15 | this.playable = playable; 16 | } 17 | 18 | public IAuthenticator connect_getAuthenticator() { 19 | return this; 20 | } 21 | 22 | public IPlayable connect_getPlayable() { 23 | return this.playable; 24 | } 25 | 26 | public abstract Map connect_getLogins(); 27 | 28 | public boolean authenticate(String username, String password, String authenticationKey) { 29 | Map logins = this.connect_getLogins(); 30 | if(!logins.containsKey(username)) { 31 | return false; 32 | } 33 | String realPassword = SecurityUtils.shaHex(SecurityUtils.shaHex(authenticationKey) + SecurityUtils.shaHex(logins.get(username))); 34 | if(!realPassword.equals(password)) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /server-standalone-connect/src/main/java/lilypad/server/standalone/connect/Connect.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.connect; 2 | 3 | import java.util.Scanner; 4 | 5 | import lilypad.server.common.config.FileConfigGson; 6 | import lilypad.server.common.service.ServiceManager; 7 | import lilypad.server.connect.ConnectService; 8 | 9 | public class Connect { 10 | 11 | public static final String build = Connect.class.getPackage().getImplementationVersion(); 12 | 13 | public static void main(String[] args) { 14 | System.out.println("[LilyPad] build " + build + " of Connect"); 15 | 16 | ConnectService connectService = new ConnectService(); 17 | 18 | FileConfigGson fileConfigJson; 19 | try { 20 | fileConfigJson = new FileConfigGson("connect", ConnectConfig.class); 21 | } catch(Exception exception) { 22 | System.out.println("[LilyPad] fatal error: config"); 23 | exception.printStackTrace(); 24 | return; 25 | } 26 | fileConfigJson.load(); 27 | fileConfigJson.save(); 28 | Config config = fileConfigJson.getConfig(); 29 | config.init(new ConnectPlayable(connectService)); 30 | 31 | ServiceManager serviceManager = new ServiceManager(); 32 | try { 33 | serviceManager.enableService(connectService, config); 34 | Scanner scanner = new Scanner(System.in); 35 | try { 36 | String scannerLine; 37 | while((scannerLine = scanner.next()) != null) { 38 | if(scannerLine.equals("halt") || scannerLine.equals("stop")) { 39 | break; 40 | } 41 | } 42 | } finally { 43 | scanner.close(); 44 | } 45 | } catch(Exception exception) { 46 | System.out.println("[LilyPad] fatal error: services"); 47 | exception.printStackTrace(); 48 | return; 49 | } finally { 50 | serviceManager.disableAllServices(); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /server-standalone-connect/src/main/java/lilypad/server/standalone/connect/ConnectConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.connect; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import lilypad.server.common.config.FileConfig; 8 | 9 | public class ConnectConfig extends Config implements FileConfig { 10 | 11 | private transient InetSocketAddress connectBindAddress; 12 | private transient Map loginsMap; 13 | 14 | public Bind bind = new Bind(); 15 | public Login[] logins = { new Login() }; 16 | 17 | public ConnectConfig() { 18 | this.bind.port = 5091; 19 | } 20 | 21 | public class Login { 22 | public String username = "example"; 23 | public String password = "example"; 24 | } 25 | 26 | public class Bind { 27 | public String address = "0.0.0.0"; 28 | public int port; 29 | } 30 | 31 | public InetSocketAddress connect_getBindAddress() { 32 | if(this.connectBindAddress == null) { 33 | this.connectBindAddress = new InetSocketAddress(this.bind.address, this.bind.port); 34 | } 35 | return this.connectBindAddress; 36 | } 37 | 38 | public Map connect_getLogins() { 39 | if(this.loginsMap == null) { 40 | this.loginsMap = new HashMap(); 41 | for(Login login : this.logins) { 42 | this.loginsMap.put(login.username, login.password); 43 | } 44 | } 45 | return this.loginsMap; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /server-standalone-connect/src/main/java/lilypad/server/standalone/connect/ConnectPlayable.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.connect; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.Set; 5 | 6 | import lilypad.packet.connect.impl.RedirectPacket; 7 | import lilypad.server.common.IPlayable; 8 | import lilypad.server.common.IServer; 9 | import lilypad.server.connect.ConnectService; 10 | import lilypad.server.connect.node.NodeSession; 11 | 12 | public class ConnectPlayable implements IPlayable { 13 | 14 | private ConnectService connectService; 15 | 16 | public ConnectPlayable(ConnectService connectService) { 17 | this.connectService = connectService; 18 | } 19 | 20 | public String getMotd() { 21 | return this.connectService.getProxyCache().getMotd(); 22 | } 23 | 24 | public InetSocketAddress getBindAddress() { 25 | return this.connectService.getProxyCache().getAddress(); 26 | } 27 | 28 | public Set getPlayers() { 29 | return this.connectService.getProxyCache().getPlayers(); 30 | } 31 | 32 | public int getPlayerMaximum() { 33 | return this.connectService.getProxyCache().getMaximumPlayers(); 34 | } 35 | 36 | public String getVersion() { 37 | return this.connectService.getProxyCache().getVersion(); 38 | } 39 | 40 | public boolean redirect(String name, IServer server) { 41 | NodeSession nodeSession = this.connectService.getProxyCache().getProxyByPlayer(name); 42 | if(nodeSession == null) { 43 | return false; 44 | } 45 | nodeSession.write(new RedirectPacket(server.getIdentification(), name)); 46 | return true; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /server-standalone-proxy/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-standalone-proxy/src/main/java/lilypad/server/standalone/proxy/Config.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.proxy; 2 | 3 | import java.security.KeyPair; 4 | 5 | import lilypad.client.connect.api.ConnectSettings; 6 | import lilypad.server.proxy.ProxyConfig; 7 | import lilypad.server.common.IPlayerCallback; 8 | import lilypad.server.common.IServerSource; 9 | 10 | public abstract class Config implements ProxyConfig, ConnectSettings { 11 | 12 | private transient IServerSource serverSource; 13 | private transient IPlayerCallback playerCallback; 14 | private transient KeyPair keyPair; 15 | 16 | public void init(IServerSource serverSource, IPlayerCallback playerCallback, KeyPair keyPair) { 17 | this.serverSource = serverSource; 18 | this.playerCallback = playerCallback; 19 | this.keyPair = keyPair; 20 | } 21 | 22 | public KeyPair proxy_getKeyPair() { 23 | return this.keyPair; 24 | } 25 | 26 | public IPlayerCallback proxy_getPlayerCallback() { 27 | return this.playerCallback; 28 | } 29 | 30 | public IServerSource proxy_getServerSource() { 31 | return this.serverSource; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /server-standalone-proxy/src/main/java/lilypad/server/standalone/proxy/ConnectServer.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.proxy; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import lilypad.server.common.IServer; 6 | 7 | public class ConnectServer implements IServer { 8 | 9 | private String server; 10 | private InetSocketAddress address; 11 | private String securityKey; 12 | 13 | public ConnectServer(String server, InetSocketAddress address, String securityKey) { 14 | this.server = server; 15 | this.address = address; 16 | this.securityKey = securityKey; 17 | } 18 | 19 | public String getIdentification() { 20 | return this.server; 21 | } 22 | 23 | public InetSocketAddress getInboundAddress() { 24 | return this.address; 25 | } 26 | 27 | public String getSecurityKey() { 28 | return this.securityKey; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /server-standalone-proxy/src/main/java/lilypad/server/standalone/proxy/ConnectServerRedirect.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.proxy; 2 | 3 | import lilypad.client.connect.api.event.EventListener; 4 | import lilypad.client.connect.api.event.RedirectEvent; 5 | import lilypad.server.common.IRedirectable; 6 | import lilypad.server.common.IServer; 7 | 8 | public class ConnectServerRedirect { 9 | 10 | private ConnectServerSource connectServerSource; 11 | private IRedirectable redirectable; 12 | 13 | public ConnectServerRedirect(ConnectServerSource connectServerSource, IRedirectable redirectable) { 14 | this.connectServerSource = connectServerSource; 15 | this.redirectable = redirectable; 16 | } 17 | 18 | @EventListener 19 | public void onRedirect(RedirectEvent redirectEvent) { 20 | IServer server = this.connectServerSource.getServerByName(redirectEvent.getServer()); 21 | if(server == null) { 22 | return; 23 | } 24 | this.redirectable.redirect(redirectEvent.getPlayer(), server); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /server-standalone-proxy/src/main/java/lilypad/server/standalone/proxy/ConnectServerSource.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.proxy; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | import lilypad.client.connect.api.Connect; 8 | import lilypad.client.connect.api.event.EventListener; 9 | import lilypad.client.connect.api.event.ServerAddEvent; 10 | import lilypad.client.connect.api.event.ServerRemoveEvent; 11 | import lilypad.server.common.IServer; 12 | import lilypad.server.common.IServerSource; 13 | 14 | public class ConnectServerSource implements IServerSource { 15 | 16 | private Map servers = new ConcurrentHashMap(); 17 | private Connect connect; 18 | 19 | public ConnectServerSource(Connect connect) { 20 | this.connect = connect; 21 | } 22 | 23 | public IServer getServerByName(String username) { 24 | return this.servers.get(username); 25 | } 26 | 27 | @EventListener 28 | public void onServerAdd(ServerAddEvent event) { 29 | String address = event.getAddress().getAddress().getHostAddress(); 30 | if(address.equals("127.0.0.1") || address.equals("localhost")) { 31 | this.servers.put(event.getServer(), new ConnectServer(event.getServer(), new InetSocketAddress(this.connect.getSettings().getOutboundAddress().getHostName(), event.getAddress().getPort()), event.getSecurityKey())); 32 | } else { 33 | this.servers.put(event.getServer(), new ConnectServer(event.getServer(), event.getAddress(), event.getSecurityKey())); 34 | } 35 | } 36 | 37 | @EventListener 38 | public void onServerRemove(ServerRemoveEvent event) { 39 | this.servers.remove(event.getServer()); 40 | } 41 | 42 | public void clearServers() { 43 | this.servers.clear(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /server-standalone-query/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # vim 14 | .*.sw[a-p] 15 | 16 | # Build 17 | /build 18 | /bin 19 | /dist 20 | /manifest.mf 21 | 22 | # Mac OS X 23 | /.DS_Store 24 | 25 | # Intellij 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # Temp 32 | *~ 33 | -------------------------------------------------------------------------------- /server-standalone-query/src/main/java/lilypad/server/standalone/query/Config.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.query; 2 | 3 | import lilypad.client.connect.api.ConnectSettings; 4 | import lilypad.server.common.IPlayable; 5 | import lilypad.server.query.tcp.QueryTcpConfig; 6 | import lilypad.server.query.udp.QueryUdpConfig; 7 | 8 | public abstract class Config implements QueryTcpConfig, QueryUdpConfig, ConnectSettings { 9 | 10 | private transient IPlayable playable; 11 | 12 | public void init(IPlayable playable) { 13 | this.playable = playable; 14 | } 15 | 16 | public IPlayable querytcp_getPlayable() { 17 | return this.playable; 18 | } 19 | 20 | public IPlayable queryudp_getPlayable() { 21 | return this.playable; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /server-standalone-query/src/main/java/lilypad/server/standalone/query/QueryCache.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.query; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import lilypad.server.common.IPlayable; 9 | import lilypad.server.common.IServer; 10 | 11 | public class QueryCache implements IPlayable { 12 | 13 | public static final InetSocketAddress blankAddress = new InetSocketAddress("0.0.0.0", 0); 14 | 15 | private String motd; 16 | private InetSocketAddress serverAddress; 17 | private Set players = new HashSet(); 18 | private int playerMaximum; 19 | private String version; 20 | 21 | public QueryCache() { 22 | this.invalidate(); 23 | } 24 | 25 | public void invalidate() { 26 | this.motd = "Unknown"; 27 | this.serverAddress = blankAddress; 28 | this.players.clear(); 29 | this.playerMaximum = 0; 30 | this.version = "Unknown"; 31 | } 32 | 33 | public String getMotd() { 34 | return this.motd; 35 | } 36 | 37 | public void setMotd(String motd) { 38 | this.motd = motd; 39 | } 40 | 41 | public InetSocketAddress getBindAddress() { 42 | return this.serverAddress; 43 | } 44 | 45 | public void setServerAddress(InetSocketAddress serverAddress) { 46 | this.serverAddress = serverAddress; 47 | } 48 | 49 | public Set getPlayers() { 50 | return Collections.unmodifiableSet(this.players); 51 | } 52 | 53 | public void replacePlayers(Set players) { 54 | this.players = players; 55 | } 56 | 57 | public int getPlayerMaximum() { 58 | return this.playerMaximum; 59 | } 60 | 61 | public void setPlayerMaximum(int playerMaximum) { 62 | this.playerMaximum = playerMaximum; 63 | } 64 | 65 | public String getVersion() { 66 | return this.version; 67 | } 68 | 69 | public void setVersion(String version) { 70 | this.version = version; 71 | } 72 | 73 | public boolean redirect(String name, IServer server) { 74 | throw new UnsupportedOperationException(); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /server-standalone-query/src/main/java/lilypad/server/standalone/query/QueryConfig.java: -------------------------------------------------------------------------------- 1 | package lilypad.server.standalone.query; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import lilypad.server.common.config.FileConfig; 6 | 7 | public class QueryConfig extends Config implements FileConfig { 8 | 9 | public Connect connect = new Connect(); 10 | public QueryTcp queryTcp = new QueryTcp(); 11 | public QueryUdp queryUdp = new QueryUdp(); 12 | 13 | private transient InetSocketAddress connectAddress; 14 | private transient InetSocketAddress querytcpBindAddress; 15 | private transient InetSocketAddress queryudpBindAddress; 16 | 17 | public class Connect { 18 | public String address = "127.0.0.1"; 19 | public int port = 5091; 20 | public Credentials credentials = new Credentials(); 21 | 22 | public class Credentials { 23 | public String username = "example"; 24 | public String password = "example"; 25 | } 26 | } 27 | 28 | public class QueryTcp { 29 | public Bind bind = new Bind(); 30 | 31 | public QueryTcp() { 32 | this.bind.port = 5555; 33 | } 34 | } 35 | 36 | public class QueryUdp { 37 | public Bind bind = new Bind(); 38 | 39 | public QueryUdp() { 40 | this.bind.port = 25565; 41 | } 42 | } 43 | 44 | public class Bind { 45 | public String address = "0.0.0.0"; 46 | public int port; 47 | } 48 | 49 | public InetSocketAddress querytcp_getBindAddress() { 50 | if(this.querytcpBindAddress == null) { 51 | this.querytcpBindAddress = new InetSocketAddress(this.queryTcp.bind.address, this.queryTcp.bind.port); 52 | } 53 | return this.querytcpBindAddress; 54 | } 55 | 56 | public InetSocketAddress queryudp_getBindAddress() { 57 | if(this.queryudpBindAddress == null) { 58 | this.queryudpBindAddress = new InetSocketAddress(this.queryUdp.bind.address, this.queryUdp.bind.port); 59 | } 60 | return this.queryudpBindAddress; 61 | } 62 | 63 | public InetSocketAddress getOutboundAddress() { 64 | if(this.connectAddress == null) { 65 | this.connectAddress = new InetSocketAddress(this.connect.address, this.connect.port); 66 | } 67 | return this.connectAddress; 68 | } 69 | 70 | public String getUsername() { 71 | return this.connect.credentials.username; 72 | } 73 | 74 | public String getPassword() { 75 | return this.connect.credentials.password; 76 | } 77 | 78 | } 79 | --------------------------------------------------------------------------------