Add LAN games support.

This commit is contained in:
LambdAurora 2020-10-25 17:29:19 +01:00
parent c426c335d7
commit a9b414c675
6 changed files with 207 additions and 15 deletions

View File

@ -28,7 +28,7 @@ package org.geysermc.platform.fabric;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.MinecraftServer;
@ -57,8 +57,9 @@ import java.nio.file.Path;
import java.util.*;
import java.util.function.Function;
@Environment(EnvType.SERVER)
public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBootstrap {
public class GeyserFabricMod implements ModInitializer, GeyserBootstrap {
private static GeyserFabricMod instance;
private GeyserConnector connector;
private Path dataFolder;
@ -71,8 +72,14 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo
private IGeyserPingPassthrough geyserPingPassthrough;
@Override
public void onInitializeServer() {
public void onInitialize() {
instance = this;
this.onEnable();
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
// Set as an event so we can get the proper IP and port if needed
ServerLifecycleEvents.SERVER_STARTED.register(this::startGeyser);
}
}
@Override
@ -99,29 +106,27 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo
if (server == null) {
// Server has yet to start
// Set as an event so we can get the proper IP and port if needed
ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
this.server = server;
startGeyser();
});
// Register onDisable so players are properly kicked
ServerLifecycleEvents.SERVER_STOPPING.register((server) -> onDisable());
} else {
// Server has started and this is a reload
startGeyser();
startGeyser(this.server);
}
}
/**
* Initialize core Geyser.
* A function, as it needs to be called in different places depending on if Geyser is being reloaded or not.
*
* @param server The minecraft server.
*/
public void startGeyser() {
public void startGeyser(MinecraftServer server) {
this.server = server;
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
this.geyserConfig.setAutoconfiguredRemote(true);
String ip = server.getServerIp();
int port = server.getServerPort();
int port = ((GeyserServerPortGetter) server).geyser$getServerPort();
if (ip != null && !ip.isEmpty() && !ip.equals("0.0.0.0")) {
this.geyserConfig.getRemote().setAddress(ip);
}
@ -157,6 +162,7 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo
connector.shutdown();
connector = null;
}
this.server = null;
}
@Override
@ -212,4 +218,8 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo
return file;
}
public static GeyserFabricMod getInstance() {
return instance;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.fabric;
import net.minecraft.server.MinecraftServer;
/**
* Represents a getter to the server port in the dedicated server and in the integrated server.
*/
public interface GeyserServerPortGetter {
/**
* Returns the server port.
*
* <ul>
* <li>If it's a dedicated server, it will return the server port specified in the {@code server.properties} file.</li>
* <li>If it's an integrated server, it will return the LAN port if opened, else -1.</li>
* </ul>
*
* The reason is that {@link MinecraftServer#getServerPort()} doesn't return the LAN port if it's the integrated server,
* and changing the behavior of this method via a mixin should be avoided as it could have unexpected consequences.
*
* @return The server port.
*/
int geyser$getServerPort();
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.fabric.mixin.client;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.world.GameMode;
import org.geysermc.platform.fabric.GeyserFabricMod;
import org.geysermc.platform.fabric.GeyserServerPortGetter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Environment(EnvType.CLIENT)
@Mixin(IntegratedServer.class)
public class IntegratedServerMixin implements GeyserServerPortGetter {
@Shadow
private int lanPort;
@Inject(method = "openToLan", at = @At("RETURN"))
private void onOpenToLan(GameMode gameMode, boolean cheatsAllowed, int port, CallbackInfoReturnable<Boolean> cir) {
if (cir.getReturnValueZ()) {
// If the LAN is opened, starts Geyser.
GeyserFabricMod.getInstance().startGeyser((MinecraftServer) (Object) this);
}
}
@Override
public int geyser$getServerPort() {
return this.lanPort;
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.platform.fabric.mixin.server;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.datafixers.DataFixer;
import net.minecraft.resource.ResourcePackManager;
import net.minecraft.resource.ServerResourceManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListenerFactory;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.util.UserCache;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.world.SaveProperties;
import net.minecraft.world.level.storage.LevelStorage;
import org.geysermc.platform.fabric.GeyserServerPortGetter;
import org.spongepowered.asm.mixin.Mixin;
import java.net.Proxy;
@Mixin(MinecraftDedicatedServer.class)
public abstract class MinecraftDedicatedServerMixin extends MinecraftServer implements GeyserServerPortGetter
{
// Constructor to compile
public MinecraftDedicatedServerMixin(Thread thread, DynamicRegistryManager.Impl impl, LevelStorage.Session session, SaveProperties saveProperties, ResourcePackManager resourcePackManager, Proxy proxy, DataFixer dataFixer, ServerResourceManager serverResourceManager, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, UserCache userCache, WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory) {
super(thread, impl, session, saveProperties, resourcePackManager, proxy, dataFixer, serverResourceManager, minecraftSessionService, gameProfileRepository, userCache, worldGenerationProgressListenerFactory);
}
@Override
public int geyser$getServerPort() {
return this.getServerPort();
}
}

View File

@ -13,12 +13,15 @@
},
"license": "MIT",
"icon": "assets/fabric/icon.png",
"environment": "server",
"environment": "*",
"entrypoints": {
"server": [
"main": [
"org.geysermc.platform.fabric.GeyserFabricMod"
]
},
"mixins": [
"geyser-fabric.mixins.json"
],
"depends": {
"fabricloader": ">=0.10.1+build.209",
"fabric": "*",

View File

@ -0,0 +1,14 @@
{
"required": true,
"package": "org.geysermc.platform.fabric.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"client.IntegratedServerMixin"
],
"server": [
"server.MinecraftDedicatedServerMixin"
],
"injectors": {
"defaultRequire": 1
}
}