| package zinit; |
| |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.ServerSocket; |
| import java.nio.file.FileVisitResult; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.nio.file.SimpleFileVisitor; |
| import java.nio.file.attribute.BasicFileAttributes; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.FutureTask; |
| import java.util.concurrent.TimeUnit; |
| import java.util.concurrent.TimeoutException; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import org.bukkit.Bukkit; |
| import org.bukkit.Server; |
| import org.bukkit.craftbukkit.Main; |
| import org.bukkit.craftbukkit.v1_17_R1.CraftServer; |
| import org.junit.jupiter.api.Assertions; |
| |
| import net.minecraft.server.MinecraftServer; |
| import protocolsupport.zplatform.ServerPlatform; |
| |
| public class PlatformInit { |
| |
| private static final AtomicBoolean init = new AtomicBoolean(false); |
| |
| static { |
| if (init.compareAndSet(false, true)) { |
| try { |
| Files.walkFileTree(Paths.get("."), new SimpleFileVisitor<Path>() { |
| @Override |
| public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { |
| if (file.toString().endsWith(".lock")) { |
| Files.delete(file); |
| } |
| return FileVisitResult.CONTINUE; |
| } |
| }); |
| } catch (IOException e) { |
| Assertions.fail("Failed to delete .lock files", e); |
| } |
| |
| System.setProperty("com.mojang.eula.agree", "true"); |
| System.setProperty("IReallyKnowWhatIAmDoingISwear", "true"); |
| int port = -1; |
| try { |
| try (ServerSocket serverSocket = new ServerSocket(0)) { |
| port = serverSocket.getLocalPort(); |
| } |
| } catch (IOException e) { |
| } |
| Assertions.assertTrue(port > 0, "Unable to find free port for server"); |
| Main.main(new String[] {"--host", InetAddress.getLoopbackAddress().getHostAddress(), "--port", Integer.toString(port), "nogui"}); |
| FutureTask<Void> taskWaitServerStart = new FutureTask<>(new Runnable() { |
| @Override |
| public void run() { |
| Server server = null; |
| try { |
| while ((server = Bukkit.getServer()) == null) { |
| Thread.sleep(1000); |
| } |
| } catch (InterruptedException e) { |
| throw new IllegalStateException("Interrupted while waiting for Bukkit#getServer init", e); |
| } |
| MinecraftServer minecraftserver = ((CraftServer) server).getServer(); |
| FutureTask<Void> taskWaitServerTick = new FutureTask<>(new Callable<Void>() { |
| @Override |
| public Void call() { |
| return null; |
| } |
| }); |
| minecraftserver.processQueue.add(taskWaitServerTick); |
| try { |
| for (;;) { |
| if (minecraftserver.hasStopped()) { |
| throw new IllegalStateException("Server has stopped while starting"); |
| } |
| try { |
| taskWaitServerTick.get(1, TimeUnit.SECONDS); |
| break; |
| } catch (TimeoutException e) { |
| } |
| } |
| } catch (ExecutionException | InterruptedException e) { |
| throw new IllegalStateException("Interrupted while waiting for Server tick wait task to complete", e); |
| } |
| } |
| }, null); |
| try { |
| new Thread(taskWaitServerStart, "Server start wait thread").start(); |
| taskWaitServerStart.get(10, TimeUnit.MINUTES); |
| } catch (Throwable t) { |
| Assertions.fail("Failed to start server", t); |
| } |
| |
| ServerPlatform.detect(); |
| } |
| } |
| |
| } |