DedicatedServer.java

net.minecraft.server.dedicated.DedicatedServer

信息

  • 全限定名:net.minecraft.server.dedicated.DedicatedServer
  • 类型:public class
  • 包:net.minecraft.server.dedicated
  • 源码路径:src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
  • 起始行号:L83
  • 继承:MinecraftServer
  • 实现:ServerInterface
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L84
    • 说明:

      TODO

  • CONVERSION_RETRY_DELAY_MS

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L85
    • 说明:

      TODO

  • CONVERSION_RETRIES

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L86
    • 说明:

      TODO

  • consoleInput

    • 类型: List<ConsoleInput>
    • 修饰符: private final
    • 源码定位: L87
    • 说明:

      TODO

  • queryThreadGs4

    • 类型: QueryThreadGs4
    • 修饰符: private
    • 源码定位: L88
    • 说明:

      TODO

  • rconConsoleSource

    • 类型: RconConsoleSource
    • 修饰符: private final
    • 源码定位: L89
    • 说明:

      TODO

  • rconThread

    • 类型: RconThread
    • 修饰符: private
    • 源码定位: L90
    • 说明:

      TODO

  • settings

    • 类型: DedicatedServerSettings
    • 修饰符: private final
    • 源码定位: L91
    • 说明:

      TODO

  • gui

    • 类型: MinecraftServerGui
    • 修饰符: private
    • 源码定位: L92
    • 说明:

      TODO

  • serverTextFilter

    • 类型: ServerTextFilter
    • 修饰符: private final
    • 源码定位: L93
    • 说明:

      TODO

  • tickTimeLogger

    • 类型: RemoteSampleLogger
    • 修饰符: private
    • 源码定位: L94
    • 说明:

      TODO

  • isTickTimeLoggingEnabled

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L95
    • 说明:

      TODO

  • serverLinks

    • 类型: ServerLinks
    • 修饰符: private final
    • 源码定位: L96
    • 说明:

      TODO

  • codeOfConductTexts

    • 类型: Map<String,String>
    • 修饰符: private final
    • 源码定位: L97
    • 说明:

      TODO

  • jsonRpcServer

    • 类型: ManagementServer
    • 修饰符: private
    • 源码定位: L98
    • 说明:

      TODO

  • lastHeartbeat

    • 类型: long
    • 修饰符: private
    • 源码定位: L99
    • 说明:

      TODO

内部类/嵌套类型

构造器

public DedicatedServer(Thread serverThread, LevelStorageSource.LevelStorageAccess levelStorageSource, PackRepository packRepository, WorldStem worldStem, Optional<GameRules> gameRules, DedicatedServerSettings settings, DataFixer fixerUpper, Services services) @ L101

  • 构造器名:DedicatedServer
  • 源码定位:L101
  • 修饰符:public

参数:

  • serverThread: Thread
  • levelStorageSource: LevelStorageSource.LevelStorageAccess
  • packRepository: PackRepository
  • worldStem: WorldStem
  • gameRules: Optional
  • settings: DedicatedServerSettings
  • fixerUpper: DataFixer
  • services: Services

说明:

TODO

方法

下面的方法块按源码顺序生成。

private static Map<String,String> readCodeOfConducts() @ L134

  • 方法名:readCodeOfConducts
  • 源码定位:L134
  • 返回类型:Map<String,String>
  • 修饰符:private static

参数:

说明:

TODO

private SslContext createSslContext() @ L170

  • 方法名:createSslContext
  • 源码定位:L170
  • 返回类型:SslContext
  • 修饰符:private

参数:

说明:

TODO

protected boolean initServer() @ L181

  • 方法名:initServer
  • 源码定位:L181
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

public boolean isEnforceWhitelist() @ L325

  • 方法名:isEnforceWhitelist
  • 源码定位:L325
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setEnforceWhitelist(boolean enforceWhitelist) @ L330

  • 方法名:setEnforceWhitelist
  • 源码定位:L330
  • 返回类型:void
  • 修饰符:public

参数:

  • enforceWhitelist: boolean

说明:

TODO

public boolean isUsingWhitelist() @ L335

  • 方法名:isUsingWhitelist
  • 源码定位:L335
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setUsingWhitelist(boolean usingWhitelist) @ L340

  • 方法名:setUsingWhitelist
  • 源码定位:L340
  • 返回类型:void
  • 修饰符:public

参数:

  • usingWhitelist: boolean

说明:

TODO

protected void tickServer(BooleanSupplier haveTime) @ L345

  • 方法名:tickServer
  • 源码定位:L345
  • 返回类型:void
  • 修饰符:protected

参数:

  • haveTime: BooleanSupplier

说明:

TODO

public boolean saveAllChunks(boolean silent, boolean flush, boolean force) @ L363

  • 方法名:saveAllChunks
  • 源码定位:L363
  • 返回类型:boolean
  • 修饰符:public

参数:

  • silent: boolean
  • flush: boolean
  • force: boolean

说明:

TODO

public void sendLowDiskSpaceWarning() @ L371

  • 方法名:sendLowDiskSpaceWarning
  • 源码定位:L371
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean allowFlight() @ L382

  • 方法名:allowFlight
  • 源码定位:L382
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setAllowFlight(boolean allowed) @ L387

  • 方法名:setAllowFlight
  • 源码定位:L387
  • 返回类型:void
  • 修饰符:public

参数:

  • allowed: boolean

说明:

TODO

public DedicatedServerProperties getProperties() @ L391

  • 方法名:getProperties
  • 源码定位:L391
  • 返回类型:DedicatedServerProperties
  • 修饰符:public

参数:

说明:

TODO

public void setDifficulty(Difficulty difficulty) @ L396

  • 方法名:setDifficulty
  • 源码定位:L396
  • 返回类型:void
  • 修饰符:public

参数:

  • difficulty: Difficulty

说明:

TODO

protected void forceDifficulty() @ L401

  • 方法名:forceDifficulty
  • 源码定位:L401
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

public int viewDistance() @ L406

  • 方法名:viewDistance
  • 源码定位:L406
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setViewDistance(int viewDistance) @ L410

  • 方法名:setViewDistance
  • 源码定位:L410
  • 返回类型:void
  • 修饰符:public

参数:

  • viewDistance: int

说明:

TODO

public int simulationDistance() @ L415

  • 方法名:simulationDistance
  • 源码定位:L415
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setSimulationDistance(int simulationDistance) @ L419

  • 方法名:setSimulationDistance
  • 源码定位:L419
  • 返回类型:void
  • 修饰符:public

参数:

  • simulationDistance: int

说明:

TODO

public SystemReport fillServerSystemReport(SystemReport systemReport) @ L424

  • 方法名:fillServerSystemReport
  • 源码定位:L424
  • 返回类型:SystemReport
  • 修饰符:public

参数:

  • systemReport: SystemReport

说明:

TODO

public void dumpServerProperties(Path path) @ L431

  • 方法名:dumpServerProperties
  • 源码定位:L431
  • 返回类型:void
  • 修饰符:public

参数:

  • path: Path

说明:

TODO

protected void onServerExit() @ L448

  • 方法名:onServerExit
  • 源码定位:L448
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void tickConnection() @ L475

  • 方法名:tickConnection
  • 源码定位:L475
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

public void handleConsoleInput(String msg, CommandSourceStack source) @ L481

  • 方法名:handleConsoleInput
  • 源码定位:L481
  • 返回类型:void
  • 修饰符:public

参数:

  • msg: String
  • source: CommandSourceStack

说明:

TODO

public void handleConsoleInputs() @ L485

  • 方法名:handleConsoleInputs
  • 源码定位:L485
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean isDedicatedServer() @ L492

  • 方法名:isDedicatedServer
  • 源码定位:L492
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public int getRateLimitPacketsPerSecond() @ L497

  • 方法名:getRateLimitPacketsPerSecond
  • 源码定位:L497
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public boolean useNativeTransport() @ L502

  • 方法名:useNativeTransport
  • 源码定位:L502
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public DedicatedPlayerList getPlayerList() @ L507

  • 方法名:getPlayerList
  • 源码定位:L507
  • 返回类型:DedicatedPlayerList
  • 修饰符:public

参数:

说明:

TODO

public int getMaxPlayers() @ L511

  • 方法名:getMaxPlayers
  • 源码定位:L511
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setMaxPlayers(int maxPlayers) @ L516

  • 方法名:setMaxPlayers
  • 源码定位:L516
  • 返回类型:void
  • 修饰符:public

参数:

  • maxPlayers: int

说明:

TODO

public boolean isPublished() @ L520

  • 方法名:isPublished
  • 源码定位:L520
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public String getServerIp() @ L525

  • 方法名:getServerIp
  • 源码定位:L525
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public int getServerPort() @ L530

  • 方法名:getServerPort
  • 源码定位:L530
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public String getServerName() @ L535

  • 方法名:getServerName
  • 源码定位:L535
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public void showGui() @ L540

  • 方法名:showGui
  • 源码定位:L540
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public int spawnProtectionRadius() @ L546

  • 方法名:spawnProtectionRadius
  • 源码定位:L546
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setSpawnProtectionRadius(int spawnProtectionRadius) @ L550

  • 方法名:setSpawnProtectionRadius
  • 源码定位:L550
  • 返回类型:void
  • 修饰符:public

参数:

  • spawnProtectionRadius: int

说明:

TODO

public boolean isUnderSpawnProtection(ServerLevel level, BlockPos pos, Player player) @ L554

  • 方法名:isUnderSpawnProtection
  • 源码定位:L554
  • 返回类型:boolean
  • 修饰符:public

参数:

  • level: ServerLevel
  • pos: BlockPos
  • player: Player

说明:

TODO

public boolean repliesToStatus() @ L574

  • 方法名:repliesToStatus
  • 源码定位:L574
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setRepliesToStatus(boolean enable) @ L579

  • 方法名:setRepliesToStatus
  • 源码定位:L579
  • 返回类型:void
  • 修饰符:public

参数:

  • enable: boolean

说明:

TODO

public boolean hidesOnlinePlayers() @ L583

  • 方法名:hidesOnlinePlayers
  • 源码定位:L583
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setHidesOnlinePlayers(boolean hide) @ L588

  • 方法名:setHidesOnlinePlayers
  • 源码定位:L588
  • 返回类型:void
  • 修饰符:public

参数:

  • hide: boolean

说明:

TODO

public LevelBasedPermissionSet operatorUserPermissions() @ L592

  • 方法名:operatorUserPermissions
  • 源码定位:L592
  • 返回类型:LevelBasedPermissionSet
  • 修饰符:public

参数:

说明:

TODO

public void setOperatorUserPermissions(LevelBasedPermissionSet permissions) @ L597

  • 方法名:setOperatorUserPermissions
  • 源码定位:L597
  • 返回类型:void
  • 修饰符:public

参数:

  • permissions: LevelBasedPermissionSet

说明:

TODO

public PermissionSet getFunctionCompilationPermissions() @ L601

  • 方法名:getFunctionCompilationPermissions
  • 源码定位:L601
  • 返回类型:PermissionSet
  • 修饰符:public

参数:

说明:

TODO

public int playerIdleTimeout() @ L606

  • 方法名:playerIdleTimeout
  • 源码定位:L606
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setPlayerIdleTimeout(int playerIdleTimeout) @ L611

  • 方法名:setPlayerIdleTimeout
  • 源码定位:L611
  • 返回类型:void
  • 修饰符:public

参数:

  • playerIdleTimeout: int

说明:

TODO

public int statusHeartbeatInterval() @ L616

  • 方法名:statusHeartbeatInterval
  • 源码定位:L616
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setStatusHeartbeatInterval(int statusHeartbeatInterval) @ L620

  • 方法名:setStatusHeartbeatInterval
  • 源码定位:L620
  • 返回类型:void
  • 修饰符:public

参数:

  • statusHeartbeatInterval: int

说明:

TODO

public String getMotd() @ L624

  • 方法名:getMotd
  • 源码定位:L624
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public void setMotd(String motd) @ L629

  • 方法名:setMotd
  • 源码定位:L629
  • 返回类型:void
  • 修饰符:public

参数:

  • motd: String

说明:

TODO

public boolean shouldRconBroadcast() @ L634

  • 方法名:shouldRconBroadcast
  • 源码定位:L634
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean shouldInformAdmins() @ L639

  • 方法名:shouldInformAdmins
  • 源码定位:L639
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public int getAbsoluteMaxWorldSize() @ L644

  • 方法名:getAbsoluteMaxWorldSize
  • 源码定位:L644
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public int getCompressionThreshold() @ L649

  • 方法名:getCompressionThreshold
  • 源码定位:L649
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public boolean enforceSecureProfile() @ L654

  • 方法名:enforceSecureProfile
  • 源码定位:L654
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean logIPs() @ L660

  • 方法名:logIPs
  • 源码定位:L660
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

protected boolean convertOldUsers() @ L665

  • 方法名:convertOldUsers
  • 源码定位:L665
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

private void waitForRetry() @ L724

  • 方法名:waitForRetry
  • 源码定位:L724
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public long getMaxTickLength() @ L731

  • 方法名:getMaxTickLength
  • 源码定位:L731
  • 返回类型:long
  • 修饰符:public

参数:

说明:

TODO

public int getMaxChainedNeighborUpdates() @ L735

  • 方法名:getMaxChainedNeighborUpdates
  • 源码定位:L735
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public String getPluginNames() @ L740

  • 方法名:getPluginNames
  • 源码定位:L740
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String runCommand(String command) @ L745

  • 方法名:runCommand
  • 源码定位:L745
  • 返回类型:String
  • 修饰符:public

参数:

  • command: String

说明:

TODO

protected void stopServer() @ L752

  • 方法名:stopServer
  • 源码定位:L752
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

public boolean isSingleplayerOwner(NameAndId nameAndId) @ L759

  • 方法名:isSingleplayerOwner
  • 源码定位:L759
  • 返回类型:boolean
  • 修饰符:public

参数:

  • nameAndId: NameAndId

说明:

TODO

public int getScaledTrackingDistance(int range) @ L764

  • 方法名:getScaledTrackingDistance
  • 源码定位:L764
  • 返回类型:int
  • 修饰符:public

参数:

  • range: int

说明:

TODO

public int entityBroadcastRangePercentage() @ L769

  • 方法名:entityBroadcastRangePercentage
  • 源码定位:L769
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setEntityBroadcastRangePercentage(int range) @ L773

  • 方法名:setEntityBroadcastRangePercentage
  • 源码定位:L773
  • 返回类型:void
  • 修饰符:public

参数:

  • range: int

说明:

TODO

public String getLevelIdName() @ L777

  • 方法名:getLevelIdName
  • 源码定位:L777
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public boolean forceSynchronousWrites() @ L782

  • 方法名:forceSynchronousWrites
  • 源码定位:L782
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public TextFilter createTextFilterForPlayer(ServerPlayer player) @ L787

  • 方法名:createTextFilterForPlayer
  • 源码定位:L787
  • 返回类型:TextFilter
  • 修饰符:public

参数:

  • player: ServerPlayer

说明:

TODO

public GameType getForcedGameType() @ L792

  • 方法名:getForcedGameType
  • 源码定位:L792
  • 返回类型:GameType
  • 修饰符:public

参数:

说明:

TODO

public boolean forceGameMode() @ L797

  • 方法名:forceGameMode
  • 源码定位:L797
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setForceGameMode(boolean forceGameMode) @ L801

  • 方法名:setForceGameMode
  • 源码定位:L801
  • 返回类型:void
  • 修饰符:public

参数:

  • forceGameMode: boolean

说明:

TODO

public GameType gameMode() @ L806

  • 方法名:gameMode
  • 源码定位:L806
  • 返回类型:GameType
  • 修饰符:public

参数:

说明:

TODO

public void setGameMode(GameType gameMode) @ L810

  • 方法名:setGameMode
  • 源码定位:L810
  • 返回类型:void
  • 修饰符:public

参数:

  • gameMode: GameType

说明:

TODO

public Optional<MinecraftServer.ServerResourcePackInfo> getServerResourcePack() @ L816

  • 方法名:getServerResourcePack
  • 源码定位:L816
  • 返回类型:Optional<MinecraftServer.ServerResourcePackInfo>
  • 修饰符:public

参数:

说明:

TODO

protected void endMetricsRecordingTick() @ L821

  • 方法名:endMetricsRecordingTick
  • 源码定位:L821
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected SampleLogger getTickTimeLogger() @ L827

  • 方法名:getTickTimeLogger
  • 源码定位:L827
  • 返回类型:SampleLogger
  • 修饰符:protected

参数:

说明:

TODO

public boolean isTickTimeLoggingEnabled() @ L832

  • 方法名:isTickTimeLoggingEnabled
  • 源码定位:L832
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean acceptsTransfers() @ L837

  • 方法名:acceptsTransfers
  • 源码定位:L837
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setAcceptsTransfers(boolean acceptTransfers) @ L842

  • 方法名:setAcceptsTransfers
  • 源码定位:L842
  • 返回类型:void
  • 修饰符:public

参数:

  • acceptTransfers: boolean

说明:

TODO

  • 方法名:serverLinks
  • 源码定位:L846
  • 返回类型:ServerLinks
  • 修饰符:public

参数:

说明:

TODO

public int pauseWhenEmptySeconds() @ L851

  • 方法名:pauseWhenEmptySeconds
  • 源码定位:L851
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void setPauseWhenEmptySeconds(int seconds) @ L856

  • 方法名:setPauseWhenEmptySeconds
  • 源码定位:L856
  • 返回类型:void
  • 修饰符:public

参数:

  • seconds: int

说明:

TODO

  • 方法名:createServerLinks
  • 源码定位:L860
  • 返回类型:ServerLinks
  • 修饰符:private static

参数:

  • settings: DedicatedServerSettings

说明:

TODO

private static Optional<URI> parseBugReportLink(DedicatedServerProperties properties) @ L866

  • 方法名:parseBugReportLink
  • 源码定位:L866
  • 返回类型:Optional
  • 修饰符:private static

参数:

  • properties: DedicatedServerProperties

说明:

TODO

public Map<String,String> getCodeOfConducts() @ L880

  • 方法名:getCodeOfConducts
  • 源码定位:L880
  • 返回类型:Map<String,String>
  • 修饰符:public

参数:

说明:

TODO

代码

public class DedicatedServer extends MinecraftServer implements ServerInterface {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final int CONVERSION_RETRY_DELAY_MS = 5000;
    private static final int CONVERSION_RETRIES = 2;
    private final List<ConsoleInput> consoleInput = Collections.synchronizedList(Lists.newArrayList());
    private @Nullable QueryThreadGs4 queryThreadGs4;
    private final RconConsoleSource rconConsoleSource;
    private @Nullable RconThread rconThread;
    private final DedicatedServerSettings settings;
    private @Nullable MinecraftServerGui gui;
    private final @Nullable ServerTextFilter serverTextFilter;
    private @Nullable RemoteSampleLogger tickTimeLogger;
    private boolean isTickTimeLoggingEnabled;
    private final ServerLinks serverLinks;
    private final Map<String, String> codeOfConductTexts;
    private @Nullable ManagementServer jsonRpcServer;
    private long lastHeartbeat;
 
    public DedicatedServer(
        Thread serverThread,
        LevelStorageSource.LevelStorageAccess levelStorageSource,
        PackRepository packRepository,
        WorldStem worldStem,
        Optional<GameRules> gameRules,
        DedicatedServerSettings settings,
        DataFixer fixerUpper,
        Services services
    ) {
        super(
            serverThread,
            levelStorageSource,
            packRepository,
            worldStem,
            gameRules,
            Proxy.NO_PROXY,
            fixerUpper,
            services,
            LoggingLevelLoadListener.forDedicatedServer(),
            true
        );
        this.settings = settings;
        this.rconConsoleSource = new RconConsoleSource(this);
        this.serverTextFilter = ServerTextFilter.createFromConfig(settings.getProperties());
        this.serverLinks = createServerLinks(settings);
        if (settings.getProperties().codeOfConduct) {
            this.codeOfConductTexts = readCodeOfConducts();
        } else {
            this.codeOfConductTexts = Map.of();
        }
    }
 
    private static Map<String, String> readCodeOfConducts() {
        Path path = Path.of("codeofconduct");
        if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
            throw new IllegalArgumentException("Code of Conduct folder does not exist: " + path);
        } else {
            try {
                Builder<String, String> builder = ImmutableMap.builder();
 
                try (Stream<Path> files = Files.list(path)) {
                    for (Path file : files.toList()) {
                        String filename = file.getFileName().toString();
                        if (filename.endsWith(".txt")) {
                            String language = filename.substring(0, filename.length() - 4).toLowerCase(Locale.ROOT);
                            if (!file.toRealPath().getParent().equals(path.toAbsolutePath())) {
                                throw new IllegalArgumentException(
                                    "Failed to read Code of Conduct file \"" + filename + "\" because it links to a file outside the allowed directory"
                                );
                            }
 
                            try {
                                String codeOfConduct = String.join("\n", Files.readAllLines(file, StandardCharsets.UTF_8));
                                builder.put(language, StringUtil.stripColor(codeOfConduct));
                            } catch (IOException var9) {
                                throw new IllegalArgumentException("Failed to read Code of Conduct file " + filename, var9);
                            }
                        }
                    }
                }
 
                return builder.build();
            } catch (IOException var11) {
                throw new IllegalArgumentException("Failed to read Code of Conduct folder", var11);
            }
        }
    }
 
    private SslContext createSslContext() {
        try {
            return JsonRpcSslContextProvider.createFrom(
                this.getProperties().managementServerTlsKeystore, this.getProperties().managementServerTlsKeystorePassword
            );
        } catch (Exception var2) {
            JsonRpcSslContextProvider.printInstructions();
            throw new IllegalStateException("Failed to configure TLS for the server management protocol", var2);
        }
    }
 
    @Override
    protected boolean initServer() throws IOException {
        int managementPort = this.getProperties().managementServerPort;
        if (this.getProperties().managementServerEnabled) {
            String managementServerSecret = this.settings.getProperties().managementServerSecret;
            if (!SecurityConfig.isValid(managementServerSecret)) {
                throw new IllegalStateException("Invalid management server secret, must be 40 alphanumeric characters");
            }
 
            String managementHost = this.getProperties().managementServerHost;
            HostAndPort hostAndPort = HostAndPort.fromParts(managementHost, managementPort);
            SecurityConfig securityConfig = new SecurityConfig(managementServerSecret);
            String allowedOrigins = this.getProperties().managementServerAllowedOrigins;
            AuthenticationHandler authenticationHandler = new AuthenticationHandler(securityConfig, allowedOrigins);
            LOGGER.info("Starting json RPC server on {}", hostAndPort);
            this.jsonRpcServer = new ManagementServer(hostAndPort, authenticationHandler);
            MinecraftApi minecraftApi = MinecraftApi.of(this);
            minecraftApi.notificationManager().registerService(new JsonRpcNotificationService(minecraftApi, this.jsonRpcServer));
            if (this.getProperties().managementServerTlsEnabled) {
                SslContext sslContext = this.createSslContext();
                this.jsonRpcServer.startWithTls(minecraftApi, sslContext);
            } else {
                this.jsonRpcServer.startWithoutTls(minecraftApi);
            }
        }
 
        Thread consoleThread = new Thread("Server console handler") {
            {
                Objects.requireNonNull(DedicatedServer.this);
            }
 
            @Override
            public void run() {
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
 
                String line;
                try {
                    while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning() && (line = reader.readLine()) != null) {
                        DedicatedServer.this.handleConsoleInput(line, DedicatedServer.this.createCommandSourceStack());
                    }
                } catch (IOException var4) {
                    DedicatedServer.LOGGER.error("Exception handling console input", (Throwable)var4);
                }
            }
        };
        consoleThread.setDaemon(true);
        consoleThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
        consoleThread.start();
        LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().name());
        if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
            LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
        }
 
        LOGGER.info("Loading properties");
        DedicatedServerProperties properties = this.settings.getProperties();
        if (this.isSingleplayer()) {
            this.setLocalIp("127.0.0.1");
        } else {
            this.setUsesAuthentication(properties.onlineMode);
            this.setPreventProxyConnections(properties.preventProxyConnections);
            this.setLocalIp(properties.serverIp);
        }
 
        this.worldData.setGameType(properties.gameMode.get());
        LOGGER.info("Default game type: {}", properties.gameMode.get());
        InetAddress localAddress = null;
        if (!this.getLocalIp().isEmpty()) {
            localAddress = InetAddress.getByName(this.getLocalIp());
        }
 
        if (this.getPort() < 0) {
            this.setPort(properties.serverPort);
        }
 
        this.initializeKeyPair();
        LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort());
 
        try {
            this.getConnection().startTcpServerListener(localAddress, this.getPort());
        } catch (IOException var11) {
            LOGGER.warn("**** FAILED TO BIND TO PORT!");
            LOGGER.warn("The exception was: {}", var11.toString());
            LOGGER.warn("Perhaps a server is already running on that port?");
            return false;
        }
 
        if (!this.usesAuthentication()) {
            LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
            LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
            LOGGER.warn(
                "While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."
            );
            LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
        }
 
        if (this.convertOldUsers()) {
            this.services.nameToIdCache().save();
        }
 
        if (!OldUsersConverter.areOldUserlistsRemoved()) {
            return false;
        } else {
            this.setPlayerList(new DedicatedPlayerList(this, this.registries(), this.playerDataStorage));
            this.tickTimeLogger = new RemoteSampleLogger(TpsDebugDimensions.values().length, this.debugSubscribers(), RemoteDebugSampleType.TICK_TIME);
            long levelNanoTime = Util.getNanos();
            this.services.nameToIdCache().resolveOfflineUsers(!this.usesAuthentication());
            LOGGER.info("Preparing level \"{}\"", this.getLevelIdName());
            this.loadLevel();
            long elapsed = Util.getNanos() - levelNanoTime;
            String time = String.format(Locale.ROOT, "%.3fs", elapsed / 1.0E9);
            LOGGER.info("Done ({})! For help, type \"help\"", time);
            if (properties.announcePlayerAchievements != null) {
                this.getGameRules().set(GameRules.SHOW_ADVANCEMENT_MESSAGES, properties.announcePlayerAchievements, this);
            }
 
            if (properties.enableQuery) {
                LOGGER.info("Starting GS4 status listener");
                this.queryThreadGs4 = QueryThreadGs4.create(this);
            }
 
            if (properties.enableRcon) {
                LOGGER.info("Starting remote control listener");
                this.rconThread = RconThread.create(this);
            }
 
            if (this.getMaxTickLength() > 0L) {
                Thread watchdog = new Thread(new ServerWatchdog(this));
                watchdog.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandlerWithName(LOGGER));
                watchdog.setName("Server Watchdog");
                watchdog.setDaemon(true);
                watchdog.start();
            }
 
            if (properties.enableJmxMonitoring) {
                MinecraftServerStatistics.registerJmxMonitoring(this);
                LOGGER.info("JMX monitoring enabled");
            }
 
            this.saveEverything(false, true, true);
            this.notificationManager().serverStarted();
            return true;
        }
    }
 
    @Override
    public boolean isEnforceWhitelist() {
        return this.settings.getProperties().enforceWhitelist.get();
    }
 
    @Override
    public void setEnforceWhitelist(boolean enforceWhitelist) {
        this.settings.update(p -> p.enforceWhitelist.update(this.registryAccess(), enforceWhitelist));
    }
 
    @Override
    public boolean isUsingWhitelist() {
        return this.settings.getProperties().whiteList.get();
    }
 
    @Override
    public void setUsingWhitelist(boolean usingWhitelist) {
        this.settings.update(p -> p.whiteList.update(this.registryAccess(), usingWhitelist));
    }
 
    @Override
    protected void tickServer(BooleanSupplier haveTime) {
        super.tickServer(haveTime);
        if (this.jsonRpcServer != null) {
            this.jsonRpcServer.tick();
        }
 
        long millis = Util.getMillis();
        int heartbeatInterval = this.statusHeartbeatInterval();
        if (heartbeatInterval > 0) {
            long intervalMillis = heartbeatInterval * TimeUtil.MILLISECONDS_PER_SECOND;
            if (millis - this.lastHeartbeat >= intervalMillis) {
                this.lastHeartbeat = millis;
                this.notificationManager().statusHeartbeat();
            }
        }
    }
 
    @Override
    public boolean saveAllChunks(boolean silent, boolean flush, boolean force) {
        this.notificationManager().serverSaveStarted();
        boolean savedChunks = super.saveAllChunks(silent, flush, force);
        this.notificationManager().serverSaveCompleted();
        return savedChunks;
    }
 
    @Override
    public void sendLowDiskSpaceWarning() {
        super.sendLowDiskSpaceWarning();
        Permission.HasCommandLevel adminCheck = new Permission.HasCommandLevel(PermissionLevel.ADMINS);
        this.getPlayerList()
            .getPlayers()
            .stream()
            .filter(p -> p.permissions().hasPermission(adminCheck))
            .forEach(p -> p.connection.send(ClientboundLowDiskSpaceWarningPacket.INSTANCE));
    }
 
    @Override
    public boolean allowFlight() {
        return this.settings.getProperties().allowFlight.get();
    }
 
    public void setAllowFlight(boolean allowed) {
        this.settings.update(p -> p.allowFlight.update(this.registryAccess(), allowed));
    }
 
    @Override
    public DedicatedServerProperties getProperties() {
        return this.settings.getProperties();
    }
 
    public void setDifficulty(Difficulty difficulty) {
        this.settings.update(p -> p.difficulty.update(this.registryAccess(), difficulty));
        this.forceDifficulty();
    }
 
    @Override
    protected void forceDifficulty() {
        this.setDifficulty(this.getProperties().difficulty.get(), true);
    }
 
    public int viewDistance() {
        return this.settings.getProperties().viewDistance.get();
    }
 
    public void setViewDistance(int viewDistance) {
        this.settings.update(p -> p.viewDistance.update(this.registryAccess(), viewDistance));
        this.getPlayerList().setViewDistance(viewDistance);
    }
 
    public int simulationDistance() {
        return this.settings.getProperties().simulationDistance.get();
    }
 
    public void setSimulationDistance(int simulationDistance) {
        this.settings.update(p -> p.simulationDistance.update(this.registryAccess(), simulationDistance));
        this.getPlayerList().setSimulationDistance(simulationDistance);
    }
 
    @Override
    public SystemReport fillServerSystemReport(SystemReport systemReport) {
        systemReport.setDetail("Is Modded", () -> this.getModdedStatus().fullDescription());
        systemReport.setDetail("Type", () -> "Dedicated Server");
        return systemReport;
    }
 
    @Override
    public void dumpServerProperties(Path path) throws IOException {
        DedicatedServerProperties serverProperties = this.getProperties();
 
        try (Writer output = Files.newBufferedWriter(path)) {
            output.write(String.format(Locale.ROOT, "sync-chunk-writes=%s%n", serverProperties.syncChunkWrites));
            output.write(String.format(Locale.ROOT, "gamemode=%s%n", serverProperties.gameMode.get()));
            output.write(String.format(Locale.ROOT, "entity-broadcast-range-percentage=%d%n", serverProperties.entityBroadcastRangePercentage.get()));
            output.write(String.format(Locale.ROOT, "max-world-size=%d%n", serverProperties.maxWorldSize));
            output.write(String.format(Locale.ROOT, "view-distance=%d%n", serverProperties.viewDistance.get()));
            output.write(String.format(Locale.ROOT, "simulation-distance=%d%n", serverProperties.simulationDistance.get()));
            output.write(String.format(Locale.ROOT, "generate-structures=%s%n", serverProperties.worldOptions.generateStructures()));
            output.write(String.format(Locale.ROOT, "use-native=%s%n", serverProperties.useNativeTransport));
            output.write(String.format(Locale.ROOT, "rate-limit=%d%n", serverProperties.rateLimitPacketsPerSecond));
        }
    }
 
    @Override
    protected void onServerExit() {
        if (this.serverTextFilter != null) {
            this.serverTextFilter.close();
        }
 
        if (this.gui != null) {
            this.gui.close();
        }
 
        if (this.rconThread != null) {
            this.rconThread.stop();
        }
 
        if (this.queryThreadGs4 != null) {
            this.queryThreadGs4.stop();
        }
 
        if (this.jsonRpcServer != null) {
            try {
                this.jsonRpcServer.stop(true);
            } catch (InterruptedException var2) {
                LOGGER.error("Interrupted while stopping the management server", (Throwable)var2);
            }
        }
    }
 
    @Override
    protected void tickConnection() {
        super.tickConnection();
        this.handleConsoleInputs();
    }
 
    public void handleConsoleInput(String msg, CommandSourceStack source) {
        this.consoleInput.add(new ConsoleInput(msg, source));
    }
 
    public void handleConsoleInputs() {
        while (!this.consoleInput.isEmpty()) {
            ConsoleInput input = this.consoleInput.remove(0);
            this.getCommands().performPrefixedCommand(input.source, input.msg);
        }
    }
 
    @Override
    public boolean isDedicatedServer() {
        return true;
    }
 
    @Override
    public int getRateLimitPacketsPerSecond() {
        return this.getProperties().rateLimitPacketsPerSecond;
    }
 
    @Override
    public boolean useNativeTransport() {
        return this.getProperties().useNativeTransport;
    }
 
    public DedicatedPlayerList getPlayerList() {
        return (DedicatedPlayerList)super.getPlayerList();
    }
 
    @Override
    public int getMaxPlayers() {
        return this.settings.getProperties().maxPlayers.get();
    }
 
    public void setMaxPlayers(int maxPlayers) {
        this.settings.update(p -> p.maxPlayers.update(this.registryAccess(), maxPlayers));
    }
 
    @Override
    public boolean isPublished() {
        return true;
    }
 
    @Override
    public String getServerIp() {
        return this.getLocalIp();
    }
 
    @Override
    public int getServerPort() {
        return this.getPort();
    }
 
    @Override
    public String getServerName() {
        return this.getMotd();
    }
 
    public void showGui() {
        if (this.gui == null) {
            this.gui = MinecraftServerGui.showFrameFor(this);
        }
    }
 
    public int spawnProtectionRadius() {
        return this.getProperties().spawnProtection.get();
    }
 
    public void setSpawnProtectionRadius(int spawnProtectionRadius) {
        this.settings.update(p -> p.spawnProtection.update(this.registryAccess(), spawnProtectionRadius));
    }
 
    @Override
    public boolean isUnderSpawnProtection(ServerLevel level, BlockPos pos, Player player) {
        LevelData.RespawnData respawnData = level.getRespawnData();
        if (level.dimension() != respawnData.dimension()) {
            return false;
        } else if (this.getPlayerList().getOps().isEmpty()) {
            return false;
        } else if (this.getPlayerList().isOp(player.nameAndId())) {
            return false;
        } else if (this.spawnProtectionRadius() <= 0) {
            return false;
        } else {
            BlockPos spawnPos = respawnData.pos();
            int xd = Mth.abs(pos.getX() - spawnPos.getX());
            int zd = Mth.abs(pos.getZ() - spawnPos.getZ());
            int dist = Math.max(xd, zd);
            return dist <= this.spawnProtectionRadius();
        }
    }
 
    @Override
    public boolean repliesToStatus() {
        return this.getProperties().enableStatus.get();
    }
 
    public void setRepliesToStatus(boolean enable) {
        this.settings.update(p -> p.enableStatus.update(this.registryAccess(), enable));
    }
 
    @Override
    public boolean hidesOnlinePlayers() {
        return this.getProperties().hideOnlinePlayers.get();
    }
 
    public void setHidesOnlinePlayers(boolean hide) {
        this.settings.update(p -> p.hideOnlinePlayers.update(this.registryAccess(), hide));
    }
 
    @Override
    public LevelBasedPermissionSet operatorUserPermissions() {
        return this.getProperties().opPermissions.get();
    }
 
    public void setOperatorUserPermissions(LevelBasedPermissionSet permissions) {
        this.settings.update(p -> p.opPermissions.update(this.registryAccess(), permissions));
    }
 
    @Override
    public PermissionSet getFunctionCompilationPermissions() {
        return this.getProperties().functionPermissions;
    }
 
    @Override
    public int playerIdleTimeout() {
        return this.settings.getProperties().playerIdleTimeout.get();
    }
 
    @Override
    public void setPlayerIdleTimeout(int playerIdleTimeout) {
        this.settings.update(p -> p.playerIdleTimeout.update(this.registryAccess(), playerIdleTimeout));
    }
 
    public int statusHeartbeatInterval() {
        return this.settings.getProperties().statusHeartbeatInterval.get();
    }
 
    public void setStatusHeartbeatInterval(int statusHeartbeatInterval) {
        this.settings.update(p -> p.statusHeartbeatInterval.update(this.registryAccess(), statusHeartbeatInterval));
    }
 
    @Override
    public String getMotd() {
        return this.settings.getProperties().motd.get();
    }
 
    @Override
    public void setMotd(String motd) {
        this.settings.update(p -> p.motd.update(this.registryAccess(), motd));
    }
 
    @Override
    public boolean shouldRconBroadcast() {
        return this.getProperties().broadcastRconToOps;
    }
 
    @Override
    public boolean shouldInformAdmins() {
        return this.getProperties().broadcastConsoleToOps;
    }
 
    @Override
    public int getAbsoluteMaxWorldSize() {
        return this.getProperties().maxWorldSize;
    }
 
    @Override
    public int getCompressionThreshold() {
        return this.getProperties().networkCompressionThreshold;
    }
 
    @Override
    public boolean enforceSecureProfile() {
        DedicatedServerProperties properties = this.getProperties();
        return properties.enforceSecureProfile && properties.onlineMode && this.services.canValidateProfileKeys();
    }
 
    @Override
    public boolean logIPs() {
        return this.getProperties().logIPs;
    }
 
    protected boolean convertOldUsers() {
        boolean userBanlistConverted = false;
 
        for (int retries = 0; !userBanlistConverted && retries <= 2; retries++) {
            if (retries > 0) {
                LOGGER.warn("Encountered a problem while converting the user banlist, retrying in a few seconds");
                this.waitForRetry();
            }
 
            userBanlistConverted = OldUsersConverter.convertUserBanlist(this);
        }
 
        boolean ipBanlistConverted = false;
 
        for (int var7 = 0; !ipBanlistConverted && var7 <= 2; var7++) {
            if (var7 > 0) {
                LOGGER.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds");
                this.waitForRetry();
            }
 
            ipBanlistConverted = OldUsersConverter.convertIpBanlist(this);
        }
 
        boolean opListConverted = false;
 
        for (int var8 = 0; !opListConverted && var8 <= 2; var8++) {
            if (var8 > 0) {
                LOGGER.warn("Encountered a problem while converting the op list, retrying in a few seconds");
                this.waitForRetry();
            }
 
            opListConverted = OldUsersConverter.convertOpsList(this);
        }
 
        boolean whitelistConverted = false;
 
        for (int var9 = 0; !whitelistConverted && var9 <= 2; var9++) {
            if (var9 > 0) {
                LOGGER.warn("Encountered a problem while converting the whitelist, retrying in a few seconds");
                this.waitForRetry();
            }
 
            whitelistConverted = OldUsersConverter.convertWhiteList(this);
        }
 
        boolean playersConverted = false;
 
        for (int var10 = 0; !playersConverted && var10 <= 2; var10++) {
            if (var10 > 0) {
                LOGGER.warn("Encountered a problem while converting the player save files, retrying in a few seconds");
                this.waitForRetry();
            }
 
            playersConverted = OldUsersConverter.convertPlayers(this);
        }
 
        return userBanlistConverted || ipBanlistConverted || opListConverted || whitelistConverted || playersConverted;
    }
 
    private void waitForRetry() {
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException var2) {
        }
    }
 
    public long getMaxTickLength() {
        return this.getProperties().maxTickTime;
    }
 
    @Override
    public int getMaxChainedNeighborUpdates() {
        return this.getProperties().maxChainedNeighborUpdates;
    }
 
    @Override
    public String getPluginNames() {
        return "";
    }
 
    @Override
    public String runCommand(String command) {
        this.rconConsoleSource.prepareForCommand();
        this.executeBlocking(() -> this.getCommands().performPrefixedCommand(this.rconConsoleSource.createCommandSourceStack(), command));
        return this.rconConsoleSource.getCommandResponse();
    }
 
    @Override
    protected void stopServer() {
        this.notificationManager().serverShuttingDown();
        super.stopServer();
        Util.shutdownExecutors();
    }
 
    @Override
    public boolean isSingleplayerOwner(NameAndId nameAndId) {
        return false;
    }
 
    @Override
    public int getScaledTrackingDistance(int range) {
        return this.entityBroadcastRangePercentage() * range / 100;
    }
 
    public int entityBroadcastRangePercentage() {
        return this.getProperties().entityBroadcastRangePercentage.get();
    }
 
    public void setEntityBroadcastRangePercentage(int range) {
        this.settings.update(p -> p.entityBroadcastRangePercentage.update(this.registryAccess(), range));
    }
 
    @Override
    public String getLevelIdName() {
        return this.storageSource.getLevelId();
    }
 
    @Override
    public boolean forceSynchronousWrites() {
        return this.settings.getProperties().syncChunkWrites;
    }
 
    @Override
    public TextFilter createTextFilterForPlayer(ServerPlayer player) {
        return this.serverTextFilter != null ? this.serverTextFilter.createContext(player.getGameProfile()) : TextFilter.DUMMY;
    }
 
    @Override
    public @Nullable GameType getForcedGameType() {
        return this.forceGameMode() ? this.worldData.getGameType() : null;
    }
 
    public boolean forceGameMode() {
        return this.settings.getProperties().forceGameMode.get();
    }
 
    public void setForceGameMode(boolean forceGameMode) {
        this.settings.update(p -> p.forceGameMode.update(this.registryAccess(), forceGameMode));
        this.enforceGameTypeForPlayers(this.getForcedGameType());
    }
 
    public GameType gameMode() {
        return this.getProperties().gameMode.get();
    }
 
    public void setGameMode(GameType gameMode) {
        this.settings.update(p -> p.gameMode.update(this.registryAccess(), gameMode));
        this.worldData.setGameType(this.gameMode());
        this.enforceGameTypeForPlayers(this.getForcedGameType());
    }
 
    @Override
    public Optional<MinecraftServer.ServerResourcePackInfo> getServerResourcePack() {
        return this.settings.getProperties().serverResourcePackInfo;
    }
 
    @Override
    protected void endMetricsRecordingTick() {
        super.endMetricsRecordingTick();
        this.isTickTimeLoggingEnabled = this.debugSubscribers().hasAnySubscriberFor(DebugSubscriptions.DEDICATED_SERVER_TICK_TIME);
    }
 
    @Override
    protected SampleLogger getTickTimeLogger() {
        return this.tickTimeLogger;
    }
 
    @Override
    public boolean isTickTimeLoggingEnabled() {
        return this.isTickTimeLoggingEnabled;
    }
 
    @Override
    public boolean acceptsTransfers() {
        return this.settings.getProperties().acceptsTransfers.get();
    }
 
    public void setAcceptsTransfers(boolean acceptTransfers) {
        this.settings.update(p -> p.acceptsTransfers.update(this.registryAccess(), acceptTransfers));
    }
 
    @Override
    public ServerLinks serverLinks() {
        return this.serverLinks;
    }
 
    @Override
    public int pauseWhenEmptySeconds() {
        return this.settings.getProperties().pauseWhenEmptySeconds.get();
    }
 
    public void setPauseWhenEmptySeconds(int seconds) {
        this.settings.update(p -> p.pauseWhenEmptySeconds.update(this.registryAccess(), seconds));
    }
 
    private static ServerLinks createServerLinks(DedicatedServerSettings settings) {
        Optional<URI> bugReportLink = parseBugReportLink(settings.getProperties());
        return bugReportLink.<ServerLinks>map(bugLink -> new ServerLinks(List.of(ServerLinks.KnownLinkType.BUG_REPORT.create(bugLink))))
            .orElse(ServerLinks.EMPTY);
    }
 
    private static Optional<URI> parseBugReportLink(DedicatedServerProperties properties) {
        String bugReportLink = properties.bugReportLink;
        if (bugReportLink.isEmpty()) {
            return Optional.empty();
        } else {
            try {
                return Optional.of(Util.parseAndValidateUntrustedUri(bugReportLink));
            } catch (Exception var3) {
                LOGGER.warn("Failed to parse bug link {}", bugReportLink, var3);
                return Optional.empty();
            }
        }
    }
 
    @Override
    public Map<String, String> getCodeOfConducts() {
        return this.codeOfConductTexts;
    }
}

引用的其他类