2021-07-24 13:10:48 +02:00
/ *
* This file is part of Player Analytics ( Plan ) .
*
* Plan is free software : you can redistribute it and / or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Plan 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 Plan . If not , see < https : //www.gnu.org/licenses/>.
* /
package net.playeranalytics.plan ;
import com.djrapitops.plan.PlanPlugin ;
import com.djrapitops.plan.PlanSystem ;
import com.djrapitops.plan.commands.use.ColorScheme ;
import com.djrapitops.plan.commands.use.Subcommand ;
import com.djrapitops.plan.exceptions.EnableException ;
import com.djrapitops.plan.gathering.ServerShutdownSave ;
import com.djrapitops.plan.settings.locale.Locale ;
import com.djrapitops.plan.settings.locale.lang.PluginLang ;
import com.djrapitops.plan.settings.theme.PlanColorScheme ;
2021-08-09 06:36:15 +02:00
import io.github.slimjar.app.builder.ApplicationBuilder ;
import io.github.slimjar.resolver.data.Repository ;
2021-07-24 13:10:48 +02:00
import net.fabricmc.api.DedicatedServerModInitializer ;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback ;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents ;
2021-08-09 06:36:15 +02:00
import net.fabricmc.loader.api.FabricLoader ;
2021-07-24 13:10:48 +02:00
import net.minecraft.server.dedicated.MinecraftDedicatedServer ;
import net.playeranalytics.plan.commands.CommandManager ;
2021-07-24 15:23:18 +02:00
import net.playeranalytics.plan.identification.properties.FabricServerProperties ;
2021-07-24 13:10:48 +02:00
import net.playeranalytics.plugin.FabricPlatformLayer ;
import net.playeranalytics.plugin.PlatformAbstractionLayer ;
import net.playeranalytics.plugin.scheduling.RunnableFactory ;
2021-08-09 06:36:15 +02:00
import net.playeranalytics.plugin.server.FabricPluginLogger ;
2021-07-24 13:10:48 +02:00
import java.io.File ;
2021-08-09 06:36:15 +02:00
import java.io.IOException ;
2021-07-24 13:10:48 +02:00
import java.io.InputStream ;
2021-08-09 06:36:15 +02:00
import java.net.URISyntaxException ;
import java.net.URL ;
import java.nio.file.Paths ;
import java.security.NoSuchAlgorithmException ;
import java.util.Collections ;
2021-07-24 13:10:48 +02:00
import java.util.Optional ;
import java.util.concurrent.ExecutionException ;
import java.util.concurrent.Future ;
import java.util.concurrent.TimeUnit ;
import java.util.concurrent.TimeoutException ;
/ * *
* Main class for Plan ' s Fabric version .
*
* @author Kopo942
* /
public class PlanFabric implements PlanPlugin , DedicatedServerModInitializer {
private MinecraftDedicatedServer server ;
private CommandManager commandManager ;
private PlanSystem system ;
private Locale locale ;
private ServerShutdownSave serverShutdownSave ;
2021-08-09 06:36:15 +02:00
private FabricPluginLogger pluginLogger ;
2021-07-24 13:10:48 +02:00
private RunnableFactory runnableFactory ;
private PlatformAbstractionLayer abstractionLayer ;
@Override
public InputStream getResource ( String resource ) {
return this . getClass ( ) . getResourceAsStream ( " / " + resource ) ;
}
@Override
public ColorScheme getColorScheme ( ) {
return PlanColorScheme . create ( system . getConfigSystem ( ) . getConfig ( ) , pluginLogger ) ;
}
@Override
public PlanSystem getSystem ( ) {
return system ;
}
@Override
public void registerCommand ( Subcommand command ) {
commandManager . registerRoot ( command , runnableFactory ) ;
}
@Override
public void onEnable ( ) {
abstractionLayer = new FabricPlatformLayer ( this ) ;
2021-08-09 06:36:15 +02:00
pluginLogger = ( FabricPluginLogger ) abstractionLayer . getPluginLogger ( ) ;
2021-07-24 13:10:48 +02:00
runnableFactory = abstractionLayer . getRunnableFactory ( ) ;
2021-08-09 06:36:15 +02:00
pluginLogger . info ( " Loading dependencies, this might take a while... " ) ;
try {
ApplicationBuilder . appending ( " Plan " )
. logger ( ( message , args ) - > pluginLogger . info ( message , args ) )
// Use paper repository for downloading slimjar dependencies
. internalRepositories ( Collections . singletonList ( new Repository ( new URL ( " https://papermc.io/repo/repository/maven-public/ " ) ) ) )
. downloadDirectoryPath ( Paths . get ( getDataFolder ( ) . getAbsolutePath ( ) ) . resolve ( " libraries " ) )
. build ( ) ;
} catch ( IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e ) {
String version = abstractionLayer . getPluginInformation ( ) . getVersion ( ) ;
pluginLogger . error ( this . getClass ( ) . getSimpleName ( ) + " -v " + version , e ) ;
pluginLogger . error ( " Plan failed to load its dependencies correctly! " ) ;
pluginLogger . error ( " This error should be reported at https://github.com/plan-player-analytics/Plan/issues " ) ;
onDisable ( ) ;
}
2021-07-24 13:10:48 +02:00
PlanFabricComponent component = DaggerPlanFabricComponent . builder ( )
. plan ( this )
. abstractionLayer ( abstractionLayer )
. server ( server )
2021-07-24 15:23:18 +02:00
. serverProperties ( new FabricServerProperties ( getServer ( ) ) )
2021-07-24 13:10:48 +02:00
. build ( ) ;
try {
system = component . system ( ) ;
serverShutdownSave = component . serverShutdownSave ( ) ;
locale = system . getLocaleSystem ( ) . getLocale ( ) ;
system . enable ( ) ;
pluginLogger . info ( locale . getString ( PluginLang . ENABLED ) ) ;
} catch ( AbstractMethodError e ) {
pluginLogger . error ( " Plugin ran into AbstractMethodError, server restart is required! This error is likely caused by updating the JAR without a restart. " ) ;
} catch ( EnableException e ) {
pluginLogger . error ( " ---------------------------------------- " ) ;
pluginLogger . error ( " Error: " + e . getMessage ( ) ) ;
pluginLogger . error ( " ---------------------------------------- " ) ;
pluginLogger . error ( " Plugin failed to initialize correctly. If this issue is caused by config settings you can use /plan reload " ) ;
onDisable ( ) ;
} catch ( Exception e ) {
String version = abstractionLayer . getPluginInformation ( ) . getVersion ( ) ;
pluginLogger . error ( this . getClass ( ) . getSimpleName ( ) + " -v " + version , e ) ;
pluginLogger . error ( " Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload " ) ;
pluginLogger . error ( " This error should be reported at https://github.com/plan-player-analytics/Plan/issues " ) ;
onDisable ( ) ;
}
registerCommand ( component . planCommand ( ) . build ( ) ) ;
if ( system ! = null ) {
system . getProcessing ( ) . submitNonCritical ( ( ) - > system . getListenerSystem ( ) . callEnableEvent ( this ) ) ;
}
}
@Override
public void onDisable ( ) {
storeSessionsOnShutdown ( ) ;
runnableFactory . cancelAllKnownTasks ( ) ;
if ( system ! = null ) system . disable ( ) ;
pluginLogger . info ( Locale . getStringNullSafe ( locale , PluginLang . DISABLED ) ) ;
}
private void storeSessionsOnShutdown ( ) {
if ( serverShutdownSave ! = null ) {
Optional < Future < ? > > complete = serverShutdownSave . performSave ( ) ;
if ( complete . isPresent ( ) ) {
try {
complete . get ( ) . get ( 4 , TimeUnit . SECONDS ) ; // wait for completion for 4s
} catch ( InterruptedException e ) {
Thread . currentThread ( ) . interrupt ( ) ;
} catch ( ExecutionException e ) {
pluginLogger . error ( " Failed to save sessions to database on shutdown: " + e . getCause ( ) . getMessage ( ) ) ;
} catch ( TimeoutException e ) {
pluginLogger . info ( Locale . getStringNullSafe ( locale , PluginLang . DISABLED_UNSAVED_SESSIONS_TIMEOUT ) ) ;
}
}
}
}
@Override
public File getDataFolder ( ) {
2021-08-09 06:36:15 +02:00
return FabricLoader . getInstance ( ) . getGameDir ( ) . resolve ( " mods " ) . resolve ( " Plan " ) . toFile ( ) ;
2021-07-24 13:10:48 +02:00
}
@Override
public void onInitializeServer ( ) {
ServerLifecycleEvents . SERVER_STARTING . register ( server - > {
this . server = ( MinecraftDedicatedServer ) server ;
onEnable ( ) ;
} ) ;
2021-07-24 15:02:24 +02:00
CommandRegistrationCallback . EVENT . register ( ( dispatcher , dedicated ) - > commandManager = new CommandManager ( dispatcher , this ) ) ;
2021-07-24 13:10:48 +02:00
ServerLifecycleEvents . SERVER_STOPPING . register ( server - > onDisable ( ) ) ;
}
2021-07-24 15:23:18 +02:00
public MinecraftDedicatedServer getServer ( ) {
2021-07-24 13:10:48 +02:00
return server ;
}
}