Add backend RPC protocol classes

This commit is contained in:
lax1dude 2024-08-09 19:58:17 -07:00
parent 7a9c154254
commit d8ef6423c5
37 changed files with 3352 additions and 0 deletions

View File

@ -0,0 +1,147 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client.*;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server.*;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EaglerBackendRPCProtocol {
INIT(0,
define_CLIENT_(0x00, CPacketRPCEnabled.class),
define_SERVER_(0x01, SPacketRPCEnabledSuccess.class),
define_SERVER_(0x02, SPacketRPCEnabledFailure.class)
), V1(1,
define_CLIENT_(0x03, CPacketRPCDisabled.class),
define_CLIENT_(0x04, CPacketRPCRequestPlayerInfo.class),
define_CLIENT_(0x05, CPacketRPCSubscribeEvents.class),
define_CLIENT_(0x06, CPacketRPCSetPlayerSkin.class),
define_CLIENT_(0x07, CPacketRPCSetPlayerCape.class),
define_CLIENT_(0x08, CPacketRPCSetPlayerCookie.class),
define_CLIENT_(0x09, CPacketRPCSetPlayerFNAWEn.class),
define_CLIENT_(0x0A, CPacketRPCSetPauseMenuCustom.class),
define_CLIENT_(0x0B, CPacketRPCRedirectPlayer.class),
define_CLIENT_(0x0C, CPacketRPCResetPlayerMulti.class),
define_SERVER_(0x0D, SPacketRPCResponseTypeNull.class),
define_SERVER_(0x0E, SPacketRPCResponseTypeBytes.class),
define_SERVER_(0x0F, SPacketRPCResponseTypeString.class),
define_SERVER_(0x10, SPacketRPCResponseTypeUUID.class),
define_SERVER_(0x11, SPacketRPCResponseTypeCookie.class),
define_SERVER_(0x12, SPacketRPCResponseTypeVoiceStatus.class),
define_SERVER_(0x13, SPacketRPCResponseTypeWebViewStatus.class),
define_SERVER_(0x14, SPacketRPCResponseTypeError.class),
define_CLIENT_(0x15, CPacketRPCSendWebViewMessage.class),
define_SERVER_(0x16, SPacketRPCEventWebViewOpenClose.class),
define_SERVER_(0x17, SPacketRPCEventWebViewMessage.class),
define_SERVER_(0x18, SPacketRPCEventToggledVoice.class),
define_CLIENT_(0x19, CPacketRPCNotifIconRegister.class),
define_CLIENT_(0x1A, CPacketRPCNotifIconRelease.class),
define_CLIENT_(0x1B, CPacketRPCNotifBadgeShow.class),
define_CLIENT_(0x1C, CPacketRPCNotifBadgeHide.class),
define_CLIENT_(0x1D, CPacketRPCSendRawMessage.class)
);
public static final String CHANNEL_NAME = "EAG|1.8-RPC";
public static final String CHANNEL_NAME_READY = "EAG|1.8-Ready";
public static final int CLIENT_TO_SERVER = 0;
public static final int SERVER_TO_CLIENT = 1;
public final int vers;
private final PacketDef[] idMap = new PacketDef[32]; // May need to grow this in the future
private final Map<Class<? extends EaglerBackendRPCPacket>, PacketDef> classMap = new HashMap<>();
private EaglerBackendRPCProtocol(int vers, PacketDef...pkts) {
this.vers = vers;
for(int i = 0; i < pkts.length; ++i) {
PacketDef def = pkts[i];
if(idMap[def.id] != null) {
throw new IllegalArgumentException("Packet ID " + def.id + " registered twice!");
}
idMap[def.id] = def;
if(classMap.put(def.pkt, def) != null) {
throw new IllegalArgumentException("Packet class " + def.pkt.getSimpleName() + " registered twice!");
}
}
}
private static PacketDef define_CLIENT_(int id, Class<? extends EaglerBackendRPCPacket> pkt) {
return new PacketDef(id, 0, pkt);
}
private static PacketDef define_SERVER_(int id, Class<? extends EaglerBackendRPCPacket> pkt) {
return new PacketDef(id, 1, pkt);
}
private static class PacketDef {
private final int id;
private final int dir;
private final Class<? extends EaglerBackendRPCPacket> pkt;
private PacketDef(int id, int dir, Class<? extends EaglerBackendRPCPacket> pkt) {
this.id = id;
this.dir = dir;
this.pkt = pkt;
}
}
public EaglerBackendRPCPacket readPacket(DataInput buffer, int dir) throws IOException {
int pktId = buffer.readUnsignedByte();
if(pktId >= idMap.length) {
throw new IOException("Packet ID is out of range: 0x" + Integer.toHexString(pktId));
}
PacketDef pp = idMap[pktId];
if(pp == null || pp.dir != dir) {
throw new IOException("Unknown packet ID: 0x" + Integer.toHexString(pktId));
}
EaglerBackendRPCPacket newPkt;
try {
newPkt = pp.pkt.newInstance();
}catch(Throwable t) {
throw new RuntimeException("Reflection failed to call packet constructor for \"" + pp.pkt.getSimpleName() + "\"! (is it defined?)", t);
}
newPkt.readPacket(buffer);
return newPkt;
}
public void writePacket(DataOutput buffer, int dir, EaglerBackendRPCPacket packet) throws IOException {
Class<? extends EaglerBackendRPCPacket> clazz = packet.getClass();
PacketDef def = classMap.get(clazz);
if(def == null || def.dir != dir) {
throw new IOException("Unknown packet type or wrong direction: " + clazz);
}
buffer.writeByte(def.id);
packet.writePacket(buffer);
}
public static EaglerBackendRPCProtocol getByID(int id) {
switch(id) {
case 0: return INIT;
case 1: return V1;
default: return null;
}
}
}

View File

@ -0,0 +1,143 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client.*;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server.*;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface EaglerBackendRPCHandler {
default void handleClient(CPacketRPCEnabled packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCRequestPlayerInfo packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSubscribeEvents packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSetPlayerSkin packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSetPlayerCape packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSetPlayerCookie packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSetPlayerFNAWEn packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCRedirectPlayer packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCResetPlayerMulti packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSendWebViewMessage packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSetPauseMenuCustom packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCNotifIconRegister packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCNotifIconRelease packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCNotifBadgeShow packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCNotifBadgeHide packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCDisabled packet) {
throw new WrongRPCPacketException();
}
default void handleClient(CPacketRPCSendRawMessage packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCEnabledSuccess packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCEnabledFailure packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeNull packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeBytes packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeString packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeUUID packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeCookie packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeVoiceStatus packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeWebViewStatus packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCResponseTypeError packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCEventWebViewOpenClose packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCEventWebViewMessage packet) {
throw new WrongRPCPacketException();
}
default void handleServer(SPacketRPCEventToggledVoice packet) {
throw new WrongRPCPacketException();
}
}

View File

@ -0,0 +1,72 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface EaglerBackendRPCPacket {
void readPacket(DataInput buffer) throws IOException;
void writePacket(DataOutput buffer) throws IOException;
void handlePacket(EaglerBackendRPCHandler handler);
int length();
public static void writeString(DataOutput buffer, String str, boolean len16, Charset charset) throws IOException {
if(str == null || str.length() == 0) {
if(len16) {
buffer.writeShort(0);
}else {
buffer.writeByte(0);
}
return;
}
byte[] bytes = str.getBytes(charset);
if(bytes.length > (len16 ? 65535 : 255)) {
throw new IOException("String is too long!");
}
if(len16) {
buffer.writeShort(bytes.length);
}else {
buffer.writeByte(bytes.length);
}
buffer.write(bytes);
}
public static String readString(DataInput buffer, int maxLen, boolean len16, Charset charset) throws IOException {
int len = len16 ? buffer.readUnsignedShort() : buffer.readUnsignedByte();
if(len > maxLen) {
throw new IOException("String is too long!");
}
if(len == 0) {
return "";
}
byte[] toRead = new byte[len];
buffer.readFully(toRead);
String ret = new String(toRead, charset);
if(charset != StandardCharsets.US_ASCII && ret.length() > maxLen) {
throw new IOException("String is too long!");
}
return ret;
}
}

View File

@ -0,0 +1,24 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class WrongRPCPacketException extends RuntimeException {
public WrongRPCPacketException() {
super("Wrong RPC packet type recieved for the current handler!");
}
}

View File

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCDisabled implements EaglerBackendRPCPacket {
public CPacketRPCDisabled() {
}
@Override
public void readPacket(DataInput buffer) throws IOException {
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 0;
}
}

View File

@ -0,0 +1,62 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCEnabled implements EaglerBackendRPCPacket {
public int[] supportedProtocols;
public CPacketRPCEnabled() {
}
public CPacketRPCEnabled(int[] supportedProtocols) {
this.supportedProtocols = supportedProtocols;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
supportedProtocols = new int[buffer.readUnsignedShort()];
for(int i = 0; i < supportedProtocols.length; ++i) {
supportedProtocols[i] = buffer.readUnsignedShort();
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeShort(supportedProtocols.length);
for(int i = 0; i < supportedProtocols.length; ++i) {
buffer.writeShort(supportedProtocols[i]);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 2 + supportedProtocols.length * 2;
}
}

View File

@ -0,0 +1,58 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCNotifBadgeHide implements EaglerBackendRPCPacket {
public UUID badgeUUID;
public CPacketRPCNotifBadgeHide() {
}
public CPacketRPCNotifBadgeHide(UUID badgeUUID) {
this.badgeUUID = badgeUUID;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
badgeUUID = new UUID(buffer.readLong(), buffer.readLong());
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeLong(badgeUUID.getMostSignificantBits());
buffer.writeLong(badgeUUID.getLeastSignificantBits());
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 16;
}
}

View File

@ -0,0 +1,167 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.readString;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.writeString;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCNotifBadgeShow implements EaglerBackendRPCPacket {
public static enum EnumBadgePriority {
LOW(0), NORMAL(1), HIGHER(2), HIGHEST(3);
public final int priority;
private EnumBadgePriority(int priority) {
this.priority = priority;
}
private static final EnumBadgePriority[] lookup = new EnumBadgePriority[4];
public static EnumBadgePriority getByID(int id) {
if(id >= 0 && id < lookup.length) {
return lookup[id];
}else {
return NORMAL;
}
}
static {
EnumBadgePriority[] _values = values();
for(int i = 0; i < _values.length; ++i) {
lookup[_values[i].priority] = _values[i];
}
}
}
public UUID badgeUUID;
public String bodyComponent;
public String titleComponent;
public String sourceComponent;
public long originalTimestampSec;
public boolean silent;
public EnumBadgePriority priority;
public UUID mainIconUUID;
public UUID titleIconUUID;
public int hideAfterSec;
public int expireAfterSec;
public int backgroundColor;
public int bodyTxtColor;
public int titleTxtColor;
public int sourceTxtColor;
public CPacketRPCNotifBadgeShow() {
}
public CPacketRPCNotifBadgeShow(UUID badgeUUID, String bodyComponent, String titleComponent, String sourceComponent,
long originalTimestampSec, UUID mainIconUUID, UUID titleIconUUID, boolean silent,
EnumBadgePriority priority, int hideAfterSec, int expireAfterSec, int backgroundColor, int bodyTxtColor,
int titleTxtColor, int sourceTxtColor) {
this.badgeUUID = badgeUUID;
this.bodyComponent = bodyComponent;
this.titleComponent = titleComponent;
this.sourceComponent = sourceComponent;
this.originalTimestampSec = originalTimestampSec;
this.mainIconUUID = mainIconUUID;
this.titleIconUUID = titleIconUUID;
this.silent = silent;
this.priority = priority;
this.hideAfterSec = hideAfterSec;
this.expireAfterSec = expireAfterSec;
this.backgroundColor = backgroundColor;
this.bodyTxtColor = bodyTxtColor;
this.titleTxtColor = titleTxtColor;
this.sourceTxtColor = sourceTxtColor;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
badgeUUID = new UUID(buffer.readLong(), buffer.readLong());
bodyComponent = readString(buffer, 32767, true, StandardCharsets.UTF_8);
titleComponent = readString(buffer, 255, false, StandardCharsets.UTF_8);
sourceComponent = readString(buffer, 255, false, StandardCharsets.UTF_8);
originalTimestampSec = ((long)buffer.readUnsignedShort() << 32l) | ((long)buffer.readInt() & 0xFFFFFFFFl);
int flags = buffer.readUnsignedByte();
silent = (flags & 1) != 0;
priority = EnumBadgePriority.getByID((flags >>> 1) & 3);
hideAfterSec = buffer.readUnsignedByte();
expireAfterSec = buffer.readUnsignedShort();
mainIconUUID = (flags & 8) != 0 ? new UUID(buffer.readLong(), buffer.readLong()) : null;
titleIconUUID = (flags & 16) != 0 ? new UUID(buffer.readLong(), buffer.readLong()) : null;
backgroundColor = (buffer.readUnsignedByte() << 16) | (buffer.readUnsignedByte() << 8) | buffer.readUnsignedByte();
bodyTxtColor = (buffer.readUnsignedByte() << 16) | (buffer.readUnsignedByte() << 8) | buffer.readUnsignedByte();
titleTxtColor = (buffer.readUnsignedByte() << 16) | (buffer.readUnsignedByte() << 8) | buffer.readUnsignedByte();
sourceTxtColor = (buffer.readUnsignedByte() << 16) | (buffer.readUnsignedByte() << 8) | buffer.readUnsignedByte();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeLong(badgeUUID.getMostSignificantBits());
buffer.writeLong(badgeUUID.getLeastSignificantBits());
writeString(buffer, bodyComponent, true, StandardCharsets.UTF_8);
writeString(buffer, titleComponent, false, StandardCharsets.UTF_8);
writeString(buffer, sourceComponent, false, StandardCharsets.UTF_8);
buffer.writeShort((int)((originalTimestampSec >> 32l) & 0xFFFFl));
buffer.writeInt((int)(originalTimestampSec & 0xFFFFFFFFl));
int flags = (silent ? 1 : 0);
flags |= ((priority != null ? priority.priority : 1) << 1);
flags |= (mainIconUUID != null ? 8 : 0);
flags |= (titleIconUUID != null ? 16 : 0);
buffer.writeByte(flags);
buffer.writeByte(hideAfterSec);
buffer.writeShort(expireAfterSec);
if(mainIconUUID != null) {
buffer.writeLong(mainIconUUID.getMostSignificantBits());
buffer.writeLong(mainIconUUID.getLeastSignificantBits());
}
if(titleIconUUID != null) {
buffer.writeLong(titleIconUUID.getMostSignificantBits());
buffer.writeLong(titleIconUUID.getLeastSignificantBits());
}
buffer.writeByte((backgroundColor >>> 16) & 0xFF);
buffer.writeByte((backgroundColor >>> 8) & 0xFF);
buffer.writeByte(backgroundColor & 0xFF);
buffer.writeByte((bodyTxtColor >>> 16) & 0xFF);
buffer.writeByte((bodyTxtColor >>> 8) & 0xFF);
buffer.writeByte(bodyTxtColor & 0xFF);
buffer.writeByte((titleTxtColor >>> 16) & 0xFF);
buffer.writeByte((titleTxtColor >>> 8) & 0xFF);
buffer.writeByte(titleTxtColor & 0xFF);
buffer.writeByte((sourceTxtColor >>> 16) & 0xFF);
buffer.writeByte((sourceTxtColor >>> 8) & 0xFF);
buffer.writeByte(sourceTxtColor & 0xFF);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return -1;
}
}

View File

@ -0,0 +1,85 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.util.PacketImageData;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCNotifIconRegister implements EaglerBackendRPCPacket {
public Map<UUID,PacketImageData> notifIcons;
public CPacketRPCNotifIconRegister() {
}
public CPacketRPCNotifIconRegister(Map<UUID,PacketImageData> notifIcons) {
this.notifIcons = notifIcons;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
notifIcons = new HashMap<>();
int cnt = buffer.readUnsignedByte();
for(int i = 0; i < cnt; ++i) {
UUID uuid = new UUID(buffer.readLong(), buffer.readLong());
PacketImageData img = PacketImageData.readRGB16(buffer);
notifIcons.put(uuid, img);
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(notifIcons != null && !notifIcons.isEmpty()) {
int l = notifIcons.size();
if(l > 255) {
throw new IOException("Too many notification icons in packet! (Max is 255, got " + l + " total)");
}
buffer.writeByte(l);
for(Entry<UUID,PacketImageData> etr : notifIcons.entrySet()) {
UUID uuid = etr.getKey();
buffer.writeLong(uuid.getMostSignificantBits());
buffer.writeLong(uuid.getLeastSignificantBits());
PacketImageData.writeRGB16(buffer, etr.getValue());
}
}else {
buffer.writeByte(0);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
int i = 1 + (notifIcons.size() << 4);
for(PacketImageData dat : notifIcons.values()) {
i += dat.getByteLengthRGB16();
}
return i;
}
}

View File

@ -0,0 +1,86 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCNotifIconRelease implements EaglerBackendRPCPacket {
public Collection<UUID> iconsToRelease;
public CPacketRPCNotifIconRelease() {
}
public CPacketRPCNotifIconRelease(Collection<UUID> iconsToRelease) {
this.iconsToRelease = iconsToRelease;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
int cnt = buffer.readUnsignedByte();
iconsToRelease = new ArrayList<>(cnt);
for(int i = 0; i < cnt; ++i) {
iconsToRelease.add(new UUID(buffer.readLong(), buffer.readLong()));
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(iconsToRelease != null && !iconsToRelease.isEmpty()) {
int cnt = iconsToRelease.size();
if(cnt > 255) {
throw new IOException("Too many notification icons in packet! (Max is 255, got " + cnt + " total)");
}
buffer.writeByte(cnt);
if(iconsToRelease instanceof RandomAccess) {
List<UUID> vigg = (List<UUID>)iconsToRelease;
for(int i = 0; i < cnt; ++i) {
UUID uuid = vigg.get(i);
buffer.writeLong(uuid.getMostSignificantBits());
buffer.writeLong(uuid.getLeastSignificantBits());
}
}else {
for(UUID uuid : iconsToRelease) {
buffer.writeLong(uuid.getMostSignificantBits());
buffer.writeLong(uuid.getLeastSignificantBits());
}
}
}else {
buffer.writeByte(0);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 1 + (iconsToRelease.size() << 4);
}
}

View File

@ -0,0 +1,64 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCRedirectPlayer implements EaglerBackendRPCPacket {
public String redirectURI;
public CPacketRPCRedirectPlayer() {
}
public CPacketRPCRedirectPlayer(String redirectURI) {
this.redirectURI = redirectURI;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
byte[] redirectURIBytes = new byte[buffer.readUnsignedShort()];
buffer.readFully(redirectURIBytes);
redirectURI = new String(redirectURIBytes, StandardCharsets.US_ASCII);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(redirectURI.length() > 65535) {
throw new IOException("Redirect URI is too long!");
}
byte[] redirectURIBytes = redirectURI.getBytes(StandardCharsets.US_ASCII);
buffer.writeShort(redirectURIBytes.length);
buffer.write(redirectURIBytes);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 2 + redirectURI.length();
}
}

View File

@ -0,0 +1,74 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCRequestPlayerInfo implements EaglerBackendRPCPacket {
public static final int REQUEST_PLAYER_REAL_UUID = 0;
public static final int REQUEST_PLAYER_REAL_IP = 1;
public static final int REQUEST_PLAYER_ORIGIN = 2;
public static final int REQUEST_PLAYER_USER_AGENT = 3;
public static final int REQUEST_PLAYER_SKIN_DATA = 4;
public static final int REQUEST_PLAYER_CAPE_DATA = 5;
public static final int REQUEST_PLAYER_COOKIE = 6;
public static final int REQUEST_PLAYER_CLIENT_BRAND_STR = 7;
public static final int REQUEST_PLAYER_CLIENT_VERSION_STR = 8;
public static final int REQUEST_PLAYER_CLIENT_BRAND_VERSION_STR = 9;
public static final int REQUEST_PLAYER_CLIENT_BRAND_UUID = 10;
public static final int REQUEST_PLAYER_CLIENT_VOICE_STATUS = 11;
public static final int REQUEST_PLAYER_CLIENT_WEBVIEW_STATUS = 12;
public int requestID;
public int requestType;
public CPacketRPCRequestPlayerInfo() {
}
public CPacketRPCRequestPlayerInfo(int requestID, int requestType) {
this.requestID = requestID;
this.requestType = requestType;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
requestType = buffer.readUnsignedByte();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
buffer.writeByte(requestType);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 5;
}
}

View File

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCResetPlayerMulti implements EaglerBackendRPCPacket {
public boolean resetSkin;
public boolean resetCape;
public boolean resetFNAWForce;
public boolean notifyOtherPlayers;
public CPacketRPCResetPlayerMulti() {
}
public CPacketRPCResetPlayerMulti(boolean resetSkin, boolean resetCape, boolean resetFNAWForce,
boolean notifyOtherPlayers) {
this.resetSkin = resetSkin;
this.resetCape = resetCape;
this.resetFNAWForce = resetFNAWForce;
this.notifyOtherPlayers = notifyOtherPlayers;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
int flags = buffer.readUnsignedByte();
resetSkin = (flags & 1) != 0;
resetCape = (flags & 2) != 0;
resetFNAWForce = (flags & 4) != 0;
notifyOtherPlayers = (flags & 8) != 0;
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeByte((resetSkin ? 1 : 0) | (resetCape ? 2 : 0) |
(resetFNAWForce ? 4 : 0) | (notifyOtherPlayers ? 8 : 0));
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 1;
}
}

View File

@ -0,0 +1,72 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.readString;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.writeString;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSendRawMessage implements EaglerBackendRPCPacket {
public String messageChannel;
public byte[] messageData;
public CPacketRPCSendRawMessage() {
}
public CPacketRPCSendRawMessage(String messageChannel, byte[] messageData) {
this.messageChannel = messageChannel;
this.messageData = messageData;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
messageChannel = readString(buffer, 32, false, StandardCharsets.US_ASCII);
messageData = new byte[buffer.readUnsignedShort()];
buffer.readFully(messageData);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(messageChannel.length() > 32) {
throw new IOException("Message channel name cannot be longer than 32 chars!");
}
if(messageData.length > 32720) {
throw new IOException("Message data cannot be longer than 32720 bytes!");
}
writeString(buffer, messageChannel, false, StandardCharsets.US_ASCII);
buffer.writeShort(messageData.length);
buffer.write(messageData);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 1 + messageChannel.length() + 2 + messageData.length;
}
}

View File

@ -0,0 +1,86 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSendWebViewMessage implements EaglerBackendRPCPacket {
public static final int MESSAGE_TYPE_STRING = 0;
public static final int MESSAGE_TYPE_BINARY = 1;
public String channelName;
public int messageType;
public byte[] messageContent;
public CPacketRPCSendWebViewMessage() {
}
public CPacketRPCSendWebViewMessage(String channelName, int messageType, byte[] messageContent) {
this.channelName = channelName;
this.messageType = messageType;
this.messageContent = messageContent;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
byte[] nameBytes = new byte[buffer.readUnsignedByte()];
buffer.readFully(nameBytes);
channelName = new String(nameBytes, StandardCharsets.US_ASCII);
messageType = buffer.readUnsignedByte();
messageContent = new byte[buffer.readUnsignedShort()];
buffer.readFully(messageContent);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(channelName == null || channelName.length() == 0) {
throw new IOException("Channel name cannot be empty!");
}
if(channelName.length() > 255) {
throw new IOException("Channel name cannot be more than 255 chars! (got " + channelName.length() + " chars)");
}
if(messageContent == null) {
throw new IOException("Message contents cannot be null!");
}
if(messageContent.length > 32720) {
throw new IOException("Message contents cannot be more then 32720 bytes! (got " + messageContent.length + " bytes)");
}
byte[] nameBytes = channelName.getBytes(StandardCharsets.US_ASCII);
buffer.writeByte(nameBytes.length);
buffer.write(nameBytes);
buffer.writeByte(messageType);
buffer.writeShort(messageContent.length);
buffer.write(messageContent);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 4 + channelName.length() + messageContent.length;
}
}

View File

@ -0,0 +1,217 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.util.PacketImageData;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.readString;
import static net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket.writeString;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSetPauseMenuCustom implements EaglerBackendRPCPacket {
public static final int SERVER_INFO_MODE_NONE = 0;
public static final int SERVER_INFO_MODE_EXTERNAL_URL = 1;
public static final int SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP = 2;
public static final int SERVER_INFO_MODE_SHOW_EMBED_OVER_WS = 3;
public static final int SERVER_INFO_MODE_INHERIT_DEFAULT = 4;
public static final int SERVER_INFO_EMBED_PERMS_JAVASCRIPT = 1;
public static final int SERVER_INFO_EMBED_PERMS_MESSAGE_API = 2;
public static final int SERVER_INFO_EMBED_PERMS_STRICT_CSP = 4;
public static final int DISCORD_MODE_NONE = 0;
public static final int DISCORD_MODE_INVITE_URL = 1;
public static final int DISCORD_MODE_INHERIT_DEFAULT = 2;
public int serverInfoMode;
public String serverInfoButtonText;
public String serverInfoURL;
public byte[] serverInfoHash;
public int serverInfoEmbedPerms;
public String serverInfoEmbedTitle;
public int discordButtonMode;
public String discordButtonText;
public String discordInviteURL;
public Map<String,Integer> imageMappings;
public List<PacketImageData> imageData;
public CPacketRPCSetPauseMenuCustom() {
}
public CPacketRPCSetPauseMenuCustom(int serverInfoMode, String serverInfoButtonText, String serverInfoURL,
byte[] serverInfoHash, int serverInfoEmbedPerms, String serverInfoEmbedTitle, int discordButtonMode,
String discordButtonText, String discordInviteURL, Map<String, Integer> imageMappings,
List<PacketImageData> imageData) {
this.serverInfoMode = serverInfoMode;
this.serverInfoButtonText = serverInfoButtonText;
this.serverInfoURL = serverInfoURL;
this.serverInfoHash = serverInfoHash;
this.serverInfoEmbedPerms = serverInfoEmbedPerms;
this.serverInfoEmbedTitle = serverInfoEmbedTitle;
this.discordButtonMode = discordButtonMode;
this.discordButtonText = discordButtonText;
this.discordInviteURL = discordInviteURL;
this.imageMappings = imageMappings;
this.imageData = imageData;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
imageMappings = null;
imageData = null;
int flags = buffer.readUnsignedByte();
serverInfoMode = (flags & 15);
discordButtonMode = ((flags >> 4) & 15);
switch(serverInfoMode) {
case SERVER_INFO_MODE_EXTERNAL_URL:
serverInfoButtonText = readString(buffer, 127, false, StandardCharsets.UTF_8);
serverInfoURL = readString(buffer, 65535, true, StandardCharsets.US_ASCII);
serverInfoEmbedPerms = 0;
serverInfoHash = null;
break;
case SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP:
serverInfoButtonText = readString(buffer, 127, false, StandardCharsets.UTF_8);
serverInfoURL = readString(buffer, 65535, true, StandardCharsets.US_ASCII);
serverInfoEmbedPerms = buffer.readUnsignedByte();
serverInfoHash = null;
serverInfoEmbedTitle = readString(buffer, 127, false, StandardCharsets.UTF_8);
break;
case SERVER_INFO_MODE_SHOW_EMBED_OVER_WS:
serverInfoButtonText = readString(buffer, 127, false, StandardCharsets.UTF_8);
serverInfoURL = null;
serverInfoEmbedPerms = buffer.readUnsignedByte();
serverInfoHash = new byte[20];
serverInfoEmbedTitle = readString(buffer, 127, false, StandardCharsets.UTF_8);
buffer.readFully(serverInfoHash);
break;
case SERVER_INFO_MODE_INHERIT_DEFAULT:
default:
serverInfoButtonText = null;
serverInfoURL = null;
serverInfoEmbedPerms = 0;
serverInfoHash = null;
break;
}
if(discordButtonMode == DISCORD_MODE_INVITE_URL) {
discordButtonText = readString(buffer, 127, false, StandardCharsets.UTF_8);
discordInviteURL = readString(buffer, 65535, true, StandardCharsets.US_ASCII);
}else {
discordButtonText = null;
discordInviteURL = null;
}
int mappingsCount = buffer.readUnsignedShort();
if(mappingsCount > 0) {
imageMappings = new HashMap<>();
imageData = new ArrayList<>();
for(int i = 0; i < mappingsCount; ++i) {
imageMappings.put(readString(buffer, 255, false, StandardCharsets.US_ASCII), buffer.readUnsignedShort());
}
int imageDataCount = buffer.readUnsignedShort();
for(int i = 0; i < imageDataCount; ++i) {
int w = buffer.readUnsignedByte();
int h = buffer.readUnsignedByte();
int pixelCount = w * h;
int[] pixels = new int[pixelCount];
for(int j = 0, p, pR, pG, pB; j < pixelCount; ++j) {
p = buffer.readUnsignedShort();
pR = (p >>> 11) & 0x1F;
pG = (p >>> 5) & 0x3F;
pB = p & 0x1F;
if(pR + pG + pB > 0) {
pB = (pB - 1) * 31 / 30;
pixels[j] = 0xFF000000 | (pR << 19) | (pG << 10) | (pB << 3);
}else {
pixels[j] = 0;
}
}
imageData.add(new PacketImageData(w, h, pixels));
}
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeByte(serverInfoMode | (discordButtonMode << 4));
switch(serverInfoMode) {
case SERVER_INFO_MODE_EXTERNAL_URL:
writeString(buffer, serverInfoButtonText, false, StandardCharsets.UTF_8);
writeString(buffer, serverInfoURL, true, StandardCharsets.US_ASCII);
break;
case SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP:
writeString(buffer, serverInfoButtonText, false, StandardCharsets.UTF_8);
writeString(buffer, serverInfoURL, true, StandardCharsets.US_ASCII);
buffer.writeByte(serverInfoEmbedPerms);
writeString(buffer, serverInfoEmbedTitle, false, StandardCharsets.UTF_8);
break;
case SERVER_INFO_MODE_SHOW_EMBED_OVER_WS:
writeString(buffer, serverInfoButtonText, false, StandardCharsets.UTF_8);
buffer.writeByte(serverInfoEmbedPerms);
writeString(buffer, serverInfoEmbedTitle, false, StandardCharsets.UTF_8);
if(serverInfoHash.length != 20) {
throw new IOException("Hash must be 20 bytes! (" + serverInfoHash.length + " given)");
}
buffer.write(serverInfoHash);
break;
case SERVER_INFO_MODE_INHERIT_DEFAULT:
default:
break;
}
if(discordButtonMode == DISCORD_MODE_INVITE_URL) {
writeString(buffer, discordButtonText, false, StandardCharsets.UTF_8);
writeString(buffer, discordInviteURL, true, StandardCharsets.US_ASCII);
}
if(imageMappings != null && !imageMappings.isEmpty()) {
buffer.writeShort(imageMappings.size());
for(Entry<String,Integer> etr : imageMappings.entrySet()) {
writeString(buffer, etr.getKey(), false, StandardCharsets.US_ASCII);
buffer.writeShort(etr.getValue().intValue());
}
buffer.writeShort(imageData.size());
for(PacketImageData etr : imageData) {
if(etr.width < 1 || etr.width > 64 || etr.height < 1 || etr.height > 64) {
throw new IOException("Invalid image dimensions in packet, must be between 1x1 and 64x64, got " + etr.width + "x" + etr.height);
}
PacketImageData.writeRGB16(buffer, etr);
}
}else {
buffer.writeByte(0);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return -1;
}
}

View File

@ -0,0 +1,65 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSetPlayerCape implements EaglerBackendRPCPacket {
public boolean notifyOthers;
public byte[] capePacket;
public CPacketRPCSetPlayerCape() {
}
public CPacketRPCSetPlayerCape(boolean notifyOthers, byte[] capePacket) {
this.notifyOthers = notifyOthers;
this.capePacket = capePacket;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
notifyOthers = buffer.readBoolean();
capePacket = new byte[buffer.readUnsignedShort()];
buffer.readFully(capePacket);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(capePacket.length > 32720) {
throw new IOException("Cape data cannot be longer than 32720 bytes!");
}
buffer.writeBoolean(notifyOthers);
buffer.writeShort(capePacket.length);
buffer.write(capePacket);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 3 + capePacket.length;
}
}

View File

@ -0,0 +1,83 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSetPlayerCookie implements EaglerBackendRPCPacket {
public boolean revokeQuerySupported;
public boolean saveToDisk;
public int expires;
public byte[] cookieData;
public CPacketRPCSetPlayerCookie() {
}
public CPacketRPCSetPlayerCookie(boolean revokeQuerySupported, boolean saveToDisk, int expires,
byte[] cookieData) {
this.revokeQuerySupported = revokeQuerySupported;
this.saveToDisk = saveToDisk;
this.expires = expires;
this.cookieData = cookieData;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
int flags = buffer.readUnsignedByte();
revokeQuerySupported = (flags & 1) == 1;
saveToDisk = (flags & 2) == 2;
expires = buffer.readInt();
int cookieLen = buffer.readUnsignedByte();
if(cookieLen > 0) {
cookieData = new byte[cookieLen];
buffer.readFully(cookieData);
}else {
cookieData = null;
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(cookieData != null && cookieData.length > 255) {
throw new IOException("Cookie cannot be longer than 255 bytes!");
}
buffer.writeByte((revokeQuerySupported ? 1 : 0) | (saveToDisk ? 2 : 0));
buffer.writeInt(expires);
if(cookieData != null) {
buffer.writeByte(cookieData.length);
buffer.write(cookieData);
}else {
buffer.writeByte(0);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 6 + (cookieData != null ? cookieData.length : 0);
}
}

View File

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSetPlayerFNAWEn implements EaglerBackendRPCPacket {
public boolean enable;
public boolean force;
public CPacketRPCSetPlayerFNAWEn() {
}
public CPacketRPCSetPlayerFNAWEn(boolean enable, boolean force) {
this.enable = enable;
this.force = force;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
int flags = buffer.readUnsignedByte();
enable = (flags & 1) != 0;
force = (flags & 2) != 0;
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeByte((enable ? 1 : 0) | (force ? 2 : 0));
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 1;
}
}

View File

@ -0,0 +1,65 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSetPlayerSkin implements EaglerBackendRPCPacket {
public boolean notifyOthers;
public byte[] skinPacket;
public CPacketRPCSetPlayerSkin() {
}
public CPacketRPCSetPlayerSkin(boolean notifyOthers, byte[] skinPacket) {
this.notifyOthers = notifyOthers;
this.skinPacket = skinPacket;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
notifyOthers = buffer.readBoolean();
skinPacket = new byte[buffer.readUnsignedShort()];
buffer.readFully(skinPacket);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(skinPacket.length > 32720) {
throw new IOException("Skin data cannot be longer than 32720 bytes!");
}
buffer.writeBoolean(notifyOthers);
buffer.writeShort(skinPacket.length);
buffer.write(skinPacket);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 3 + skinPacket.length;
}
}

View File

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CPacketRPCSubscribeEvents implements EaglerBackendRPCPacket {
public static final int SUBSCRIBE_EVENT_WEBVIEW_OPEN_CLOSE = 1;
public static final int SUBSCRIBE_EVENT_WEBVIEW_MESSAGE = 2;
public static final int SUBSCRIBE_EVENT_TOGGLE_VOICE = 4;
public int eventsToEnable;
public CPacketRPCSubscribeEvents() {
}
public CPacketRPCSubscribeEvents(int eventsToEnable) {
this.eventsToEnable = eventsToEnable;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
eventsToEnable = buffer.readUnsignedShort();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeShort(eventsToEnable);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleClient(this);
}
@Override
public int length() {
return 2;
}
}

View File

@ -0,0 +1,62 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCEnabledFailure implements EaglerBackendRPCPacket {
public static final int FAILURE_CODE_NOT_ENABLED = 0;
public static final int FAILURE_CODE_NOT_EAGLER_PLAYER = 1;
public static final int FAILURE_CODE_OUTDATED_SERVER = 2;
public static final int FAILURE_CODE_OUTDATED_CLIENT = 3;
public static final int FAILURE_CODE_INTERNAL_ERROR = 0xFF;
public int failureCode;
public SPacketRPCEnabledFailure() {
}
public SPacketRPCEnabledFailure(int failureCode) {
this.failureCode = failureCode;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
failureCode = buffer.readUnsignedByte();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeByte(failureCode);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 1;
}
}

View File

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCEnabledSuccess implements EaglerBackendRPCPacket {
public int selectedRPCProtocol;
public int playerClientProtocol;
public SPacketRPCEnabledSuccess() {
}
public SPacketRPCEnabledSuccess(int selectedRPCProtocol, int playerClientProtocol) {
this.selectedRPCProtocol = selectedRPCProtocol;
this.playerClientProtocol = playerClientProtocol;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
selectedRPCProtocol = buffer.readUnsignedShort();
playerClientProtocol = buffer.readUnsignedShort();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeShort(selectedRPCProtocol);
buffer.writeShort(playerClientProtocol);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 4;
}
}

View File

@ -0,0 +1,64 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCEventToggledVoice implements EaglerBackendRPCPacket {
public static final int VOICE_STATE_SERVER_DISABLE = 0;
public static final int VOICE_STATE_DISABLED = 1;
public static final int VOICE_STATE_ENABLED = 2;
public int oldVoiceState;
public int newVoiceState;
public SPacketRPCEventToggledVoice() {
}
public SPacketRPCEventToggledVoice(int oldVoiceState, int newVoiceState) {
this.oldVoiceState = oldVoiceState;
this.newVoiceState = newVoiceState;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
int i = buffer.readUnsignedByte();
oldVoiceState = (i >>> 4) & 15;
newVoiceState = i & 15;
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeByte((oldVoiceState << 4) | newVoiceState);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 1;
}
}

View File

@ -0,0 +1,86 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCEventWebViewMessage implements EaglerBackendRPCPacket {
public static final int MESSAGE_TYPE_STRING = 0;
public static final int MESSAGE_TYPE_BINARY = 1;
public String channelName;
public int messageType;
public byte[] messageContent;
public SPacketRPCEventWebViewMessage() {
}
public SPacketRPCEventWebViewMessage(String channelName, int messageType, byte[] messageContent) {
this.channelName = channelName;
this.messageType = messageType;
this.messageContent = messageContent;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
byte[] nameBytes = new byte[buffer.readUnsignedByte()];
buffer.readFully(nameBytes);
channelName = new String(nameBytes, StandardCharsets.US_ASCII);
messageType = buffer.readUnsignedByte();
messageContent = new byte[buffer.readUnsignedShort()];
buffer.readFully(messageContent);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(channelName == null || channelName.length() == 0) {
throw new IOException("Channel name cannot be empty!");
}
if(channelName.length() > 255) {
throw new IOException("Channel name cannot be more than 255 chars! (got " + channelName.length() + " chars)");
}
if(messageContent == null) {
throw new IOException("Message contents cannot be null!");
}
if(messageContent.length > 32720) {
throw new IOException("Message contents cannot be more then 32720 bytes! (got " + messageContent.length + " bytes)");
}
byte[] nameBytes = channelName.getBytes(StandardCharsets.US_ASCII);
buffer.writeByte(nameBytes.length);
buffer.write(nameBytes);
buffer.writeByte(messageType);
buffer.writeShort(messageContent.length);
buffer.write(messageContent);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 4 + channelName.length() + messageContent.length;
}
}

View File

@ -0,0 +1,71 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCEventWebViewOpenClose implements EaglerBackendRPCPacket {
public boolean channelOpen;
public String channelName;
public SPacketRPCEventWebViewOpenClose() {
}
public SPacketRPCEventWebViewOpenClose(boolean channelOpen, String channelName) {
this.channelOpen = channelOpen;
this.channelName = channelName;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
channelOpen = buffer.readBoolean();
byte[] nameBytes = new byte[buffer.readUnsignedByte()];
buffer.readFully(nameBytes);
channelName = new String(nameBytes, StandardCharsets.US_ASCII);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(channelName == null || channelName.length() == 0) {
throw new IOException("Channel name cannot be empty!");
}
if(channelName.length() > 255) {
throw new IOException("Channel name cannot be more than 255 chars! (got " + channelName.length() + " chars)");
}
buffer.writeBoolean(channelOpen);
byte[] nameBytes = channelName.getBytes(StandardCharsets.US_ASCII);
buffer.writeByte(nameBytes.length);
buffer.write(nameBytes);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 2 + channelName.length();
}
}

View File

@ -0,0 +1,65 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeBytes implements EaglerBackendRPCPacket {
public int requestID;
public byte[] response;
public SPacketRPCResponseTypeBytes() {
}
public SPacketRPCResponseTypeBytes(int requestID, byte[] response) {
this.requestID = requestID;
this.response = response;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
response = new byte[buffer.readUnsignedShort()];
buffer.readFully(response);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
if(response.length > 32720) {
throw new IOException("Response is too long, max is 32720 bytes! (got " + response.length + " bytes)");
}
buffer.writeInt(requestID);
buffer.writeShort(response.length);
buffer.write(response);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 6 + response.length;
}
}

View File

@ -0,0 +1,83 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeCookie implements EaglerBackendRPCPacket {
public int requestID;
public boolean cookiesEnabled;
public byte[] cookieData;
public SPacketRPCResponseTypeCookie() {
}
public SPacketRPCResponseTypeCookie(int requestID, boolean cookiesEnabled, byte[] cookieData) {
this.requestID = requestID;
this.cookiesEnabled = cookiesEnabled;
this.cookieData = cookieData;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
int flags = buffer.readUnsignedByte();
cookiesEnabled = (flags & 1) != 0;
int len = cookiesEnabled ? buffer.readUnsignedByte() : 0;
if(cookiesEnabled && len > 0) {
cookieData = new byte[len];
buffer.readFully(cookieData);
}else {
cookieData = null;
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
if(cookiesEnabled) {
buffer.writeByte(1);
if(cookieData != null && cookieData.length > 0) {
if(cookieData.length > 255) {
throw new IOException("Cookie is too long, max is 255 bytes! (got " + cookieData.length + " bytes)");
}
buffer.writeByte(cookieData.length);
buffer.write(cookieData);
}else {
buffer.writeByte(0);
}
}else {
buffer.writeByte(0);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return cookiesEnabled ? (cookieData != null ? (6 + cookieData.length) : 6) : 5;
}
}

View File

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeError implements EaglerBackendRPCPacket {
public int requestID;
public String errorMessage;
public SPacketRPCResponseTypeError() {
}
public SPacketRPCResponseTypeError(int requestID, String errorMessage) {
this.requestID = requestID;
this.errorMessage = errorMessage;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
errorMessage = buffer.readUTF();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
buffer.writeUTF(errorMessage);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return -1;
}
}

View File

@ -0,0 +1,56 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeNull implements EaglerBackendRPCPacket {
public int requestID;
public SPacketRPCResponseTypeNull() {
}
public SPacketRPCResponseTypeNull(int requestID) {
this.requestID = requestID;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 4;
}
}

View File

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeString implements EaglerBackendRPCPacket {
public int requestID;
public String response;
public SPacketRPCResponseTypeString() {
}
public SPacketRPCResponseTypeString(int requestID, String response) {
this.requestID = requestID;
this.response = response;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
byte[] responseBytes = new byte[buffer.readUnsignedShort()];
buffer.readFully(responseBytes);
response = new String(responseBytes, StandardCharsets.UTF_8);
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);
if(responseBytes.length > 32720) {
throw new IOException("Response is too long, max is 32720 bytes! (got " + responseBytes.length + " bytes)");
}
buffer.writeInt(requestID);
buffer.writeShort(responseBytes.length);
buffer.write(responseBytes);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return -1;
}
}

View File

@ -0,0 +1,62 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeUUID implements EaglerBackendRPCPacket {
public int requestID;
public UUID uuid;
public SPacketRPCResponseTypeUUID() {
}
public SPacketRPCResponseTypeUUID(int requestID, UUID uuid) {
this.requestID = requestID;
this.uuid = uuid;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
uuid = new UUID(buffer.readLong(), buffer.readLong());
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
buffer.writeLong(uuid.getMostSignificantBits());
buffer.writeLong(uuid.getLeastSignificantBits());
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 20;
}
}

View File

@ -0,0 +1,64 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeVoiceStatus implements EaglerBackendRPCPacket {
public static final int VOICE_STATE_SERVER_DISABLE = 0;
public static final int VOICE_STATE_DISABLED = 1;
public static final int VOICE_STATE_ENABLED = 2;
public int requestID;
public int voiceState;
public SPacketRPCResponseTypeVoiceStatus() {
}
public SPacketRPCResponseTypeVoiceStatus(int requestID, int voiceState) {
this.requestID = requestID;
this.voiceState = voiceState;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
voiceState = buffer.readUnsignedByte();
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
buffer.writeByte(voiceState);
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return 5;
}
}

View File

@ -0,0 +1,81 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.server;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCHandler;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.EaglerBackendRPCPacket;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SPacketRPCResponseTypeWebViewStatus implements EaglerBackendRPCPacket {
public static final int WEBVIEW_STATE_NOT_SUPPORTED = 0;
public static final int WEBVIEW_STATE_SERVER_DISABLE = 1;
public static final int WEBVIEW_STATE_CHANNEL_CLOSED = 2;
public static final int WEBVIEW_STATE_CHANNEL_OPEN = 3;
public int requestID;
public int webviewState;
public String channelName;
public SPacketRPCResponseTypeWebViewStatus() {
}
public SPacketRPCResponseTypeWebViewStatus(int requestID, int webviewState, String channelName) {
this.requestID = requestID;
this.webviewState = webviewState;
this.channelName = channelName;
}
@Override
public void readPacket(DataInput buffer) throws IOException {
requestID = buffer.readInt();
webviewState = buffer.readUnsignedByte();
if(webviewState == WEBVIEW_STATE_CHANNEL_OPEN) {
byte[] nameBytes = new byte[buffer.readUnsignedByte()];
buffer.readFully(nameBytes);
channelName = new String(nameBytes, StandardCharsets.US_ASCII);
}
}
@Override
public void writePacket(DataOutput buffer) throws IOException {
buffer.writeInt(requestID);
buffer.writeByte(webviewState);
if(webviewState == WEBVIEW_STATE_CHANNEL_OPEN) {
if(channelName.length() > 255) {
throw new IOException("Channel name cannot be more than 255 chars! (got " + channelName.length() + " chars)");
}
byte[] nameBytes = channelName.getBytes(StandardCharsets.US_ASCII);
buffer.writeByte(nameBytes.length);
buffer.write(nameBytes);
}
}
@Override
public void handlePacket(EaglerBackendRPCHandler handler) {
handler.handleServer(this);
}
@Override
public int length() {
return webviewState == WEBVIEW_STATE_CHANNEL_OPEN ? (6 + channelName.length()) : 5;
}
}

View File

@ -0,0 +1,372 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.util;
import java.util.UUID;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client.CPacketRPCNotifBadgeShow;
import net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.pkt.client.CPacketRPCNotifBadgeShow.EnumBadgePriority;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class NotificationBadgeBuilder {
public static enum BadgePriority {
LOW, NORMAL, HIGHER, HIGHEST;
}
private UUID badgeUUID = null;
private BaseComponent bodyComponent = null;
private BaseComponent titleComponent = null;
private BaseComponent sourceComponent = null;
private long originalTimestampSec = 0l;
private boolean silent = false;
private BadgePriority priority = BadgePriority.NORMAL;
private UUID mainIconUUID = null;
private UUID titleIconUUID = null;
private int hideAfterSec = 10;
private int expireAfterSec = 3600;
private int backgroundColor = 0xFFFFFF;
private int bodyTxtColor = 0xFFFFFF;
private int titleTxtColor = 0xFFFFFF;
private int sourceTxtColor = 0xFFFFFF;
private CPacketRPCNotifBadgeShow packetCache = null;
private boolean packetDirty = true;
public NotificationBadgeBuilder() {
originalTimestampSec = System.currentTimeMillis() / 1000l;
}
public NotificationBadgeBuilder(NotificationBadgeBuilder builder) {
badgeUUID = builder.badgeUUID;
bodyComponent = builder.bodyComponent;
titleComponent = builder.titleComponent;
sourceComponent = builder.sourceComponent;
originalTimestampSec = builder.originalTimestampSec;
silent = builder.silent;
priority = builder.priority;
mainIconUUID = builder.mainIconUUID;
titleIconUUID = builder.titleIconUUID;
hideAfterSec = builder.hideAfterSec;
backgroundColor = builder.backgroundColor;
bodyTxtColor = builder.bodyTxtColor;
titleTxtColor = builder.titleTxtColor;
sourceTxtColor = builder.sourceTxtColor;
packetCache = !builder.packetDirty ? builder.packetCache : null;
packetDirty = builder.packetDirty;
}
private static BaseComponent fixParsedComponent(BaseComponent[] comps) {
if(comps.length == 0) {
return null;
}else if(comps.length == 1) {
return comps[0];
}else {
TextComponent cmp = new TextComponent("");
for(int i = 0; i < comps.length; ++i) {
cmp.addExtra(comps[i]);
}
return cmp;
}
}
public NotificationBadgeBuilder(CPacketRPCNotifBadgeShow packet) {
badgeUUID = packet.badgeUUID;
try {
bodyComponent = fixParsedComponent(ComponentSerializer.parse(packet.bodyComponent));
}catch(Throwable t) {
bodyComponent = new TextComponent(packet.bodyComponent);
}
try {
titleComponent = fixParsedComponent(ComponentSerializer.parse(packet.titleComponent));
}catch(Throwable t) {
titleComponent = new TextComponent(packet.titleComponent);
}
try {
sourceComponent = fixParsedComponent(ComponentSerializer.parse(packet.sourceComponent));
}catch(Throwable t) {
sourceComponent = new TextComponent(packet.sourceComponent);
}
originalTimestampSec = packet.originalTimestampSec;
silent = packet.silent;
switch(packet.priority) {
case LOW:
default:
priority = BadgePriority.LOW;
break;
case NORMAL:
priority = BadgePriority.NORMAL;
break;
case HIGHER:
priority = BadgePriority.HIGHER;
break;
case HIGHEST:
priority = BadgePriority.HIGHEST;
break;
}
mainIconUUID = packet.mainIconUUID;
titleIconUUID = packet.titleIconUUID;
hideAfterSec = packet.hideAfterSec;
backgroundColor = packet.backgroundColor;
bodyTxtColor = packet.bodyTxtColor;
titleTxtColor = packet.titleTxtColor;
sourceTxtColor = packet.sourceTxtColor;
packetCache = packet;
packetDirty = false;
}
public UUID getBadgeUUID() {
return badgeUUID;
}
public NotificationBadgeBuilder setBadgeUUID(UUID badgeUUID) {
this.badgeUUID = badgeUUID;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setBadgeUUIDRandom() {
this.badgeUUID = UUID.randomUUID();
this.packetDirty = true;
return this;
}
public BaseComponent getBodyComponent() {
return bodyComponent;
}
public NotificationBadgeBuilder setBodyComponent(BaseComponent bodyComponent) {
this.bodyComponent = bodyComponent;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setBodyComponent(String bodyText) {
this.bodyComponent = new TextComponent(bodyText);
this.packetDirty = true;
return this;
}
public BaseComponent getTitleComponent() {
return titleComponent;
}
public NotificationBadgeBuilder setTitleComponent(BaseComponent titleComponent) {
this.titleComponent = titleComponent;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setTitleComponent(String titleText) {
this.titleComponent = new TextComponent(titleText);
this.packetDirty = true;
return this;
}
public BaseComponent getSourceComponent() {
return sourceComponent;
}
public NotificationBadgeBuilder setSourceComponent(BaseComponent sourceComponent) {
this.sourceComponent = sourceComponent;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setSourceComponent(String sourceText) {
this.sourceComponent = new TextComponent(sourceText);
this.packetDirty = true;
return this;
}
public long getOriginalTimestampSec() {
return originalTimestampSec;
}
public NotificationBadgeBuilder setOriginalTimestampSec(long originalTimestampSec) {
this.originalTimestampSec = originalTimestampSec;
this.packetDirty = true;
return this;
}
public boolean isSilent() {
return silent;
}
public NotificationBadgeBuilder setSilent(boolean silent) {
this.silent = silent;
this.packetDirty = true;
return this;
}
public BadgePriority getPriority() {
return priority;
}
public NotificationBadgeBuilder setPriority(BadgePriority priority) {
this.priority = priority;
this.packetDirty = true;
return this;
}
public UUID getMainIconUUID() {
return mainIconUUID;
}
public NotificationBadgeBuilder setMainIconUUID(UUID mainIconUUID) {
this.mainIconUUID = mainIconUUID;
this.packetDirty = true;
return this;
}
public UUID getTitleIconUUID() {
return titleIconUUID;
}
public NotificationBadgeBuilder setTitleIconUUID(UUID titleIconUUID) {
this.titleIconUUID = titleIconUUID;
this.packetDirty = true;
return this;
}
public int getHideAfterSec() {
return hideAfterSec;
}
public NotificationBadgeBuilder setHideAfterSec(int hideAfterSec) {
this.hideAfterSec = hideAfterSec;
this.packetDirty = true;
return this;
}
public int getExpireAfterSec() {
return expireAfterSec;
}
public NotificationBadgeBuilder setExpireAfterSec(int expireAfterSec) {
this.expireAfterSec = expireAfterSec;
this.packetDirty = true;
return this;
}
public int getBackgroundColor() {
return backgroundColor;
}
public NotificationBadgeBuilder setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
this.packetDirty = true;
return this;
}
public int getBodyTxtColorRGB() {
return bodyTxtColor;
}
public NotificationBadgeBuilder setBodyTxtColorRGB(int colorRGB) {
this.bodyTxtColor = colorRGB;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setBodyTxtColorRGB(int colorR, int colorG, int colorB) {
this.bodyTxtColor = (colorR << 16) | (colorG << 8) | colorB;
this.packetDirty = true;
return this;
}
public int getTitleTxtColorRGB() {
return titleTxtColor;
}
public NotificationBadgeBuilder setTitleTxtColorRGB(int colorRGB) {
this.titleTxtColor = colorRGB;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setTitleTxtColorRGB(int colorR, int colorG, int colorB) {
this.titleTxtColor = (colorR << 16) | (colorG << 8) | colorB;
this.packetDirty = true;
return this;
}
public int getSourceTxtColorRGB() {
return sourceTxtColor;
}
public NotificationBadgeBuilder setSourceTxtColorRGB(int colorRGB) {
this.sourceTxtColor = colorRGB;
this.packetDirty = true;
return this;
}
public NotificationBadgeBuilder setSourceTxtColorRGB(int colorR, int colorG, int colorB) {
this.sourceTxtColor = (colorR << 16) | (colorG << 8) | colorB;
this.packetDirty = true;
return this;
}
public Object clone() {
return new NotificationBadgeBuilder(this);
}
public CPacketRPCNotifBadgeShow buildPacket() {
if(packetDirty || packetCache == null) {
if(badgeUUID == null) {
badgeUUID = UUID.randomUUID();
}else if(badgeUUID.getMostSignificantBits() == 0l && badgeUUID.getLeastSignificantBits() == 0l) {
throw new IllegalStateException("Badge UUID cannot be 0!");
}
EnumBadgePriority internalPriority;
switch(priority) {
case LOW:
default:
internalPriority = EnumBadgePriority.LOW;
break;
case NORMAL:
internalPriority = EnumBadgePriority.NORMAL;
break;
case HIGHER:
internalPriority = EnumBadgePriority.HIGHER;
break;
case HIGHEST:
internalPriority = EnumBadgePriority.HIGHEST;
break;
}
String bodyComp = bodyComponent != null ? ComponentSerializer.toString(bodyComponent) : "";
if(bodyComp.length() > 32767) {
throw new IllegalStateException("Body component is longer than 32767 chars serialized!");
}
String titleComp = titleComponent != null ? ComponentSerializer.toString(titleComponent) : "";
if(titleComp.length() > 255) {
throw new IllegalStateException("Title component is longer than 255 chars serialized!");
}
String sourceComp = sourceComponent != null ? ComponentSerializer.toString(sourceComponent) : "";
if(sourceComp.length() > 255) {
throw new IllegalStateException("Body component is longer than 255 chars serialized!");
}
packetCache = new CPacketRPCNotifBadgeShow(badgeUUID, bodyComp, titleComp, sourceComp, originalTimestampSec,
mainIconUUID, titleIconUUID, silent, internalPriority, hideAfterSec, expireAfterSec,
backgroundColor, bodyTxtColor, titleTxtColor, sourceTxtColor);
packetDirty = false;
}
return packetCache;
}
}

View File

@ -0,0 +1,78 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.util;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PacketImageData {
public final int width;
public final int height;
public final int[] rgba;
public PacketImageData(int width, int height, int[] rgba) {
this.width = width;
this.height = height;
this.rgba = rgba;
}
public int getByteLengthRGB16() {
return 2 + (rgba.length << 1);
}
public static PacketImageData readRGB16(DataInput buffer) throws IOException {
int w = buffer.readUnsignedByte();
int h = buffer.readUnsignedByte();
int pixelCount = w * h;
int[] pixels = new int[pixelCount];
for(int j = 0, p, pR, pG, pB; j < pixelCount; ++j) {
p = buffer.readUnsignedShort();
pR = (p >>> 11) & 0x1F;
pG = (p >>> 5) & 0x3F;
pB = p & 0x1F;
if(pR + pG + pB > 0) {
pB = (int)((pB - 1) * 8.5f);
pixels[j] = 0xFF000000 | (pR << 19) | (pG << 10) | pB;
}else {
pixels[j] = 0;
}
}
return new PacketImageData(w, h, pixels);
}
public static void writeRGB16(DataOutput buffer, PacketImageData imageData) throws IOException {
if(imageData.width < 1 || imageData.width > 255 || imageData.height < 1 || imageData.height > 255) {
throw new IOException("Invalid image dimensions in packet, must be between 1x1 and 255x255, got " + imageData.width + "x" + imageData.height);
}
buffer.writeByte(imageData.width);
buffer.writeByte(imageData.height);
int pixelCount = imageData.width * imageData.height;
for(int j = 0, p, pR, pG, pB; j < pixelCount; ++j) {
p = imageData.rgba[j];
if((p >>> 24) > 0x7F) {
pR = (p >>> 19) & 0x1F;
pG = (p >>> 10) & 0x3F;
pB = (int)((p & 0xFF) * 0.1176471f) + 1;
buffer.writeShort((pR << 11) | (pG << 5) | pB);
}else {
buffer.writeShort(0);
}
}
}
}

View File

@ -0,0 +1,214 @@
package net.lax1dude.eaglercraft.v1_8.plugin.backend_rpc_protocol.util;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SkinPacketHelper {
public static byte[] writePresetSkinPacket(int presetId) {
byte[] tex = new byte[5];
tex[0] = (byte)1;
tex[1] = (byte)(presetId >>> 24);
tex[2] = (byte)(presetId >>> 16);
tex[3] = (byte)(presetId >>> 8);
tex[4] = (byte)(presetId & 0xFF);
return tex;
}
public static byte[] loadCustomSkin(File texture64x64) throws IOException {
return loadCustomSkin(ImageIO.read(texture64x64));
}
public static byte[] loadCustomSkin(InputStream texture64x64) throws IOException {
return loadCustomSkin(ImageIO.read(texture64x64));
}
public static byte[] loadCustomSkin(BufferedImage texture64x64) {
if(texture64x64.getWidth() != 64 || texture64x64.getHeight() != 64) {
throw new IllegalArgumentException("Image is not 64x64!");
}
byte[] tex = new byte[16384];
for(int y = 0; y < 64; ++y) {
for(int x = 0; x < 64; ++x) {
int idx = (y << 8) | (x << 2);
int rgba = texture64x64.getRGB(x, y);
tex[idx] = (byte)(rgba >>> 24);
tex[idx + 1] = (byte)(rgba & 0xFF);
tex[idx + 2] = (byte)(rgba >>> 8);
tex[idx + 3] = (byte)(rgba >>> 16);
}
}
return tex;
}
public static byte[] writeCustomSkinPacket(int modelId, byte[] texture64x64) {
if(texture64x64.length != 16384) {
throw new IllegalArgumentException("Wrong array length for 64x64 RGBA texture!");
}
byte[] tex = new byte[2 + texture64x64.length];
tex[0] = (byte)2;
tex[1] = (byte)modelId;
System.arraycopy(texture64x64, 0, tex, 2, texture64x64.length);
return tex;
}
public static byte[] writeCustomSkinPacket(int modelId, File texture64x64) throws IOException {
return writeCustomSkinPacket(modelId, ImageIO.read(texture64x64));
}
public static byte[] writeCustomSkinPacket(int modelId, InputStream texture64x64) throws IOException {
return writeCustomSkinPacket(modelId, ImageIO.read(texture64x64));
}
public static byte[] writeCustomSkinPacket(int modelId, BufferedImage texture64x64) {
if(texture64x64.getWidth() != 64 || texture64x64.getHeight() != 64) {
throw new IllegalArgumentException("Image is not 64x64!");
}
byte[] tex = new byte[16386];
tex[0] = (byte)2;
tex[1] = (byte)modelId;
for(int y = 0; y < 64; ++y) {
for(int x = 0; x < 64; ++x) {
int idx = (y << 8) | (x << 2);
int rgba = texture64x64.getRGB(x, y);
tex[idx + 2] = (byte)(rgba >>> 24);
tex[idx + 3] = (byte)(rgba & 0xFF);
tex[idx + 4] = (byte)(rgba >>> 8);
tex[idx + 5] = (byte)(rgba >>> 16);
}
}
return tex;
}
public static byte[] writePresetCapePacket(int presetId) {
byte[] tex = new byte[5];
tex[0] = (byte)1;
tex[1] = (byte)(presetId >>> 24);
tex[2] = (byte)(presetId >>> 16);
tex[3] = (byte)(presetId >>> 8);
tex[4] = (byte)(presetId & 0xFF);
return tex;
}
public static byte[] loadCustomCape(File textureNx32) throws IOException {
return loadCustomCape(ImageIO.read(textureNx32));
}
public static byte[] loadCustomCape(InputStream textureNx32) throws IOException {
return loadCustomCape(ImageIO.read(textureNx32));
}
public static byte[] loadCustomCape(BufferedImage textureNx32) {
if((textureNx32.getWidth() != 32 && textureNx32.getWidth() != 64) || textureNx32.getHeight() != 32) {
throw new IllegalArgumentException("Image is not 32x32 or 64x32!");
}
byte[] tex = new byte[4096];
for(int y = 0; y < 32; ++y) {
for(int x = 0; x < 32; ++x) {
int idx = (y << 7) | (x << 2);
int rgba = textureNx32.getRGB(x, y);
tex[idx] = (byte)(rgba >>> 24);
tex[idx + 1] = (byte)(rgba & 0xFF);
tex[idx + 2] = (byte)(rgba >>> 8);
tex[idx + 3] = (byte)(rgba >>> 16);
}
}
return tex;
}
public static byte[] writeCustomCapePacket(File textureNx32) throws IOException {
return writeCustomCapePacket(ImageIO.read(textureNx32));
}
public static byte[] writeCustomCapePacket(InputStream textureNx32) throws IOException {
return writeCustomCapePacket(ImageIO.read(textureNx32));
}
public static byte[] writeCustomCapePacket(BufferedImage textureNx32) {
byte[] tex = loadCustomCape(textureNx32);
byte[] ret = new byte[1174];
ret[0] = (byte)2;
convertCape32x32RGBAto23x17RGB(tex, 0, ret, 1);
return ret;
}
public static byte[] writeCustomCapePacket(byte[] texture32x32) {
if(texture32x32.length != 4096) {
throw new IllegalArgumentException("Wrong array length for 32x32 RGBA texture!");
}
byte[] tex = new byte[1174];
tex[0] = (byte)2;
convertCape32x32RGBAto23x17RGB(texture32x32, 0, tex, 1);
return tex;
}
public static void convertCape32x32RGBAto23x17RGB(byte[] skinIn, byte[] skinOut) {
convertCape32x32RGBAto23x17RGB(skinIn, 0, skinOut, 0);
}
public static void convertCape32x32RGBAto23x17RGB(byte[] skinIn, int inOffset, byte[] skinOut, int outOffset) {
int i, j;
for(int y = 0; y < 17; ++y) {
for(int x = 0; x < 22; ++x) {
i = inOffset + ((y * 32 + x) << 2);
j = outOffset + ((y * 23 + x) * 3);
skinOut[j] = skinIn[i + 1];
skinOut[j + 1] = skinIn[i + 2];
skinOut[j + 2] = skinIn[i + 3];
}
}
for(int y = 0; y < 11; ++y) {
i = inOffset + (((y + 11) * 32 + 22) << 2);
j = outOffset + (((y + 6) * 23 + 22) * 3);
skinOut[j] = skinIn[i + 1];
skinOut[j + 1] = skinIn[i + 2];
skinOut[j + 2] = skinIn[i + 3];
}
}
public static void convertCape23x17RGBto32x32RGBA(byte[] skinIn, byte[] skinOut) {
convertCape23x17RGBto32x32RGBA(skinIn, 0, skinOut, 0);
}
public static void convertCape23x17RGBto32x32RGBA(byte[] skinIn, int inOffset, byte[] skinOut, int outOffset) {
int i, j;
for(int y = 0; y < 17; ++y) {
for(int x = 0; x < 22; ++x) {
i = outOffset + ((y * 32 + x) << 2);
j = inOffset + ((y * 23 + x) * 3);
skinOut[i] = (byte)0xFF;
skinOut[i + 1] = skinIn[j];
skinOut[i + 2] = skinIn[j + 1];
skinOut[i + 3] = skinIn[j + 2];
}
}
for(int y = 0; y < 11; ++y) {
i = outOffset + (((y + 11) * 32 + 22) << 2);
j = inOffset + (((y + 6) * 23 + 22) * 3);
skinOut[i] = (byte)0xFF;
skinOut[i + 1] = skinIn[j];
skinOut[i + 2] = skinIn[j + 1];
skinOut[i + 3] = skinIn[j + 2];
}
}
}