Skip to content

Commit b3e1f06

Browse files
committed
fix: Tracker#show
1 parent 3b9bb42 commit b3e1f06

File tree

7 files changed

+176
-116
lines changed

7 files changed

+176
-116
lines changed

api/src/main/java/kr/toxicity/model/api/data/renderer/RenderPipeline.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public void viewFilter(@NotNull Predicate<Player> filter) {
109109
this.viewFilter = this.viewFilter.and(Objects.requireNonNull(filter));
110110
}
111111
public void hideFilter(@NotNull Predicate<Player> filter) {
112-
this.hideFilter = this.hideFilter.and(Objects.requireNonNull(filter));
112+
this.hideFilter = this.hideFilter.or(Objects.requireNonNull(filter));
113113
}
114114

115115
public void spawnPacketHandler(@NotNull Consumer<PacketBundler> spawnPacketHandler) {
@@ -296,8 +296,7 @@ public int playerCount() {
296296
}
297297

298298
public boolean hide(@NotNull Player player) {
299-
if (isHide(player)) return false;
300-
hidePlayerSet.add(player.getUniqueId());
299+
if (isHide(player) || !hidePlayerSet.add(player.getUniqueId())) return false;
301300
if (isSpawned(player.getUniqueId())) {
302301
var bundler = createBundler();
303302
iterateTree(b -> b.forceUpdate(false, bundler));
@@ -313,8 +312,7 @@ public boolean isHide(@NotNull Player player) {
313312
}
314313

315314
public boolean show(@NotNull Player player) {
316-
if (!isHide(player)) return false;
317-
hidePlayerSet.remove(player.getUniqueId());
315+
if (!isHide(player) || !hidePlayerSet.remove(player.getUniqueId())) return false;
318316
if (isSpawned(player.getUniqueId())) {
319317
var bundler = createBundler();
320318
iterateTree(b -> b.forceUpdate(true, bundler));

api/src/main/java/kr/toxicity/model/api/tracker/EntityTrackerRegistry.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import kr.toxicity.model.api.util.ThreadUtil;
2424
import kr.toxicity.model.api.util.lock.DuplexLock;
2525
import lombok.RequiredArgsConstructor;
26+
import lombok.ToString;
2627
import org.bukkit.NamespacedKey;
2728
import org.bukkit.entity.Entity;
2829
import org.bukkit.entity.Player;
@@ -44,6 +45,7 @@
4445
/**
4546
* A registry of each entity's tracker
4647
*/
48+
@ToString(onlyExplicitlyIncluded = true)
4749
public final class EntityTrackerRegistry {
4850

4951
private static final Object2ReferenceMap<UUID, EntityTrackerRegistry> UUID_REGISTRY_MAP = new Object2ReferenceOpenHashMap<>();
@@ -54,13 +56,16 @@ public final class EntityTrackerRegistry {
5456
*/
5557
public static final NamespacedKey TRACKING_ID = Objects.requireNonNull(NamespacedKey.fromString("bettermodel_tracker"));
5658

59+
@ToString.Include
5760
private final AtomicBoolean closed = new AtomicBoolean();
5861
private final AtomicBoolean loaded = new AtomicBoolean();
62+
@ToString.Include
5963
private final Entity entity;
6064
private final int id;
6165
private final UUID uuid;
6266
private final EntityAdapter adapter;
6367
private final ConcurrentNavigableMap<String, EntityTracker> trackerMap = new ConcurrentSkipListMap<>();
68+
@ToString.Include
6469
private final Collection<EntityTracker> trackers = Collections.unmodifiableCollection(trackerMap.values());
6570
private final Map<UUID, PlayerChannelCache> viewedPlayerMap = new ConcurrentHashMap<>();
6671
final Map<UUID, MountedHitBox> mountedHitBoxCache = new ConcurrentHashMap<>();

api/src/main/java/kr/toxicity/model/api/tracker/Tracker.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,11 @@ private void send() {
899899
}
900900
}
901901

902+
@Override
903+
public String toString() {
904+
return name();
905+
}
906+
902907
@RequiredArgsConstructor
903908
public enum CloseReason {
904909
REMOVE(false),

core/src/main/kotlin/kr/toxicity/model/command/CommandModule.kt

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import dev.jorel.commandapi.CommandAPICommand
1010
import dev.jorel.commandapi.SuggestionInfo
1111
import dev.jorel.commandapi.arguments.Argument
1212
import dev.jorel.commandapi.arguments.ArgumentSuggestions
13+
import dev.jorel.commandapi.arguments.IntegerArgument
1314
import dev.jorel.commandapi.commandsenders.BukkitCommandSender
1415
import dev.jorel.commandapi.executors.CommandArguments
1516
import dev.jorel.commandapi.executors.CommandExecutionInfo
@@ -35,6 +36,13 @@ fun Argument<*>.suggestNullable(block: (SuggestionInfo<CommandSender>) -> Collec
3536
inline fun <reified T : Any> CommandArguments.map(name: String, ifNull: () -> T) = get(name) as? T ?: ifNull()
3637
inline fun <reified T : Any> CommandArguments.map(name: String, ifNull: T) = get(name) as? T ?: ifNull
3738
inline fun <reified T : Any> CommandArguments.map(name: String) = get(name) as T
39+
inline fun <reified T : Any> CommandArguments.any(name: String, block: (T) -> Boolean): Boolean {
40+
var success = false
41+
mapNullable<Collection<T>>(name)?.forEach {
42+
if (block(it)) success = true
43+
}
44+
return success
45+
}
3846
inline fun <reified T : Any> CommandArguments.mapNullable(name: String) = get(name) as? T
3947
inline fun <reified T : Any> CommandArguments.mapString(name: String, mapper: (String) -> T) = map<String>(name).let(mapper)
4048
inline fun <reified T : Any> CommandArguments.mapNullableString(name: String, mapper: (String) -> T?) = mapNullable<String>(name)?.let(mapper)
@@ -45,111 +53,119 @@ class CommandModule(
4553
parent: CommandModule?,
4654
private val delegate: CommandAPICommand
4755
) : CommandExecutionInfo {
48-
companion object {
49-
private val upperLineMessage = componentOf("------ BetterModel ${PLUGIN.semver()} ------") {
50-
color(GRAY)
51-
}
52-
private val underLineMessage = componentOf("----------------------------------") {
53-
color(GRAY)
54-
}
55-
private val requiredMessage = componentOf(
56-
" <arg>".toComponent(RED),
57-
spaceComponentOf(),
58-
" - required".toComponent()
59-
)
60-
private val optionalMessage = componentOf(
61-
" [arg]".toComponent(DARK_AQUA),
62-
spaceComponentOf(),
63-
" - optional".toComponent()
56+
private companion object {
57+
const val PAGE_SPLIT_INDEX = 6
58+
59+
val prefix = listOf(
60+
emptyComponentOf(),
61+
"------ BetterModel ${PLUGIN.semver()} ------".toComponent(GRAY),
62+
emptyComponentOf()
6463
)
65-
private val usefulLinks = componentOf {
66-
decorate(TextDecoration.BOLD)
67-
append(spaceComponentOf())
68-
append(componentOf("[Wiki]") {
69-
color(AQUA)
70-
toURLComponent("https://github.com/toxicity188/BetterModel/wiki")
71-
})
72-
append(spaceComponentOf())
73-
append(componentOf("[Download]") {
74-
color(GREEN)
75-
toURLComponent("https://modrinth.com/plugin/bettermodel/versions")
76-
})
77-
append(spaceComponentOf())
78-
append(componentOf("[Discord]") {
79-
color(BLUE)
80-
toURLComponent("https://discord.com/invite/rePyFESDbk")
81-
})
82-
}
8364

84-
private fun TextComponent.Builder.toURLComponent(url: String) = hoverEvent(HoverEvent.showText(componentOf(
65+
val fullPrefix = listOf(
66+
prefix,
67+
listOf(
68+
componentOf {
69+
decorate(TextDecoration.BOLD)
70+
append(spaceComponentOf())
71+
append(componentOf("[Wiki]") {
72+
color(AQUA)
73+
toURLComponent("https://github.com/toxicity188/BetterModel/wiki")
74+
})
75+
append(spaceComponentOf())
76+
append(componentOf("[Download]") {
77+
color(GREEN)
78+
toURLComponent("https://modrinth.com/plugin/bettermodel/versions")
79+
})
80+
append(spaceComponentOf())
81+
append(componentOf("[Discord]") {
82+
color(BLUE)
83+
toURLComponent("https://discord.com/invite/rePyFESDbk")
84+
})
85+
},
86+
emptyComponentOf(),
87+
componentOf(
88+
" <arg>".toComponent(RED),
89+
spaceComponentOf(),
90+
" - required".toComponent()
91+
),
92+
componentOf(
93+
" [arg]".toComponent(DARK_AQUA),
94+
spaceComponentOf(),
95+
" - optional".toComponent()
96+
),
97+
emptyComponentOf()
98+
)
99+
).flatten()
100+
101+
fun TextComponent.Builder.toURLComponent(url: String) = hoverEvent(HoverEvent.showText(componentOf(
85102
url.toComponent(DARK_AQUA),
86103
lineComponentOf(),
87104
lineComponentOf(),
88105
"Click to open link.".toComponent()
89106
))).clickEvent(ClickEvent.openUrl(url))
90107

91-
private val CommandAPICommand.shortName get() = if (aliases.isNotEmpty()) aliases.first() else name
108+
val CommandAPICommand.shortName: String get() = if (aliases.isNotEmpty()) aliases.first() else name
92109

93-
private fun String.toTypeName() = lowercase().replace('_', ' ')
110+
fun String.toTypeName() = lowercase().replace('_', ' ')
94111
}
95112

96113
private val rootName: String = parent?.let { "${it.rootName} ${delegate.name}" } ?: delegate.shortName
97114
private val rootPermission: String = parent?.let { "${it.rootPermission}.${delegate.name}" } ?: delegate.name
115+
116+
private val rootNameComponent = "/$rootName".toComponent(YELLOW)
117+
private val sub = mutableMapOf<String, CommandAPICommand>()
118+
private val maxPage get() = sub.size / PAGE_SPLIT_INDEX + 1
119+
private val helpComponentRange get() = 1..maxPage
98120
private val helpComponents by lazy {
99-
mutableListOf(
100-
emptyComponentOf(),
101-
upperLineMessage,
102-
emptyComponentOf(),
103-
usefulLinks,
104-
emptyComponentOf(),
105-
requiredMessage,
106-
optionalMessage,
107-
emptyComponentOf(),
108-
).apply {
109-
sub.sortedBy {
110-
it.name
111-
}.forEach {
112-
add(it.toComponent())
113-
}
114-
add(underLineMessage)
115-
add(emptyComponentOf())
116-
}.toTypedArray()
121+
helpComponentRange.map { index ->
122+
(if (index == 1) fullPrefix else prefix).toMutableList()
123+
.also { list ->
124+
sub.values.toList().subList(PAGE_SPLIT_INDEX * (index - 1), (PAGE_SPLIT_INDEX * index).coerceAtMost(sub.size)).forEach {
125+
list += it.toComponent()
126+
}
127+
list += "/$rootName [help] [page] - help command.".toComponent(LIGHT_PURPLE)
128+
list += emptyComponentOf()
129+
list += "---------< Page $index / $maxPage >---------".toComponent(GRAY)
130+
}.toTypedArray()
131+
}
117132
}
133+
private val pageArgs get() = IntegerArgument("page")
118134

119135
init {
120136
delegate.withPermission(rootPermission)
137+
command("help") {
138+
withAliases("h")
139+
withOptionalArguments(pageArgs.suggest { helpComponentRange.map(Any::toString) })
140+
withShortDescription("shows help command to player.")
141+
executes(this@CommandModule)
142+
}
121143
}
122144

123-
private fun CommandAPICommand.autoPermission() = withPermission("$rootPermission.$name")
124-
private val sub = mutableListOf(
125-
CommandAPICommand("help")
126-
.withAliases("h")
127-
.withShortDescription("shows help command to player.")
128-
.autoPermission()
129-
.executes(this)
130-
)
131-
132145
fun command(name: String, block: CommandAPICommand.() -> Unit): CommandModule {
133-
sub.add(CommandAPICommand(name)
134-
.autoPermission()
146+
sub[name] = CommandAPICommand(name)
147+
.withPermission("$rootPermission.$name")
135148
.apply(block)
136-
)
137149
return this
138150
}
139151

140152
fun commandModule(name: String, block: CommandAPICommand.() -> Unit) = CommandModule(this, CommandAPICommand(name).apply(block))
141153

142154
fun build(): CommandAPICommand = delegate
143-
.withSubcommands(*sub.toTypedArray())
155+
.withOptionalArguments(pageArgs)
156+
.withSubcommands(*sub.values.toTypedArray())
144157
.executes(this)
145158

146159

147160
override fun run(info: ExecutionInfo<CommandSender, BukkitCommandSender<out CommandSender>>) {
148-
info.sender().audience().info(*helpComponents)
161+
val page = (info.args().mapNullable<Int>("page") ?: 1)
162+
.coerceAtLeast(1)
163+
.coerceAtMost(sub.size / PAGE_SPLIT_INDEX + 1)
164+
info.sender().audience().info(*helpComponents[page - 1])
149165
}
150166

151167
private fun CommandAPICommand.toComponent() = componentOf {
152-
append("/$rootName".toComponent(YELLOW))
168+
append(rootNameComponent)
153169
append(spaceComponentOf())
154170
append(name.toComponent())
155171
append(arguments.map {

0 commit comments

Comments
 (0)