2019-07-08 19:13:31 +00:00
/ *
2020-04-15 19:39:21 +00:00
* Copyright ( c ) 2019 - 2020 GeyserMC . http : //geysermc.org
2019-07-08 19:13:31 +00:00
*
2019-07-11 21:30:35 +00:00
* 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 :
2019-07-08 19:13:31 +00:00
*
2019-07-11 21:30:35 +00:00
* 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 .
2019-07-08 19:13:31 +00:00
*
* @author GeyserMC
* @link https : //github.com/GeyserMC/Geyser
* /
2019-12-01 21:16:52 +00:00
package org.geysermc.platform.bukkit ;
2019-07-08 19:13:31 +00:00
2020-04-27 20:45:14 +00:00
import org.bukkit.Bukkit ;
2019-12-01 21:16:52 +00:00
import org.bukkit.plugin.java.JavaPlugin ;
2019-12-21 17:53:19 +00:00
import org.geysermc.common.PlatformType ;
2019-12-01 21:16:52 +00:00
import org.geysermc.connector.GeyserConnector ;
2020-04-29 20:01:53 +00:00
import org.geysermc.connector.bootstrap.GeyserBootstrap ;
2020-04-19 23:08:14 +00:00
import org.geysermc.connector.command.CommandManager ;
2020-06-10 22:58:29 +00:00
import org.geysermc.connector.configuration.GeyserConfiguration ;
2020-04-29 20:01:53 +00:00
import org.geysermc.connector.network.translators.world.WorldManager ;
2020-05-23 21:50:04 +00:00
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough ;
import org.geysermc.connector.ping.IGeyserPingPassthrough ;
2020-06-10 22:58:29 +00:00
import org.geysermc.connector.utils.FileUtils ;
2020-03-17 16:43:09 +00:00
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor ;
2020-04-19 23:08:14 +00:00
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager ;
2020-05-10 20:25:28 +00:00
import org.geysermc.platform.bukkit.world.GeyserBukkitBlockPlaceListener ;
2020-04-29 20:01:53 +00:00
import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager ;
2020-05-10 02:37:18 +00:00
import us.myles.ViaVersion.api.Via ;
2019-07-08 19:13:31 +00:00
2020-06-10 22:58:29 +00:00
import java.io.File ;
import java.io.IOException ;
2020-06-20 17:54:40 +00:00
import java.nio.file.Path ;
2019-12-01 21:16:52 +00:00
import java.util.UUID ;
2020-06-10 22:58:29 +00:00
import java.util.logging.Level ;
2019-08-02 20:15:32 +00:00
2020-04-29 20:01:53 +00:00
public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
2019-07-08 19:13:31 +00:00
2020-04-19 23:08:14 +00:00
private GeyserBukkitCommandManager geyserCommandManager ;
2019-12-01 21:16:52 +00:00
private GeyserBukkitConfiguration geyserConfig ;
private GeyserBukkitLogger geyserLogger ;
2020-05-23 21:50:04 +00:00
private IGeyserPingPassthrough geyserBukkitPingPassthrough ;
2020-05-10 20:25:28 +00:00
private GeyserBukkitBlockPlaceListener blockPlaceListener ;
2020-04-29 20:01:53 +00:00
private GeyserBukkitWorldManager geyserWorldManager ;
2019-08-02 20:15:32 +00:00
2020-03-17 16:43:09 +00:00
private GeyserConnector connector ;
2019-12-01 21:16:52 +00:00
@Override
public void onEnable ( ) {
2020-06-10 22:58:29 +00:00
// This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed
try {
if ( ! getDataFolder ( ) . exists ( ) )
getDataFolder ( ) . mkdir ( ) ;
File configFile = FileUtils . fileOrCopiedFromResource ( new File ( getDataFolder ( ) , " config.yml " ) , " config.yml " , ( x ) - > x . replaceAll ( " generateduuid " , UUID . randomUUID ( ) . toString ( ) ) ) ;
this . geyserConfig = FileUtils . loadConfig ( configFile , GeyserBukkitConfiguration . class ) ;
} catch ( IOException ex ) {
getLogger ( ) . log ( Level . WARNING , " Failed to read/create config.yml! Make sure it's up to date and/or readable+writable! " , ex ) ;
ex . printStackTrace ( ) ;
2019-12-01 21:16:52 +00:00
}
2019-08-06 01:59:54 +00:00
2020-04-27 20:45:14 +00:00
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
2020-05-09 03:58:29 +00:00
if ( ! Bukkit . getIp ( ) . equals ( " 0.0.0.0 " ) & & ! Bukkit . getIp ( ) . equals ( " " ) ) {
2020-06-10 22:58:29 +00:00
geyserConfig . getRemote ( ) . setAddress ( Bukkit . getIp ( ) ) ;
2020-04-27 20:45:14 +00:00
}
2020-06-10 22:58:29 +00:00
geyserConfig . getRemote ( ) . setPort ( Bukkit . getPort ( ) ) ;
2020-04-27 20:45:14 +00:00
2020-03-17 16:43:09 +00:00
this . geyserLogger = new GeyserBukkitLogger ( getLogger ( ) , geyserConfig . isDebugMode ( ) ) ;
2020-05-21 14:29:32 +00:00
GeyserConfiguration . checkGeyserConfiguration ( geyserConfig , geyserLogger ) ;
2020-05-03 20:30:20 +00:00
2020-06-10 22:58:29 +00:00
if ( geyserConfig . getRemote ( ) . getAuthType ( ) . equals ( " floodgate " ) & & Bukkit . getPluginManager ( ) . getPlugin ( " floodgate-bukkit " ) = = null ) {
geyserLogger . severe ( " Auth type set to Floodgate but Floodgate not found! Disabling... " ) ;
this . getPluginLoader ( ) . disablePlugin ( this ) ;
return ;
}
2020-05-03 20:30:20 +00:00
geyserConfig . loadFloodgate ( this ) ;
2020-03-17 16:43:09 +00:00
this . connector = GeyserConnector . start ( PlatformType . BUKKIT , this ) ;
2019-09-22 22:08:12 +00:00
2020-05-23 21:50:04 +00:00
if ( geyserConfig . isLegacyPingPassthrough ( ) ) {
this . geyserBukkitPingPassthrough = GeyserLegacyPingPassthrough . init ( connector ) ;
} else {
this . geyserBukkitPingPassthrough = new GeyserBukkitPingPassthrough ( geyserLogger ) ;
}
2020-04-19 23:08:14 +00:00
this . geyserCommandManager = new GeyserBukkitCommandManager ( this , connector ) ;
2020-05-10 02:37:18 +00:00
boolean isViaVersion = false ;
// Used to determine if Block.getBlockData() is present.
boolean isLegacy = ! isCompatible ( Bukkit . getServer ( ) . getVersion ( ) , " 1.13.0 " ) ;
if ( isLegacy )
geyserLogger . debug ( " Legacy version of Minecraft (1.12.2 or older) detected. " ) ;
if ( Bukkit . getPluginManager ( ) . getPlugin ( " ViaVersion " ) ! = null ) {
// TODO: Update when ViaVersion updates
// API changes between 2.2.3 and 3.0.0-SNAPSHOT require this check
2020-06-24 21:38:41 +00:00
if ( Via . getAPI ( ) . getVersion ( ) . contains ( " 2.2.3 " ) & & isLegacy ) {
geyserLogger . info ( " ViaVersion detected but not the newest version of ViaVersion. Please update your ViaVersion plugin for compatibility with Geyser. " ) ;
2020-05-10 02:37:18 +00:00
} else {
isViaVersion = true ;
}
}
this . geyserWorldManager = new GeyserBukkitWorldManager ( isLegacy , isViaVersion ) ;
2020-05-13 21:07:41 +00:00
this . blockPlaceListener = new GeyserBukkitBlockPlaceListener ( connector , isLegacy , isViaVersion ) ;
2020-05-10 20:25:28 +00:00
Bukkit . getServer ( ) . getPluginManager ( ) . registerEvents ( blockPlaceListener , this ) ;
2020-04-19 23:08:14 +00:00
2020-03-17 16:43:09 +00:00
this . getCommand ( " geyser " ) . setExecutor ( new GeyserBukkitCommandExecutor ( connector ) ) ;
2019-12-01 21:16:52 +00:00
}
2019-10-02 20:45:29 +00:00
2019-12-01 21:16:52 +00:00
@Override
public void onDisable ( ) {
2020-06-10 22:58:29 +00:00
if ( connector ! = null )
connector . shutdown ( ) ;
2019-12-01 21:16:52 +00:00
}
@Override
public GeyserBukkitConfiguration getGeyserConfig ( ) {
return geyserConfig ;
}
@Override
public GeyserBukkitLogger getGeyserLogger ( ) {
return geyserLogger ;
}
2020-04-19 23:08:14 +00:00
@Override
public CommandManager getGeyserCommandManager ( ) {
return this . geyserCommandManager ;
}
2020-04-29 20:01:53 +00:00
2020-05-23 21:50:04 +00:00
@Override
public IGeyserPingPassthrough getGeyserPingPassthrough ( ) {
return geyserBukkitPingPassthrough ;
}
2020-04-29 20:01:53 +00:00
@Override
public WorldManager getWorldManager ( ) {
return this . geyserWorldManager ;
}
2020-05-10 02:37:18 +00:00
2020-06-20 17:54:40 +00:00
@Override
public Path getConfigFolder ( ) {
return getDataFolder ( ) . toPath ( ) ;
}
2020-05-10 02:37:18 +00:00
public boolean isCompatible ( String version , String whichVersion ) {
int [ ] currentVersion = parseVersion ( version ) ;
int [ ] otherVersion = parseVersion ( whichVersion ) ;
int length = Math . max ( currentVersion . length , otherVersion . length ) ;
for ( int index = 0 ; index < length ; index = index + 1 ) {
int self = ( index < currentVersion . length ) ? currentVersion [ index ] : 0 ;
int other = ( index < otherVersion . length ) ? otherVersion [ index ] : 0 ;
if ( self ! = other ) {
return ( self - other ) > 0 ;
}
}
return true ;
}
private int [ ] parseVersion ( String versionParam ) {
versionParam = ( versionParam = = null ) ? " " : versionParam ;
if ( versionParam . contains ( " (MC: " ) ) {
versionParam = versionParam . split ( " \\ (MC: " ) [ 1 ] ;
versionParam = versionParam . split ( " \\ ) " ) [ 0 ] ;
}
String [ ] stringArray = versionParam . split ( " [_.-] " ) ;
int [ ] temp = new int [ stringArray . length ] ;
for ( int index = 0 ; index < = ( stringArray . length - 1 ) ; index = index + 1 ) {
String t = stringArray [ index ] . replaceAll ( " \\ D " , " " ) ;
try {
temp [ index ] = Integer . parseInt ( t ) ;
} catch ( NumberFormatException ex ) {
temp [ index ] = 0 ;
}
}
return temp ;
}
2020-06-20 17:54:40 +00:00
2019-09-29 18:05:41 +00:00
}