Tab-list
This commit is contained in:
@@ -7,6 +7,8 @@ package mc.core.network;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class NetStream {
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -24,6 +26,7 @@ public abstract class NetStream {
|
||||
public abstract float readFloat();
|
||||
public abstract double readDouble();
|
||||
public abstract String readString();
|
||||
public abstract UUID readUUID();
|
||||
|
||||
public abstract void writeBoolean(boolean value);
|
||||
public abstract void writeByte(int value);
|
||||
@@ -36,6 +39,7 @@ public abstract class NetStream {
|
||||
public abstract void writeFloat(float value);
|
||||
public abstract void writeDouble(double value);
|
||||
public abstract void writeString(String value);
|
||||
public abstract void writeUUID(UUID uuid);
|
||||
|
||||
public abstract void skipBytes(int count);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.network.NetStream;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
public abstract class NetStream_p340 extends NetStream {
|
||||
@@ -70,4 +71,15 @@ public abstract class NetStream_p340 extends NetStream {
|
||||
writeBytes(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID readUUID() {
|
||||
return new UUID(readLong(), readLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeUUID(UUID uuid) {
|
||||
writeLong(uuid.getMostSignificantBits());
|
||||
writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +60,13 @@ public enum State {
|
||||
.put(PluginMessagePacket.class, 0x18)
|
||||
.put(KeepAlivePacket.class, 0x1F)
|
||||
.put(JoinGamePacket.class, 0x23)
|
||||
.put(PlayerAbilitiesPacket.class, 0x2C)
|
||||
.put(PlayerListItemPacket.class, 0x2E)
|
||||
.put(PlayerPositionAndLookPacket.class, 0x2F)
|
||||
.put(SpawnPositionPacket.class, 0x46)
|
||||
.put(TimeUpdatePacket.class, 0x47)
|
||||
.put(TitlePacket.class, 0x48)
|
||||
.put(PlayerAbilitiesPacket.class, 0x2C)
|
||||
.put(PlayerPositionAndLookPacket.class, 0x2F)
|
||||
.put(PlayerListHeaderAndFooterPacket.class, 0x4A)
|
||||
.build()
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2018-07-11
|
||||
*/
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import mc.core.network.NetStream;
|
||||
import mc.core.network.SCPacket;
|
||||
import mc.core.network.proto_1_12_2.serializers.TextSerializer;
|
||||
import mc.core.text.Text;
|
||||
|
||||
@Setter
|
||||
@ToString
|
||||
public class PlayerListHeaderAndFooterPacket implements SCPacket {
|
||||
// To remove the header/footer, send a empty translatable component: {"translate":""}
|
||||
private Text header;
|
||||
private Text footer;
|
||||
|
||||
@Override
|
||||
public void writeSelf(NetStream netStream) {
|
||||
if (header == null) {
|
||||
netStream.writeString("{\"translate\":\"\"}");
|
||||
} else {
|
||||
netStream.writeString(TextSerializer.serialize(header).toString());
|
||||
}
|
||||
|
||||
if (footer == null) {
|
||||
netStream.writeString("{\"translate\":\"\"}");
|
||||
} else {
|
||||
netStream.writeString(TextSerializer.serialize(footer).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* DmitriyMX <dimon550@gmail.com>
|
||||
* 2018-07-11
|
||||
*/
|
||||
package mc.core.network.proto_1_12_2.packets;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import mc.core.network.NetStream;
|
||||
import mc.core.network.SCPacket;
|
||||
import mc.core.network.proto_1_12_2.serializers.TextSerializer;
|
||||
import mc.core.player.PlayerMode;
|
||||
import mc.core.text.Text;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class PlayerListItemPacket implements SCPacket {
|
||||
public static final int ACTION_ADD_PLAYER = 0,
|
||||
ACTION_UPDATE_GAMEMODE = 1,
|
||||
ACTION_UPDATE_LATENCY = 2,
|
||||
ACTION_UPDATE_DISPLAY_NAME = 3,
|
||||
ACTION_REMOVE_PLAYER = 4;
|
||||
|
||||
@Data
|
||||
@ToString
|
||||
public static class PlayerData {
|
||||
private UUID uuid;
|
||||
private String name;
|
||||
private Properties properties = new Properties();
|
||||
private PlayerMode gameMode;
|
||||
private int ping;
|
||||
private boolean hasDisplayName = false;
|
||||
private Text displayName;
|
||||
}
|
||||
|
||||
private int action;
|
||||
private List<PlayerData> listPlayers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void writeSelf(NetStream netStream) {
|
||||
netStream.writeVarInt(action);
|
||||
netStream.writeVarInt(listPlayers.size());
|
||||
|
||||
for (PlayerData playerData : listPlayers) {
|
||||
netStream.writeUUID(playerData.uuid);
|
||||
|
||||
if (action == ACTION_ADD_PLAYER) {
|
||||
netStream.writeString(playerData.name);
|
||||
netStream.writeVarInt(playerData.properties.size());
|
||||
|
||||
for (Map.Entry<Object, Object> entry : playerData.properties.entrySet()) {
|
||||
netStream.writeString(entry.getKey().toString());
|
||||
netStream.writeString(entry.getValue().toString());
|
||||
netStream.writeBoolean(false); // Is Signed
|
||||
}
|
||||
}
|
||||
|
||||
if (action == ACTION_ADD_PLAYER || action == ACTION_UPDATE_GAMEMODE) {
|
||||
netStream.writeVarInt(playerData.gameMode.getId());
|
||||
}
|
||||
|
||||
if (action == ACTION_ADD_PLAYER || action == ACTION_UPDATE_LATENCY) {
|
||||
netStream.writeVarInt(playerData.ping);
|
||||
}
|
||||
|
||||
if (action == ACTION_ADD_PLAYER || action == ACTION_UPDATE_DISPLAY_NAME) {
|
||||
netStream.writeBoolean(playerData.hasDisplayName);
|
||||
if (playerData.hasDisplayName) {
|
||||
netStream.writeString(TextSerializer.serialize(playerData.displayName).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import mc.core.player.PlayerManager;
|
||||
import mc.core.player.PlayerMode;
|
||||
import mc.core.text.Text;
|
||||
import mc.core.text.TextColor;
|
||||
import mc.core.text.TextStyle;
|
||||
import mc.core.world.World;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -86,6 +87,31 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
|
||||
channel.writeAndFlush(pkt4);
|
||||
|
||||
player.setChannel(new WrapperNetChannel(channel));
|
||||
|
||||
// Send <Tab> items
|
||||
PlayerListItemPacket pkt5 = new PlayerListItemPacket();
|
||||
pkt5.setAction(PlayerListItemPacket.ACTION_ADD_PLAYER);
|
||||
PlayerListItemPacket.PlayerData playerData = new PlayerListItemPacket.PlayerData();
|
||||
playerData.setUuid(player.getUUID());
|
||||
playerData.setName(player.getName());
|
||||
playerData.setGameMode(PlayerMode.CREATIVE);
|
||||
playerData.setPing(0);
|
||||
playerData.setHasDisplayName(true);
|
||||
playerData.setDisplayName(Text.builder()
|
||||
.append(Text.of(TextColor.RED, TextStyle.BOLD, player.getName().substring(0,1)))
|
||||
.append(Text.of(TextColor.WHITE, player.getName().substring(1)))
|
||||
.build()
|
||||
);
|
||||
pkt5.getListPlayers().add(playerData);
|
||||
channel.writeAndFlush(pkt5);
|
||||
|
||||
// Send header/footer БЕфиЮ list
|
||||
PlayerListHeaderAndFooterPacket pkt6 = new PlayerListHeaderAndFooterPacket();
|
||||
Text text = Text.of(TextColor.GOLD, "=============================");
|
||||
pkt6.setHeader(text);
|
||||
pkt6.setFooter(text);
|
||||
channel.writeAndFlush(pkt6);
|
||||
|
||||
playerManager.joinServer(player);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user