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
2019-05-23 23:02:15 +00:00
import net.minecraft.network.ProtocolType ;
2018-06-21 19:37:32 +00:00
import net.minecraft.network.NetworkManager ;
2019-05-23 23:02:15 +00:00
import net.minecraft.network.handshake.client.CHandshakePacket ;
import net.minecraft.network.login.server.SDisconnectLoginPacket ;
2018-06-21 19:37:32 +00:00
import net.minecraft.server.MinecraftServer ;
2019-05-23 23:02:15 +00:00
import net.minecraft.util.text.StringTextComponent ;
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 ;
2019-02-28 05:59:27 +00:00
import net.minecraftforge.fml.network.ConnectionType ;
import net.minecraftforge.fml.network.FMLNetworkConstants ;
2018-06-21 19:37:32 +00:00
import net.minecraftforge.fml.network.NetworkHooks ;
2019-02-28 05:59:27 +00:00
import net.minecraftforge.fml.network.NetworkRegistry ;
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 ) ;
2019-05-23 23:02:15 +00:00
public static boolean handleServerLogin ( final CHandshakePacket packet , final NetworkManager manager ) {
2018-06-21 19:37:32 +00:00
if ( ! allowLogins . get ( ) )
{
2019-05-23 23:02:15 +00:00
StringTextComponent text = new StringTextComponent ( " 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 ( ) ) ;
2019-05-23 23:02:15 +00:00
manager . sendPacket ( new SDisconnectLoginPacket ( text ) ) ;
2018-06-21 19:37:32 +00:00
manager . closeChannel ( text ) ;
return false ;
}
2019-05-23 23:02:15 +00:00
if ( packet . getRequestedState ( ) = = ProtocolType . LOGIN ) {
2019-02-28 05:59:27 +00:00
final ConnectionType connectionType = ConnectionType . forVersionFlag ( packet . getFMLVersion ( ) ) ;
final int versionNumber = connectionType . getFMLVersionNumber ( packet . getFMLVersion ( ) ) ;
if ( connectionType = = ConnectionType . MODDED & & versionNumber ! = FMLNetworkConstants . FMLNETVERSION ) {
rejectConnection ( manager , connectionType , " This modded server is not network compatible with your modded client. Please verify your Forge version closely matches the server. Got net version " + versionNumber + " this server is net version " + FMLNetworkConstants . FMLNETVERSION ) ;
return false ;
}
if ( connectionType = = ConnectionType . VANILLA & & ! NetworkRegistry . acceptsVanillaClientConnections ( ) ) {
rejectConnection ( manager , connectionType , " This server has mods that require Forge to be installed on the client. Contact your server admin for more details. " ) ;
return false ;
}
2018-06-21 19:37:32 +00:00
}
2019-05-23 23:02:15 +00:00
if ( packet . getRequestedState ( ) = = ProtocolType . STATUS ) return true ;
2019-02-16 02:45:28 +00:00
2018-09-05 00:23:45 +00:00
NetworkHooks . registerServerLoginChannel ( manager , packet ) ;
2018-06-21 19:37:32 +00:00
return true ;
}
2019-02-28 05:59:27 +00:00
private static void rejectConnection ( final NetworkManager manager , ConnectionType type , String message ) {
2019-05-23 23:02:15 +00:00
manager . setConnectionState ( ProtocolType . LOGIN ) ;
2019-06-08 14:45:28 +00:00
LOGGER . info ( SERVERHOOKS , " Disconnecting {} connection attempt: {} " , type , message ) ;
2019-05-23 23:02:15 +00:00
StringTextComponent text = new StringTextComponent ( message ) ;
manager . sendPacket ( new SDisconnectLoginPacket ( text ) ) ;
2019-02-28 05:59:27 +00:00
manager . closeChannel ( text ) ;
}
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 ) ;
}
}