Skip to content

Commit

Permalink
Fixed null ref exception
Browse files Browse the repository at this point in the history
  • Loading branch information
Gollorum committed Jan 23, 2022
1 parent 791699b commit b7010c5
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 53 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ package_group=gollorum.signpost
mc_version=1.18.1
forge_version=39.0.10

mod_version=2.00.4
mod_version=2.00.5
6 changes: 4 additions & 2 deletions src/main/java/gollorum/signpost/WaystoneLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ public WaystoneLocationData getLocationData(WaystoneHandle.Vanilla waystoneId) {
return allWaystones.get(waystoneId).locationData;
}

public WaystoneData getData(WaystoneHandle.Vanilla waystoneId) {
public Optional<WaystoneData> getData(WaystoneHandle.Vanilla waystoneId) {
assert Signpost.getServerType().isServer;
WaystoneEntry entry = allWaystones.get(waystoneId);
return new WaystoneData(waystoneId, entry.name, entry.locationData, entry.isLocked);
return Optional.ofNullable(
entry == null ? null : new WaystoneData(waystoneId, entry.name, entry.locationData, entry.isLocked)
);
}

private static class WaystoneEntry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import gollorum.signpost.minecraft.gui.PaintSignGui;
import gollorum.signpost.minecraft.gui.RequestSignGui;
import gollorum.signpost.minecraft.items.Brush;
import gollorum.signpost.minecraft.utils.LangKeys;
import gollorum.signpost.networking.PacketHandler;
import gollorum.signpost.relations.ExternalWaystone;
import gollorum.signpost.security.WithOwner;
Expand Down Expand Up @@ -268,24 +269,27 @@ public InteractionResult interact(InteractionInfo info) {
private void tryTeleport(ServerPlayer player, PostTile.TilePartInfo tilePartInfo) {
if(Config.Server.teleport.enableTeleport.get() && coreData.destination.isPresent() && (!(coreData.destination.get() instanceof WaystoneHandle.Vanilla) || WaystoneLibrary.getInstance().contains((WaystoneHandle.Vanilla) coreData.destination.get()))) {
WaystoneHandle dest = coreData.destination.get();
Optional<WaystoneHandle.Vanilla> vanillaHandle = dest instanceof WaystoneHandle.Vanilla ? Optional.of((WaystoneHandle.Vanilla) dest) : Optional.empty();
Optional<WaystoneHandle.Vanilla> vanillaHandle = dest instanceof WaystoneHandle.Vanilla
? Optional.of((WaystoneHandle.Vanilla) dest)
: Optional.empty();
PacketHandler.send(
PacketDistributor.PLAYER.with(() -> player),
new Teleport.RequestGui.Package(
Either.rightIfPresent(vanillaHandle, () -> ((ExternalWaystone.Handle) dest).noTeleportLangKey())
.mapRight(h -> {
WaystoneData data = WaystoneLibrary.getInstance().getData(h);
boolean isDiscovered = WaystoneLibrary.getInstance()
.isDiscovered(new PlayerHandle(player), h) || !Config.Server.teleport.enforceDiscovery.get();
int distance = (int) data.location.spawn.distanceTo(Vector3.fromVec3d(player.position()));
return new Teleport.RequestGui.Package.Info(
Config.Server.teleport.maximumDistance.get(),
distance,
isDiscovered,
data.name,
Teleport.getCost(player, Vector3.fromBlockPos(data.location.block.blockPos), data.location.spawn)
);
}),
.flatMapRight(h ->
Either.rightIfPresent(WaystoneLibrary.getInstance().getData(h), () -> LangKeys.waystoneNotFound).mapRight(data -> {
boolean isDiscovered = WaystoneLibrary.getInstance()
.isDiscovered(new PlayerHandle(player), h) || !Config.Server.teleport.enforceDiscovery.get();
int distance = (int) data.location.spawn.distanceTo(Vector3.fromVec3d(player.position()));
return new Teleport.RequestGui.Package.Info(
Config.Server.teleport.maximumDistance.get(),
distance,
isDiscovered,
data.name,
Teleport.getCost(player, Vector3.fromBlockPos(data.location.block.blockPos), data.location.spawn)
);
})
),
Optional.of(tilePartInfo)
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public static void openGuiIfHasPermission(ServerPlayer player, WorldLocation wor
assert Signpost.getServerType().isServer;
Optional<WaystoneData> data = WaystoneLibrary.getInstance()
.getHandleByLocation(worldLocation)
.map(WaystoneLibrary.getInstance()::getData);
boolean wantsToOpenGui = !data.isPresent()
.flatMap(WaystoneLibrary.getInstance()::getData);
boolean wantsToOpenGui = data.isEmpty()
|| WaystoneLibrary.getInstance().isDiscovered(PlayerHandle.from(player), data.get().handle);
boolean mayOpenGui = data.map(d -> d.hasThePermissionToEdit(player)).orElse(true);
if(wantsToOpenGui && mayOpenGui){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,11 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeWideSi
Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets,
float y
) {
Tuple<BlockPos, WaystoneHandle.Vanilla> target = possibleTargets.poll();
if(target == null) return new Tuple<>(Collections.emptySet(), x -> {});
WaystoneData targetData = WaystoneLibrary.getInstance().getData(target._2);
Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> nextTargetOption = fetchNextTarget(possibleTargets);
if(nextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
Tuple<BlockPos, WaystoneHandle.Vanilla> target = nextTargetOption.get()._1;
WaystoneData targetData = nextTargetOption.get()._2;

Angle rotation = SignBlockPart.pointingAt(tilePos, target._1);
Consumer<PostTile> onTileFetched = tile -> {
if(tile.getParts().stream().anyMatch(instance -> !(instance.blockPart instanceof PostBlockPart) && isNearly(instance.offset.y, y)))
Expand Down Expand Up @@ -242,9 +244,11 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets,
float y
) {
Tuple<BlockPos, WaystoneHandle.Vanilla> target = possibleTargets.poll();
if(target == null) return new Tuple<>(Collections.emptySet(), x -> {});
WaystoneData targetData = WaystoneLibrary.getInstance().getData(target._2);
Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> nextTargetOption = fetchNextTarget(possibleTargets);
if(nextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
Tuple<BlockPos, WaystoneHandle.Vanilla> target = nextTargetOption.get()._1;
WaystoneData targetData = nextTargetOption.get()._2;

Angle rotation = SignBlockPart.pointingAt(tilePos, target._1);
boolean shouldFlip = shouldFlip(facing, rotation);
Optional<Overlay> overlay = overlayFor(world, tilePos);
Expand All @@ -262,15 +266,20 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
ItemStack.EMPTY,
PlayerHandle.Invalid
));
Tuple<BlockPos, WaystoneHandle.Vanilla> secondTarget = possibleTargets.poll();

Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> secondNextTargetOption = fetchNextTarget(possibleTargets);
if(secondNextTargetOption.isEmpty()) return new Tuple<>(Collections.emptySet(), x -> {});
Tuple<BlockPos, WaystoneHandle.Vanilla> secondTarget = secondNextTargetOption.get()._1;

List<Tuple<BlockPos, WaystoneHandle.Vanilla>> skippedTargets = new ArrayList<>();
while(secondTarget != null) {
WaystoneData secondTargetData = WaystoneLibrary.getInstance().getData(secondTarget._2);
WaystoneData secondTargetData = secondNextTargetOption.get()._2;
Angle secondRotation = SignBlockPart.pointingAt(tilePos, secondTarget._1);
boolean shouldSecondFlip = shouldFlip(facing, secondRotation);
if(shouldSecondFlip == shouldFlip) {
skippedTargets.add(secondTarget);
secondTarget = possibleTargets.poll();
secondNextTargetOption = fetchNextTarget(possibleTargets);
secondTarget = secondNextTargetOption.isEmpty() ? null : secondNextTargetOption.get()._1;
continue;
}
WaystoneHandle.Vanilla secondTargetHandle = secondTarget._2;
Expand Down Expand Up @@ -303,6 +312,19 @@ private Tuple<Collection<WaystoneHandle.Vanilla>, Consumer<PostTile>> makeShortS
);
}

private Optional<Tuple<Tuple<BlockPos, WaystoneHandle.Vanilla>, WaystoneData>> fetchNextTarget(Queue<Tuple<BlockPos, WaystoneHandle.Vanilla>> possibleTargets) {
Tuple<BlockPos, WaystoneHandle.Vanilla> target = null;
WaystoneData targetData = null;
while(target == null && possibleTargets.size() > 0) {
target = possibleTargets.poll();
if(target == null) continue;
Optional<WaystoneData> dataOptional = WaystoneLibrary.getInstance().getData(target._2);
if(dataOptional.isPresent()) targetData = dataOptional.get();
else target = null;
}
return target == null ? Optional.empty() : Optional.of(Tuple.of(target, targetData));
}

private static boolean shouldFlip(Direction facing, Angle signRotation) {
float degrees = signRotation.add(Angle.fromDegrees(facing.toYRot())).normalized().degrees();
return degrees < -90 || degrees > 90;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import gollorum.signpost.WaystoneLibrary;
import gollorum.signpost.minecraft.utils.LangKeys;
import gollorum.signpost.minecraft.utils.TextComponents;
import gollorum.signpost.utils.WaystoneData;
import io.netty.util.internal.PlatformDependent;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
Expand All @@ -18,6 +19,7 @@
import net.minecraftforge.eventbus.api.SubscribeEvent;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;

public class WaystoneDiscoveryEventListener {
Expand All @@ -34,23 +36,27 @@ public static void initialize() {
@SubscribeEvent
public static void onWatchChunk(ChunkWatchEvent.Watch event) {
if(!WaystoneLibrary.hasInstance()) return;
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.generatedWaystonesByChunk.get(
new WaystoneJigsawPiece.ChunkEntryKey(
event.getPos(),
event.getPlayer().level.dimension().location()
)
WaystoneJigsawPiece.ChunkEntryKey key = new WaystoneJigsawPiece.ChunkEntryKey(
event.getPos(),
event.getPlayer().level.dimension().location()
);
Map<WaystoneJigsawPiece.ChunkEntryKey, WaystoneHandle.Vanilla> allEntries = WaystoneJigsawPiece.getAllEntriesByChunk();
WaystoneHandle.Vanilla handle = allEntries.get(key);
if(handle != null && !WaystoneLibrary.getInstance().isDiscovered(PlayerHandle.from(event.getPlayer()), handle)) {
trackedPlayers.computeIfAbsent(event.getPlayer(), p -> PlatformDependent.newConcurrentHashMap())
.putIfAbsent(handle, WaystoneLibrary.getInstance().getData(handle).location.block.blockPos);
Optional<WaystoneData> dataOption = WaystoneLibrary.getInstance().getData(handle);
dataOption.ifPresentOrElse(
data -> trackedPlayers.computeIfAbsent(event.getPlayer(), p -> PlatformDependent.newConcurrentHashMap())
.putIfAbsent(handle, data.location.block.blockPos),
() -> allEntries.remove(key)
);
}
}

@SubscribeEvent
public static void onUnWatchChunk(ChunkWatchEvent.UnWatch event) {
ConcurrentMap<WaystoneHandle.Vanilla, BlockPos> set = trackedPlayers.get(event.getPlayer());
if(set == null) return;
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.generatedWaystonesByChunk.get(
WaystoneHandle.Vanilla handle = WaystoneJigsawPiece.getAllEntriesByChunk().get(
new WaystoneJigsawPiece.ChunkEntryKey(
event.getPos(),
event.getPlayer().level.dimension().location()
Expand All @@ -66,13 +72,15 @@ public static void onTick(TickEvent.ServerTickEvent event) {
for(Map.Entry<ServerPlayer, ConcurrentMap<WaystoneHandle.Vanilla, BlockPos>> map : trackedPlayers.entrySet()) {
for(Map.Entry<WaystoneHandle.Vanilla, BlockPos> inner : map.getValue().entrySet()) {
if(inner.getValue().closerThan(map.getKey().blockPosition(), discoveryDistance)) {
if(WaystoneLibrary.getInstance().addDiscovered(new PlayerHandle(map.getKey()), inner.getKey())) {
map.getKey().sendMessage(
new TranslatableComponent(
LangKeys.discovered,
TextComponents.waystone(map.getKey(), WaystoneLibrary.getInstance().getData(inner.getKey()).name)
), Util.NIL_UUID);
}
WaystoneLibrary.getInstance().getData(inner.getKey()).ifPresent(data -> {
if(WaystoneLibrary.getInstance().addDiscovered(new PlayerHandle(map.getKey()), inner.getKey())) {
map.getKey().sendMessage(
new TranslatableComponent(
LangKeys.discovered,
TextComponents.waystone(map.getKey(), data.name)
), Util.NIL_UUID);
}
});
map.getValue().remove(inner.getKey());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public ChunkEntryKey read(CompoundTag compound) {

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

public static void reset() {
generatedWaystones.clear();
Expand Down Expand Up @@ -250,9 +250,23 @@ private static void registerGenerated(String name, BlockPos referencePos, Server
}

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

public static Map<ChunkEntryKey, WaystoneHandle.Vanilla> getAllEntriesByChunk() {
List<ChunkEntryKey> toRemove = generatedWaystonesByChunk.entrySet().stream()
.filter(e -> WaystoneLibrary.getInstance().getData(e.getValue()).isEmpty())
.map(Map.Entry::getKey)
.toList();
for(ChunkEntryKey key : toRemove) generatedWaystonesByChunk.remove(key);
return generatedWaystonesByChunk;
}

private static List<ModelWaystone> getAllowedWaystones() {
return ModelWaystone.variants.stream()
.filter(v -> Config.Server.worldGen.allowedVillageWaystones.get().contains(v.name))
Expand Down
23 changes: 15 additions & 8 deletions src/main/java/gollorum/signpost/utils/Either.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,15 @@ public Either<Right, Left> flip() {
public abstract Right rightOr(Function<Left, Right> func);
public abstract Left leftOr(Function<Right, Left> func);

public abstract <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping);
public abstract <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping);
public abstract <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping);
public abstract <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping);

public final <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
return flatMapRight(r -> Either.right(mapping.apply(r)));
}
public final <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
return flatMapLeft(l -> Either.left(mapping.apply(l)));
}

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

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

@Override
public <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
public <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping) {
return Either.left(left);
}

@Override
public <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
return Either.left(mapping.apply(left));
public <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping) {
return mapping.apply(left);
}

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

@Override
public <NewRight> Either<Left, NewRight> mapRight(Function<Right, NewRight> mapping) {
return Either.right(mapping.apply(right));
public <NewRight> Either<Left, NewRight> flatMapRight(Function<Right, Either<Left, NewRight>> mapping) {
return mapping.apply(right);
}

@Override
public <NewLeft> Either<NewLeft, Right> mapLeft(Function<Left, NewLeft> mapping) {
public <NewLeft> Either<NewLeft, Right> flatMapLeft(Function<Left, Either<NewLeft, Right>> mapping) {
return Either.right(right);
}

Expand Down

0 comments on commit b7010c5

Please sign in to comment.