2018-06-21 19:37:32 +00:00
/ *
* Minecraft Forge
2019-02-10 22:57:03 +00:00
* Copyright ( c ) 2016 - 2019 .
2018-06-21 19:37:32 +00:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2 . 1
* of the License .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
* /
2018-08-27 17:10:07 +00:00
package net.minecraftforge.fml.server ;
2018-06-21 19:37:32 +00:00
import net.minecraft.network.EnumConnectionState ;
import net.minecraft.network.NetworkManager ;
2018-08-27 17:10:07 +00:00
import net.minecraft.network.handshake.client.CPacketHandshake ;
import net.minecraft.network.login.server.SPacketDisconnectLogin ;
2018-06-21 19:37:32 +00:00
import net.minecraft.server.MinecraftServer ;
import net.minecraft.util.text.TextComponentString ;
2018-10-06 01:42:15 +00:00
import net.minecraftforge.api.distmarker.Dist ;
2018-06-21 19:37:32 +00:00
import net.minecraftforge.common.MinecraftForge ;
2018-10-06 01:42:15 +00:00
import net.minecraftforge.fml.DistExecutor ;
2018-08-27 17:10:07 +00:00
import net.minecraftforge.fml.LogicalSidedProvider ;
2019-01-29 03:42:37 +00:00
import net.minecraftforge.fml.config.ConfigTracker ;
import net.minecraftforge.fml.config.ModConfig ;
2019-01-15 03:32:43 +00:00
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent ;
import net.minecraftforge.fml.event.server.FMLServerStartingEvent ;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent ;
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent ;
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent ;
2019-01-29 03:42:37 +00:00
import net.minecraftforge.fml.loading.FileUtils ;
2018-06-21 19:37:32 +00:00
import net.minecraftforge.fml.network.NetworkHooks ;
2018-10-06 01:42:15 +00:00
import net.minecraftforge.fml.packs.ResourcePackLoader ;
2018-06-21 19:37:32 +00:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
import org.apache.logging.log4j.Marker ;
import org.apache.logging.log4j.MarkerManager ;
2019-01-29 03:42:37 +00:00
import java.nio.file.Path ;
2018-06-21 19:37:32 +00:00
import java.util.List ;
import java.util.concurrent.CountDownLatch ;
import java.util.concurrent.atomic.AtomicBoolean ;
public class ServerLifecycleHooks
{
2018-08-27 17:10:07 +00:00
private static final Logger LOGGER = LogManager . getLogger ( ) ;
2018-06-21 19:37:32 +00:00
private static final Marker SERVERHOOKS = MarkerManager . getMarker ( " SERVERHOOKS " ) ;
private static volatile CountDownLatch exitLatch = null ;
private static MinecraftServer currentServer ;
public static boolean handleServerAboutToStart ( final MinecraftServer server )
{
currentServer = server ;
2018-06-23 02:45:01 +00:00
LogicalSidedProvider . setServer ( ( ) - > server ) ;
2019-01-29 03:42:37 +00:00
final Path serverConfig = server . getActiveAnvilConverter ( ) . getFile ( server . getFolderName ( ) , " serverconfig " ) . toPath ( ) ;
FileUtils . getOrCreateDirectory ( serverConfig , " serverconfig " ) ;
ConfigTracker . INSTANCE . loadConfigs ( ModConfig . Type . SERVER , serverConfig ) ;
2018-10-06 01:42:15 +00:00
ResourcePackLoader . loadResourcePacks ( currentServer . getResourcePacks ( ) ) ;
2018-06-21 19:37:32 +00:00
return ! MinecraftForge . EVENT_BUS . post ( new FMLServerAboutToStartEvent ( server ) ) ;
}
public static boolean handleServerStarting ( final MinecraftServer server )
{
2018-10-06 01:42:15 +00:00
DistExecutor . runWhenOn ( Dist . DEDICATED_SERVER , ( ) - > ( ) - > LanguageHook . loadLanguagesOnServer ( server ) ) ;
2018-06-21 19:37:32 +00:00
return ! MinecraftForge . EVENT_BUS . post ( new FMLServerStartingEvent ( server ) ) ;
}
2018-07-01 20:10:13 +00:00
public static void handleServerStarted ( final MinecraftServer server )
2018-06-21 19:37:32 +00:00
{
2018-07-01 20:10:13 +00:00
MinecraftForge . EVENT_BUS . post ( new FMLServerStartedEvent ( server ) ) ;
2018-06-21 19:37:32 +00:00
allowLogins . set ( true ) ;
}
2018-07-01 20:10:13 +00:00
public static void handleServerStopping ( final MinecraftServer server )
2018-06-21 19:37:32 +00:00
{
allowLogins . set ( false ) ;
2018-07-01 20:10:13 +00:00
MinecraftForge . EVENT_BUS . post ( new FMLServerStoppingEvent ( server ) ) ;
2018-06-21 19:37:32 +00:00
}
public static void expectServerStopped ( )
{
exitLatch = new CountDownLatch ( 1 ) ;
}
public static void handleServerStopped ( final MinecraftServer server )
{
2018-07-01 20:10:13 +00:00
MinecraftForge . EVENT_BUS . post ( new FMLServerStoppedEvent ( server ) ) ;
2018-06-21 19:37:32 +00:00
currentServer = null ;
2018-06-23 02:45:01 +00:00
LogicalSidedProvider . setServer ( null ) ;
2018-06-21 19:37:32 +00:00
CountDownLatch latch = exitLatch ;
if ( latch ! = null )
{
latch . countDown ( ) ;
exitLatch = null ;
}
}
public static MinecraftServer getCurrentServer ( )
{
return currentServer ;
}
private static AtomicBoolean allowLogins = new AtomicBoolean ( false ) ;
2018-08-27 17:10:07 +00:00
public static boolean handleServerLogin ( final CPacketHandshake packet , final NetworkManager manager ) {
2018-06-21 19:37:32 +00:00
if ( ! allowLogins . get ( ) )
{
TextComponentString text = new TextComponentString ( " Server is still starting! Please wait before reconnecting. " ) ;
2018-08-27 17:10:07 +00:00
LOGGER . info ( SERVERHOOKS , " Disconnecting Player (server is still starting): {} " , text . getUnformattedComponentText ( ) ) ;
manager . sendPacket ( new SPacketDisconnectLogin ( text ) ) ;
2018-06-21 19:37:32 +00:00
manager . closeChannel ( text ) ;
return false ;
}
if ( packet . getRequestedState ( ) = = EnumConnectionState . LOGIN & & ! NetworkHooks . accepts ( packet ) )
{
manager . setConnectionState ( EnumConnectionState . LOGIN ) ;
TextComponentString text = new TextComponentString ( " This server has mods that require Forge to be installed on the client. Contact your server admin for more details. " ) ;
List < String > modNames = net . minecraftforge . fml . network . NetworkRegistry . getNonVanillaNetworkMods ( ) ;
LOGGER . info ( SERVERHOOKS , " Disconnecting vanilla connection attempt. Required mods {} " , modNames ) ;
2018-08-27 17:10:07 +00:00
manager . sendPacket ( new SPacketDisconnectLogin ( text ) ) ;
2018-06-21 19:37:32 +00:00
manager . closeChannel ( text ) ;
return false ;
}
2019-02-16 02:45:28 +00:00
if ( packet . getRequestedState ( ) = = EnumConnectionState . STATUS ) return true ;
2018-09-05 00:23:45 +00:00
NetworkHooks . registerServerLoginChannel ( manager , packet ) ;
2018-06-21 19:37:32 +00:00
return true ;
}
2018-11-29 06:15:05 +00:00
public static void handleExit ( int retVal )
2018-06-21 19:37:32 +00:00
{
/ *
CountDownLatch latch = exitLatch ;
if ( latch ! = null )
{
try
{
2018-09-14 16:30:56 +00:00
LOGGER . info ( " Waiting for the server to terminate/save. " ) ;
2018-06-21 19:37:32 +00:00
if ( ! latch . await ( 10 , TimeUnit . SECONDS ) )
{
2018-09-14 16:30:56 +00:00
LOGGER . warn ( " The server didn't stop within 10 seconds, exiting anyway. " ) ;
2018-06-21 19:37:32 +00:00
}
else
{
2018-09-14 16:30:56 +00:00
LOGGER . info ( " Server terminated. " ) ;
2018-06-21 19:37:32 +00:00
}
}
catch ( InterruptedException e )
{
2018-09-14 16:30:56 +00:00
LOGGER . warn ( " Interrupted wait, exiting. " ) ;
2018-06-21 19:37:32 +00:00
}
}
* /
System . exit ( retVal ) ;
}
}