Merge pull request #12 from drunderscore/feature/player-selected-slot

Track the players selected slot index
This commit is contained in:
LOOHP 2021-02-22 22:24:59 +08:00 committed by GitHub
commit 2a0839963a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 134 additions and 6 deletions

View File

@ -0,0 +1,32 @@
package com.loohp.limbo.Events;
import com.loohp.limbo.Player.Player;
public class PlayerSelectedSlotChangeEvent extends PlayerEvent implements Cancellable {
private boolean cancel = false;
private byte slot;
public PlayerSelectedSlotChangeEvent(Player player, byte slot) {
super(player);
this.slot = slot;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancel = cancelled;
}
@Override
public boolean isCancelled() {
return cancel;
}
public byte getSlot() {
return slot;
}
public void setSlot(byte slot) {
this.slot = slot;
}
}

View File

@ -18,6 +18,7 @@ import com.loohp.limbo.Server.Packets.PacketPlayOutChat;
import com.loohp.limbo.Server.Packets.PacketPlayOutGameState; import com.loohp.limbo.Server.Packets.PacketPlayOutGameState;
import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook; import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook;
import com.loohp.limbo.Server.Packets.PacketPlayOutRespawn; import com.loohp.limbo.Server.Packets.PacketPlayOutRespawn;
import com.loohp.limbo.Server.Packets.PacketPlayOutHeldItemChange;
import com.loohp.limbo.Utils.GameMode; import com.loohp.limbo.Utils.GameMode;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -32,6 +33,7 @@ public class Player extends LivingEntity implements CommandSender {
protected final String username; protected final String username;
protected GameMode gamemode; protected GameMode gamemode;
protected DataWatcher watcher; protected DataWatcher watcher;
protected byte selectedSlot;
@WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT) @WatchableField(MetadataIndex = 14, WatchableObjectType = WatchableObjectType.FLOAT)
protected float additionalHearts = 0.0F; protected float additionalHearts = 0.0F;
@ -56,7 +58,23 @@ public class Player extends LivingEntity implements CommandSender {
this.watcher = new DataWatcher(this); this.watcher = new DataWatcher(this);
this.watcher.update(); this.watcher.update();
} }
public byte getSelectedSlot() {
return selectedSlot;
}
public void setSelectedSlot(byte slot) {
if(slot == selectedSlot)
return;
try {
PacketPlayOutHeldItemChange state = new PacketPlayOutHeldItemChange(slot);
clientConnection.sendPacket(state);
} catch (IOException e) {
e.printStackTrace();
}
this.selectedSlot = slot;
}
public GameMode getGamemode() { public GameMode getGamemode() {
return gamemode; return gamemode;
} }

View File

@ -22,5 +22,10 @@ public class Unsafe {
public void a(Player a, Location b) { public void a(Player a, Location b) {
a.setLocation(b); a.setLocation(b);
} }
@Deprecated
public void a(Player a, byte b) {
a.selectedSlot = b;
}
} }

View File

@ -23,6 +23,7 @@ import com.loohp.limbo.Events.PlayerLoginEvent;
import com.loohp.limbo.Events.PlayerMoveEvent; import com.loohp.limbo.Events.PlayerMoveEvent;
import com.loohp.limbo.Events.PlayerQuitEvent; import com.loohp.limbo.Events.PlayerQuitEvent;
import com.loohp.limbo.Events.StatusPingEvent; import com.loohp.limbo.Events.StatusPingEvent;
import com.loohp.limbo.Events.PlayerSelectedSlotChangeEvent;
import com.loohp.limbo.File.ServerProperties; import com.loohp.limbo.File.ServerProperties;
import com.loohp.limbo.Location.Location; import com.loohp.limbo.Location.Location;
import com.loohp.limbo.Player.Player; import com.loohp.limbo.Player.Player;
@ -58,6 +59,8 @@ import com.loohp.limbo.Server.Packets.PacketStatusInPing;
import com.loohp.limbo.Server.Packets.PacketStatusInRequest; import com.loohp.limbo.Server.Packets.PacketStatusInRequest;
import com.loohp.limbo.Server.Packets.PacketStatusOutPong; import com.loohp.limbo.Server.Packets.PacketStatusOutPong;
import com.loohp.limbo.Server.Packets.PacketStatusOutResponse; import com.loohp.limbo.Server.Packets.PacketStatusOutResponse;
import com.loohp.limbo.Server.Packets.PacketPlayInHeldItemChange;
import com.loohp.limbo.Server.Packets.PacketPlayOutHeldItemChange;
import com.loohp.limbo.Utils.CustomStringUtils; import com.loohp.limbo.Utils.CustomStringUtils;
import com.loohp.limbo.Utils.DataTypeIO; import com.loohp.limbo.Utils.DataTypeIO;
import com.loohp.limbo.Utils.GameMode; import com.loohp.limbo.Utils.GameMode;
@ -423,6 +426,19 @@ public class ClientConnection extends Thread {
} else { } else {
player.chat(chat.getMessage()); player.chat(chat.getMessage());
} }
} else if(packetType.equals(PacketPlayInHeldItemChange.class)) {
PacketPlayInHeldItemChange change = new PacketPlayInHeldItemChange(input);
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte)change.getSlot()));
if(event.isCancelled()) {
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
sendPacket(cancelPacket);
} else if(change.getSlot() != event.getSlot()) {
PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot());
sendPacket(changePacket);
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
} else {
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
}
} else { } else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }

View File

@ -0,0 +1,21 @@
package com.loohp.limbo.Server.Packets;
import java.io.DataInputStream;
import java.io.IOException;
public class PacketPlayInHeldItemChange extends PacketIn {
private final short slot;
public PacketPlayInHeldItemChange(short slot) {
this.slot = slot;
}
public PacketPlayInHeldItemChange(DataInputStream in) throws IOException {
this(in.readShort());
}
public short getSlot() {
return slot;
}
}

View File

@ -0,0 +1,29 @@
package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class PacketPlayOutHeldItemChange extends PacketOut {
private final byte slot;
public PacketPlayOutHeldItemChange(byte slot) {
this.slot = slot;
}
public byte getSlot() {
return slot;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeByte(slot);
return buffer.toByteArray();
}
}

View File

@ -28,12 +28,17 @@ public class Unsafe {
worldConstructor.setAccessible(false); worldConstructor.setAccessible(false);
} catch (Exception e) {e.printStackTrace();} } catch (Exception e) {e.printStackTrace();}
} }
@Deprecated @Deprecated
public void setPlayerGameModeSilently(Player player, GameMode mode) { public void setPlayerGameModeSilently(Player player, GameMode mode) {
playerUnsafe.a(player, mode); playerUnsafe.a(player, mode);
} }
@Deprecated
public void setSelectedSlotSilently(Player player, byte slot) {
playerUnsafe.a(player, slot);
}
@Deprecated @Deprecated
public void setPlayerEntityId(Player player, int entityId) { public void setPlayerEntityId(Player player, int entityId) {
playerUnsafe.a(player, entityId); playerUnsafe.a(player, entityId);

View File

@ -18,7 +18,8 @@
"0x12": "PacketPlayInPosition", "0x12": "PacketPlayInPosition",
"0x14": "PacketPlayInRotation", "0x14": "PacketPlayInRotation",
"0x0B": "PacketPlayInPluginMessaging", "0x0B": "PacketPlayInPluginMessaging",
"0x06": "PacketPlayInTabComplete" "0x06": "PacketPlayInTabComplete",
"0x25": "PacketPlayInHeldItemChange"
}, },
"PlayOut": { "PlayOut": {
"PacketPlayOutLogin": "0x24", "PacketPlayOutLogin": "0x24",
@ -41,7 +42,8 @@
"PacketPlayOutEntityDestroy": "0x36", "PacketPlayOutEntityDestroy": "0x36",
"PacketPlayOutEntityMetadata": "0x44", "PacketPlayOutEntityMetadata": "0x44",
"PacketPlayOutSpawnEntity": "0x00", "PacketPlayOutSpawnEntity": "0x00",
"PacketPlayOutSpawnEntityLiving": "0x02" "PacketPlayOutSpawnEntityLiving": "0x02",
"PacketPlayOutHeldItemChange": "0x3F"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",