Skip to content

Commit

Permalink
Fixup some via race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Jan 28, 2025
1 parent 8df92ff commit 5db96a9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
17 changes: 10 additions & 7 deletions server/src/main/java/com/soulfiremc/server/plugins/POVServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
import org.slf4j.event.Level;

import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -188,7 +189,8 @@ private static void startPOVServer(InstanceSettingsSource settingsSource, int po
server.bind();
}

private static <T> T awaitReceived(Session session, Class<T> clazz) {
@SuppressWarnings("SameParameterValue")
private static <T> CompletableFuture<T> awaitReceived(Session session, Class<T> clazz) {
var future = new CompletableFuture<T>();

session.addListener(
Expand All @@ -201,36 +203,37 @@ public void packetReceived(Session session, Packet packet) {
}
});

return future.orTimeout(30, TimeUnit.SECONDS).join();
return future.orTimeout(30, TimeUnit.SECONDS);
}

private static void syncBotAndUser(BotConnection botConnection, Session clientSession) {
Objects.requireNonNull(botConnection);
var protocol = (MinecraftProtocol) clientSession.getPacketProtocol();
var dataManager = botConnection.dataManager();

clientSession.send(new ClientboundStartConfigurationPacket());
clientSession.switchOutboundState(() -> ((MinecraftProtocol) clientSession.getPacketProtocol()).setOutboundState(ProtocolState.CONFIGURATION));
awaitReceived(clientSession, ServerboundConfigurationAcknowledgedPacket.class);
clientSession.switchOutboundState(() -> protocol.setOutboundState(ProtocolState.CONFIGURATION));
TimeUtil.waitCondition(() -> protocol.getInboundState() != ProtocolState.CONFIGURATION, Duration.ofSeconds(30));

if (dataManager.serverEnabledFeatures() != null) {
clientSession.send(
new ClientboundUpdateEnabledFeaturesPacket(
dataManager.serverEnabledFeatures()));
}

var clientPacks = awaitReceived(clientSession, ServerboundSelectKnownPacks.class);
if (dataManager.serverKnownPacks() != null) {
clientSession.send(new ClientboundSelectKnownPacks(dataManager.serverKnownPacks()));
}

var clientPacks = awaitReceived(clientSession, ServerboundSelectKnownPacks.class);
for (var entry : dataManager.resolvedRegistryData().entrySet()) {
var registryKey = entry.getKey();

var sentEntries = new ArrayList<RegistryEntry>();
for (var value : entry.getValue()) {
var holderKey = value.getId();
var serverHolderData = value.getData();
var packData = BuiltInKnownPackRegistry.INSTANCE.findDataOptionally(registryKey, holderKey, clientPacks.getKnownPacks());
var packData = BuiltInKnownPackRegistry.INSTANCE.findDataOptionally(registryKey, holderKey, clientPacks.join().getKnownPacks());

RegistryEntry entryToSend;
if (packData.isPresent() && packData.get().equals(serverHolderData)) {
Expand All @@ -250,7 +253,7 @@ private static void syncBotAndUser(BotConnection botConnection, Session clientSe
clientSession.send(tagsPacket);

clientSession.send(new ClientboundFinishConfigurationPacket());
awaitReceived(clientSession, ServerboundFinishConfigurationPacket.class);
TimeUtil.waitCondition(() -> protocol.getInboundState() != ProtocolState.GAME, Duration.ofSeconds(30));

var spawnInfo =
new PlayerSpawnInfo(
Expand Down
10 changes: 9 additions & 1 deletion server/src/main/java/com/soulfiremc/server/util/TimeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/
package com.soulfiremc.server.util;

import org.jetbrains.annotations.Nullable;

import java.time.Duration;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
Expand Down Expand Up @@ -54,10 +57,15 @@ public boolean block() throws InterruptedException {
}

public static void waitCondition(BooleanSupplier condition) {
waitCondition(condition, null);
}

public static void waitCondition(BooleanSupplier condition, @Nullable Duration timeout) {
var startTime = System.nanoTime();
try {
ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {
public boolean isReleasable() {
return !condition.getAsBoolean();
return !condition.getAsBoolean() || (timeout != null && System.nanoTime() - startTime >= timeout.toNanos());
}

public boolean block() throws InterruptedException {
Expand Down

0 comments on commit 5db96a9

Please sign in to comment.