Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 311fd32acb | |||
| 06dc3306f9 | |||
| 896aed0f2d | |||
| daa146c8b5 | |||
| e0d42cb1d3 | |||
| 559b2e089a | |||
| a07649d14d | |||
| 6aa709cf75 | |||
| 6a452799cc |
@@ -85,7 +85,7 @@ jobs:
|
||||
echo "release_exists=${release_exists}" >> $GITHUB_ENV
|
||||
|
||||
- name: Check If Branch In Expectations
|
||||
if: github.event_name != 'pull_request'
|
||||
if: github.event_name != 'pull_request' && env.flag_release == 'true'
|
||||
run: |
|
||||
if [[ "$GITHUB_REF_NAME" == ver/* ]] || [[ "$GITHUB_REF_NAME" == exp/* ]] || [[ "$GITHUB_REF_NAME" == dev/* ]]; then
|
||||
echo "Branch is in expected prefixes"
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ weightVersion=2.0.7
|
||||
release=2
|
||||
# 0 for skip release, 1 for pre-release, 2 for release
|
||||
|
||||
luminolRef=e605804fc5600aa41b18863543873bff65e125e9
|
||||
luminolRef=274f341465b3143c421de2c3110a69da4b68b75b
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
|
||||
@@ -446,10 +446,10 @@ index 8f80c469c309bf61328c4f98037495f47a38c3c1..b4127d4b4386b98205275a9a0ef8067c
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 53c50d776e5ca66e5903a464d763a7df5b7672be..6cdb59762b5b223a220d420ff99fa9eadc64f3e0 100644
|
||||
index 4ae14236535d04713990f5abb3777001071f591c..3d2bf6371d39946576745aa7977cdc0f2ff07036 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -155,7 +155,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
public void setItem(int index, ItemStack stack) {
|
||||
this.unpackLootTable(null);
|
||||
this.getItems().set(index, stack);
|
||||
@@ -458,7 +458,7 @@ index 53c50d776e5ca66e5903a464d763a7df5b7672be..6cdb59762b5b223a220d420ff99fa9ea
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -741,9 +741,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -751,9 +751,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (item.isEmpty()) {
|
||||
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
|
||||
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
||||
|
||||
@@ -8,10 +8,10 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 435acf0fe5e80ca371d1145befc2cfaa917a89e3..77577d0df9b14a7ad55b2866c2ac31863226458b 100644
|
||||
index 5a72b032150209b6ab053934b05e39eae4bceda5..6b281405e05931396a17d7e48c034d9205574cae 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -758,6 +758,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
@@ -759,6 +759,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
public void setLoaded(boolean loaded) {
|
||||
this.loaded = loaded;
|
||||
|
||||
@@ -10,10 +10,10 @@ Licensed under: MIT
|
||||
This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 6cdb59762b5b223a220d420ff99fa9eadc64f3e0..fe93f0d6b2b7e8503da068179f5d7667634c7ff3 100644
|
||||
index 3d2bf6371d39946576745aa7977cdc0f2ff07036..ed906ec726fa0eb12c0108dc751af2dcadf2bfb1 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -229,8 +229,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -239,8 +239,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
flag |= validator.getAsBoolean(); // Paper - note: this is not a validator, it's what adds/sucks in items
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ index 6cdb59762b5b223a220d420ff99fa9eadc64f3e0..fe93f0d6b2b7e8503da068179f5d7667
|
||||
setChanged(level, pos, state);
|
||||
// Leaves start - Lithium Sleeping Block Entity
|
||||
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled
|
||||
@@ -462,6 +484,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -472,6 +494,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
// Paper end - Perf: Optimize Hoppers
|
||||
|
||||
private static boolean ejectItems(Level level, BlockPos pos, HopperBlockEntity blockEntity) {
|
||||
@@ -58,7 +58,7 @@ index 6cdb59762b5b223a220d420ff99fa9eadc64f3e0..fe93f0d6b2b7e8503da068179f5d7667
|
||||
Container attachedContainer = me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled ? blockEntity.getInsertInventory(level) : getAttachedContainer(level, pos, blockEntity); // Leaves - Lithium Sleeping Block Entity
|
||||
if (attachedContainer == null) {
|
||||
return false;
|
||||
@@ -537,6 +566,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -547,6 +576,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ index 6cdb59762b5b223a220d420ff99fa9eadc64f3e0..fe93f0d6b2b7e8503da068179f5d7667
|
||||
private static int[] getSlots(Container container, Direction direction) {
|
||||
if (container instanceof WorldlyContainer worldlyContainer) {
|
||||
return worldlyContainer.getSlotsForFace(direction);
|
||||
@@ -681,6 +730,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -691,6 +740,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
public static boolean addItem(Container container, ItemEntity item) {
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Instant Block Updater
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index 33d186d660ce3e3dc8cf26cd521fa99291ff78a5..ce1918d12b88835ea79a5c0dc90e0315c408830b 100644
|
||||
index 111fd492351601a22cd29391bc4e3602709adb54..166089c786210d645c22f96569f266cc50fe7d6c 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -494,7 +494,7 @@ public final class RegionizedWorldData {
|
||||
@@ -484,7 +484,7 @@ public final class RegionizedWorldData {
|
||||
public long lastMidTickExecuteFailure;
|
||||
// From Level
|
||||
public boolean populating;
|
||||
@@ -17,7 +17,7 @@ index 33d186d660ce3e3dc8cf26cd521fa99291ff78a5..ce1918d12b88835ea79a5c0dc90e0315
|
||||
public boolean captureBlockStates = false;
|
||||
public boolean captureTreeGeneration = false;
|
||||
public final Map<BlockPos, CraftBlockState> capturedBlockStates = new java.util.LinkedHashMap<>(); // Paper
|
||||
@@ -582,7 +582,7 @@ public final class RegionizedWorldData {
|
||||
@@ -572,7 +572,7 @@ public final class RegionizedWorldData {
|
||||
this.world = world;
|
||||
this.blockLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, true);
|
||||
this.fluidLevelTicks = new LevelTicks<>(world::isPositionTickingWithEntitiesLoaded, world, false);
|
||||
|
||||
+2
-2
@@ -46,10 +46,10 @@ index a5d3caab2072b2c9bf8fdcbdb7c52c2dee16cfaf..4bb36d2965785fadf628a9bfac4fa2aa
|
||||
// CraftBukkit start
|
||||
if (bukkitState != null) {
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 73dd8e67938fbfff745b189c06a93174976ba1bf..8e56c2237f9d49d0b09b62c0933283f77aaae679 100644
|
||||
index 318725a0c9b2bdece7e6287cd521844af81aaf69..b1829ac08ba90e8e1522ee790b7f96515da2b9c4 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -1001,12 +1001,14 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
@@ -1005,12 +1005,14 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
profilerFiller.pop();
|
||||
} catch (Throwable var5) {
|
||||
|
||||
@@ -5,10 +5,10 @@ Subject: [PATCH] Global Entities Counter
|
||||
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index ce1918d12b88835ea79a5c0dc90e0315c408830b..c5caad99caed20e2bb4475fcf057417ee27d737c 100644
|
||||
index 166089c786210d645c22f96569f266cc50fe7d6c..c7de740dd9babfc1373a5663cd552214b75a0674 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -576,6 +576,9 @@ public final class RegionizedWorldData {
|
||||
@@ -566,6 +566,9 @@ public final class RegionizedWorldData {
|
||||
}
|
||||
// Luminol end
|
||||
|
||||
@@ -18,7 +18,7 @@ index ce1918d12b88835ea79a5c0dc90e0315c408830b..c5caad99caed20e2bb4475fcf057417e
|
||||
public final TickRegions.TickRegionData regionData;
|
||||
|
||||
public RegionizedWorldData(final ServerLevel world, final TickRegions.TickRegionData regionData) {
|
||||
@@ -588,6 +591,15 @@ public final class RegionizedWorldData {
|
||||
@@ -578,6 +581,15 @@ public final class RegionizedWorldData {
|
||||
this.turbo = new io.papermc.paper.redstone.RedstoneWireTurbo((RedStoneWireBlock)Blocks.REDSTONE_WIRE);
|
||||
this.regionData = regionData;
|
||||
|
||||
|
||||
+4
-4
@@ -6,10 +6,10 @@ Subject: [PATCH] Add null check in RegionizedWorldData >> conections
|
||||
some of our function patches will crash because of get null in conn.getPlayer(), then when we process player.chunkPosition() will get NPE, so we need to fix it.
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedWorldData.java b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
index c5caad99caed20e2bb4475fcf057417ee27d737c..c2e50a03a41958d9b44753adc9a9bf4ea1fb24a4 100644
|
||||
index c7de740dd9babfc1373a5663cd552214b75a0674..61deaf0184c984a71d104a495b4dee34b27766f1 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedWorldData.java
|
||||
@@ -251,14 +251,17 @@ public final class RegionizedWorldData {
|
||||
@@ -241,14 +241,17 @@ public final class RegionizedWorldData {
|
||||
regionToData.get(CoordinateUtils.getChunkKey(pos.x >> chunkToRegionShift, pos.z >> chunkToRegionShift)).itemEntityMovementTrackerMap.put(key, tracker);
|
||||
}
|
||||
// Luminol end
|
||||
@@ -27,7 +27,7 @@ index c5caad99caed20e2bb4475fcf057417ee27d737c..c2e50a03a41958d9b44753adc9a9bf4e
|
||||
}
|
||||
// entities
|
||||
for (final ServerPlayer player : from.localPlayers) {
|
||||
@@ -269,6 +272,13 @@ public final class RegionizedWorldData {
|
||||
@@ -259,6 +262,13 @@ public final class RegionizedWorldData {
|
||||
into.localPlayers.add(player);
|
||||
player.getBukkitEntity().updateRegion(into);
|
||||
into.nearbyPlayers.addPlayer(player);
|
||||
@@ -41,7 +41,7 @@ index c5caad99caed20e2bb4475fcf057417ee27d737c..c2e50a03a41958d9b44753adc9a9bf4e
|
||||
}
|
||||
for (final Entity entity : from.allEntities) {
|
||||
final ChunkPos pos = entity.chunkPosition();
|
||||
@@ -636,6 +646,7 @@ public final class RegionizedWorldData {
|
||||
@@ -626,6 +636,7 @@ public final class RegionizedWorldData {
|
||||
private static void cleanUpConnection(final Connection conn) {
|
||||
// note: ALL connections HERE have a player
|
||||
final ServerPlayer player = conn.getPlayer();
|
||||
|
||||
@@ -154,7 +154,7 @@ index e6ec0788b88d3431c06134c879b4bae9c769dac1..bc94a9094e3cee5d5d4c5b919bf4c2a1
|
||||
|
||||
public ClientInformation clientInformation() {
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 4a079d3033908f3b732c70eddab3c8e86d2c3e78..4d95e36855aecc8be0133c1d6f7d6a58bf26b0a0 100644
|
||||
index fd74636d911596daae8cfe563c2dd5e3d37a1549..555cdf2558dec481d6f11c0b1c33da1637e89224 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2050,7 +2050,13 @@ public class ServerGamePacketListenerImpl
|
||||
@@ -980,10 +980,10 @@ index 00da328f21e5ce5de6f968323b14a7832a6cbd62..a68ffb1197a19173f00577f656b5894f
|
||||
+ }
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 474ca0ce0d3095fc586f8f9e9a584ed4f7c91471..07c2b0fb1fa2dd299687d389d7fe91c5fd5b5b91 100644
|
||||
index ed906ec726fa0eb12c0108dc751af2dcadf2bfb1..0942fd82d4ea32f5c75f255ecd6c7b160851706e 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -513,6 +513,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -523,6 +523,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
for (int i = 0; i < blockEntity.getContainerSize(); i++) {
|
||||
ItemStack item = blockEntity.getItem(i);
|
||||
if (!item.isEmpty()) {
|
||||
@@ -991,7 +991,7 @@ index 474ca0ce0d3095fc586f8f9e9a584ed4f7c91471..07c2b0fb1fa2dd299687d389d7fe91c5
|
||||
int count = item.getCount();
|
||||
// CraftBukkit start - Call event when pushing items into other inventories
|
||||
ItemStack original = item.copy();
|
||||
@@ -544,15 +545,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -554,15 +555,23 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
int origCount = event.getItem().getAmount(); // Spigot
|
||||
ItemStack itemStack = HopperBlockEntity.addItem(blockEntity, attachedContainer, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), opposite);
|
||||
// CraftBukkit end
|
||||
@@ -1045,7 +1045,7 @@ index 0de2f6627fb6295d7927ac3e37026f4daf68cfd3..727abe6be81fdaa0753035bbf89ffead
|
||||
return offsetFunction != null ? offsetFunction.evaluate(this.asState(), pos) : Vec3.ZERO;
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 8e56c2237f9d49d0b09b62c0933283f77aaae679..64bd2da70f4a0beb0efbb8a74478eef95ca013f2 100644
|
||||
index b1829ac08ba90e8e1522ee790b7f96515da2b9c4..8f5e19a15f42aadedfe7c998568f846657a5ec8c 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -406,10 +406,11 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
|
||||
|
||||
+14
-4
@@ -1,6 +1,8 @@
|
||||
package fun.bm.lophine.carpet;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.papermc.paper.threadedregions.RegionizedWorldData;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
@@ -24,9 +26,10 @@ import java.util.WeakHashMap;
|
||||
|
||||
public final class LagFreeSpawningCompatHelper {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Map<ServerLevel, Map<EntityType<?>, Mob>> PRECOOKED_MOBS = new WeakHashMap<>();
|
||||
private static final Map<RegionizedWorldData, Map<EntityType<?>, Mob>> PRECOOKED_MOBS = new WeakHashMap<>();
|
||||
|
||||
public static boolean hasNoCollision(ServerLevel world, AABB bb) {
|
||||
if (!TickThread.isTickThreadFor(world, bb)) return world.noCollision(bb);
|
||||
int minX = Mth.floor(bb.minX);
|
||||
int minY = Mth.floor(bb.minY);
|
||||
int minZ = Mth.floor(bb.minZ);
|
||||
@@ -84,15 +87,22 @@ public final class LagFreeSpawningCompatHelper {
|
||||
}
|
||||
|
||||
public static @Nullable Mob getOrCreateMob(ServerLevel level, EntityType<?> entityType) {
|
||||
Map<EntityType<?>, Mob> cache = PRECOOKED_MOBS.computeIfAbsent(level, key -> new HashMap<>());
|
||||
RegionizedWorldData data = level.getCurrentWorldData();
|
||||
if (data == null) return createMob(level, entityType);
|
||||
Map<EntityType<?>, Mob> cache = PRECOOKED_MOBS.computeIfAbsent(level.getCurrentWorldData(), key -> new HashMap<>());
|
||||
Mob mob = cache.get(entityType);
|
||||
if (mob != null && !mob.isRemoved()) {
|
||||
if (!TickThread.isTickThreadFor(mob)) return createMob(level, entityType);
|
||||
return mob;
|
||||
}
|
||||
|
||||
return createMob(level, entityType);
|
||||
}
|
||||
|
||||
public static @Nullable Mob createMob(ServerLevel level, EntityType<?> entityType) {
|
||||
try {
|
||||
if (entityType.create(level, EntitySpawnReason.NATURAL) instanceof Mob created) {
|
||||
cache.put(entityType, created);
|
||||
PRECOOKED_MOBS.get(level.getCurrentWorldData()).put(entityType, created);
|
||||
return created;
|
||||
}
|
||||
LOGGER.warn("Can't precook non-mob entity type: {}", entityType);
|
||||
@@ -104,7 +114,7 @@ public final class LagFreeSpawningCompatHelper {
|
||||
}
|
||||
|
||||
public static void markSpawned(ServerLevel level, EntityType<?> entityType) {
|
||||
Map<EntityType<?>, Mob> cache = PRECOOKED_MOBS.get(level);
|
||||
Map<EntityType<?>, Mob> cache = PRECOOKED_MOBS.get(level.getCurrentWorldData());
|
||||
if (cache != null) {
|
||||
cache.remove(entityType);
|
||||
}
|
||||
|
||||
+8
@@ -13,4 +13,12 @@ public class LanguageConfig implements IConfigModule {
|
||||
Please use the key from https://minecraft.wiki/w/Language
|
||||
Sample of format: en_us zh_cn zh_hk zh_tw""")
|
||||
public static String lang = "en_us";
|
||||
|
||||
@ConfigInfo(name = "full_blocking_load", comments = """
|
||||
Whether to allow blocking server loading when loading localized language.
|
||||
If you want only use your localized language to shown in your terminal,
|
||||
you need to enable it.
|
||||
|
||||
WARNING: This may slow down the startup speed!""")
|
||||
public static boolean full_blocking_load = false;
|
||||
}
|
||||
@@ -64,7 +64,11 @@ public class ServerI18nUtil {
|
||||
langJsonPath = "minecraft/lang/" + LanguageConfig.lang + ".json";
|
||||
lophineLangPath = "/assets/lophine/lang/" + LanguageConfig.lang + ".json";
|
||||
logger.info("Starting load language: {}", LanguageConfig.lang);
|
||||
preloadTask.thenAcceptAsync(v -> loadI18n(LanguageConfig.lang, 2));
|
||||
if (LanguageConfig.full_blocking_load) {
|
||||
loadI18n(LanguageConfig.lang, 2);
|
||||
} else {
|
||||
preloadTask.thenAcceptAsync(v -> loadI18n(LanguageConfig.lang, 2));
|
||||
}
|
||||
}
|
||||
|
||||
public static void preInit() {
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractConcurrentTable<X, Y, Z> {
|
||||
public abstract void put(X x, Y y, Z z);
|
||||
|
||||
public abstract void remove(X x, Y y, Z z);
|
||||
|
||||
public abstract List<Z> getZ(X x, Y y);
|
||||
|
||||
public abstract List<Y> getY(X x, Z z);
|
||||
|
||||
public abstract List<X> getX(Y y, Z z);
|
||||
|
||||
public abstract Map<X, Y> getXY(Z z);
|
||||
|
||||
public abstract Map<Y, Z> getYZ(X x);
|
||||
|
||||
public abstract Map<X, Z> getXZ(Y y);
|
||||
|
||||
public abstract List<X> getAllX();
|
||||
|
||||
public abstract List<Y> getAllY();
|
||||
|
||||
public abstract List<Z> getAllZ();
|
||||
|
||||
public abstract void clearXY(Z z);
|
||||
|
||||
public abstract void clearYZ(X x);
|
||||
|
||||
public abstract void clearXZ(Y y);
|
||||
|
||||
public abstract void clearAll();
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ConcurrentTable<X, Y, Z> extends AbstractConcurrentTable<X, Y, Z> {
|
||||
protected final ConcurrentLinkedDeque<TableEntry<X, Y, Z>> data = new ConcurrentLinkedDeque<>();
|
||||
protected final boolean flagX;
|
||||
protected final boolean flagY;
|
||||
protected final boolean flagZ;
|
||||
|
||||
public ConcurrentTable() {
|
||||
this(false, false, false);
|
||||
}
|
||||
|
||||
public ConcurrentTable(boolean flagX, boolean flagY, boolean flagZ) {
|
||||
this.flagX = flagX;
|
||||
this.flagY = flagY;
|
||||
this.flagZ = flagZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(X x, Y y, Z z) {
|
||||
put(x, y, z, false);
|
||||
}
|
||||
|
||||
public void put(X x, Y y, Z z, boolean flag) {
|
||||
if (!flag) {
|
||||
if (flagX) {
|
||||
List<X> datas = getX(y, z);
|
||||
for (X x1 : datas) {
|
||||
if (!x1.equals(x)) {
|
||||
remove(x1, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flagY) {
|
||||
List<Y> datas = getY(x, z);
|
||||
for (Y y1 : datas) {
|
||||
if (!y1.equals(y)) {
|
||||
remove(x, y1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flagZ) {
|
||||
List<Z> datas = getZ(x, y);
|
||||
for (Z z1 : datas) {
|
||||
if (!z1.equals(z)) {
|
||||
remove(x, y, z1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data.add(new TableEntry<>(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(X x, Y y, Z z) {
|
||||
data.removeIf(entry -> entry.getX().equals(x) && entry.getY().equals(y) && entry.getZ().equals(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getZ(X x, Y y) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getX().equals(x) && entry.getY().equals(y),
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getY(X x, Z z) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getX().equals(x) && entry.getZ().equals(z),
|
||||
TableEntry::getY
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getX(Y y, Z z) {
|
||||
return filterAndCollect(
|
||||
entry -> entry.getY().equals(y) && entry.getZ().equals(z),
|
||||
TableEntry::getX
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<X, Y> getXY(Z z) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getZ().equals(z),
|
||||
TableEntry::getX,
|
||||
TableEntry::getY
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Y, Z> getYZ(X x) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getX().equals(x),
|
||||
TableEntry::getY,
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<X, Z> getXZ(Y y) {
|
||||
return filterAndMap(
|
||||
entry -> entry.getY().equals(y),
|
||||
TableEntry::getX,
|
||||
TableEntry::getZ
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getAllX() {
|
||||
return collectAll(TableEntry::getX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getAllY() {
|
||||
return collectAll(TableEntry::getY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getAllZ() {
|
||||
return collectAll(TableEntry::getZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXY(Z z) {
|
||||
data.removeIf(entry -> entry.getZ().equals(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearYZ(X x) {
|
||||
data.removeIf(entry -> entry.getX().equals(x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXZ(Y y) {
|
||||
data.removeIf(entry -> entry.getY().equals(y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAll() {
|
||||
data.clear();
|
||||
}
|
||||
|
||||
private <T> List<T> filterAndCollect(Predicate<TableEntry<X, Y, Z>> filter,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, T> mapper) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (filter.test(entry)) {
|
||||
result.add(mapper.apply(entry));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private <K, V> Map<K, V> filterAndMap(Predicate<TableEntry<X, Y, Z>> filter,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, K> keyMapper,
|
||||
java.util.function.Function<TableEntry<X, Y, Z>, V> valueMapper) {
|
||||
Map<K, V> map = new HashMap<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
if (filter.test(entry)) {
|
||||
map.put(keyMapper.apply(entry), valueMapper.apply(entry));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private <T> List<T> collectAll(java.util.function.Function<TableEntry<X, Y, Z>, T> mapper) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (TableEntry<X, Y, Z> entry : data) {
|
||||
result.add(mapper.apply(entry));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class OptimizedConcurrentTable<X, Y, Z> extends ConcurrentTable<X, Y, Z> {
|
||||
private final ConcurrentHashMap<X, ConcurrentHashMap<Y, Set<Z>>> xyIndex = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Y, ConcurrentHashMap<Z, Set<X>>> yzIndex = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Z, ConcurrentHashMap<X, Set<Y>>> zxIndex = new ConcurrentHashMap<>();
|
||||
|
||||
public OptimizedConcurrentTable() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OptimizedConcurrentTable(boolean flagX, boolean flagY, boolean flagZ) {
|
||||
super(flagX, flagY, flagZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(X x, Y y, Z z) {
|
||||
if (flagX) {
|
||||
List<X> datas = getX(y, z);
|
||||
for (X x1 : datas) {
|
||||
if (!x1.equals(x)) {
|
||||
remove(x1, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flagY) {
|
||||
List<Y> datas = getY(x, z);
|
||||
for (Y y1 : datas) {
|
||||
if (!y1.equals(y)) {
|
||||
remove(x, y1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flagZ) {
|
||||
List<Z> datas = getZ(x, y);
|
||||
for (Z z1 : datas) {
|
||||
if (!z1.equals(z)) {
|
||||
remove(x, y, z1);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.put(x, y, z, true);
|
||||
xyIndex.computeIfAbsent(x, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(y, k -> ConcurrentHashMap.newKeySet()).add(z);
|
||||
yzIndex.computeIfAbsent(y, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(z, k -> ConcurrentHashMap.newKeySet()).add(x);
|
||||
zxIndex.computeIfAbsent(z, k -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(x, k -> ConcurrentHashMap.newKeySet()).add(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(X x, Y y, Z z) {
|
||||
super.remove(x, y, z);
|
||||
removeFromIndex(xyIndex, x, y, z);
|
||||
removeFromIndex(yzIndex, y, z, x);
|
||||
removeFromIndex(zxIndex, z, x, y);
|
||||
}
|
||||
|
||||
private <K, V, T> void removeFromIndex(ConcurrentHashMap<K, ConcurrentHashMap<V, Set<T>>> index,
|
||||
K key1, V key2, T value) {
|
||||
index.computeIfPresent(key1, (k, map) -> {
|
||||
map.computeIfPresent(key2, (k2, set) -> {
|
||||
set.remove(value);
|
||||
return set.isEmpty() ? null : set;
|
||||
});
|
||||
return map.isEmpty() ? null : map;
|
||||
});
|
||||
}
|
||||
|
||||
public void removeAll(Predicate<TableEntry<X, Y, Z>> predicate) {
|
||||
data.removeIf(entry -> {
|
||||
boolean shouldRemove = predicate.test(entry);
|
||||
if (shouldRemove) {
|
||||
removeFromIndex(xyIndex, entry.getX(), entry.getY(), entry.getZ());
|
||||
removeFromIndex(yzIndex, entry.getY(), entry.getZ(), entry.getX());
|
||||
removeFromIndex(zxIndex, entry.getZ(), entry.getX(), entry.getY());
|
||||
}
|
||||
return shouldRemove;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean putIfAbsent(X x, Y y, Z z) {
|
||||
if (data.stream().anyMatch(entry ->
|
||||
Objects.equals(entry.getX(), x) &&
|
||||
Objects.equals(entry.getY(), y) &&
|
||||
Objects.equals(entry.getZ(), z))) {
|
||||
return false;
|
||||
}
|
||||
put(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getZ(X x, Y y) {
|
||||
Set<Z> result = xyIndex.getOrDefault(x, new ConcurrentHashMap<>()).get(y);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getY(X x, Z z) {
|
||||
Set<Y> result = zxIndex.getOrDefault(z, new ConcurrentHashMap<>()).get(x);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<X> getX(Y y, Z z) {
|
||||
Set<X> result = yzIndex.getOrDefault(y, new ConcurrentHashMap<>()).get(z);
|
||||
return result != null ? new ArrayList<>(result) : new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<X, Y> getXY(Z z) {
|
||||
return buildMapFromIndex(zxIndex.get(z), Function.identity(), Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Y, Z> getYZ(X x) {
|
||||
return buildMapFromIndex(xyIndex.get(x), Function.identity(), Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<X, Z> getXZ(Y y) {
|
||||
return reverseMapFromIndex(yzIndex.get(y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<X> getAllX() {
|
||||
Set<X> resultSet = new HashSet<>(xyIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Y> getAllY() {
|
||||
Set<Y> resultSet = new HashSet<>(yzIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Z> getAllZ() {
|
||||
Set<Z> resultSet = new HashSet<>(zxIndex.keySet());
|
||||
return new ArrayList<>(resultSet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearXY(Z z) {
|
||||
super.clearXY(z);
|
||||
zxIndex.remove(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearYZ(X x) {
|
||||
super.clearYZ(x);
|
||||
xyIndex.remove(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearXZ(Y y) {
|
||||
super.clearXZ(y);
|
||||
yzIndex.remove(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAll() {
|
||||
super.clearAll();
|
||||
xyIndex.clear();
|
||||
yzIndex.clear();
|
||||
zxIndex.clear();
|
||||
}
|
||||
|
||||
|
||||
private <K, V, R, S> Map<R, S> buildMapFromIndex(ConcurrentHashMap<K, Set<V>> indexMap, java.util.function.Function<K, R> keyMapper, java.util.function.Function<V, S> valueMapper) {
|
||||
Map<R, S> result = new HashMap<>();
|
||||
if (indexMap != null) {
|
||||
for (Map.Entry<K, Set<V>> entry : indexMap.entrySet()) {
|
||||
K key = entry.getKey();
|
||||
Set<V> valueSet = entry.getValue();
|
||||
if (valueSet != null && !valueSet.isEmpty()) {
|
||||
for (V value : valueSet) {
|
||||
result.put(keyMapper.apply(key), valueMapper.apply(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private <K, V> Map<V, K> reverseMapFromIndex(ConcurrentHashMap<K, Set<V>> indexMap) {
|
||||
Map<V, K> result = new HashMap<>();
|
||||
if (indexMap != null) {
|
||||
for (Map.Entry<K, Set<V>> entry : indexMap.entrySet()) {
|
||||
K key = entry.getKey();
|
||||
Set<V> valueSet = entry.getValue();
|
||||
if (valueSet != null && !valueSet.isEmpty()) {
|
||||
for (V value : valueSet) {
|
||||
result.put(value, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fun.bm.lophine.utils.concurrent;
|
||||
|
||||
public class TableEntry<X, Y, Z> {
|
||||
private final X x;
|
||||
private final Y y;
|
||||
private final Z z;
|
||||
|
||||
public TableEntry(X x, Y y, Z z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public X getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public Y getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public Z getZ() {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
+10
-8
@@ -17,10 +17,10 @@
|
||||
|
||||
package org.leavesmc.leaves.protocol.servux;
|
||||
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Table;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import fun.bm.lophine.config.modules.function.protocol.ServuxProtocolConfig;
|
||||
import fun.bm.lophine.utils.concurrent.AbstractConcurrentTable;
|
||||
import fun.bm.lophine.utils.concurrent.OptimizedConcurrentTable;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -53,12 +53,12 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
||||
|
||||
public static final int PROTOCOL_VERSION = 2;
|
||||
|
||||
private static final List<ServerPlayer> players = new ArrayList<>();
|
||||
private static final Set<ServerPlayer> players = ConcurrentHashMap.newKeySet();
|
||||
private static final int updateInterval = 80;
|
||||
|
||||
private static final Map<ServerPlayer, List<DataLogger.Type>> loggerPlayers = new ConcurrentHashMap<>();
|
||||
private static final Map<DataLogger.Type, DataLogger<?>> LOGGERS = new ConcurrentHashMap<>();
|
||||
private static final Table<DataLogger.Type, ServerPlayer, Tag> DATA = HashBasedTable.create();
|
||||
private static final AbstractConcurrentTable<DataLogger.Type, ServerPlayer, Tag> DATA = new OptimizedConcurrentTable<>(false, false, true);
|
||||
|
||||
public static boolean refreshSpawnMetadata = false;
|
||||
|
||||
@@ -84,7 +84,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
||||
private static void onPlayerLeave(ServerPlayer player) {
|
||||
players.remove(player);
|
||||
loggerPlayers.remove(player);
|
||||
DATA.rowMap().values().forEach(row -> row.remove(player));
|
||||
DATA.clearXZ(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = HudDataPayload.class)
|
||||
@@ -259,10 +259,12 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
||||
loggerPlayers.forEach((player, list) -> {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
for (DataLogger.Type type : list) {
|
||||
Tag data = DATA.get(type, player);
|
||||
List<Tag> data0 = DATA.getZ(type, player);
|
||||
if (data0.isEmpty()) continue;
|
||||
Tag data = data0.getFirst();
|
||||
if (data != null) {
|
||||
nbt.put(type.getSerializedName(), data);
|
||||
DATA.remove(type, player);
|
||||
DATA.remove(type, player, data);
|
||||
}
|
||||
}
|
||||
if (!nbt.isEmpty()) {
|
||||
@@ -373,4 +375,4 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
|
||||
this(type, new CompoundTag(), buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-2
@@ -28,6 +28,7 @@ import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.syncmatica.exchange.*;
|
||||
@@ -40,6 +41,8 @@ import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static fun.bm.lophine.LophineLogger.LOGGER;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "syncmatica")
|
||||
public class CommunicationManager implements LeavesProtocol {
|
||||
|
||||
@@ -178,6 +181,10 @@ public class CommunicationManager implements LeavesProtocol {
|
||||
if (id.equals(PacketType.MODIFY_REQUEST.identifier)) {
|
||||
final UUID placementId = packetBuf.readUUID();
|
||||
final ModifyExchangeServer modifier = new ModifyExchangeServer(placementId, source);
|
||||
if (modifier.getPlacement() == null) {
|
||||
LOGGER.warn("Could not find placement for modify request {}", placementId);
|
||||
return;
|
||||
}
|
||||
startExchange(modifier);
|
||||
}
|
||||
}
|
||||
@@ -351,8 +358,12 @@ public class CommunicationManager implements LeavesProtocol {
|
||||
return downloadState.getOrDefault(syncmatic.getHash(), false);
|
||||
}
|
||||
|
||||
public static void setModifier(final @NotNull ServerPlacement syncmatic, final Exchange exchange) {
|
||||
modifyState.put(syncmatic.getHash(), exchange);
|
||||
public static void setModifier(final @NotNull ServerPlacement syncmatic, final @Nullable Exchange exchange) {
|
||||
if (exchange == null) {
|
||||
modifyState.remove(syncmatic.getHash());
|
||||
} else {
|
||||
modifyState.put(syncmatic.getHash(), exchange);
|
||||
}
|
||||
}
|
||||
|
||||
public static Exchange getModifier(final @NotNull ServerPlacement syncmatic) {
|
||||
|
||||
Reference in New Issue
Block a user