mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
Updated Upstream (Paper/Purpur/Leaves)
Upstream has released updates that appear to apply and compile correctly Paper Changes: PaperMC/Paper@a5f2f614 Fix offhand item desync on cancelling interact events (#12828) PaperMC/Paper@10318775 [ci/skip] Update mache for codebook 1.0.15 (#12887) Purpur Changes: PurpurMC/Purpur@c4e5604c Updated Upstream (Paper) PurpurMC/Purpur@c130b18e Updated Upstream (Paper) PurpurMC/Purpur@60bdf1c7 Final Paper Upstream PurpurMC/Purpur@a39c4cb0 Updated Upstream (Paper) PurpurMC/Purpur@ea7b18ab Updated Upstream (Paper) PurpurMC/Purpur@0f82c210 Updated Upstream (Paper) PurpurMC/Purpur@8de15d66 this is important for the build to not fail.. PurpurMC/Purpur@5053eb0c use a different method for dropping lapis, closes #1692 Leaves Changes: LeavesMC/Leaves@df8397c7 Fix bot invulnerable LeavesMC/Leaves@e1c21d3f Movable Budding Amethyst bind carpet rule (#561) LeavesMC/Leaves@550dba49 Configurable item damage check and good shear behavior (#559) LeavesMC/Leaves@cb64df44 Old Throwable Projectile tick order (#520) LeavesMC/Leaves@b5793e80 Fix bot infinity desync (#584) LeavesMC/Leaves@c5ecbe85 1.21.7/8 (#587) LeavesMC/Leaves@5497dfb4 Fix CI LeavesMC/Leaves@2f8255bd Fix LitematicaEasyPlaceProtocol LeavesMC/Leaves@a416f476 Fix bot use actions (#606) (#605) LeavesMC/Leaves@bfde470a fix: revert Configurable-collision-behavior patch (#607) LeavesMC/Leaves@aaa2323d Fix Syncmatica file name
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package org.leavesmc.leaves.entity;
|
||||
package org.leavesmc.leaves.entity.photographer;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.leavesmc.leaves.entity;
|
||||
package org.leavesmc.leaves.entity.photographer;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Location;
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.world.level.GameRules;
|
||||
import org.dreeam.leaf.config.modules.network.ProtocolSupport;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.Context;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
@@ -16,6 +17,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "appleskin")
|
||||
public class AppleSkinProtocol implements LeavesProtocol {
|
||||
@@ -32,7 +34,7 @@ public class AppleSkinProtocol implements LeavesProtocol {
|
||||
private static final Map<ServerPlayer, Float> previousExhaustionLevels = new HashMap<>();
|
||||
private static final Map<ServerPlayer, Boolean> previousNaturalRegeneration = new HashMap<>();
|
||||
|
||||
private static final Map<ServerPlayer, Set<String>> subscribedChannels = new HashMap<>();
|
||||
private static final Map<UUID, Set<String>> subscribedChannels = new HashMap<>();
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
@@ -46,21 +48,24 @@ public class AppleSkinProtocol implements LeavesProtocol {
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
subscribedChannels.remove(player);
|
||||
subscribedChannels.remove(player.getUUID());
|
||||
resetPlayerData(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.MinecraftRegister(onlyNamespace = true)
|
||||
public static void onPlayerSubscribed(@NotNull ServerPlayer player, ResourceLocation id) {
|
||||
subscribedChannels.computeIfAbsent(player, k -> new HashSet<>()).add(id.getPath());
|
||||
public static void onPlayerSubscribed(@NotNull Context context, ResourceLocation id) {
|
||||
subscribedChannels.computeIfAbsent(context.profile().getId(), k -> new HashSet<>()).add(id.getPath());
|
||||
}
|
||||
|
||||
@ProtocolHandler.Ticker
|
||||
public static void tick() {
|
||||
for (Map.Entry<ServerPlayer, Set<String>> entry : subscribedChannels.entrySet()) {
|
||||
ServerPlayer player = entry.getKey();
|
||||
FoodData data = player.getFoodData();
|
||||
for (Map.Entry<UUID, Set<String>> entry : subscribedChannels.entrySet()) {
|
||||
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FoodData data = player.getFoodData();
|
||||
for (String channel : entry.getValue()) {
|
||||
switch (channel) {
|
||||
case "saturation" -> {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
public class ChatImageIndex {
|
||||
|
||||
public int index;
|
||||
public int total;
|
||||
public String url;
|
||||
public String bytes;
|
||||
|
||||
public ChatImageIndex(int index, int total, String url, String bytes) {
|
||||
this.index = index;
|
||||
this.total = total;
|
||||
this.url = url;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.dreeam.leaf.config.modules.network.ProtocolSupport;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.chatimage.ServerBlockCache.SERVER_BLOCK_CACHE;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "chatimage")
|
||||
public class ChatImageProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "chatimage";
|
||||
public static final Gson gson = new Gson();
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID, path);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = FileChannelPayload.class)
|
||||
public void serverFileChannelReceived(ServerPlayer player, FileChannelPayload payload) {
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
String res = payload.message();
|
||||
ChatImageIndex title = gson.fromJson(res, ChatImageIndex.class);
|
||||
Map<Integer, String> blocks = SERVER_BLOCK_CACHE.createBlock(title, res);
|
||||
if (title.total != blocks.size()) {
|
||||
return;
|
||||
}
|
||||
List<UUID> names = SERVER_BLOCK_CACHE.getUsers(title.url);
|
||||
if (names == null || player == null) {
|
||||
return;
|
||||
}
|
||||
for (UUID uuid : names) {
|
||||
ServerPlayer serverPlayer = server.getPlayerList().getPlayer(uuid);
|
||||
if (serverPlayer != null) {
|
||||
ProtocolUtils.sendPayloadPacket(serverPlayer, new FileInfoChannelPayload("true->" + title.url));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = FileInfoChannelPayload.class)
|
||||
public void serverGetFileChannelReceived(ServerPlayer player, FileInfoChannelPayload packet) {
|
||||
String url = packet.message();
|
||||
Map<Integer, String> list = SERVER_BLOCK_CACHE.getBlock(url);
|
||||
if (list == null) {
|
||||
ProtocolUtils.sendPayloadPacket(player, new FileInfoChannelPayload("null->" + url));
|
||||
SERVER_BLOCK_CACHE.tryAddUser(url, player.getUUID());
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<Integer, String> entry : list.entrySet()) {
|
||||
ProtocolUtils.sendPayloadPacket(player, new DownloadFileChannelPayload(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return ProtocolSupport.chatImageProtocol;
|
||||
}
|
||||
|
||||
public record ChatImageIndex(int index, int total, String url, String bytes) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
|
||||
public record DownloadFileChannelPayload(String message) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation ID = ChatImageProtocol.id("download_file_channel");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, DownloadFileChannelPayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.STRING_UTF8, DownloadFileChannelPayload::message, DownloadFileChannelPayload::new
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
|
||||
public record FileChannelPayload(String message) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation ID = ChatImageProtocol.id("get_file_channel");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, FileChannelPayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.STRING_UTF8, FileChannelPayload::message, FileChannelPayload::new
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
|
||||
public record FileInfoChannelPayload(String message) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation ID = ChatImageProtocol.id("file_info");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, FileInfoChannelPayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.STRING_UTF8, FileInfoChannelPayload::message, FileInfoChannelPayload::new
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.leavesmc.leaves.protocol.chatimage;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.leavesmc.leaves.LeavesLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ServerBlockCache {
|
||||
|
||||
public static final ServerBlockCache SERVER_BLOCK_CACHE = new ServerBlockCache();
|
||||
|
||||
public Cache<String, List<UUID>> userCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.SECONDS).build();
|
||||
public Cache<String, Map<Integer, String>> blockCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.SECONDS).build();
|
||||
public Cache<String, Integer> fileCount = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.SECONDS).build();
|
||||
|
||||
public Map<Integer, String> createBlock(ChatImageProtocol.ChatImageIndex title, String imgBytes) {
|
||||
try {
|
||||
Map<Integer, String> blocks = this.blockCache.get(title.url(), HashMap::new);
|
||||
blocks.put(title.index(), imgBytes);
|
||||
this.blockCache.put(title.url(), blocks);
|
||||
this.fileCount.put(title.url(), title.total());
|
||||
return blocks;
|
||||
} catch (Exception e) {
|
||||
LeavesLogger.LOGGER.warning("Failed to create block for title " + title.url() + ": " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, String> getBlock(String url) {
|
||||
Map<Integer, String> list;
|
||||
Integer total;
|
||||
if ((list = this.blockCache.getIfPresent(url)) != null && (total = this.fileCount.getIfPresent(url)) != null) {
|
||||
if (total == list.size()) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void tryAddUser(String url, UUID uuid) {
|
||||
try {
|
||||
List<UUID> names = this.userCache.get(url, Lists::newArrayList);
|
||||
names.add(uuid);
|
||||
this.userCache.put(url, names);
|
||||
} catch (Exception e) {
|
||||
LeavesLogger.LOGGER.warning("Failed to add user " + uuid + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<UUID> getUsers(String url) {
|
||||
List<UUID> names;
|
||||
if ((names = this.userCache.getIfPresent(url)) != null) {
|
||||
this.userCache.put(url, Lists.newArrayList());
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.network.Connection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record Context(@NotNull GameProfile profile, Connection connection) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record IdentifierSelector(@Nullable Context context, @Nullable ServerPlayer player) {
|
||||
|
||||
public Object select(ProtocolHandler.Stage stage) {
|
||||
return stage == ProtocolHandler.Stage.CONFIGURATION ? context : player;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.papermc.paper.connection.PluginMessageBridgeImpl;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
@@ -15,9 +14,6 @@ import org.leavesmc.leaves.protocol.core.invoker.MinecraftRegisterInvokerHolder;
|
||||
import org.leavesmc.leaves.protocol.core.invoker.PayloadReceiverInvokerHolder;
|
||||
import org.leavesmc.leaves.protocol.core.invoker.PlayerInvokerHolder;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -238,27 +234,27 @@ public class LeavesProtocolManager {
|
||||
codec.encode(ProtocolUtils.decorate(buf), payload);
|
||||
}
|
||||
|
||||
public static void handlePayload(ServerPlayer player, LeavesCustomPayload payload) {
|
||||
public static void handlePayload(IdentifierSelector selector, LeavesCustomPayload payload) {
|
||||
PayloadReceiverInvokerHolder holder;
|
||||
if ((holder = PAYLOAD_RECEIVERS.get(payload.getClass())) != null) {
|
||||
holder.invoke(player, payload);
|
||||
holder.invoke(selector, payload);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean handleBytebuf(ServerPlayer player, ResourceLocation location, ByteBuf buf) {
|
||||
public static boolean handleBytebuf(IdentifierSelector selector, ResourceLocation location, ByteBuf buf) {
|
||||
RegistryFriendlyByteBuf buf1 = ProtocolUtils.decorate(buf);
|
||||
BytebufReceiverInvokerHolder holder;
|
||||
if ((holder = STRICT_BYTEBUF_RECEIVERS.get(location.toString())) != null) {
|
||||
holder.invoke(player, buf1);
|
||||
holder.invoke(selector, buf1);
|
||||
return true;
|
||||
}
|
||||
if ((holder = NAMESPACED_BYTEBUF_RECEIVERS.get(location.getNamespace())) != null) {
|
||||
if (holder.invoke(player, buf1)) {
|
||||
if (holder.invoke(selector, buf1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var holder1 : GENERIC_BYTEBUF_RECEIVERS) {
|
||||
if (holder1.invoke(player, buf1)) {
|
||||
if (holder1.invoke(selector, buf1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -298,31 +294,22 @@ public class LeavesProtocolManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleMinecraftRegister(String channelId, PluginMessageBridgeImpl bridge) {
|
||||
ServerPlayer player = null;
|
||||
if (bridge instanceof CraftPlayer craftPlayer) {
|
||||
player = craftPlayer.getHandle();
|
||||
}
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static void handleMinecraftRegister(String channelId, IdentifierSelector selector) {
|
||||
ResourceLocation location = ResourceLocation.tryParse(channelId);
|
||||
if (location == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var wildHolder : WILD_MINECRAFT_REGISTER) {
|
||||
wildHolder.invoke(player, location);
|
||||
wildHolder.invoke(selector, location);
|
||||
}
|
||||
|
||||
MinecraftRegisterInvokerHolder holder;
|
||||
if ((holder = STRICT_MINECRAFT_REGISTER.get(location.toString())) != null) {
|
||||
holder.invoke(player, location);
|
||||
holder.invoke(selector, location);
|
||||
}
|
||||
if ((holder = NAMESPACED_MINECRAFT_REGISTER.get(location.getNamespace())) != null) {
|
||||
holder.invoke(player, location);
|
||||
holder.invoke(selector, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.leavesmc.leaves.protocol.core;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -16,6 +18,8 @@ public class ProtocolHandler {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PayloadReceiver {
|
||||
Class<? extends LeavesCustomPayload> payload();
|
||||
|
||||
Stage stage() default Stage.GAME;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -24,6 +28,8 @@ public class ProtocolHandler {
|
||||
String key() default "";
|
||||
|
||||
boolean onlyNamespace() default false;
|
||||
|
||||
Stage stage() default Stage.GAME;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@@ -53,10 +59,27 @@ public class ProtocolHandler {
|
||||
String key() default "";
|
||||
|
||||
boolean onlyNamespace() default false;
|
||||
|
||||
Stage stage() default Stage.CONFIGURATION;
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ReloadDataPack {
|
||||
}
|
||||
|
||||
public enum Stage {
|
||||
CONFIGURATION(Context.class),
|
||||
GAME(ServerPlayer.class);
|
||||
|
||||
private final Class<?> identifier;
|
||||
|
||||
Stage(Class<?> identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public Class<?> identifier() {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,10 @@ import net.minecraft.network.protocol.common.custom.DiscardedPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerCommonPacketListenerImpl;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
@@ -19,26 +22,50 @@ import java.util.function.Function;
|
||||
public class ProtocolUtils {
|
||||
|
||||
private static final Function<ByteBuf, RegistryFriendlyByteBuf> bufDecorator = buf -> buf instanceof RegistryFriendlyByteBuf registry ? registry : new RegistryFriendlyByteBuf(buf, MinecraftServer.getServer().registryAccess());
|
||||
private static final byte[] EMPTY = new byte[0];
|
||||
|
||||
public static String buildProtocolVersion(String protocol) {
|
||||
return protocol + "-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE);
|
||||
}
|
||||
|
||||
public static void sendEmptyPacket(ServerPlayer player, ResourceLocation id) {
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, null)));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
|
||||
}
|
||||
|
||||
public static void sendBytebufPacket(@NotNull ServerPlayer player, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
|
||||
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
|
||||
consumer.accept(buf);
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
}
|
||||
|
||||
public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) {
|
||||
player.internalConnection.send(new ClientboundCustomPayloadPacket(payload));
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(payload));
|
||||
}
|
||||
|
||||
public static void sendEmptyPacket(Context context, ResourceLocation id) {
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY)));
|
||||
}
|
||||
|
||||
public static void sendBytebufPacket(@NotNull Context context, ResourceLocation id, Consumer<? super RegistryFriendlyByteBuf> consumer) {
|
||||
RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer());
|
||||
consumer.accept(buf);
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf))));
|
||||
}
|
||||
|
||||
public static void sendPayloadPacket(Context context, CustomPacketPayload payload) {
|
||||
context.connection().send(new ClientboundCustomPayloadPacket(payload));
|
||||
}
|
||||
|
||||
public static RegistryFriendlyByteBuf decorate(ByteBuf buf) {
|
||||
return bufDecorator.apply(buf);
|
||||
}
|
||||
|
||||
public static IdentifierSelector createSelector(ServerCommonPacketListenerImpl common) {
|
||||
ServerPlayer player = common instanceof ServerGamePacketListenerImpl game ? game.getPlayer() : null;
|
||||
return new IdentifierSelector(new Context(common.profile, common.connection), player);
|
||||
}
|
||||
|
||||
public static ByteBuf wrapNullable(byte @Nullable [] data) {
|
||||
return data == null ? Unpooled.wrappedBuffer(EMPTY) : Unpooled.wrappedBuffer(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public abstract class AbstractInvokerHolder<T> {
|
||||
protected final T handler;
|
||||
protected final Class<?> returnType;
|
||||
protected final Class<?>[] parameterTypes;
|
||||
protected final boolean isStatic;
|
||||
|
||||
protected AbstractInvokerHolder(LeavesProtocol owner, Method invoker, T handler, @Nullable Class<?> returnType, @NotNull Class<?>... parameterTypes) {
|
||||
this.owner = owner;
|
||||
@@ -21,6 +22,7 @@ public abstract class AbstractInvokerHolder<T> {
|
||||
this.handler = handler;
|
||||
this.returnType = returnType;
|
||||
this.parameterTypes = parameterTypes;
|
||||
this.isStatic = Modifier.isStatic(invoker.getModifiers());
|
||||
|
||||
validateMethodSignature();
|
||||
}
|
||||
@@ -58,7 +60,7 @@ public abstract class AbstractInvokerHolder<T> {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (Modifier.isStatic(invoker.getModifiers())) {
|
||||
if (isStatic) {
|
||||
return invoker.invoke(null, args);
|
||||
} else {
|
||||
return invoker.invoke(owner, args);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class BytebufReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.BytebufReceiver> {
|
||||
public BytebufReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.BytebufReceiver handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, FriendlyByteBuf.class);
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), FriendlyByteBuf.class);
|
||||
}
|
||||
|
||||
public boolean invoke(ServerPlayer player, FriendlyByteBuf buf) {
|
||||
return invoke0(false, player, buf) instanceof Boolean b && b;
|
||||
public boolean invoke(IdentifierSelector selector, FriendlyByteBuf buf) {
|
||||
return invoke0(false, selector.select(handler.stage()), buf) instanceof Boolean b && b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class MinecraftRegisterInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.MinecraftRegister> {
|
||||
public MinecraftRegisterInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.MinecraftRegister handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, ResourceLocation.class);
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), ResourceLocation.class);
|
||||
}
|
||||
|
||||
public void invoke(ServerPlayer player, ResourceLocation id) {
|
||||
invoke0(false, player, id);
|
||||
public void invoke(IdentifierSelector selector, ResourceLocation id) {
|
||||
invoke0(false, selector.select(handler.stage()), id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.core.invoker;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.leavesmc.leaves.protocol.core.IdentifierSelector;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
@@ -9,10 +9,10 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class PayloadReceiverInvokerHolder extends AbstractInvokerHolder<ProtocolHandler.PayloadReceiver> {
|
||||
public PayloadReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.PayloadReceiver handler) {
|
||||
super(owner, invoker, handler, null, ServerPlayer.class, handler.payload());
|
||||
super(owner, invoker, handler, null, handler.stage().identifier(), handler.payload());
|
||||
}
|
||||
|
||||
public void invoke(ServerPlayer player, LeavesCustomPayload payload) {
|
||||
invoke0(false, player, payload);
|
||||
public void invoke(IdentifierSelector selector, LeavesCustomPayload payload) {
|
||||
invoke0(false, selector.select(handler.stage()), payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ import java.util.Set;
|
||||
public class JadeProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "jade";
|
||||
public static final String PROTOCOL_VERSION = "7";
|
||||
public static final String PROTOCOL_VERSION = "8";
|
||||
public static final HierarchyLookup<IServerDataProvider<EntityAccessor>> entityDataProviders = new HierarchyLookup<>(Entity.class);
|
||||
public static final PairHierarchyLookup<IServerDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
|
||||
public static final WrappedHierarchyLookup<IServerExtensionProvider<ItemStack>> itemStorageProviders = WrappedHierarchyLookup.forAccessor();
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Accessor<T extends HitResult> {
|
||||
Level getLevel();
|
||||
ServerLevel getLevel();
|
||||
|
||||
Player getPlayer();
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@@ -14,20 +14,20 @@ import java.util.function.Supplier;
|
||||
|
||||
public abstract class AccessorImpl<T extends HitResult> implements Accessor<T> {
|
||||
|
||||
private final Level level;
|
||||
private final ServerLevel level;
|
||||
private final Player player;
|
||||
private final Supplier<T> hit;
|
||||
protected boolean verify;
|
||||
private RegistryFriendlyByteBuf buffer;
|
||||
|
||||
public AccessorImpl(Level level, Player player, Supplier<T> hit) {
|
||||
public AccessorImpl(ServerLevel level, Player player, Supplier<T> hit) {
|
||||
this.level = level;
|
||||
this.player = player;
|
||||
this.hit = hit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getLevel() {
|
||||
public ServerLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@@ -23,7 +23,7 @@ public interface BlockAccessor extends Accessor<BlockHitResult> {
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(Level level);
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
@@ -61,14 +61,14 @@ public class BlockAccessorImpl extends AccessorImpl<BlockHitResult> implements B
|
||||
}
|
||||
|
||||
public static class Builder implements BlockAccessor.Builder {
|
||||
private Level level;
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private BlockHitResult hit;
|
||||
private BlockState blockState = Blocks.AIR.defaultBlockState();
|
||||
private Supplier<BlockEntity> blockEntity;
|
||||
|
||||
@Override
|
||||
public Builder level(Level level) {
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface EntityAccessor extends Accessor<EntityHitResult> {
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(Level level);
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import com.google.common.base.Suppliers;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,13 +41,13 @@ public class EntityAccessorImpl extends AccessorImpl<EntityHitResult> implements
|
||||
}
|
||||
|
||||
public static class Builder implements EntityAccessor.Builder {
|
||||
private Level level;
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private Supplier<EntityHitResult> hit;
|
||||
private Supplier<Entity> entity;
|
||||
|
||||
@Override
|
||||
public Builder level(Level level) {
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ import java.util.Map;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.jade.util.JadeCodec.PRIMITIVE_STREAM_CODEC;
|
||||
|
||||
public record ServerHandshakePayload(Map<ResourceLocation, Object> serverConfig, List<Block> shearableBlocks, List<ResourceLocation> blockProviderIds, List<ResourceLocation> entityProviderIds) implements LeavesCustomPayload {
|
||||
public record ServerHandshakePayload(
|
||||
Map<ResourceLocation, Object> serverConfig,
|
||||
List<Block> shearableBlocks,
|
||||
List<ResourceLocation> blockProviderIds,
|
||||
List<ResourceLocation> entityProviderIds
|
||||
) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_SERVER_HANDSHAKE = JadeProtocol.id("server_handshake");
|
||||
|
||||
@@ -13,7 +13,6 @@ import net.minecraft.world.entity.vehicle.ContainerEntity;
|
||||
import net.minecraft.world.inventory.PlayerEnderChestContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.EnderChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
|
||||
@@ -58,7 +57,11 @@ public enum ItemStorageExtensionProvider implements IServerExtensionProvider<Ite
|
||||
if (blockEntity.getBlockState().getBlock() instanceof ChestBlock chestBlock) {
|
||||
Container compound = null;
|
||||
if (blockEntity.getLevel() != null) {
|
||||
compound = ChestBlock.getContainer(chestBlock, blockEntity.getBlockState(), blockEntity.getLevel(), blockEntity.getBlockPos(), false);
|
||||
compound = ChestBlock.getContainer(
|
||||
chestBlock, blockEntity.getBlockState(),
|
||||
blockEntity.getLevel(), blockEntity.getBlockPos(),
|
||||
true // Bypass lock check
|
||||
);
|
||||
}
|
||||
if (compound != null) {
|
||||
return compound;
|
||||
|
||||
@@ -22,7 +22,7 @@ public enum MobSpawnerCooldownProvider implements StreamServerDataProvider<Block
|
||||
public @Nullable Integer streamData(@NotNull BlockAccessor accessor) {
|
||||
TrialSpawnerBlockEntity spawner = (TrialSpawnerBlockEntity) accessor.getBlockEntity();
|
||||
TrialSpawnerStateData spawnerData = spawner.getTrialSpawner().getStateData();
|
||||
ServerLevel level = ((ServerLevel) accessor.getLevel());
|
||||
ServerLevel level = accessor.getLevel();
|
||||
if (spawner.getTrialSpawner().canSpawnInLevel(level) && level.getGameTime() < spawnerData.cooldownEndsAt) {
|
||||
return (int) (spawnerData.cooldownEndsAt - level.getGameTime());
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ItemCollector<T> {
|
||||
return null;
|
||||
}
|
||||
long currentVersion = iterator.getVersion(container);
|
||||
long gameTime = request.getLevel().getGameTime();
|
||||
long gameTime = request.getLevel().getServer().getTickCount();
|
||||
if (mergedResult != null && iterator.isFinished()) {
|
||||
if (version == currentVersion) {
|
||||
return mergedResult; // content not changed
|
||||
@@ -73,7 +73,7 @@ public class ItemCollector<T> {
|
||||
items.addTo(def, stack.getCount());
|
||||
}
|
||||
});
|
||||
iterator.afterPopulate(count.get());
|
||||
iterator.afterPopulate(container, count.get());
|
||||
if (mergedResult != null && !iterator.isFinished()) {
|
||||
updateCollectingProgress(mergedResult.getFirst());
|
||||
return mergedResult;
|
||||
|
||||
@@ -15,6 +15,7 @@ public abstract class ItemIterator<T> {
|
||||
protected final int fromIndex;
|
||||
protected boolean finished;
|
||||
protected int currentIndex;
|
||||
protected float progress;
|
||||
|
||||
protected ItemIterator(Function<Object, @Nullable T> containerFinder, int fromIndex) {
|
||||
this.containerFinder = containerFinder;
|
||||
@@ -35,16 +36,19 @@ public abstract class ItemIterator<T> {
|
||||
|
||||
public abstract Stream<ItemStack> populate(T container);
|
||||
|
||||
protected abstract int getSlotCount(T container);
|
||||
|
||||
public void reset() {
|
||||
currentIndex = fromIndex;
|
||||
finished = false;
|
||||
}
|
||||
|
||||
public void afterPopulate(int count) {
|
||||
public void afterPopulate(T container, int count) {
|
||||
currentIndex += count;
|
||||
if (count == 0 || currentIndex >= 10000) {
|
||||
finished = true;
|
||||
}
|
||||
progress = (float) (currentIndex - fromIndex) / (getSlotCount(container) - fromIndex);
|
||||
}
|
||||
|
||||
public float getCollectingProgress() {
|
||||
@@ -52,14 +56,11 @@ public abstract class ItemIterator<T> {
|
||||
}
|
||||
|
||||
public static abstract class SlottedItemIterator<T> extends ItemIterator<T> {
|
||||
protected float progress;
|
||||
|
||||
public SlottedItemIterator(Function<Object, @Nullable T> containerFinder, int fromIndex) {
|
||||
super(containerFinder, fromIndex);
|
||||
}
|
||||
|
||||
protected abstract int getSlotCount(T container);
|
||||
|
||||
protected abstract ItemStack getItemInSlot(T container, int slot);
|
||||
|
||||
@Override
|
||||
@@ -70,7 +71,6 @@ public abstract class ItemIterator<T> {
|
||||
toIndex = slotCount;
|
||||
finished = true;
|
||||
}
|
||||
progress = (float) (currentIndex - fromIndex) / (slotCount - fromIndex);
|
||||
return IntStream.range(currentIndex, toIndex).mapToObj(slot -> getItemInSlot(container, slot));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,12 +28,20 @@ public class ServerPlacement {
|
||||
|
||||
public ServerPlacement(final UUID id, final String fileName, final UUID hashValue, final PlayerIdentifier owner) {
|
||||
this.id = id;
|
||||
this.fileName = fileName;
|
||||
this.fileName = removeExtension(fileName);
|
||||
this.hashValue = hashValue;
|
||||
this.owner = owner;
|
||||
lastModifiedBy = owner;
|
||||
}
|
||||
|
||||
private static String removeExtension(final String fileName) {
|
||||
final int pos = fileName.lastIndexOf(".");
|
||||
if (pos < 0) {
|
||||
return fileName;
|
||||
}
|
||||
return fileName.substring(0, pos);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ServerPlacement fromJson(final @NotNull JsonObject obj) {
|
||||
if (obj.has("id")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.leavesmc.leaves.protocol.syncmatica;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.dreeam.leaf.config.modules.network.ProtocolSupport;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -81,11 +82,16 @@ public class SyncmaticaProtocol {
|
||||
|
||||
@NotNull
|
||||
public static String sanitizeFileName(final @NotNull String badFileName) {
|
||||
String input = badFileName;
|
||||
try {
|
||||
input = FilenameUtils.getName(input);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
final StringBuilder sanitized = new StringBuilder();
|
||||
final int len = badFileName.codePointCount(0, badFileName.length());
|
||||
final int len = input.codePointCount(0, input.length());
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
final int c = badFileName.codePointAt(i);
|
||||
final int c = input.codePointAt(i);
|
||||
if (Arrays.binarySearch(ILLEGAL_CHARS, c) < 0) {
|
||||
sanitized.appendCodePoint(c);
|
||||
if (sanitized.length() == 255) {
|
||||
|
||||
@@ -14,8 +14,8 @@ import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.LeavesLogger;
|
||||
import org.leavesmc.leaves.bot.BotStatsCounter;
|
||||
import org.leavesmc.leaves.entity.CraftPhotographer;
|
||||
import org.leavesmc.leaves.entity.Photographer;
|
||||
import org.leavesmc.leaves.entity.photographer.CraftPhotographer;
|
||||
import org.leavesmc.leaves.entity.photographer.Photographer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -77,7 +77,7 @@ public class ServerPhotographer extends ServerPlayer {
|
||||
super.tick();
|
||||
super.doTick();
|
||||
|
||||
if (this.server.getTickCount() % 10 == 0) {
|
||||
if (this.getServer().getTickCount() % 10 == 0) {
|
||||
connection.resetPosition();
|
||||
this.level().chunkSource.move(this);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class ServerPhotographer extends ServerPlayer {
|
||||
super.remove(RemovalReason.KILLED);
|
||||
photographers.remove(this);
|
||||
this.recorder.stop();
|
||||
this.server.getPlayerList().removePhotographer(this);
|
||||
this.getServer().getPlayerList().removePhotographer(this);
|
||||
|
||||
LeavesLogger.LOGGER.info("Photographer " + createState.id + " removed");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user