Skip to content

Commit

Permalink
Add waypoint sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
UnRealDinnerbone committed Jul 4, 2024
1 parent 5af9ab0 commit c978728
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 15 deletions.
27 changes: 22 additions & 5 deletions common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.ftb.mods.ftbchunks;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
Expand Down Expand Up @@ -38,6 +39,7 @@
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
import net.minecraft.commands.arguments.coordinates.Coordinates;
import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
Expand Down Expand Up @@ -190,8 +192,14 @@ public static void registerCommands(CommandDispatcher<CommandSourceStack> dispat
.then(Commands.argument("name", StringArgumentType.string())
.then(Commands.argument("position", BlockPosArgument.blockPos())
.executes(context -> addWaypoint(context.getSource(), StringArgumentType.getString(context, "name"), BlockPosArgument.getLoadedBlockPos(context, "position")))
.then(Commands.argument("color", ColorArgument.color())
.executes(context -> addWaypoint(context.getSource(), StringArgumentType.getString(context, "name"), BlockPosArgument.getLoadedBlockPos(context, "position"), ColorArgument.getColor(context, "color")))
.then(Commands.argument("dimension", DimensionArgument.dimension())
.executes(context -> addWaypoint(context.getSource(), StringArgumentType.getString(context, "name"), DimensionArgument.getDimension(context, "dimension"), BlockPosArgument.getLoadedBlockPos(context, "position")))
.then(Commands.argument("color", ColorArgument.color())
.executes(context -> addWaypoint(context.getSource(), StringArgumentType.getString(context, "name"), DimensionArgument.getDimension(context, "dimension"), BlockPosArgument.getLoadedBlockPos(context, "position"), ColorArgument.getColor(context, "color")))
.then(Commands.argument("gui", BoolArgumentType.bool())
.executes(context -> addWaypoint(context.getSource(), StringArgumentType.getString(context, "name"), DimensionArgument.getDimension(context, "dimension"), BlockPosArgument.getLoadedBlockPos(context, "position"), ColorArgument.getColor(context, "color"), BoolArgumentType.getBool(context, "gui")))
)
)
)
)
)
Expand All @@ -202,16 +210,25 @@ public static void registerCommands(CommandDispatcher<CommandSourceStack> dispat
dispatcher.register(Commands.literal("chunks").redirect(command));
}

private static int addWaypoint(CommandSourceStack source, String name, BlockPos position, ChatFormatting color) throws CommandSyntaxException {
private static int addWaypoint(CommandSourceStack source, String name, ServerLevel level, BlockPos position, ChatFormatting color, boolean useGui) throws CommandSyntaxException {
if (color.getColor() != null) {
NetworkManager.sendToPlayer(source.getPlayerOrException(), new AddWaypointPacket(name, position, color.getColor()));
NetworkManager.sendToPlayer(source.getPlayerOrException(), new AddWaypointPacket(name, new GlobalPos(level.dimension(), position), color.getColor(), useGui));
}
return 1;
}

private static int addWaypoint(CommandSourceStack source, String name, ServerLevel level, BlockPos position, ChatFormatting color) throws CommandSyntaxException {
return addWaypoint(source, name, level ,position, color, false);
}

private static int addWaypoint(CommandSourceStack source, String name, BlockPos position) throws CommandSyntaxException {
int idx = source.getPlayerOrException().getRandom().nextInt(ChatFormatting.values().length);
return addWaypoint(source, name, position, ChatFormatting.values()[idx]);
return addWaypoint(source, name, source.getLevel() ,position, ChatFormatting.values()[idx], false);
}

private static int addWaypoint(CommandSourceStack source, String name, ServerLevel level, BlockPos position) throws CommandSyntaxException {
int idx = source.getPlayerOrException().getRandom().nextInt(ChatFormatting.values().length);
return addWaypoint(source, name, level ,position, ChatFormatting.values()[idx], false);
}

private static int bypassProtection(CommandSourceStack source) throws CommandSyntaxException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public interface FTBChunksWorldConfig {
DoubleValue MAX_IDLE_DAYS_BEFORE_UNFORCE = FORCE_LOADING.addDouble("max_idle_days_before_unforce", 0D, 0D, 3650D).comment("Maximum time (in real-world days) where if no player in a team logs in, any forceloaded chunks owned by the team are no longer forceloaded.", "Prevents chunks being forceloaded indefinitely by teams who no longer play.","Default of 0 means no automatic loss of forceloading.");
IntValue HARD_TEAM_FORCE_LIMIT = FORCE_LOADING.addInt("hard_team_force_limit", 0, 0, Integer.MAX_VALUE).comment("Hard limit for the number of chunks a team can force-load, regardless of how many members. Default of 0 means no hard limit.");

SNBTConfig WAYPOINT_SHARING = CONFIG.addGroup("waypoint_sharing");
BooleanValue WAYPOINT_SHARING_SERVER = WAYPOINT_SHARING.addBoolean("waypoint_sharing_server", true).comment("Allow players to share waypoints with the entire server.");
BooleanValue WAYPOINT_SHARING_PARTY = WAYPOINT_SHARING.addBoolean("waypoint_sharing_party", true).comment("Allow players to share waypoints with their party.");
BooleanValue WAYPOINT_SHARING_TEAM = WAYPOINT_SHARING.addBoolean("waypoint_sharing_players", true).comment("Allow players to share waypoints with other players.");

static int getMaxClaimedChunks(ChunkTeamData playerData, ServerPlayer player) {
if (player != null) {
return PermissionsHelper.getMaxClaimedChunks(player, MAX_CLAIMED_CHUNKS.get()) + playerData.getExtraClaimChunks();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1175,25 +1175,31 @@ public int getMinimapTextureId() {
return minimapTextureId;
}

public static Waypoint addWaypoint(Player player, String name, BlockPos position, int color) {
return FTBChunksAPI.clientApi().getWaypointManager(player.level().dimension()).map(mgr -> {
Waypoint wp = mgr.addWaypointAt(position, name);
public static Waypoint addWaypoint(String name, GlobalPos position, int color) {
return FTBChunksAPI.clientApi().getWaypointManager(position.dimension()).map(mgr -> {
Waypoint wp = mgr.addWaypointAt(position.pos(), name);
wp.setColor(color);
return wp;
}).orElse(null);
}

private static class WaypointAddScreen extends BaseScreen {
public static class WaypointAddScreen extends BaseScreen {
private final StringConfig name;
private final Player player;
private final GlobalPos waypointLocation;

public WaypointAddScreen(StringConfig name, Player player) {
public WaypointAddScreen(StringConfig name, Player player, GlobalPos waypointLocation) {
super();
this.name = name;
this.player = player;
this.waypointLocation = waypointLocation;
this.setHeight(35);
}

public WaypointAddScreen(StringConfig name, Player player) {
this(name, player, new GlobalPos(player.level().dimension(), player.blockPosition()));
}

@Override
public void drawBackground(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) {
}
Expand All @@ -1204,7 +1210,7 @@ public void addWidgets() {
col.setValue(Color4I.hsb(MathUtils.RAND.nextFloat(), 1F, 1F));
AddWaypointOverlay overlay = new AddWaypointOverlay(this, name, col, set -> {
if (set && !name.getValue().isEmpty()) {
Waypoint wp = addWaypoint(player, name.getValue(), player.blockPosition(), col.getValue().rgba());
Waypoint wp = addWaypoint(name.getValue(), waypointLocation, col.getValue().rgba());
Minecraft.getInstance().player.displayClientMessage(
Component.translatable("ftbchunks.waypoint_added",
Component.literal(wp.getName()).withStyle(ChatFormatting.YELLOW)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package dev.ftb.mods.ftbchunks.client.mapicon;

import com.mojang.authlib.GameProfile;
import com.mojang.blaze3d.systems.RenderSystem;
import dev.architectury.networking.NetworkManager;
import dev.ftb.mods.ftbchunks.FTBChunksWorldConfig;
import dev.ftb.mods.ftbchunks.api.client.icon.MapType;
import dev.ftb.mods.ftbchunks.api.client.icon.WaypointIcon;
import dev.ftb.mods.ftbchunks.client.gui.LargeMapScreen;
import dev.ftb.mods.ftbchunks.client.map.WaypointImpl;
import dev.ftb.mods.ftbchunks.net.ShareWaypointPacket;
import dev.ftb.mods.ftbchunks.net.TeleportFromMapPacket;
import dev.ftb.mods.ftblibrary.config.ColorConfig;
import dev.ftb.mods.ftblibrary.config.StringConfig;
import dev.ftb.mods.ftblibrary.icon.Color4I;
import dev.ftb.mods.ftblibrary.icon.FaceIcon;
import dev.ftb.mods.ftblibrary.icon.Icon;
import dev.ftb.mods.ftblibrary.icon.Icons;
import dev.ftb.mods.ftblibrary.icon.ImageIcon;
Expand All @@ -18,21 +22,32 @@
import dev.ftb.mods.ftblibrary.ui.BaseScreen;
import dev.ftb.mods.ftblibrary.ui.ColorSelectorPanel;
import dev.ftb.mods.ftblibrary.ui.ContextMenuItem;
import dev.ftb.mods.ftblibrary.ui.NordButton;
import dev.ftb.mods.ftblibrary.ui.Panel;
import dev.ftb.mods.ftblibrary.ui.input.Key;
import dev.ftb.mods.ftblibrary.ui.input.MouseButton;
import dev.ftb.mods.ftblibrary.ui.misc.AbstractButtonListScreen;
import dev.ftb.mods.ftblibrary.util.TooltipList;
import dev.ftb.mods.ftbteams.api.FTBTeamsAPI;
import dev.ftb.mods.ftbteams.api.client.KnownClientPlayer;
import dev.ftb.mods.ftbteams.client.gui.PlayerListScreen;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.Commands;
import net.minecraft.core.GlobalPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.item.Items;
import org.lwjgl.glfw.GLFW;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

public class WaypointMapIcon extends StaticMapIcon implements WaypointIcon {
private final WaypointImpl waypoint;
Expand Down Expand Up @@ -104,13 +119,83 @@ private void openWPContextMenu(LargeMapScreen screen) {
contextMenu.add(ContextMenuItem.SEPARATOR);

LocalPlayer player = Minecraft.getInstance().player;
GlobalPos waypointPos = new GlobalPos(waypoint.getDimension(), waypoint.getPos());
if(player.hasPermissions(Commands.LEVEL_GAMEMASTERS)) {
contextMenu.add(new ContextMenuItem(Component.translatable("ftbchunks.gui.teleport"), ItemIcon.getItemIcon(Items.ENDER_PEARL), b -> {
NetworkManager.sendToServer(new TeleportFromMapPacket(waypoint.getPos().above(), false, waypoint.getDimension()));
screen.closeGui(false);
}));
}

boolean shareServer = FTBChunksWorldConfig.WAYPOINT_SHARING_SERVER.get();
boolean shareParty = FTBChunksWorldConfig.WAYPOINT_SHARING_PARTY.get();
boolean sharePlayers = FTBChunksWorldConfig.WAYPOINT_SHARING_TEAM.get();

List<ContextMenuItem> shareMenu = new ArrayList<>();
if(shareServer) {
shareMenu.add(new ContextMenuItem(Component.translatable("ftbchunks.waypoint.share.server"), Icons.BEACON, b -> {
NetworkManager.sendToServer(new ShareWaypointPacket(waypoint.getName(), waypointPos, ShareWaypointPacket.ShareType.SERVER, Optional.empty()));
screen.closeGui(false);
}));
}
if(shareParty) {
shareMenu.add(new ContextMenuItem(Component.translatable("ftbchunks.waypoint.share.party"), Icons.BELL, b -> {
NetworkManager.sendToServer(new ShareWaypointPacket(waypoint.getName(), waypointPos, ShareWaypointPacket.ShareType.PARTY, Optional.empty()));
screen.closeGui(false);
}));
}
if(sharePlayers) {
shareMenu.add(new ContextMenuItem(Component.translatable("ftbchunks.waypoint.share.player"), Icons.PLAYER, b -> {
Collection<KnownClientPlayer> knownClientPlayers = FTBTeamsAPI.api().getClientManager().knownClientPlayers();
List<GameProfile> list = knownClientPlayers.stream()
.filter(KnownClientPlayer::online)
.filter(p -> !p.id().equals(player.getGameProfile().getId()))
.map(KnownClientPlayer::profile).toList();
List<GameProfile> selectedProfiles = new ArrayList<>();
new AbstractButtonListScreen() {

@Override
protected void doCancel() {
screen.closeGui(true);
}

@Override
protected void doAccept() {
NetworkManager.sendToServer(new ShareWaypointPacket(waypoint.getName(), waypointPos, ShareWaypointPacket.ShareType.PLAYER, Optional.of(selectedProfiles.stream().map(GameProfile::getId).toList())));
screen.closeGui(false);
}

@Override
public void addButtons(Panel panel) {
for (GameProfile gameProfile : list) {
Component unchecked = (Component.literal("☐ ")).append(gameProfile.getName());
Component checked = (Component.literal("☑ ").withStyle(ChatFormatting.GREEN)).append(gameProfile.getName());
NordButton widget = new NordButton(panel, unchecked, FaceIcon.getFace(gameProfile)) {
@Override
public void onClicked(MouseButton button) {
if(selectedProfiles.contains(gameProfile)) {
selectedProfiles.remove(gameProfile);
title = unchecked;
} else {
selectedProfiles.add(gameProfile);
title = checked;
}
screen.refreshWidgets();
playClickSound();
}
};
panel.add(widget);
}
}
}.openGui();

}));

}
if(shareServer || shareParty || sharePlayers) {
contextMenu.add(ContextMenuItem.subMenu(Component.translatable("ftbchunks.waypoint.share"), Icons.INFO, shareMenu));
}

contextMenu.add(new ContextMenuItem(Component.translatable("gui.rename"), Icons.CHAT, b -> {
StringConfig config = new StringConfig();
config.setValue(waypoint.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
import dev.architectury.networking.NetworkManager;
import dev.ftb.mods.ftbchunks.api.FTBChunksAPI;
import dev.ftb.mods.ftbchunks.client.FTBChunksClient;
import dev.ftb.mods.ftblibrary.config.StringConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.GlobalPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;

public record AddWaypointPacket(String name, BlockPos position, int color) implements CustomPacketPayload {
public record AddWaypointPacket(String name, GlobalPos position, int color, boolean useGui) implements CustomPacketPayload {
public static final Type<AddWaypointPacket> TYPE = new Type<>(FTBChunksAPI.rl("add_waypoint_packet"));

public static final StreamCodec<FriendlyByteBuf, AddWaypointPacket> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.STRING_UTF8, AddWaypointPacket::name,
BlockPos.STREAM_CODEC, AddWaypointPacket::position,
GlobalPos.STREAM_CODEC, AddWaypointPacket::position,
ByteBufCodecs.INT, AddWaypointPacket::color,
ByteBufCodecs.BOOL, AddWaypointPacket::useGui,
AddWaypointPacket::new
);

Expand All @@ -25,6 +28,14 @@ public Type<AddWaypointPacket> type() {
}

public static void handle(AddWaypointPacket message, NetworkManager.PacketContext context) {
context.queue(() -> FTBChunksClient.addWaypoint(context.getPlayer(), message.name, message.position, message.color));
context.queue(() -> {
if(message.useGui()) {
StringConfig configName = new StringConfig();
configName.setValue(message.name);
new FTBChunksClient.WaypointAddScreen(configName, context.getPlayer(), message.position).openGui();
}else {
FTBChunksClient.addWaypoint(message.name, message.position, message.color);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public static void init() {
NetworkHelper.registerC2S(TeleportFromMapPacket.TYPE, TeleportFromMapPacket.STREAM_CODEC, TeleportFromMapPacket::handle);
NetworkHelper.registerC2S(UpdateForceLoadExpiryPacket.TYPE, UpdateForceLoadExpiryPacket.STREAM_CODEC, UpdateForceLoadExpiryPacket::handle);
NetworkHelper.registerC2S(SyncTXPacket.TYPE, SyncTXPacket.STREAM_CODEC, SyncTXPacket::handle);
NetworkHelper.registerC2S(ShareWaypointPacket.TYPE, ShareWaypointPacket.STREAM_CODEC, ShareWaypointPacket::handle);

NetworkHelper.registerS2C(AddWaypointPacket.TYPE, AddWaypointPacket.STREAM_CODEC, AddWaypointPacket::handle);
NetworkHelper.registerS2C(ChunkChangeResponsePacket.TYPE, ChunkChangeResponsePacket.STREAM_CODEC, ChunkChangeResponsePacket::handle);
Expand Down
Loading

0 comments on commit c978728

Please sign in to comment.