Skip to content

Commit b7010c5

Browse files
committed
Fixed null ref exception
1 parent 791699b commit b7010c5

File tree

8 files changed

+110
-53
lines changed

8 files changed

+110
-53
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ package_group=gollorum.signpost
99
mc_version=1.18.1
1010
forge_version=39.0.10
1111

12-
mod_version=2.00.4
12+
mod_version=2.00.5

src/main/java/gollorum/signpost/WaystoneLibrary.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,12 @@ public WaystoneLocationData getLocationData(WaystoneHandle.Vanilla waystoneId) {
9797
return allWaystones.get(waystoneId).locationData;
9898
}
9999

100-
public WaystoneData getData(WaystoneHandle.Vanilla waystoneId) {
100+
public Optional<WaystoneData> getData(WaystoneHandle.Vanilla waystoneId) {
101101
assert Signpost.getServerType().isServer;
102102
WaystoneEntry entry = allWaystones.get(waystoneId);
103-
return new WaystoneData(waystoneId, entry.name, entry.locationData, entry.isLocked);
103+
return Optional.ofNullable(
104+
entry == null ? null : new WaystoneData(waystoneId, entry.name, entry.locationData, entry.isLocked)
105+
);
104106
}
105107

106108
private static class WaystoneEntry {

src/main/java/gollorum/signpost/blockpartdata/types/SignBlockPart.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import gollorum.signpost.minecraft.gui.PaintSignGui;
1010
import gollorum.signpost.minecraft.gui.RequestSignGui;
1111
import gollorum.signpost.minecraft.items.Brush;
12+
import gollorum.signpost.minecraft.utils.LangKeys;
1213
import gollorum.signpost.networking.PacketHandler;
1314
import gollorum.signpost.relations.ExternalWaystone;
1415
import gollorum.signpost.security.WithOwner;
@@ -268,24 +269,27 @@ public InteractionResult interact(InteractionInfo info) {
268269
private void tryTeleport(ServerPlayer player, PostTile.TilePartInfo tilePartInfo) {
269270
if(Config.Server.teleport.enableTeleport.get() && coreData.destination.isPresent() && (!(coreData.destination.get() instanceof WaystoneHandle.Vanilla) || WaystoneLibrary.getInstance().contains((WaystoneHandle.Vanilla) coreData.destination.get()))) {
270271
WaystoneHandle dest = coreData.destination.get();
271-
Optional<WaystoneHandle.Vanilla> vanillaHandle = dest instanceof WaystoneHandle.Vanilla ? Optional.of((WaystoneHandle.Vanilla) dest) : Optional.empty();
272+
Optional<WaystoneHandle.Vanilla> vanillaHandle = dest instanceof WaystoneHandle.Vanilla
273+
? Optional.of((WaystoneHandle.Vanilla) dest)
274+
: Optional.empty();
272275
PacketHandler.send(
273276
PacketDistributor.PLAYER.with(() -> player),
274277
new Teleport.RequestGui.Package(
275278
Either.rightIfPresent(vanillaHandle, () -> ((ExternalWaystone.Handle) dest).noTeleportLangKey())
276-
.mapRight(h -> {
277-
WaystoneData data = WaystoneLibrary.getInstance().getData(h);
278-
boolean isDiscovered = WaystoneLibrary.getInstance()
279-
.isDiscovered(new PlayerHandle(player), h) || !Config.Server.teleport.enforceDiscovery.get();
280-
int distance = (int) data.location.spawn.distanceTo(Vector3.fromVec3d(player.position()));
281-
return new Teleport.RequestGui.Package.Info(
282-
Config.Server.teleport.maximumDistance.get(),
283-
distance,
284-
isDiscovered,
285-
data.name,
286-
Teleport.getCost(player, Vector3.fromBlockPos(data.location.block.blockPos), data.location.spawn)
287-
);
288-
}),
279+
.flatMapRight(h ->
280+
Either.rightIfPresent(WaystoneLibrary.getInstance().getData(h), () -> LangKeys.waystoneNotFound).mapRight(data -> {
281+
boolean isDiscovered = WaystoneLibrary.getInstance()
282+
.isDiscovered(new PlayerHandle(player), h) || !Config.Server.teleport.enforceDiscovery.get();
283+
int distance = (int) data.location.spawn.distanceTo(Vector3.fromVec3d(player.position()));
284+
return new Teleport.RequestGui.Package.Info(
285+
Config.Server.teleport.maximumDistance.get(),
286+
distance,
287+
isDiscovered,
288+
data.name,
289+
Teleport.getCost(player, Vector3.fromBlockPos(data.location.block.blockPos), data.location.spawn)
290+
);
291+
})
292+
),
289293
Optional.of(tilePartInfo)
290294
)
291295
);

src/main/java/gollorum/signpost/minecraft/block/WaystoneBlock.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ public static void openGuiIfHasPermission(ServerPlayer player, WorldLocation wor
6161
assert Signpost.getServerType().isServer;
6262
Optional<WaystoneData> data = WaystoneLibrary.getInstance()
6363
.getHandleByLocation(worldLocation)
64-
.map(WaystoneLibrary.getInstance()::getData);
65-
boolean wantsToOpenGui = !data.isPresent()
64+
.flatMap(WaystoneLibrary.getInstance()::getData);
65+
boolean wantsToOpenGui = data.isEmpty()
6666
|| WaystoneLibrary.getInstance().isDiscovered(PlayerHandle.from(player), data.get().handle);
6767
boolean mayOpenGui = data.map(d -> d.hasThePermissionToEdit(player)).orElse(true);
6868
if(wantsToOpenGui && mayOpenGui){

src/main/java/gollorum/signpost/minecraft/worldgen/SignpostJigsawPiece.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,11 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeWideSi
209209
Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets,
210210
float y
211211
) {
212-
Tuple<BlockPos, WaystoneHandle.Vanilla> target = possibleTargets.poll();
213-
if(target == null) return new Tuple<>(Collections.emptySet(), x -> {});
214-
WaystoneData targetData = WaystoneLibrary.getInstance().getData(target._2);
212+
Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> nextTargetOption = fetchNextTarget(possibleTargets);
213+
if(nextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
214+
Tuple<BlockPos, WaystoneHandle.Vanilla> target = nextTargetOption.get()._1;
215+
WaystoneData targetData = nextTargetOption.get()._2;
216+
215217
Angle rotation = SignBlockPart.pointingAt(tilePos, target._1);
216218
Consumer<PostTile> onTileFetched = tile -> {
217219
if(tile.getParts().stream().anyMatch(instance -> !(instance.blockPart instanceof PostBlockPart) && isNearly(instance.offset.y, y)))
@@ -242,9 +244,11 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
242244
Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets,
243245
float y
244246
) {
245-
Tuple<BlockPos, WaystoneHandle.Vanilla> target = possibleTargets.poll();
246-
if(target == null) return new Tuple<>(Collections.emptySet(), x -> {});
247-
WaystoneData targetData = WaystoneLibrary.getInstance().getData(target._2);
247+
Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> nextTargetOption = fetchNextTarget(possibleTargets);
248+
if(nextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
249+
Tuple<BlockPos, WaystoneHandle.Vanilla> target = nextTargetOption.get()._1;
250+
WaystoneData targetData = nextTargetOption.get()._2;
251+
248252
Angle rotation = SignBlockPart.pointingAt(tilePos, target._1);
249253
boolean shouldFlip = shouldFlip(facing, rotation);
250254
Optional<Overlay> overlay = overlayFor(world, tilePos);
@@ -262,15 +266,20 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
262266
ItemStack.EMPTY,
263267
PlayerHandle.Invalid
264268
));
265-
Tuple<BlockPos, WaystoneHandle.Vanilla> secondTarget = possibleTargets.poll();
269+
270+
Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> secondNextTargetOption = fetchNextTarget(possibleTargets);
271+
if(secondNextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
272+
Tuple<BlockPos, WaystoneHandle.Vanilla> secondTarget = secondNextTargetOption.get()._1;
273+
266274
List<Tuple<BlockPos, WaystoneHandle.Vanilla>> skippedTargets = new ArrayList<>();
267275
while(secondTarget != null) {
268-
WaystoneData secondTargetData = WaystoneLibrary.getInstance().getData(secondTarget._2);
276+
WaystoneData secondTargetData = secondNextTargetOption.get()._2;
269277
Angle secondRotation = SignBlockPart.pointingAt(tilePos, secondTarget._1);
270278
boolean shouldSecondFlip = shouldFlip(facing, secondRotation);
271279
if(shouldSecondFlip == shouldFlip) {
272280
skippedTargets.add(secondTarget);
273-
secondTarget = possibleTargets.poll();
281+
secondNextTargetOption = fetchNextTarget(possibleTargets);
282+
secondTarget = secondNextTargetOption.isEmpty() ? null : secondNextTargetOption.get()._1;
274283
continue;
275284
}
276285
WaystoneHandle.Vanilla secondTargetHandle = secondTarget._2;
@@ -303,6 +312,19 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
303312
);
304313
}
305314

315+
private Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> fetchNextTarget(Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets) {
316+
Tuple<BlockPos, WaystoneHandle.Vanilla> target = null;
317+
WaystoneData targetData = null;
318+
while(target == null && possibleTargets.size() > 0) {
319+
target = possibleTargets.poll();
320+
if(target == null) continue;
321+
Optional<WaystoneData> dataOptional = WaystoneLibrary.getInstance().getData(target._2);
322+
if(dataOptional.isPresent()) targetData = dataOptional.get();
323+
else target = null;
324+
}
325+
return target == null ? Optional.empty() : Optional.of(Tuple.of(target, targetData));
326+
}
327+
306328
private static boolean shouldFlip(Direction facing, Angle signRotation) {
307329
float degrees = signRotation.add(Angle.fromDegrees(facing.toYRot())).normalized().degrees();
308330
return degrees < -90 || degrees > 90;

src/main/java/gollorum/signpost/minecraft/worldgen/WaystoneDiscoveryEventListener.java

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import gollorum.signpost.WaystoneLibrary;
77
import gollorum.signpost.minecraft.utils.LangKeys;
88
import gollorum.signpost.minecraft.utils.TextComponents;
9+
import gollorum.signpost.utils.WaystoneData;
910
import io.netty.util.internal.PlatformDependent;
1011
import net.minecraft.Util;
1112
import net.minecraft.core.BlockPos;
@@ -18,6 +19,7 @@
1819
import net.minecraftforge.eventbus.api.SubscribeEvent;
1920

2021
import java.util.Map;
22+
import java.util.Optional;
2123
import java.util.concurrent.ConcurrentMap;
2224

2325
public class WaystoneDiscoveryEventListener {
@@ -34,23 +36,27 @@ public static void initialize() {
3436
@SubscribeEvent
3537
public static void onWatchChunk(ChunkWatchEvent.Watch event) {
3638
if(!WaystoneLibrary.hasInstance()) return;
37-
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.generatedWaystonesByChunk.get(
38-
new WaystoneJigsawPiece.ChunkEntryKey(
39-
event.getPos(),
40-
event.getPlayer().level.dimension().location()
41-
)
39+
WaystoneJigsawPiece.ChunkEntryKey key = new WaystoneJigsawPiece.ChunkEntryKey(
40+
event.getPos(),
41+
event.getPlayer().level.dimension().location()
4242
);
43+
Map<WaystoneJigsawPiece.ChunkEntryKey, WaystoneHandle.Vanilla> allEntries = WaystoneJigsawPiece.getAllEntriesByChunk();
44+
WaystoneHandle.Vanilla handle = allEntries.get(key);
4345
if(handle != null && !WaystoneLibrary.getInstance().isDiscovered(PlayerHandle.from(event.getPlayer()), handle)) {
44-
trackedPlayers.computeIfAbsent(event.getPlayer(), p -> PlatformDependent.newConcurrentHashMap())
45-
.putIfAbsent(handle, WaystoneLibrary.getInstance().getData(handle).location.block.blockPos);
46+
Optional<WaystoneData> dataOption = WaystoneLibrary.getInstance().getData(handle);
47+
dataOption.ifPresentOrElse(
48+
data -> trackedPlayers.computeIfAbsent(event.getPlayer(), p -> PlatformDependent.newConcurrentHashMap())
49+
.putIfAbsent(handle, data.location.block.blockPos),
50+
() -> allEntries.remove(key)
51+
);
4652
}
4753
}
4854

4955
@SubscribeEvent
5056
public static void onUnWatchChunk(ChunkWatchEvent.UnWatch event) {
5157
ConcurrentMap<WaystoneHandle.Vanilla, BlockPos> set = trackedPlayers.get(event.getPlayer());
5258
if(set == null) return;
53-
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.generatedWaystonesByChunk.get(
59+
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.getAllEntriesByChunk().get(
5460
new WaystoneJigsawPiece.ChunkEntryKey(
5561
event.getPos(),
5662
event.getPlayer().level.dimension().location()
@@ -66,13 +72,15 @@ public static void onTick(TickEvent.ServerTickEvent event) {
6672
for(Map.Entry<ServerPlayer, ConcurrentMap<WaystoneHandle.Vanilla, BlockPos>> map : trackedPlayers.entrySet()) {
6773
for(Map.Entry<WaystoneHandle.Vanilla, BlockPos> inner : map.getValue().entrySet()) {
6874
if(inner.getValue().closerThan(map.getKey().blockPosition(), discoveryDistance)) {
69-
if(WaystoneLibrary.getInstance().addDiscovered(new PlayerHandle(map.getKey()), inner.getKey())) {
70-
map.getKey().sendMessage(
71-
new TranslatableComponent(
72-
LangKeys.discovered,
73-
TextComponents.waystone(map.getKey(), WaystoneLibrary.getInstance().getData(inner.getKey()).name)
74-
), Util.NIL_UUID);
75-
}
75+
WaystoneLibrary.getInstance().getData(inner.getKey()).ifPresent(data -> {
76+
if(WaystoneLibrary.getInstance().addDiscovered(new PlayerHandle(map.getKey()), inner.getKey())) {
77+
map.getKey().sendMessage(
78+
new TranslatableComponent(
79+
LangKeys.discovered,
80+
TextComponents.waystone(map.getKey(), data.name)
81+
), Util.NIL_UUID);
82+
}
83+
});
7684
map.getValue().remove(inner.getKey());
7785
}
7886
}

src/main/java/gollorum/signpost/minecraft/worldgen/WaystoneJigsawPiece.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ public ChunkEntryKey read(CompoundTag compound) {
100100

101101
// Key is not the position of the block, it's a reference position.
102102
// This is usually the village's position.
103-
public static final Map<BlockPos, WaystoneHandle.Vanilla> generatedWaystones = new HashMap<>();
104-
public static final Map<ChunkEntryKey, WaystoneHandle.Vanilla> generatedWaystonesByChunk = new HashMap<>();
103+
private static final Map<BlockPos, WaystoneHandle.Vanilla> generatedWaystones = new HashMap<>();
104+
private static final Map<ChunkEntryKey, WaystoneHandle.Vanilla> generatedWaystonesByChunk = new HashMap<>();
105105

106106
public static void reset() {
107107
generatedWaystones.clear();
@@ -250,9 +250,23 @@ private static void registerGenerated(String name, BlockPos referencePos, Server
250250
}
251251

252252
public static Set<Map.Entry<BlockPos, WaystoneHandle.Vanilla>> getAllEntries() {
253+
List<BlockPos> toRemove = generatedWaystones.entrySet().stream()
254+
.filter(e -> WaystoneLibrary.getInstance().getData(e.getValue()).isEmpty())
255+
.map(Map.Entry::getKey)
256+
.toList();
257+
for(BlockPos key : toRemove) generatedWaystones.remove(key);
253258
return generatedWaystones.entrySet();
254259
}
255260

261+
public static Map<ChunkEntryKey, WaystoneHandle.Vanilla> getAllEntriesByChunk() {
262+
List<ChunkEntryKey> toRemove = generatedWaystonesByChunk.entrySet().stream()
263+
.filter(e -> WaystoneLibrary.getInstance().getData(e.getValue()).isEmpty())
264+
.map(Map.Entry::getKey)
265+
.toList();
266+
for(ChunkEntryKey key : toRemove) generatedWaystonesByChunk.remove(key);
267+
return generatedWaystonesByChunk;
268+
}
269+
256270
private static List<ModelWaystone> getAllowedWaystones() {
257271
return ModelWaystone.variants.stream()
258272
.filter(v -> Config.Server.worldGen.allowedVillageWaystones.get().contains(v.name))

src/main/java/gollorum/signpost/utils/Either.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,15 @@ public Either<Right, Left> flip() {
3636
public abstract Right rightOr(Function<Left, Right> func);
3737
public abstract Left leftOr(Function<Right, Left> func);
3838

39-
public abstract <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping);
40-
public abstract <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping);
39+
public abstract <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping);
40+
public abstract <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping);
41+
42+
public final <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
43+
return flatMapRight(r -> Either.right(mapping.apply(r)));
44+
}
45+
public final <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
46+
return flatMapLeft(l -> Either.left(mapping.apply(l)));
47+
}
4148

4249
public abstract <Out> Out match(Function<Left, Out> leftMapping, Function<Right, Out> rightMapping);
4350

@@ -61,13 +68,13 @@ private static class LeftImpl<Left, Right> extends Either<Left, Right> {
6168
public Left leftOr(Function<Right, Left> func) { return left; }
6269

6370
@Override
64-
public <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
71+
public <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping) {
6572
return Either.left(left);
6673
}
6774

6875
@Override
69-
public <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
70-
return Either.left(mapping.apply(left));
76+
public <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping) {
77+
return mapping.apply(left);
7178
}
7279

7380
@Override
@@ -113,12 +120,12 @@ private static class RightImpl<Left, Right> extends Either<Left, Right> {
113120
public Left leftOr(Function<Right, Left> func) { return func.apply(right); }
114121

115122
@Override
116-
public <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
117-
return Either.right(mapping.apply(right));
123+
public <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping) {
124+
return mapping.apply(right);
118125
}
119126

120127
@Override
121-
public <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
128+
public <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping) {
122129
return Either.right(right);
123130
}
124131

0 commit comments

Comments
 (0)