Skip to content

Commit

Permalink
Merge branch 'gui'
Browse files Browse the repository at this point in the history
  • Loading branch information
TimeBather committed Dec 2, 2024
2 parents 01a4b63 + f0c78a3 commit ca835ba
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 77 deletions.
7 changes: 6 additions & 1 deletion src/main/java/kasuga/lib/core/menu/GuiMenuManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ public void init(){
GuiMenuNetworking.invoke();
locatorRegistry.register(
KasugaLib.STACKS.REGISTRY.asResource("block"),
MenuLocatorTypes.CHUNK_MENU
MenuLocatorTypes.BLOCK
);
locatorRegistry.register(
KasugaLib.STACKS.REGISTRY.asResource("entity"),
MenuLocatorTypes.ENTITY
);

}

public void initClient(){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package kasuga.lib.core.menu.locator;

import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;

import java.util.List;

public abstract class AbstractChunkBasedLocator extends MenuLocator implements IChunkBasedLocator {
protected Level level;
protected ResourceKey<Level> levelResourceKey;
protected final ChunkPos chunkPos;

protected AbstractChunkBasedLocator(MenuLocatorType<?> type, ChunkPos chunkPos) {
super(type);
this.chunkPos = chunkPos;
}

protected AbstractChunkBasedLocator(MenuLocatorType<?> type, FriendlyByteBuf byteBuf) {
super(type);
this.chunkPos = byteBuf.readChunkPos();
this.levelResourceKey = byteBuf.readResourceKey(Registry.DIMENSION_REGISTRY);
}

@Override
public void write(FriendlyByteBuf byteBuf) {
byteBuf.writeChunkPos(chunkPos);
byteBuf.writeResourceKey(levelResourceKey);
}

public void withLevel(Level level) {
if (this.levelResourceKey != null) {
return;
}
this.level = level;
this.levelResourceKey = level.dimension();
}

@Override
public void enable(LocatedMenuManager manager) {
super.enable(manager);
this.listen();
if (!level.hasChunk(chunkPos.x, chunkPos.z)) {
return;
}
this.broadcastEnable();
}

protected void broadcastEnable() {
List<ServerPlayer> players =
((ServerChunkCache) level
.getChunkSource()
)
.chunkMap
.getPlayers(chunkPos, false);
if (players == null)
return;

for (ServerPlayer player : players) {
sendUpTo(player.connection.getConnection());
}
}

protected void listen() {
ServerChunkMenuLocatorManager.register(this);
}

protected void unlisten() {
ServerChunkMenuLocatorManager.unregister(this);
}

@Override
public void disable(LocatedMenuManager manager) {
this.broadcastDisable();
super.disable(manager);
this.unlisten();
}

@Override
public ChunkPos getPosition() {
return chunkPos;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package kasuga.lib.core.menu.locator;

import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.ChunkPos;

public abstract class AbstractDynamicChunkBasedLocator extends AbstractChunkBasedLocator{
ChunkPos latestPos;

protected AbstractDynamicChunkBasedLocator(MenuLocatorType<?> type, ChunkPos chunkPos) {
super(type, chunkPos);
latestPos = chunkPos;
}

protected AbstractDynamicChunkBasedLocator(MenuLocatorType<?> type, FriendlyByteBuf byteBuf) {
super(type, byteBuf);
}

@Override
public void write(FriendlyByteBuf byteBuf) {
super.write(byteBuf);
}

@Override
protected void listen() {
ServerChunkMenuLocatorManager.register(this, latestPos);
}

@Override
protected void unlisten() {
ServerChunkMenuLocatorManager.unregister(this, latestPos);
}

protected void transfer(ChunkPos newChunk){
if(this.latestPos == newChunk)
return;
ServerChunkMenuLocatorManager.transfer(this, latestPos, newChunk);
latestPos = newChunk;
}
}
81 changes: 7 additions & 74 deletions src/main/java/kasuga/lib/core/menu/locator/BlockMenuLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,37 @@

import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.network.Connection;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;

public class BlockMenuLocator extends MenuLocator implements IChunkBasedLocator {
private Level level;
private ResourceKey<Level> levelResourceKey;

public class BlockMenuLocator extends AbstractChunkBasedLocator {
private final BlockPos blockPos;
private final ChunkPos chunkPos;

public BlockMenuLocator(BlockPos blockPos) {
super(MenuLocatorTypes.CHUNK_MENU);
super(MenuLocatorTypes.BLOCK, new ChunkPos(blockPos));
this.blockPos = blockPos;
this.chunkPos = new ChunkPos(blockPos);
}

public BlockMenuLocator(FriendlyByteBuf byteBuf){
super(MenuLocatorTypes.CHUNK_MENU);
public BlockMenuLocator(FriendlyByteBuf byteBuf) {
super(MenuLocatorTypes.BLOCK, byteBuf);
this.blockPos = byteBuf.readBlockPos();
this.chunkPos = new ChunkPos(byteBuf.readLong());
this.levelResourceKey = byteBuf.readResourceKey(Registry.DIMENSION_REGISTRY);
}

public BlockMenuLocator(Level level, BlockPos blockPos) {
this(blockPos);
this.withLevel(level);
}

public void withLevel(Level level){
if(this.levelResourceKey != null){
return;
}
this.level = level;
this.levelResourceKey = level.dimension();
}

@Override
public void enable(LocatedMenuManager manager) {
super.enable(manager);
this.listen();
if(!level.hasChunk(chunkPos.x, chunkPos.z)){
return;
}
this.broadcastEnable();
}

private void broadcastEnable() {
List<ServerPlayer> players =
((ServerChunkCache)level
.getChunkSource()
)
.chunkMap
.getPlayers(chunkPos, false);
if(players == null)
return;

for(ServerPlayer player : players){
sendUpTo(player.connection.getConnection());
}
}


private void listen() {
ServerChunkMenuLocatorManager.register(this);
}

private void unlisten() {
ServerChunkMenuLocatorManager.unregister(this);
}

@Override
public void disable(LocatedMenuManager manager) {
this.broadcastDisable();
super.disable(manager);
this.unlisten();
}

@Override
public void write(FriendlyByteBuf byteBuf) {
byteBuf.writeLong(blockPos.asLong());
byteBuf.writeLong(chunkPos.toLong());
byteBuf.writeResourceKey(levelResourceKey);
}

public ChunkPos getPosition() {
return chunkPos;
super.write(byteBuf);
byteBuf.writeBlockPos(blockPos);
}

public static BlockMenuLocator of(Level level, BlockPos blockPos){
public static BlockMenuLocator of(Level level, BlockPos blockPos) {
return new BlockMenuLocator(level, blockPos);
}

Expand Down
57 changes: 57 additions & 0 deletions src/main/java/kasuga/lib/core/menu/locator/EntityMenuLocator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package kasuga.lib.core.menu.locator;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;

import java.util.Objects;
import java.util.UUID;

public class EntityMenuLocator extends AbstractDynamicChunkBasedLocator {
protected final UUID entityId;
protected Entity entity;
protected EntityMenuLocator(MenuLocatorType<?> type, Entity entity) {
super(type, entity.chunkPosition());
this.entityId = entity.getUUID();
}

public EntityMenuLocator(Entity entity) {
super(MenuLocatorTypes.ENTITY, entity.chunkPosition());
this.entityId = entity.getUUID();
}

protected EntityMenuLocator(MenuLocatorType<?> type, FriendlyByteBuf byteBuf) {
super(type, byteBuf);
this.entityId = byteBuf.readUUID();
}

public EntityMenuLocator(FriendlyByteBuf byteBuf) {
super(MenuLocatorTypes.ENTITY, byteBuf);
this.entityId = byteBuf.readUUID();
}

@Override
public void write(FriendlyByteBuf byteBuf) {
super.write(byteBuf);
byteBuf.writeUUID(entityId);
}

public void tick(Entity entity){
transfer(entity.chunkPosition());
}

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof EntityMenuLocator)) return false;
EntityMenuLocator that = (EntityMenuLocator) object;
return Objects.equals(entityId, that.entityId);
}

@Override
public int hashCode() {
return Objects.hash(entityId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ public void openScreen(int index) {
}
manager.openScreen(index);
}


public MenuLocator getLocator() {
return locator;
}

public static class Builder {
private final LocatedMenuManager.Builder managerBuilder = new LocatedMenuManager.Builder();
private MenuLocator locator;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package kasuga.lib.core.menu.locator;

public class MenuLocatorTypes {
public static MenuLocatorType<BlockMenuLocator> CHUNK_MENU = new MenuLocatorType<>(BlockMenuLocator::new);
public static MenuLocatorType<BlockMenuLocator> BLOCK = new MenuLocatorType<>(BlockMenuLocator::new);
public static MenuLocatorType<EntityMenuLocator> ENTITY = new MenuLocatorType<>(EntityMenuLocator::new);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kasuga.lib.core.menu.locator;

import net.minecraft.network.Connection;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
import net.minecraftforge.event.level.ChunkWatchEvent;

Expand All @@ -10,6 +11,7 @@

public class ServerChunkMenuLocatorManager {
public static HashMap<ChunkPos, List<IChunkBasedLocator>> chunks = new HashMap<>();
public static HashMap<ChunkPos, List<ServerPlayer>> players = new HashMap<>();

public static void register(IChunkBasedLocator menuLocator, ChunkPos position) {
chunks.computeIfAbsent(position, k -> new ArrayList<>()).add(menuLocator);
Expand Down Expand Up @@ -46,10 +48,38 @@ public static void notifyUnload(ChunkPos position, Connection connection) {
}

public static void onWatch(ChunkWatchEvent.Watch watchEvent){
players.computeIfAbsent(watchEvent.getPos(), k -> new ArrayList<>()).add(watchEvent.getPlayer());
notifyLoad(watchEvent.getPos(), watchEvent.getPlayer().connection.getConnection());
}

public static void onUnWatch(ChunkWatchEvent.UnWatch unwatchEvent){
if(players.containsKey(unwatchEvent.getPos())){
List<ServerPlayer> playerList = players.get(unwatchEvent.getPos());
playerList.remove(unwatchEvent.getPlayer());
if(playerList.isEmpty()){
players.remove(unwatchEvent.getPos());
}
}
notifyUnload(unwatchEvent.getPos(), unwatchEvent.getPlayer().connection.getConnection());
}

public static void transfer(IChunkBasedLocator menuLocator, ChunkPos oldChunk, ChunkPos newChunk) {
chunks.computeIfAbsent(newChunk, k -> new ArrayList<>()).add(menuLocator);

if(chunks.containsKey(oldChunk)){
chunks.get(oldChunk).remove(menuLocator);
}

List<ServerPlayer> oldPlayers = players.get(oldChunk);
List<ServerPlayer> newPlayers = players.get(newChunk);
oldPlayers
.stream()
.filter(player -> !newPlayers.contains(player))
.forEach(player -> menuLocator.sendDownTo(player.connection.getConnection()));

newPlayers
.stream()
.filter(player -> !oldPlayers.contains(player))
.forEach(player -> menuLocator.sendUpTo(player.connection.getConnection()));
}
}

0 comments on commit ca835ba

Please sign in to comment.