Skip to content

Commit a2ceb71

Browse files
authored
Add Bedrock Support (#1)
* Add `floodgate` dependency * Add `floodgate` dependency in `pom.xml` * Implement floodgate detection * Update the ui to reflect bedrock specifications
1 parent d6da61f commit a2ceb71

File tree

6 files changed

+143
-26
lines changed

6 files changed

+143
-26
lines changed

pom.xml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@
4949
<pattern>games.negative.alumina</pattern>
5050
<shadedPattern>fun.supersmp.codelock.libs.alumina</shadedPattern>
5151
</relocation>
52-
<!-- <relocation>-->
53-
<!-- <pattern>de.exlll.configlib</pattern>-->
54-
<!-- <shadedPattern>fun.supersmp.codelock.libs.config</shadedPattern>-->
55-
<!-- </relocation>-->
5652
</relocations>
5753
</configuration>
5854
</plugin>
@@ -131,20 +127,26 @@
131127
<scope>provided</scope>
132128
</dependency>
133129

134-
<!-- ConfigLib -->
135-
<!-- <dependency>-->
136-
<!-- <groupId>de.exlll</groupId>-->
137-
<!-- <artifactId>configlib-yaml</artifactId>-->
138-
<!-- <version>4.5.0</version>-->
139-
<!-- <scope>compile</scope>-->
140-
<!-- </dependency>-->
141-
142130
<!-- PlaceholderAPI -->
143131
<dependency>
144132
<groupId>me.clip</groupId>
145133
<artifactId>placeholderapi</artifactId>
146134
<version>2.11.5</version>
147135
<scope>provided</scope>
148136
</dependency>
137+
138+
<!-- Floodgate API -->
139+
<dependency>
140+
<groupId>org.geysermc.floodgate</groupId>
141+
<artifactId>api</artifactId>
142+
<version>2.2.2-SNAPSHOT</version>
143+
<scope>provided</scope>
144+
<exclusions>
145+
<exclusion>
146+
<groupId>org.geysermc.cumulus</groupId>
147+
<artifactId>cumulus</artifactId>
148+
</exclusion>
149+
</exclusions>
150+
</dependency>
149151
</dependencies>
150152
</project>

src/main/java/fun/supersmp/codelock/listener/PlayerListener.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import fun.supersmp.codelock.ui.EditCodeMenu;
1010
import fun.supersmp.codelock.ui.EnterCodeMenu;
1111
import games.negative.alumina.util.NBTEditor;
12-
import lombok.RequiredArgsConstructor;
13-
import org.bukkit.Chunk;
1412
import org.bukkit.Location;
1513
import org.bukkit.block.Block;
1614
import org.bukkit.block.BlockState;
@@ -28,18 +26,23 @@
2826
import org.bukkit.event.block.BlockBreakEvent;
2927
import org.bukkit.event.block.BlockPlaceEvent;
3028
import org.bukkit.event.player.PlayerInteractEvent;
31-
import org.bukkit.material.PressureSensor;
3229
import org.bukkit.persistence.PersistentDataType;
30+
import org.geysermc.floodgate.api.FloodgateApi;
3331
import org.jetbrains.annotations.NotNull;
3432
import org.jetbrains.annotations.Nullable;
3533

3634
import java.util.List;
3735
import java.util.UUID;
3836
import java.util.stream.Collectors;
3937

40-
@RequiredArgsConstructor
4138
public class PlayerListener implements Listener {
4239

40+
private final FloodgateApi api;
41+
42+
public PlayerListener() {
43+
this.api = FloodgateApi.getInstance();
44+
}
45+
4346
@EventHandler(priority = EventPriority.LOWEST)
4447
public void onBlockPlace(@NotNull BlockPlaceEvent event) {
4548
Player player = event.getPlayer();
@@ -110,6 +113,7 @@ public void onInteract(@NotNull PlayerInteractEvent event) {
110113
if (data == null) return;
111114

112115
UUID uuid = player.getUniqueId();
116+
boolean isBedrockPlayer = api.isFloodgatePlayer(uuid);
113117
if (player.hasPermission(Perm.ADMIN) || data.authorized().contains(uuid)) {
114118
if (!isOwner(data, uuid)) return;
115119

@@ -119,15 +123,15 @@ public void onInteract(@NotNull PlayerInteractEvent event) {
119123
if (!player.isSneaking() || !event.getAction().equals(Action.LEFT_CLICK_BLOCK) || notHoldingAir) return;
120124

121125
// we're going to open the code menu to modify the code and authorized users
122-
new EditCodeMenu(jukebox, data.authorized(), data.code()).open(player);
126+
new EditCodeMenu(jukebox, data.authorized(), data.code(), isBedrockPlayer).open(player);
123127
return;
124128
}
125129

126130
event.setUseInteractedBlock(Event.Result.DENY);
127131
event.setUseItemInHand(Event.Result.DENY);
128132
event.setCancelled(true);
129133

130-
new EnterCodeMenu(jukebox, data.code()).open(player);
134+
new EnterCodeMenu(jukebox, data.code(), isBedrockPlayer).open(player);
131135
}
132136

133137
/**

src/main/java/fun/supersmp/codelock/ui/AuthorizedUsersMenu.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ public class AuthorizedUsersMenu extends PaginatedMenu {
3131
private final Jukebox data;
3232
private final List<UUID> authorized;
3333
private final String code;
34-
public AuthorizedUsersMenu(@NotNull Jukebox data, @NotNull List<UUID> authorized, @Nullable String code) {
34+
private final boolean isBedrockUser;
35+
public AuthorizedUsersMenu(@NotNull Jukebox data, @NotNull List<UUID> authorized, @Nullable String code, boolean isBedrockUser) {
3536
super("Authorized Users", 5);
3637
setCancelClicks(true);
3738

3839
this.data = data;
3940
this.authorized = authorized;
4041
this.code = code;
42+
this.isBedrockUser = isBedrockUser;
4143

4244
List<Integer> fillerSlots = IntList.getList(List.of("0-9", "17-18", "26-27", "35-44"));
4345
for (int slot : fillerSlots) {
@@ -70,7 +72,7 @@ public AuthorizedUsersMenu(@NotNull Jukebox data, @NotNull List<UUID> authorized
7072

7173
@Override
7274
public void onClose(@NotNull Player player, @NotNull InventoryCloseEvent event) {
73-
Tasks.run(() -> new EditCodeMenu(data, authorized, code).open(player), 2);
75+
Tasks.run(() -> new EditCodeMenu(data, authorized, code, isBedrockUser).open(player), 2);
7476
}
7577

7678
@RequiredArgsConstructor

src/main/java/fun/supersmp/codelock/ui/EditCodeMenu.java

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
import games.negative.alumina.builder.ItemBuilder;
66
import games.negative.alumina.menu.ChestMenu;
77
import games.negative.alumina.menu.MenuButton;
8+
import games.negative.alumina.util.ColorUtil;
89
import games.negative.alumina.util.IntList;
10+
import games.negative.alumina.util.ItemUpdater;
911
import games.negative.alumina.util.NBTEditor;
1012
import lombok.RequiredArgsConstructor;
13+
import org.bukkit.ChatColor;
1114
import org.bukkit.Material;
1215
import org.bukkit.block.Jukebox;
1316
import org.bukkit.entity.Player;
@@ -27,18 +30,34 @@ public class EditCodeMenu extends ChestMenu {
2730
private final List<UUID> users;
2831
private final String original;
2932
private String code;
30-
public EditCodeMenu(@NotNull Jukebox data, @NotNull List<UUID> users, @Nullable String code) {
31-
this.code = code;
33+
private final boolean isBedrockUser;
34+
private MenuButton display = null;
35+
public EditCodeMenu(@NotNull Jukebox data, @NotNull List<UUID> users, @Nullable String code, boolean isBedrockUser) {
36+
this.code = (code == null ? "" : code);
3237
this.original = code;
3338
this.data = data;
3439
this.users = users;
40+
this.isBedrockUser = isBedrockUser;
3541

3642
setRows(6);
3743
title();
3844
setCancelClicks(true);
3945

46+
// Only add the "display" button if the user is a Bedrock user
47+
// due to differences in packets sent to the client
48+
if (this.isBedrockUser) {
49+
display = MenuButton.builder().slot(25).item(new ItemBuilder(Material.PAPER).setName("&f ").build()).build();
50+
addButton(display);
51+
52+
updateDisplayItem();
53+
}
54+
4055
List<Integer> fillerSlots = IntList.getList(List.of("0-11", "15-20", "24-29", "33-39", "41-46", "48", "50", "52-53"));
4156
for (int slot : fillerSlots) {
57+
// Probably a better way to do this,
58+
// but this is straightforward & quick.
59+
if (this.isBedrockUser && slot == 25) continue;
60+
4261
addButton(MenuButton.builder().slot(slot).item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).setName(" ").build()).build());
4362
}
4463

@@ -73,6 +92,11 @@ public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull
7392

7493
code += character;
7594

95+
if (isBedrockUser) {
96+
updateDisplayItem();
97+
return;
98+
}
99+
76100
title();
77101
}
78102
}
@@ -84,6 +108,12 @@ public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull
84108
if (code == null || code.isEmpty()) return;
85109

86110
code = code.substring(0, code.length() - 1);
111+
112+
if (isBedrockUser) {
113+
updateDisplayItem();
114+
return;
115+
}
116+
87117
title();
88118
}
89119
}
@@ -124,11 +154,36 @@ public class AuthorizedUsersMenuClickHandler implements MenuButton.ClickAction {
124154

125155
@Override
126156
public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull InventoryClickEvent event) {
127-
new AuthorizedUsersMenu(data, users, code).open(player);
157+
new AuthorizedUsersMenu(data, users, code, isBedrockUser).open(player);
128158
}
129159
}
130160

131161
private void title() {
132162
updateTitle("Enter Code!" + ((code == null || code.isEmpty()) ? "" : " | " + code));
133163
}
164+
165+
@SuppressWarnings("deprecation") // Paper API Deprecation
166+
private void updateDisplayItem() {
167+
display.updateItem(itemStack -> {
168+
ItemUpdater.of(itemStack, meta -> {
169+
if (code == null || code.isEmpty()) {
170+
meta.setDisplayName(ChatColor.WHITE + " ");
171+
return;
172+
}
173+
174+
// Split all characters of "code" into an array
175+
char[] chars = code.toCharArray();
176+
177+
StringBuilder displayName = new StringBuilder();
178+
for (char aChar : chars) {
179+
displayName.append(ChatColor.GREEN).append(aChar).append(" ");
180+
}
181+
182+
meta.setDisplayName(ColorUtil.translate(displayName.toString()));
183+
});
184+
185+
return itemStack;
186+
});
187+
refreshButton(display.getSlot());
188+
}
134189
}

src/main/java/fun/supersmp/codelock/ui/EnterCodeMenu.java

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
import games.negative.alumina.builder.ItemBuilder;
77
import games.negative.alumina.menu.ChestMenu;
88
import games.negative.alumina.menu.MenuButton;
9+
import games.negative.alumina.util.ColorUtil;
910
import games.negative.alumina.util.IntList;
11+
import games.negative.alumina.util.ItemUpdater;
1012
import games.negative.alumina.util.NBTEditor;
1113
import lombok.RequiredArgsConstructor;
14+
import org.bukkit.ChatColor;
1215
import org.bukkit.Material;
1316
import org.bukkit.block.Jukebox;
1417
import org.bukkit.entity.Player;
@@ -28,17 +31,33 @@ public class EnterCodeMenu extends ChestMenu {
2831
private final Jukebox data;
2932
private final String code;
3033
private String current;
31-
public EnterCodeMenu(@NotNull Jukebox data, @Nullable String code) {
34+
private final boolean isBedrockUser;
35+
private MenuButton display = null;
36+
public EnterCodeMenu(@NotNull Jukebox data, @Nullable String code, boolean isBedrockUser) {
3237
this.code = (code == null ? "" : code);
3338
this.current = "";
3439
this.data = data;
40+
this.isBedrockUser = isBedrockUser;
3541

3642
setRows(6);
3743
title();
3844
setCancelClicks(true);
3945

46+
// Only add the "display" button if the user is a Bedrock user
47+
// due to differences in packets sent to the client
48+
if (this.isBedrockUser) {
49+
display = MenuButton.builder().slot(25).item(new ItemBuilder(Material.PAPER).setName("&f ").build()).build();
50+
addButton(display);
51+
52+
updateDisplayItem();
53+
}
54+
4055
List<Integer> fillerSlots = IntList.getList(List.of("0-11", "15-20", "24-29", "33-39", "41-47", "49", "51-53"));
4156
for (int slot : fillerSlots) {
57+
// Probably a better way to do this,
58+
// but this is straightforward & quick.
59+
if (this.isBedrockUser && slot == 25) continue;
60+
4261
addButton(MenuButton.builder().slot(slot).item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).setName(" ").build()).build());
4362
}
4463

@@ -70,6 +89,11 @@ public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull
7089

7190
current += character;
7291

92+
if (isBedrockUser) {
93+
updateDisplayItem();
94+
return;
95+
}
96+
7397
title();
7498
}
7599
}
@@ -81,6 +105,12 @@ public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull
81105
if (current.isEmpty()) return;
82106

83107
current = current.substring(0, current.length() - 1);
108+
109+
if (isBedrockUser) {
110+
updateDisplayItem();
111+
return;
112+
}
113+
84114
title();
85115
}
86116
}
@@ -89,7 +119,7 @@ public class SubmitClickHandler implements MenuButton.ClickAction {
89119

90120
@Override
91121
public void onClick(@NotNull MenuButton button, @NotNull Player player, @NotNull InventoryClickEvent event) {
92-
if (current.isEmpty() || current.length() == CODE_CHARACTER_LIMIT) return;
122+
if (current.isEmpty() || current.length() != CODE_CHARACTER_LIMIT) return;
93123

94124
boolean unlocked = current.equals(code);
95125
if (!unlocked) {
@@ -127,4 +157,28 @@ private void title() {
127157
updateTitle("Enter Code!" + (current.isEmpty() ? "" : " | " + current));
128158
}
129159

160+
@SuppressWarnings("deprecation") // Paper API Deprecation
161+
private void updateDisplayItem() {
162+
display.updateItem(itemStack -> {
163+
ItemUpdater.of(itemStack, meta -> {
164+
if (current == null || current.isEmpty()) {
165+
meta.setDisplayName(ChatColor.WHITE + " ");
166+
return;
167+
}
168+
169+
// Split all characters of "code" into an array
170+
char[] chars = current.toCharArray();
171+
172+
StringBuilder displayName = new StringBuilder();
173+
for (char aChar : chars) {
174+
displayName.append(ChatColor.GREEN).append(aChar).append(" ");
175+
}
176+
177+
meta.setDisplayName(ColorUtil.translate(displayName.toString()));
178+
});
179+
180+
return itemStack;
181+
});
182+
refreshButton(display.getSlot());
183+
}
130184
}

src/main/resources/plugin.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ authors: [ "ericlmao" ]
55
api-version: 1.20
66
load: POSTWORLD
77

8-
depend: ["PlaceholderAPI"]
8+
depend: ["PlaceholderAPI", "floodgate"]

0 commit comments

Comments
 (0)