MinecraftServer.java
net.minecraft.server.MinecraftServer
信息
- 全限定名:net.minecraft.server.MinecraftServer
- 类型:public abstract class
- 包:net.minecraft.server
- 源码路径:src/main/java/net/minecraft/server/MinecraftServer.java
- 起始行号:L194
- 继承:ReentrantBlockableEventLoop
- 实现:CommandSource, ServerInfo, ChunkIOErrorReporter
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L195 - 说明:
TODO
- 类型:
-
VANILLA_BRAND- 类型:
String - 修饰符:
public static final - 源码定位:
L196 - 说明:
TODO
- 类型:
-
AVERAGE_TICK_TIME_SMOOTHING- 类型:
float - 修饰符:
private static final - 源码定位:
L197 - 说明:
TODO
- 类型:
-
TICK_STATS_SPAN- 类型:
int - 修饰符:
private static final - 源码定位:
L198 - 说明:
TODO
- 类型:
-
OVERLOADED_THRESHOLD_NANOS- 类型:
long - 修饰符:
private static final - 源码定位:
L199 - 说明:
TODO
- 类型:
-
OVERLOADED_TICKS_THRESHOLD- 类型:
int - 修饰符:
private static final - 源码定位:
L200 - 说明:
TODO
- 类型:
-
OVERLOADED_WARNING_INTERVAL_NANOS- 类型:
long - 修饰符:
private static final - 源码定位:
L201 - 说明:
TODO
- 类型:
-
OVERLOADED_TICKS_WARNING_INTERVAL- 类型:
int - 修饰符:
private static final - 源码定位:
L202 - 说明:
TODO
- 类型:
-
STATUS_EXPIRE_TIME_NANOS- 类型:
long - 修饰符:
private static final - 源码定位:
L203 - 说明:
TODO
- 类型:
-
PREPARE_LEVELS_DEFAULT_DELAY_NANOS- 类型:
long - 修饰符:
private static final - 源码定位:
L204 - 说明:
TODO
- 类型:
-
MAX_STATUS_PLAYER_SAMPLE- 类型:
int - 修饰符:
private static final - 源码定位:
L205 - 说明:
TODO
- 类型:
-
SPAWN_POSITION_SEARCH_RADIUS- 类型:
int - 修饰符:
public static final - 源码定位:
L206 - 说明:
TODO
- 类型:
-
SERVER_ACTIVITY_MONITOR_SECONDS_BETWEEN_NOTIFICATIONS- 类型:
int - 修饰符:
private static final - 源码定位:
L207 - 说明:
TODO
- 类型:
-
LEGACY_WORLD_NAMES_FOR_REALMS_LOG- 类型:
Map<String,String> - 修饰符:
private static final - 源码定位:
L208 - 说明:
TODO
- 类型:
-
AUTOSAVE_INTERVAL- 类型:
int - 修饰符:
private static final - 源码定位:
L209 - 说明:
TODO
- 类型:
-
MIMINUM_AUTOSAVE_TICKS- 类型:
int - 修饰符:
private static final - 源码定位:
L210 - 说明:
TODO
- 类型:
-
MAX_TICK_LATENCY- 类型:
int - 修饰符:
private static final - 源码定位:
L211 - 说明:
TODO
- 类型:
-
ABSOLUTE_MAX_WORLD_SIZE- 类型:
int - 修饰符:
public static final - 源码定位:
L212 - 说明:
TODO
- 类型:
-
DEMO_SETTINGS- 类型:
LevelSettings - 修饰符:
public static final - 源码定位:
L213 - 说明:
TODO
- 类型:
-
DEFAULT_GAME_RULES- 类型:
Supplier<GameRules> - 修饰符:
public static final - 源码定位:
L216 - 说明:
TODO
- 类型:
-
ANONYMOUS_PLAYER_PROFILE- 类型:
NameAndId - 修饰符:
public static final - 源码定位:
L217 - 说明:
TODO
- 类型:
-
storageSource- 类型:
LevelStorageSource.LevelStorageAccess - 修饰符:
protected final - 源码定位:
L218 - 说明:
TODO
- 类型:
-
playerDataStorage- 类型:
PlayerDataStorage - 修饰符:
protected final - 源码定位:
L219 - 说明:
TODO
- 类型:
-
savedDataStorage- 类型:
SavedDataStorage - 修饰符:
private final - 源码定位:
L220 - 说明:
TODO
- 类型:
-
tickables- 类型:
List<Runnable> - 修饰符:
private final - 源码定位:
L221 - 说明:
TODO
- 类型:
-
gameRules- 类型:
GameRules - 修饰符:
private final - 源码定位:
L222 - 说明:
TODO
- 类型:
-
metricsRecorder- 类型:
MetricsRecorder - 修饰符:
private - 源码定位:
L223 - 说明:
TODO
- 类型:
-
onMetricsRecordingStopped- 类型:
Consumer<ProfileResults> - 修饰符:
private - 源码定位:
L224 - 说明:
TODO
- 类型:
-
onMetricsRecordingFinished- 类型:
Consumer<Path> - 修饰符:
private - 源码定位:
L225 - 说明:
TODO
- 类型:
-
willStartRecordingMetrics- 类型:
boolean - 修饰符:
private - 源码定位:
L226 - 说明:
TODO
- 类型:
-
debugCommandProfiler- 类型:
MinecraftServer.TimeProfiler - 修饰符:
private - 源码定位:
L227 - 说明:
TODO
- 类型:
-
debugCommandProfilerDelayStart- 类型:
boolean - 修饰符:
private - 源码定位:
L228 - 说明:
TODO
- 类型:
-
connection- 类型:
ServerConnectionListener - 修饰符:
private final - 源码定位:
L229 - 说明:
TODO
- 类型:
-
levelLoadListener- 类型:
LevelLoadListener - 修饰符:
private final - 源码定位:
L230 - 说明:
TODO
- 类型:
-
status- 类型:
ServerStatus - 修饰符:
private - 源码定位:
L231 - 说明:
TODO
- 类型:
-
statusIcon- 类型:
ServerStatus.Favicon - 修饰符:
private - 源码定位:
L232 - 说明:
TODO
- 类型:
-
random- 类型:
RandomSource - 修饰符:
private final - 源码定位:
L233 - 说明:
TODO
- 类型:
-
fixerUpper- 类型:
DataFixer - 修饰符:
private final - 源码定位:
L234 - 说明:
TODO
- 类型:
-
localIp- 类型:
String - 修饰符:
private - 源码定位:
L235 - 说明:
TODO
- 类型:
-
port- 类型:
int - 修饰符:
private - 源码定位:
L236 - 说明:
TODO
- 类型:
-
registries- 类型:
LayeredRegistryAccess<RegistryLayer> - 修饰符:
private final - 源码定位:
L237 - 说明:
TODO
- 类型:
-
levels- 类型:
Map<ResourceKey<Level>,ServerLevel> - 修饰符:
private final - 源码定位:
L238 - 说明:
TODO
- 类型:
-
playerList- 类型:
PlayerList - 修饰符:
private - 源码定位:
L239 - 说明:
TODO
- 类型:
-
running- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L240 - 说明:
TODO
- 类型:
-
stopped- 类型:
boolean - 修饰符:
private - 源码定位:
L241 - 说明:
TODO
- 类型:
-
tickCount- 类型:
int - 修饰符:
private - 源码定位:
L242 - 说明:
TODO
- 类型:
-
ticksUntilAutosave- 类型:
int - 修饰符:
private - 源码定位:
L243 - 说明:
TODO
- 类型:
-
proxy- 类型:
Proxy - 修饰符:
protected final - 源码定位:
L244 - 说明:
TODO
- 类型:
-
onlineMode- 类型:
boolean - 修饰符:
private - 源码定位:
L245 - 说明:
TODO
- 类型:
-
preventProxyConnections- 类型:
boolean - 修饰符:
private - 源码定位:
L246 - 说明:
TODO
- 类型:
-
motd- 类型:
String - 修饰符:
private - 源码定位:
L247 - 说明:
TODO
- 类型:
-
playerIdleTimeout- 类型:
int - 修饰符:
private - 源码定位:
L248 - 说明:
TODO
- 类型:
-
tickTimesNanos- 类型:
long[] - 修饰符:
private final - 源码定位:
L249 - 说明:
TODO
- 类型:
-
aggregatedTickTimesNanos- 类型:
long - 修饰符:
private - 源码定位:
L250 - 说明:
TODO
- 类型:
-
keyPair- 类型:
KeyPair - 修饰符:
private - 源码定位:
L251 - 说明:
TODO
- 类型:
-
singleplayerProfile- 类型:
GameProfile - 修饰符:
private - 源码定位:
L252 - 说明:
TODO
- 类型:
-
isDemo- 类型:
boolean - 修饰符:
private - 源码定位:
L253 - 说明:
TODO
- 类型:
-
isReady- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L254 - 说明:
TODO
- 类型:
-
lastOverloadWarningNanos- 类型:
long - 修饰符:
private - 源码定位:
L255 - 说明:
TODO
- 类型:
-
services- 类型:
Services - 修饰符:
protected final - 源码定位:
L256 - 说明:
TODO
- 类型:
-
notificationManager- 类型:
NotificationManager - 修饰符:
private final - 源码定位:
L257 - 说明:
TODO
- 类型:
-
serverActivityMonitor- 类型:
ServerActivityMonitor - 修饰符:
private final - 源码定位:
L258 - 说明:
TODO
- 类型:
-
lastServerStatus- 类型:
long - 修饰符:
private - 源码定位:
L259 - 说明:
TODO
- 类型:
-
serverThread- 类型:
Thread - 修饰符:
private final - 源码定位:
L260 - 说明:
TODO
- 类型:
-
lastTickNanos- 类型:
long - 修饰符:
private - 源码定位:
L261 - 说明:
TODO
- 类型:
-
taskExecutionStartNanos- 类型:
long - 修饰符:
private - 源码定位:
L262 - 说明:
TODO
- 类型:
-
idleTimeNanos- 类型:
long - 修饰符:
private - 源码定位:
L263 - 说明:
TODO
- 类型:
-
nextTickTimeNanos- 类型:
long - 修饰符:
private - 源码定位:
L264 - 说明:
TODO
- 类型:
-
waitingForNextTick- 类型:
boolean - 修饰符:
private - 源码定位:
L265 - 说明:
TODO
- 类型:
-
delayedTasksMaxNextTickTimeNanos- 类型:
long - 修饰符:
private - 源码定位:
L266 - 说明:
TODO
- 类型:
-
mayHaveDelayedTasks- 类型:
boolean - 修饰符:
private - 源码定位:
L267 - 说明:
TODO
- 类型:
-
packRepository- 类型:
PackRepository - 修饰符:
private final - 源码定位:
L268 - 说明:
TODO
- 类型:
-
worldGenSettings- 类型:
WorldGenSettings - 修饰符:
private final - 源码定位:
L269 - 说明:
TODO
- 类型:
-
scoreboard- 类型:
ServerScoreboard - 修饰符:
private final - 源码定位:
L270 - 说明:
TODO
- 类型:
-
stopwatches- 类型:
Stopwatches - 修饰符:
private - 源码定位:
L271 - 说明:
TODO
- 类型:
-
commandStorage- 类型:
CommandStorage - 修饰符:
private - 源码定位:
L272 - 说明:
TODO
- 类型:
-
customBossEvents- 类型:
CustomBossEvents - 修饰符:
private final - 源码定位:
L273 - 说明:
TODO
- 类型:
-
randomSequences- 类型:
RandomSequences - 修饰符:
private final - 源码定位:
L274 - 说明:
TODO
- 类型:
-
weatherData- 类型:
WeatherData - 修饰符:
private final - 源码定位:
L275 - 说明:
TODO
- 类型:
-
functionManager- 类型:
ServerFunctionManager - 修饰符:
private final - 源码定位:
L276 - 说明:
TODO
- 类型:
-
enforceWhitelist- 类型:
boolean - 修饰符:
private - 源码定位:
L277 - 说明:
TODO
- 类型:
-
usingWhitelist- 类型:
boolean - 修饰符:
private - 源码定位:
L278 - 说明:
TODO
- 类型:
-
smoothedTickTimeMillis- 类型:
float - 修饰符:
private - 源码定位:
L279 - 说明:
TODO
- 类型:
-
executor- 类型:
Executor - 修饰符:
private final - 源码定位:
L280 - 说明:
TODO
- 类型:
-
serverId- 类型:
String - 修饰符:
private - 源码定位:
L281 - 说明:
TODO
- 类型:
-
resources- 类型:
MinecraftServer.ReloadableResources - 修饰符:
private - 源码定位:
L282 - 说明:
TODO
- 类型:
-
structureTemplateManager- 类型:
StructureTemplateManager - 修饰符:
private final - 源码定位:
L283 - 说明:
TODO
- 类型:
-
tickRateManager- 类型:
ServerTickRateManager - 修饰符:
private final - 源码定位:
L284 - 说明:
TODO
- 类型:
-
debugSubscribers- 类型:
ServerDebugSubscribers - 修饰符:
private final - 源码定位:
L285 - 说明:
TODO
- 类型:
-
worldData- 类型:
WorldData - 修饰符:
protected final - 源码定位:
L286 - 说明:
TODO
- 类型:
-
effectiveRespawnData- 类型:
LevelData.RespawnData - 修饰符:
private - 源码定位:
L287 - 说明:
TODO
- 类型:
-
potionBrewing- 类型:
PotionBrewing - 修饰符:
private final - 源码定位:
L288 - 说明:
TODO
- 类型:
-
fuelValues- 类型:
FuelValues - 修饰符:
private - 源码定位:
L289 - 说明:
TODO
- 类型:
-
emptyTicks- 类型:
int - 修饰符:
private - 源码定位:
L290 - 说明:
TODO
- 类型:
-
isSaving- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L291 - 说明:
TODO
- 类型:
-
suppressedExceptions- 类型:
SuppressedExceptionCollector - 修饰符:
private final - 源码定位:
L292 - 说明:
TODO
- 类型:
-
tickFrame- 类型:
DiscontinuousFrame - 修饰符:
private final - 源码定位:
L293 - 说明:
TODO
- 类型:
-
packetProcessor- 类型:
PacketProcessor - 修饰符:
private final - 源码定位:
L294 - 说明:
TODO
- 类型:
-
scheduledEvents- 类型:
TimerQueue<MinecraftServer> - 修饰符:
private final - 源码定位:
L295 - 说明:
TODO
- 类型:
-
clockManager- 类型:
ServerClockManager - 修饰符:
private final - 源码定位:
L296 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.server.MinecraftServer.ReloadableResources- 类型:
record - 修饰符:
private - 源码定位:
L2246 - 说明:
TODO
- 类型:
-
net.minecraft.server.MinecraftServer.ServerResourcePackInfo- 类型:
record - 修饰符:
public - 源码定位:
L2253 - 说明:
TODO
- 类型:
-
net.minecraft.server.MinecraftServer.TimeProfiler- 类型:
class - 修饰符:
private static - 源码定位:
L2256 - 说明:
TODO
- 类型:
构造器
public MinecraftServer(Thread serverThread, LevelStorageSource.LevelStorageAccess storageSource, PackRepository packRepository, WorldStem worldStem, Optional<GameRules> gameRules, Proxy proxy, DataFixer fixerUpper, Services services, LevelLoadListener levelLoadListener, boolean propagatesCrashes) @ L312
- 构造器名:MinecraftServer
- 源码定位:L312
- 修饰符:public
参数:
- serverThread: Thread
- storageSource: LevelStorageSource.LevelStorageAccess
- packRepository: PackRepository
- worldStem: WorldStem
- gameRules: Optional
- proxy: Proxy
- fixerUpper: DataFixer
- services: Services
- levelLoadListener: LevelLoadListener
- propagatesCrashes: boolean
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static <S extends MinecraftServer> S spin(Function<Thread,S> factory) @ L298
- 方法名:spin
- 源码定位:L298
- 返回类型:
S - 修饰符:public static
参数:
- factory: Function<Thread,S>
说明:
TODO
protected abstract boolean initServer() @ L369
- 方法名:initServer
- 源码定位:L369
- 返回类型:boolean
- 修饰符:protected abstract
参数:
- 无
说明:
TODO
public ChunkLoadStatusView createChunkLoadStatusView(int radius) @ L371
- 方法名:createChunkLoadStatusView
- 源码定位:L371
- 返回类型:ChunkLoadStatusView
- 修饰符:public
参数:
- radius: int
说明:
TODO
protected void loadLevel() @ L403
- 方法名:loadLevel
- 源码定位:L403
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void forceDifficulty() @ L425
- 方法名:forceDifficulty
- 源码定位:L425
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void createLevels() @ L428
- 方法名:createLevels
- 源码定位:L428
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
private static void setInitialSpawn(ServerLevel level, ServerLevelData levelData, boolean spawnBonusChest, boolean isDebug, LevelLoadListener levelLoadListener) @ L489
- 方法名:setInitialSpawn
- 源码定位:L489
- 返回类型:void
- 修饰符:private static
参数:
- level: ServerLevel
- levelData: ServerLevelData
- spawnBonusChest: boolean
- isDebug: boolean
- levelLoadListener: LevelLoadListener
说明:
TODO
private void setupDebugLevel(WorldData worldData) @ L543
- 方法名:setupDebugLevel
- 源码定位:L543
- 返回类型:void
- 修饰符:private
参数:
- worldData: WorldData
说明:
TODO
private void prepareLevels() @ L552
- 方法名:prepareLevels
- 源码定位:L552
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
protected GlobalPos selectLevelLoadFocusPos() @ L577
- 方法名:selectLevelLoadFocusPos
- 源码定位:L577
- 返回类型:GlobalPos
- 修饰符:protected
参数:
- 无
说明:
TODO
public GameType getDefaultGameType() @ L581
- 方法名:getDefaultGameType
- 源码定位:L581
- 返回类型:GameType
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isHardcore() @ L585
- 方法名:isHardcore
- 源码定位:L585
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public abstract LevelBasedPermissionSet operatorUserPermissions() @ L589
- 方法名:operatorUserPermissions
- 源码定位:L589
- 返回类型:LevelBasedPermissionSet
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public abstract PermissionSet getFunctionCompilationPermissions() @ L591
- 方法名:getFunctionCompilationPermissions
- 源码定位:L591
- 返回类型:PermissionSet
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public abstract boolean shouldRconBroadcast() @ L593
- 方法名:shouldRconBroadcast
- 源码定位:L593
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public boolean saveAllChunks(boolean silent, boolean flush, boolean force) @ L595
- 方法名:saveAllChunks
- 源码定位:L595
- 返回类型:boolean
- 修饰符:public
参数:
- silent: boolean
- flush: boolean
- force: boolean
说明:
TODO
public boolean saveEverything(boolean silent, boolean flush, boolean force) @ L628
- 方法名:saveEverything
- 源码定位:L628
- 返回类型:boolean
- 修饰符:public
参数:
- silent: boolean
- flush: boolean
- force: boolean
说明:
TODO
public void close() @ L643
- 方法名:close
- 源码定位:L643
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
protected void stopServer() @ L648
- 方法名:stopServer
- 源码定位:L648
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public String getLocalIp() @ L705
- 方法名:getLocalIp
- 源码定位:L705
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public void setLocalIp(String ip) @ L709
- 方法名:setLocalIp
- 源码定位:L709
- 返回类型:void
- 修饰符:public
参数:
- ip: String
说明:
TODO
public boolean isRunning() @ L713
- 方法名:isRunning
- 源码定位:L713
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void halt(boolean wait) @ L717
- 方法名:halt
- 源码定位:L717
- 返回类型:void
- 修饰符:public
参数:
- wait: boolean
说明:
TODO
protected void runServer() @ L728
- 方法名:runServer
- 源码定位:L728
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
private void logFullTickTime() @ L814
- 方法名:logFullTickTime
- 源码定位:L814
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void startMeasuringTaskExecutionTime() @ L823
- 方法名:startMeasuringTaskExecutionTime
- 源码定位:L823
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void finishMeasuringTaskExecutionTime() @ L830
- 方法名:finishMeasuringTaskExecutionTime
- 源码定位:L830
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private static CrashReport constructOrExtractCrashReport(Throwable t) @ L838
- 方法名:constructOrExtractCrashReport
- 源码定位:L838
- 返回类型:CrashReport
- 修饰符:private static
参数:
- t: Throwable
说明:
TODO
private boolean haveTime() @ L860
- 方法名:haveTime
- 源码定位:L860
- 返回类型:boolean
- 修饰符:private
参数:
- 无
说明:
TODO
public NotificationManager notificationManager() @ L864
- 方法名:notificationManager
- 源码定位:L864
- 返回类型:NotificationManager
- 修饰符:public
参数:
- 无
说明:
TODO
protected void waitUntilNextTick() @ L868
- 方法名:waitUntilNextTick
- 源码定位:L868
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
protected void waitForTasks() @ L879
- 方法名:waitForTasks
- 源码定位:L879
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public TickTask wrapRunnable(Runnable runnable) @ L890
- 方法名:wrapRunnable
- 源码定位:L890
- 返回类型:TickTask
- 修饰符:public
参数:
- runnable: Runnable
说明:
TODO
protected boolean shouldRun(TickTask task) @ L894
- 方法名:shouldRun
- 源码定位:L894
- 返回类型:boolean
- 修饰符:protected
参数:
- task: TickTask
说明:
TODO
protected boolean pollTask() @ L898
- 方法名:pollTask
- 源码定位:L898
- 返回类型:boolean
- 修饰符:protected
参数:
- 无
说明:
TODO
private boolean pollTaskInternal() @ L905
- 方法名:pollTaskInternal
- 源码定位:L905
- 返回类型:boolean
- 修饰符:private
参数:
- 无
说明:
TODO
protected void doRunTask(TickTask task) @ L921
- 方法名:doRunTask
- 源码定位:L921
- 返回类型:void
- 修饰符:protected
参数:
- task: TickTask
说明:
TODO
private Optional<ServerStatus.Favicon> loadStatusIcon() @ L926
- 方法名:loadStatusIcon
- 源码定位:L926
- 返回类型:Optional<ServerStatus.Favicon>
- 修饰符:private
参数:
- 无
说明:
TODO
public Optional<Path> getWorldScreenshotFile() @ L946
- 方法名:getWorldScreenshotFile
- 源码定位:L946
- 返回类型:Optional
- 修饰符:public
参数:
- 无
说明:
TODO
public Path getServerDirectory() @ L950
- 方法名:getServerDirectory
- 源码定位:L950
- 返回类型:Path
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerActivityMonitor getServerActivityMonitor() @ L954
- 方法名:getServerActivityMonitor
- 源码定位:L954
- 返回类型:ServerActivityMonitor
- 修饰符:public
参数:
- 无
说明:
TODO
protected void onServerCrash(CrashReport report) @ L958
- 方法名:onServerCrash
- 源码定位:L958
- 返回类型:void
- 修饰符:protected
参数:
- report: CrashReport
说明:
TODO
protected void onServerExit() @ L961
- 方法名:onServerExit
- 源码定位:L961
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public boolean isPaused() @ L964
- 方法名:isPaused
- 源码定位:L964
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
protected void tickServer(BooleanSupplier haveTime) @ L968
- 方法名:tickServer
- 源码定位:L968
- 返回类型:void
- 修饰符:protected
参数:
- haveTime: BooleanSupplier
说明:
TODO
protected void processPacketsAndTick(boolean sprinting) @ L1014
- 方法名:processPacketsAndTick
- 源码定位:L1014
- 返回类型:void
- 修饰符:protected
参数:
- sprinting: boolean
说明:
TODO
private void autoSave() @ L1026
- 方法名:autoSave
- 源码定位:L1026
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void logTickMethodTime(long startTime) @ L1036
- 方法名:logTickMethodTime
- 源码定位:L1036
- 返回类型:void
- 修饰符:private
参数:
- startTime: long
说明:
TODO
private int computeNextAutosaveInterval() @ L1042
- 方法名:computeNextAutosaveInterval
- 源码定位:L1042
- 返回类型:int
- 修饰符:private
参数:
- 无
说明:
TODO
public void onTickRateChanged() @ L1055
- 方法名:onTickRateChanged
- 源码定位:L1055
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
protected abstract SampleLogger getTickTimeLogger() @ L1062
- 方法名:getTickTimeLogger
- 源码定位:L1062
- 返回类型:SampleLogger
- 修饰符:protected abstract
参数:
- 无
说明:
TODO
public abstract boolean isTickTimeLoggingEnabled() @ L1064
- 方法名:isTickTimeLoggingEnabled
- 源码定位:L1064
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
private ServerStatus buildServerStatus() @ L1066
- 方法名:buildServerStatus
- 源码定位:L1066
- 返回类型:ServerStatus
- 修饰符:private
参数:
- 无
说明:
TODO
private ServerStatus.Players buildPlayerStatus() @ L1077
- 方法名:buildPlayerStatus
- 源码定位:L1077
- 返回类型:ServerStatus.Players
- 修饰符:private
参数:
- 无
说明:
TODO
protected void tickChildren(BooleanSupplier haveTime) @ L1097
- 方法名:tickChildren
- 源码定位:L1097
- 返回类型:void
- 修饰符:protected
参数:
- haveTime: BooleanSupplier
说明:
TODO
private void updateEffectiveRespawnData() @ L1162
- 方法名:updateEffectiveRespawnData
- 源码定位:L1162
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
protected void tickConnection() @ L1168
- 方法名:tickConnection
- 源码定位:L1168
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public void forceGameTimeSynchronization() @ L1172
- 方法名:forceGameTimeSynchronization
- 源码定位:L1172
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void addTickable(Runnable tickable) @ L1179
- 方法名:addTickable
- 源码定位:L1179
- 返回类型:void
- 修饰符:public
参数:
- tickable: Runnable
说明:
TODO
protected void setId(String serverId) @ L1183
- 方法名:setId
- 源码定位:L1183
- 返回类型:void
- 修饰符:protected
参数:
- serverId: String
说明:
TODO
public boolean isShutdown() @ L1187
- 方法名:isShutdown
- 源码定位:L1187
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public Path getFile(String name) @ L1191
- 方法名:getFile
- 源码定位:L1191
- 返回类型:Path
- 修饰符:public
参数:
- name: String
说明:
TODO
public final ServerLevel overworld() @ L1195
- 方法名:overworld
- 源码定位:L1195
- 返回类型:ServerLevel
- 修饰符:public final
参数:
- 无
说明:
TODO
public ServerLevel getLevel(ResourceKey<Level> dimension) @ L1199
- 方法名:getLevel
- 源码定位:L1199
- 返回类型:ServerLevel
- 修饰符:public
参数:
- dimension: ResourceKey
说明:
TODO
public Set<ResourceKey<Level>> levelKeys() @ L1203
- 方法名:levelKeys
- 源码定位:L1203
- 返回类型:Set<ResourceKey
> - 修饰符:public
参数:
- 无
说明:
TODO
public Iterable<ServerLevel> getAllLevels() @ L1207
- 方法名:getAllLevels
- 源码定位:L1207
- 返回类型:Iterable
- 修饰符:public
参数:
- 无
说明:
TODO
public String getServerVersion() @ L1211
- 方法名:getServerVersion
- 源码定位:L1211
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public int getPlayerCount() @ L1216
- 方法名:getPlayerCount
- 源码定位:L1216
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public String[] getPlayerNames() @ L1221
- 方法名:getPlayerNames
- 源码定位:L1221
- 返回类型:String[]
- 修饰符:public
参数:
- 无
说明:
TODO
public String getServerModName() @ L1225
- 方法名:getServerModName
- 源码定位:L1225
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerClockManager clockManager() @ L1229
- 方法名:clockManager
- 源码定位:L1229
- 返回类型:ServerClockManager
- 修饰符:public
参数:
- 无
说明:
TODO
public SystemReport fillSystemReport(SystemReport systemReport) @ L1233
- 方法名:fillSystemReport
- 源码定位:L1233
- 返回类型:SystemReport
- 修饰符:public
参数:
- systemReport: SystemReport
说明:
TODO
public abstract SystemReport fillServerSystemReport(SystemReport systemReport) @ L1257
- 方法名:fillServerSystemReport
- 源码定位:L1257
- 返回类型:SystemReport
- 修饰符:public abstract
参数:
- systemReport: SystemReport
说明:
TODO
public ModCheck getModdedStatus() @ L1259
- 方法名:getModdedStatus
- 源码定位:L1259
- 返回类型:ModCheck
- 修饰符:public
参数:
- 无
说明:
TODO
public void sendSystemMessage(Component message) @ L1263
- 方法名:sendSystemMessage
- 源码定位:L1263
- 返回类型:void
- 修饰符:public
参数:
- message: Component
说明:
TODO
public KeyPair getKeyPair() @ L1268
- 方法名:getKeyPair
- 源码定位:L1268
- 返回类型:KeyPair
- 修饰符:public
参数:
- 无
说明:
TODO
public int getPort() @ L1272
- 方法名:getPort
- 源码定位:L1272
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void setPort(int port) @ L1276
- 方法名:setPort
- 源码定位:L1276
- 返回类型:void
- 修饰符:public
参数:
- port: int
说明:
TODO
public GameProfile getSingleplayerProfile() @ L1280
- 方法名:getSingleplayerProfile
- 源码定位:L1280
- 返回类型:GameProfile
- 修饰符:public
参数:
- 无
说明:
TODO
public void setSingleplayerProfile(GameProfile singleplayerProfile) @ L1284
- 方法名:setSingleplayerProfile
- 源码定位:L1284
- 返回类型:void
- 修饰符:public
参数:
- singleplayerProfile: GameProfile
说明:
TODO
public boolean isSingleplayer() @ L1288
- 方法名:isSingleplayer
- 源码定位:L1288
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
protected void initializeKeyPair() @ L1292
- 方法名:initializeKeyPair
- 源码定位:L1292
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public void setDifficulty(Difficulty difficulty, boolean ignoreLock) @ L1302
- 方法名:setDifficulty
- 源码定位:L1302
- 返回类型:void
- 修饰符:public
参数:
- difficulty: Difficulty
- ignoreLock: boolean
说明:
TODO
public int getScaledTrackingDistance(int baseRange) @ L1310
- 方法名:getScaledTrackingDistance
- 源码定位:L1310
- 返回类型:int
- 修饰符:public
参数:
- baseRange: int
说明:
TODO
public void updateMobSpawningFlags() @ L1314
- 方法名:updateMobSpawningFlags
- 源码定位:L1314
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void setDifficultyLocked(boolean locked) @ L1320
- 方法名:setDifficultyLocked
- 源码定位:L1320
- 返回类型:void
- 修饰符:public
参数:
- locked: boolean
说明:
TODO
private void sendDifficultyUpdate(ServerPlayer player) @ L1325
- 方法名:sendDifficultyUpdate
- 源码定位:L1325
- 返回类型:void
- 修饰符:private
参数:
- player: ServerPlayer
说明:
TODO
public boolean isDemo() @ L1330
- 方法名:isDemo
- 源码定位:L1330
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void setDemo(boolean demo) @ L1334
- 方法名:setDemo
- 源码定位:L1334
- 返回类型:void
- 修饰符:public
参数:
- demo: boolean
说明:
TODO
public Map<String,String> getCodeOfConducts() @ L1338
- 方法名:getCodeOfConducts
- 源码定位:L1338
- 返回类型:Map<String,String>
- 修饰符:public
参数:
- 无
说明:
TODO
public Optional<MinecraftServer.ServerResourcePackInfo> getServerResourcePack() @ L1342
- 方法名:getServerResourcePack
- 源码定位:L1342
- 返回类型:Optional<MinecraftServer.ServerResourcePackInfo>
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isResourcePackRequired() @ L1346
- 方法名:isResourcePackRequired
- 源码定位:L1346
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public abstract boolean isDedicatedServer() @ L1350
- 方法名:isDedicatedServer
- 源码定位:L1350
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public abstract int getRateLimitPacketsPerSecond() @ L1352
- 方法名:getRateLimitPacketsPerSecond
- 源码定位:L1352
- 返回类型:int
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public boolean usesAuthentication() @ L1354
- 方法名:usesAuthentication
- 源码定位:L1354
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void setUsesAuthentication(boolean onlineMode) @ L1358
- 方法名:setUsesAuthentication
- 源码定位:L1358
- 返回类型:void
- 修饰符:public
参数:
- onlineMode: boolean
说明:
TODO
public boolean getPreventProxyConnections() @ L1362
- 方法名:getPreventProxyConnections
- 源码定位:L1362
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void setPreventProxyConnections(boolean preventProxyConnections) @ L1366
- 方法名:setPreventProxyConnections
- 源码定位:L1366
- 返回类型:void
- 修饰符:public
参数:
- preventProxyConnections: boolean
说明:
TODO
public abstract boolean useNativeTransport() @ L1370
- 方法名:useNativeTransport
- 源码定位:L1370
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public boolean allowFlight() @ L1372
- 方法名:allowFlight
- 源码定位:L1372
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public String getMotd() @ L1376
- 方法名:getMotd
- 源码定位:L1376
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public void setMotd(String motd) @ L1381
- 方法名:setMotd
- 源码定位:L1381
- 返回类型:void
- 修饰符:public
参数:
- motd: String
说明:
TODO
public boolean isStopped() @ L1385
- 方法名:isStopped
- 源码定位:L1385
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public PlayerList getPlayerList() @ L1389
- 方法名:getPlayerList
- 源码定位:L1389
- 返回类型:PlayerList
- 修饰符:public
参数:
- 无
说明:
TODO
public void setPlayerList(PlayerList players) @ L1393
- 方法名:setPlayerList
- 源码定位:L1393
- 返回类型:void
- 修饰符:public
参数:
- players: PlayerList
说明:
TODO
public abstract boolean isPublished() @ L1397
- 方法名:isPublished
- 源码定位:L1397
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public void setDefaultGameType(GameType gameType) @ L1399
- 方法名:setDefaultGameType
- 源码定位:L1399
- 返回类型:void
- 修饰符:public
参数:
- gameType: GameType
说明:
TODO
public int enforceGameTypeForPlayers(GameType gameType) @ L1403
- 方法名:enforceGameTypeForPlayers
- 源码定位:L1403
- 返回类型:int
- 修饰符:public
参数:
- gameType: GameType
说明:
TODO
public ServerConnectionListener getConnection() @ L1419
- 方法名:getConnection
- 源码定位:L1419
- 返回类型:ServerConnectionListener
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isReady() @ L1423
- 方法名:isReady
- 源码定位:L1423
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean publishServer(GameType gameMode, boolean allowCommands, int port) @ L1427
- 方法名:publishServer
- 源码定位:L1427
- 返回类型:boolean
- 修饰符:public
参数:
- gameMode: GameType
- allowCommands: boolean
- port: int
说明:
TODO
public int getTickCount() @ L1431
- 方法名:getTickCount
- 源码定位:L1431
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isUnderSpawnProtection(ServerLevel level, BlockPos pos, Player player) @ L1435
- 方法名:isUnderSpawnProtection
- 源码定位:L1435
- 返回类型:boolean
- 修饰符:public
参数:
- level: ServerLevel
- pos: BlockPos
- player: Player
说明:
TODO
public boolean repliesToStatus() @ L1439
- 方法名:repliesToStatus
- 源码定位:L1439
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean hidesOnlinePlayers() @ L1443
- 方法名:hidesOnlinePlayers
- 源码定位:L1443
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public Proxy getProxy() @ L1447
- 方法名:getProxy
- 源码定位:L1447
- 返回类型:Proxy
- 修饰符:public
参数:
- 无
说明:
TODO
public int playerIdleTimeout() @ L1451
- 方法名:playerIdleTimeout
- 源码定位:L1451
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void setPlayerIdleTimeout(int playerIdleTimeout) @ L1455
- 方法名:setPlayerIdleTimeout
- 源码定位:L1455
- 返回类型:void
- 修饰符:public
参数:
- playerIdleTimeout: int
说明:
TODO
public Services services() @ L1459
- 方法名:services
- 源码定位:L1459
- 返回类型:Services
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerStatus getStatus() @ L1463
- 方法名:getStatus
- 源码定位:L1463
- 返回类型:ServerStatus
- 修饰符:public
参数:
- 无
说明:
TODO
public void invalidateStatus() @ L1467
- 方法名:invalidateStatus
- 源码定位:L1467
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public int getAbsoluteMaxWorldSize() @ L1471
- 方法名:getAbsoluteMaxWorldSize
- 源码定位:L1471
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean scheduleExecutables() @ L1475
- 方法名:scheduleExecutables
- 源码定位:L1475
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void executeIfPossible(Runnable command) @ L1480
- 方法名:executeIfPossible
- 源码定位:L1480
- 返回类型:void
- 修饰符:public
参数:
- command: Runnable
说明:
TODO
public Thread getRunningThread() @ L1489
- 方法名:getRunningThread
- 源码定位:L1489
- 返回类型:Thread
- 修饰符:public
参数:
- 无
说明:
TODO
public int getCompressionThreshold() @ L1494
- 方法名:getCompressionThreshold
- 源码定位:L1494
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean enforceSecureProfile() @ L1498
- 方法名:enforceSecureProfile
- 源码定位:L1498
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public long getNextTickTime() @ L1502
- 方法名:getNextTickTime
- 源码定位:L1502
- 返回类型:long
- 修饰符:public
参数:
- 无
说明:
TODO
public DataFixer getFixerUpper() @ L1506
- 方法名:getFixerUpper
- 源码定位:L1506
- 返回类型:DataFixer
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerAdvancementManager getAdvancements() @ L1510
- 方法名:getAdvancements
- 源码定位:L1510
- 返回类型:ServerAdvancementManager
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerFunctionManager getFunctions() @ L1514
- 方法名:getFunctions
- 源码定位:L1514
- 返回类型:ServerFunctionManager
- 修饰符:public
参数:
- 无
说明:
TODO
public CompletableFuture<Void> reloadResources(Collection<String> packsToEnable) @ L1518
- 方法名:reloadResources
- 源码定位:L1518
- 返回类型:CompletableFuture
- 修饰符:public
参数:
- packsToEnable: Collection
说明:
TODO
public static WorldDataConfiguration configurePackRepository(PackRepository packRepository, WorldDataConfiguration initialDataConfig, boolean initMode, boolean safeMode) @ L1570
- 方法名:configurePackRepository
- 源码定位:L1570
- 返回类型:WorldDataConfiguration
- 修饰符:public static
参数:
- packRepository: PackRepository
- initialDataConfig: WorldDataConfiguration
- initMode: boolean
- safeMode: boolean
说明:
TODO
private static WorldDataConfiguration configureRepositoryWithSelection(PackRepository packRepository, Collection<String> selected, FeatureFlagSet forcedFeatures, boolean disableInactive) @ L1628
- 方法名:configureRepositoryWithSelection
- 源码定位:L1628
- 返回类型:WorldDataConfiguration
- 修饰符:private static
参数:
- packRepository: PackRepository
- selected: Collection
- forcedFeatures: FeatureFlagSet
- disableInactive: boolean
说明:
TODO
private static void enableForcedFeaturePacks(PackRepository packRepository, FeatureFlagSet forcedFeatures) @ L1638
- 方法名:enableForcedFeaturePacks
- 源码定位:L1638
- 返回类型:void
- 修饰符:private static
参数:
- packRepository: PackRepository
- forcedFeatures: FeatureFlagSet
说明:
TODO
private static DataPackConfig getSelectedPacks(PackRepository packRepository, boolean disableInactive) @ L1667
- 方法名:getSelectedPacks
- 源码定位:L1667
- 返回类型:DataPackConfig
- 修饰符:private static
参数:
- packRepository: PackRepository
- disableInactive: boolean
说明:
TODO
public void kickUnlistedPlayers() @ L1674
- 方法名:kickUnlistedPlayers
- 源码定位:L1674
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public PackRepository getPackRepository() @ L1687
- 方法名:getPackRepository
- 源码定位:L1687
- 返回类型:PackRepository
- 修饰符:public
参数:
- 无
说明:
TODO
public Commands getCommands() @ L1691
- 方法名:getCommands
- 源码定位:L1691
- 返回类型:Commands
- 修饰符:public
参数:
- 无
说明:
TODO
public CommandSourceStack createCommandSourceStack() @ L1695
- 方法名:createCommandSourceStack
- 源码定位:L1695
- 返回类型:CommandSourceStack
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerLevel findRespawnDimension() @ L1710
- 方法名:findRespawnDimension
- 源码定位:L1710
- 返回类型:ServerLevel
- 修饰符:public
参数:
- 无
说明:
TODO
public void setRespawnData(LevelData.RespawnData respawnData) @ L1717
- 方法名:setRespawnData
- 源码定位:L1717
- 返回类型:void
- 修饰符:public
参数:
- respawnData: LevelData.RespawnData
说明:
TODO
public LevelData.RespawnData getRespawnData() @ L1727
- 方法名:getRespawnData
- 源码定位:L1727
- 返回类型:LevelData.RespawnData
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean acceptsSuccess() @ L1731
- 方法名:acceptsSuccess
- 源码定位:L1731
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean acceptsFailure() @ L1736
- 方法名:acceptsFailure
- 源码定位:L1736
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public abstract boolean shouldInformAdmins() @ L1741
- 方法名:shouldInformAdmins
- 源码定位:L1741
- 返回类型:boolean
- 修饰符:public abstract
参数:
- 无
说明:
TODO
public WorldGenSettings getWorldGenSettings() @ L1744
- 方法名:getWorldGenSettings
- 源码定位:L1744
- 返回类型:WorldGenSettings
- 修饰符:public
参数:
- 无
说明:
TODO
public RecipeManager getRecipeManager() @ L1748
- 方法名:getRecipeManager
- 源码定位:L1748
- 返回类型:RecipeManager
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerScoreboard getScoreboard() @ L1752
- 方法名:getScoreboard
- 源码定位:L1752
- 返回类型:ServerScoreboard
- 修饰符:public
参数:
- 无
说明:
TODO
public CommandStorage getCommandStorage() @ L1756
- 方法名:getCommandStorage
- 源码定位:L1756
- 返回类型:CommandStorage
- 修饰符:public
参数:
- 无
说明:
TODO
public Stopwatches getStopwatches() @ L1764
- 方法名:getStopwatches
- 源码定位:L1764
- 返回类型:Stopwatches
- 修饰符:public
参数:
- 无
说明:
TODO
public CustomBossEvents getCustomBossEvents() @ L1772
- 方法名:getCustomBossEvents
- 源码定位:L1772
- 返回类型:CustomBossEvents
- 修饰符:public
参数:
- 无
说明:
TODO
public RandomSource getRandomSequence(Identifier key) @ L1776
- 方法名:getRandomSequence
- 源码定位:L1776
- 返回类型:RandomSource
- 修饰符:public
参数:
- key: Identifier
说明:
TODO
public RandomSequences getRandomSequences() @ L1780
- 方法名:getRandomSequences
- 源码定位:L1780
- 返回类型:RandomSequences
- 修饰符:public
参数:
- 无
说明:
TODO
public void setWeatherParameters(int clearTime, int rainTime, boolean raining, boolean thundering) @ L1784
- 方法名:setWeatherParameters
- 源码定位:L1784
- 返回类型:void
- 修饰符:public
参数:
- clearTime: int
- rainTime: int
- raining: boolean
- thundering: boolean
说明:
TODO
public WeatherData getWeatherData() @ L1793
- 方法名:getWeatherData
- 源码定位:L1793
- 返回类型:WeatherData
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isEnforceWhitelist() @ L1797
- 方法名:isEnforceWhitelist
- 源码定位:L1797
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void setEnforceWhitelist(boolean enforceWhitelist) @ L1801
- 方法名:setEnforceWhitelist
- 源码定位:L1801
- 返回类型:void
- 修饰符:public
参数:
- enforceWhitelist: boolean
说明:
TODO
public boolean isUsingWhitelist() @ L1805
- 方法名:isUsingWhitelist
- 源码定位:L1805
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void setUsingWhitelist(boolean usingWhitelist) @ L1809
- 方法名:setUsingWhitelist
- 源码定位:L1809
- 返回类型:void
- 修饰符:public
参数:
- usingWhitelist: boolean
说明:
TODO
public float getCurrentSmoothedTickTime() @ L1813
- 方法名:getCurrentSmoothedTickTime
- 源码定位:L1813
- 返回类型:float
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerTickRateManager tickRateManager() @ L1817
- 方法名:tickRateManager
- 源码定位:L1817
- 返回类型:ServerTickRateManager
- 修饰符:public
参数:
- 无
说明:
TODO
public long getAverageTickTimeNanos() @ L1821
- 方法名:getAverageTickTimeNanos
- 源码定位:L1821
- 返回类型:long
- 修饰符:public
参数:
- 无
说明:
TODO
public long[] getTickTimesNanos() @ L1825
- 方法名:getTickTimesNanos
- 源码定位:L1825
- 返回类型:long[]
- 修饰符:public
参数:
- 无
说明:
TODO
public LevelBasedPermissionSet getProfilePermissions(NameAndId nameAndId) @ L1829
- 方法名:getProfilePermissions
- 源码定位:L1829
- 返回类型:LevelBasedPermissionSet
- 修饰符:public
参数:
- nameAndId: NameAndId
说明:
TODO
public abstract boolean isSingleplayerOwner(NameAndId nameAndId) @ L1846
- 方法名:isSingleplayerOwner
- 源码定位:L1846
- 返回类型:boolean
- 修饰符:public abstract
参数:
- nameAndId: NameAndId
说明:
TODO
public void dumpServerProperties(Path path) @ L1848
- 方法名:dumpServerProperties
- 源码定位:L1848
- 返回类型:void
- 修饰符:public
参数:
- path: Path
说明:
TODO
private void saveDebugReport(Path output) @ L1851
- 方法名:saveDebugReport
- 源码定位:L1851
- 返回类型:void
- 修饰符:private
参数:
- output: Path
说明:
TODO
private void dumpMiscStats(Path path) @ L1873
- 方法名:dumpMiscStats
- 源码定位:L1873
- 返回类型:void
- 修饰符:private
参数:
- path: Path
说明:
TODO
private void dumpGameRules(Path path) @ L1882
- 方法名:dumpGameRules
- 源码定位:L1882
- 返回类型:void
- 修饰符:private
参数:
- path: Path
说明:
TODO
private void dumpClasspath(Path path) @ L1903
- 方法名:dumpClasspath
- 源码定位:L1903
- 返回类型:void
- 修饰符:private
参数:
- path: Path
说明:
TODO
private void dumpThreads(Path path) @ L1915
- 方法名:dumpThreads
- 源码定位:L1915
- 返回类型:void
- 修饰符:private
参数:
- path: Path
说明:
TODO
private void dumpNativeModules(Path path) @ L1928
- 方法名:dumpNativeModules
- 源码定位:L1928
- 返回类型:void
- 修饰符:private
参数:
- path: Path
说明:
TODO
private ProfilerFiller createProfiler() @ L1947
- 方法名:createProfiler
- 源码定位:L1947
- 返回类型:ProfilerFiller
- 修饰符:private
参数:
- 无
说明:
TODO
protected void endMetricsRecordingTick() @ L1967
- 方法名:endMetricsRecordingTick
- 源码定位:L1967
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public boolean isRecordingMetrics() @ L1971
- 方法名:isRecordingMetrics
- 源码定位:L1971
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void startRecordingMetrics(Consumer<ProfileResults> onStopped, Consumer<Path> onFinished) @ L1975
- 方法名:startRecordingMetrics
- 源码定位:L1975
- 返回类型:void
- 修饰符:public
参数:
- onStopped: Consumer
- onFinished: Consumer
说明:
TODO
public void stopRecordingMetrics() @ L1984
- 方法名:stopRecordingMetrics
- 源码定位:L1984
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void finishRecordingMetrics() @ L1988
- 方法名:finishRecordingMetrics
- 源码定位:L1988
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void cancelRecordingMetrics() @ L1992
- 方法名:cancelRecordingMetrics
- 源码定位:L1992
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public Path getWorldPath(LevelResource resource) @ L1996
- 方法名:getWorldPath
- 源码定位:L1996
- 返回类型:Path
- 修饰符:public
参数:
- resource: LevelResource
说明:
TODO
public boolean forceSynchronousWrites() @ L2000
- 方法名:forceSynchronousWrites
- 源码定位:L2000
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public StructureTemplateManager getStructureManager() @ L2004
- 方法名:getStructureManager
- 源码定位:L2004
- 返回类型:StructureTemplateManager
- 修饰符:public
参数:
- 无
说明:
TODO
public WorldData getWorldData() @ L2008
- 方法名:getWorldData
- 源码定位:L2008
- 返回类型:WorldData
- 修饰符:public
参数:
- 无
说明:
TODO
public RegistryAccess.Frozen registryAccess() @ L2012
- 方法名:registryAccess
- 源码定位:L2012
- 返回类型:RegistryAccess.Frozen
- 修饰符:public
参数:
- 无
说明:
TODO
public LayeredRegistryAccess<RegistryLayer> registries() @ L2016
- 方法名:registries
- 源码定位:L2016
- 返回类型:LayeredRegistryAccess
- 修饰符:public
参数:
- 无
说明:
TODO
public ReloadableServerRegistries.Holder reloadableRegistries() @ L2020
- 方法名:reloadableRegistries
- 源码定位:L2020
- 返回类型:ReloadableServerRegistries.Holder
- 修饰符:public
参数:
- 无
说明:
TODO
public TextFilter createTextFilterForPlayer(ServerPlayer player) @ L2024
- 方法名:createTextFilterForPlayer
- 源码定位:L2024
- 返回类型:TextFilter
- 修饰符:public
参数:
- player: ServerPlayer
说明:
TODO
public ServerPlayerGameMode createGameModeForPlayer(ServerPlayer player) @ L2028
- 方法名:createGameModeForPlayer
- 源码定位:L2028
- 返回类型:ServerPlayerGameMode
- 修饰符:public
参数:
- player: ServerPlayer
说明:
TODO
public GameType getForcedGameType() @ L2032
- 方法名:getForcedGameType
- 源码定位:L2032
- 返回类型:GameType
- 修饰符:public
参数:
- 无
说明:
TODO
public ResourceManager getResourceManager() @ L2036
- 方法名:getResourceManager
- 源码定位:L2036
- 返回类型:ResourceManager
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isCurrentlySaving() @ L2040
- 方法名:isCurrentlySaving
- 源码定位:L2040
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isTimeProfilerRunning() @ L2044
- 方法名:isTimeProfilerRunning
- 源码定位:L2044
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void startTimeProfiler() @ L2048
- 方法名:startTimeProfiler
- 源码定位:L2048
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public ProfileResults stopTimeProfiler() @ L2052
- 方法名:stopTimeProfiler
- 源码定位:L2052
- 返回类型:ProfileResults
- 修饰符:public
参数:
- 无
说明:
TODO
public int getMaxChainedNeighborUpdates() @ L2062
- 方法名:getMaxChainedNeighborUpdates
- 源码定位:L2062
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void logChatMessage(Component message, ChatType.Bound chatType, String tag) @ L2066
- 方法名:logChatMessage
- 源码定位:L2066
- 返回类型:void
- 修饰符:public
参数:
- message: Component
- chatType: ChatType.Bound
- tag: String
说明:
TODO
public ChatDecorator getChatDecorator() @ L2075
- 方法名:getChatDecorator
- 源码定位:L2075
- 返回类型:ChatDecorator
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean logIPs() @ L2079
- 方法名:logIPs
- 源码定位:L2079
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void handleCustomClickAction(Identifier id, Optional<Tag> payload) @ L2083
- 方法名:handleCustomClickAction
- 源码定位:L2083
- 返回类型:void
- 修饰符:public
参数:
- id: Identifier
- payload: Optional
说明:
TODO
public LevelLoadListener getLevelLoadListener() @ L2087
- 方法名:getLevelLoadListener
- 源码定位:L2087
- 返回类型:LevelLoadListener
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean setAutoSave(boolean enable) @ L2091
- 方法名:setAutoSave
- 源码定位:L2091
- 返回类型:boolean
- 修饰符:public
参数:
- enable: boolean
说明:
TODO
public boolean isAutoSave() @ L2104
- 方法名:isAutoSave
- 源码定位:L2104
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public <T> void onGameRuleChanged(GameRule<T> rule, T value) @ L2114
- 方法名:onGameRuleChanged
- 源码定位:L2114
- 返回类型:
void - 修饰符:public
参数:
- rule: GameRule
- value: T
说明:
TODO
public GameRules getGlobalGameRules() @ L2144
- 方法名:getGlobalGameRules
- 源码定位:L2144
- 返回类型:GameRules
- 修饰符:public
参数:
- 无
说明:
TODO
public SavedDataStorage getDataStorage() @ L2149
- 方法名:getDataStorage
- 源码定位:L2149
- 返回类型:SavedDataStorage
- 修饰符:public
参数:
- 无
说明:
TODO
public TimerQueue<MinecraftServer> getScheduledEvents() @ L2153
- 方法名:getScheduledEvents
- 源码定位:L2153
- 返回类型:TimerQueue
- 修饰符:public
参数:
- 无
说明:
TODO
public GameRules getGameRules() @ L2157
- 方法名:getGameRules
- 源码定位:L2157
- 返回类型:GameRules
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean acceptsTransfers() @ L2161
- 方法名:acceptsTransfers
- 源码定位:L2161
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
private void storeChunkIoError(CrashReport report, ChunkPos pos, RegionStorageInfo storageInfo) @ L2165
- 方法名:storeChunkIoError
- 源码定位:L2165
- 返回类型:void
- 修饰符:private
参数:
- report: CrashReport
- pos: ChunkPos
- storageInfo: RegionStorageInfo
说明:
TODO
public void reportChunkLoadFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) @ L2192
- 方法名:reportChunkLoadFailure
- 源码定位:L2192
- 返回类型:void
- 修饰符:public
参数:
- throwable: Throwable
- storageInfo: RegionStorageInfo
- pos: ChunkPos
说明:
TODO
public void reportChunkSaveFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) @ L2200
- 方法名:reportChunkSaveFailure
- 源码定位:L2200
- 返回类型:void
- 修饰符:public
参数:
- throwable: Throwable
- storageInfo: RegionStorageInfo
- pos: ChunkPos
说明:
TODO
protected void warnOnLowDiskSpace() @ L2208
- 方法名:warnOnLowDiskSpace
- 源码定位:L2208
- 返回类型:void
- 修饰符:protected
参数:
- 无
说明:
TODO
public void sendLowDiskSpaceWarning() @ L2214
- 方法名:sendLowDiskSpaceWarning
- 源码定位:L2214
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void reportPacketHandlingException(Throwable throwable, PacketType<?> packetType) @ L2218
- 方法名:reportPacketHandlingException
- 源码定位:L2218
- 返回类型:void
- 修饰符:public
参数:
- throwable: Throwable
- packetType: PacketType<?>
说明:
TODO
public PotionBrewing potionBrewing() @ L2222
- 方法名:potionBrewing
- 源码定位:L2222
- 返回类型:PotionBrewing
- 修饰符:public
参数:
- 无
说明:
TODO
public FuelValues fuelValues() @ L2226
- 方法名:fuelValues
- 源码定位:L2226
- 返回类型:FuelValues
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerLinks serverLinks() @ L2230
- 方法名:serverLinks
- 源码定位:L2230
- 返回类型:ServerLinks
- 修饰符:public
参数:
- 无
说明:
TODO
protected int pauseWhenEmptySeconds() @ L2234
- 方法名:pauseWhenEmptySeconds
- 源码定位:L2234
- 返回类型:int
- 修饰符:protected
参数:
- 无
说明:
TODO
public PacketProcessor packetProcessor() @ L2238
- 方法名:packetProcessor
- 源码定位:L2238
- 返回类型:PacketProcessor
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerDebugSubscribers debugSubscribers() @ L2242
- 方法名:debugSubscribers
- 源码定位:L2242
- 返回类型:ServerDebugSubscribers
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements CommandSource, ServerInfo, ChunkIOErrorReporter {
private static final Logger LOGGER = LogUtils.getLogger();
public static final String VANILLA_BRAND = "vanilla";
private static final float AVERAGE_TICK_TIME_SMOOTHING = 0.8F;
private static final int TICK_STATS_SPAN = 100;
private static final long OVERLOADED_THRESHOLD_NANOS = 20L * TimeUtil.NANOSECONDS_PER_SECOND / 20L;
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeUtil.NANOSECONDS_PER_SECOND;
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
private static final long STATUS_EXPIRE_TIME_NANOS = 5L * TimeUtil.NANOSECONDS_PER_SECOND;
private static final long PREPARE_LEVELS_DEFAULT_DELAY_NANOS = 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND;
private static final int MAX_STATUS_PLAYER_SAMPLE = 12;
public static final int SPAWN_POSITION_SEARCH_RADIUS = 5;
private static final int SERVER_ACTIVITY_MONITOR_SECONDS_BETWEEN_NOTIFICATIONS = 30;
private static final Map<String, String> LEGACY_WORLD_NAMES_FOR_REALMS_LOG = Map.of("overworld", "world", "the_nether", "DIM-1", "the_end", "DIM1");
private static final int AUTOSAVE_INTERVAL = 6000;
private static final int MIMINUM_AUTOSAVE_TICKS = 100;
private static final int MAX_TICK_LATENCY = 3;
public static final int ABSOLUTE_MAX_WORLD_SIZE = 29999984;
public static final LevelSettings DEMO_SETTINGS = new LevelSettings(
"Demo World", GameType.SURVIVAL, LevelSettings.DifficultySettings.DEFAULT, false, WorldDataConfiguration.DEFAULT
);
public static final Supplier<GameRules> DEFAULT_GAME_RULES = () -> new GameRules(WorldDataConfiguration.DEFAULT.enabledFeatures());
public static final NameAndId ANONYMOUS_PLAYER_PROFILE = new NameAndId(Util.NIL_UUID, "Anonymous Player");
protected final LevelStorageSource.LevelStorageAccess storageSource;
protected final PlayerDataStorage playerDataStorage;
private final SavedDataStorage savedDataStorage;
private final List<Runnable> tickables = Lists.newArrayList();
private final GameRules gameRules;
private MetricsRecorder metricsRecorder = InactiveMetricsRecorder.INSTANCE;
private Consumer<ProfileResults> onMetricsRecordingStopped = results -> this.stopRecordingMetrics();
private Consumer<Path> onMetricsRecordingFinished = ignored -> {};
private boolean willStartRecordingMetrics;
private MinecraftServer.@Nullable TimeProfiler debugCommandProfiler;
private boolean debugCommandProfilerDelayStart;
private final ServerConnectionListener connection;
private final LevelLoadListener levelLoadListener;
private @Nullable ServerStatus status;
private ServerStatus.@Nullable Favicon statusIcon;
private final RandomSource random = RandomSource.create();
private final DataFixer fixerUpper;
private String localIp;
private int port = -1;
private final LayeredRegistryAccess<RegistryLayer> registries;
private final Map<ResourceKey<Level>, ServerLevel> levels = Maps.newLinkedHashMap();
private PlayerList playerList;
private volatile boolean running = true;
private boolean stopped;
private int tickCount;
private int ticksUntilAutosave = 6000;
protected final Proxy proxy;
private boolean onlineMode;
private boolean preventProxyConnections;
private @Nullable String motd;
private int playerIdleTimeout;
private final long[] tickTimesNanos = new long[100];
private long aggregatedTickTimesNanos = 0L;
private @Nullable KeyPair keyPair;
private @Nullable GameProfile singleplayerProfile;
private boolean isDemo;
private volatile boolean isReady;
private long lastOverloadWarningNanos;
protected final Services services;
private final NotificationManager notificationManager;
private final ServerActivityMonitor serverActivityMonitor;
private long lastServerStatus;
private final Thread serverThread;
private long lastTickNanos = Util.getNanos();
private long taskExecutionStartNanos = Util.getNanos();
private long idleTimeNanos;
private long nextTickTimeNanos = Util.getNanos();
private boolean waitingForNextTick = false;
private long delayedTasksMaxNextTickTimeNanos;
private boolean mayHaveDelayedTasks;
private final PackRepository packRepository;
private final WorldGenSettings worldGenSettings;
private final ServerScoreboard scoreboard = new ServerScoreboard(this);
private @Nullable Stopwatches stopwatches;
private @Nullable CommandStorage commandStorage;
private final CustomBossEvents customBossEvents;
private final RandomSequences randomSequences;
private final WeatherData weatherData;
private final ServerFunctionManager functionManager;
private boolean enforceWhitelist;
private boolean usingWhitelist;
private float smoothedTickTimeMillis;
private final Executor executor;
private @Nullable String serverId;
private MinecraftServer.ReloadableResources resources;
private final StructureTemplateManager structureTemplateManager;
private final ServerTickRateManager tickRateManager;
private final ServerDebugSubscribers debugSubscribers = new ServerDebugSubscribers(this);
protected final WorldData worldData;
private LevelData.RespawnData effectiveRespawnData = LevelData.RespawnData.DEFAULT;
private final PotionBrewing potionBrewing;
private FuelValues fuelValues;
private int emptyTicks;
private volatile boolean isSaving;
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
private final DiscontinuousFrame tickFrame;
private final PacketProcessor packetProcessor;
private final TimerQueue<MinecraftServer> scheduledEvents;
private final ServerClockManager clockManager;
public static <S extends MinecraftServer> S spin(Function<Thread, S> factory) {
AtomicReference<S> serverReference = new AtomicReference<>();
Thread thread = new Thread(() -> serverReference.get().runServer(), "Server thread");
thread.setUncaughtExceptionHandler((t, e) -> LOGGER.error("Uncaught exception in server thread", e));
if (Runtime.getRuntime().availableProcessors() > 4) {
thread.setPriority(8);
}
S server = (S)factory.apply(thread);
serverReference.set(server);
thread.start();
return server;
}
public MinecraftServer(
Thread serverThread,
LevelStorageSource.LevelStorageAccess storageSource,
PackRepository packRepository,
WorldStem worldStem,
Optional<GameRules> gameRules,
Proxy proxy,
DataFixer fixerUpper,
Services services,
LevelLoadListener levelLoadListener,
boolean propagatesCrashes
) {
super("Server", propagatesCrashes);
this.registries = worldStem.registries();
if (!this.registries.compositeAccess().lookupOrThrow(Registries.LEVEL_STEM).containsKey(LevelStem.OVERWORLD)) {
throw new IllegalStateException("Missing Overworld dimension data");
} else {
this.savedDataStorage = new SavedDataStorage(storageSource.getLevelPath(LevelResource.DATA), fixerUpper, this.registries.compositeAccess());
this.worldData = worldStem.worldDataAndGenSettings().data();
this.worldGenSettings = worldStem.worldDataAndGenSettings().genSettings();
this.savedDataStorage.set(WorldGenSettings.TYPE, this.worldGenSettings);
this.proxy = proxy;
this.packRepository = packRepository;
this.resources = new MinecraftServer.ReloadableResources(worldStem.resourceManager(), worldStem.dataPackResources());
this.services = services;
this.connection = new ServerConnectionListener(this);
this.tickRateManager = new ServerTickRateManager(this);
this.levelLoadListener = levelLoadListener;
this.storageSource = storageSource;
this.playerDataStorage = storageSource.createPlayerStorage();
this.randomSequences = this.savedDataStorage.computeIfAbsent(RandomSequences.TYPE);
this.weatherData = this.getDataStorage().computeIfAbsent(WeatherData.TYPE);
this.gameRules = new GameRules(this.worldData.enabledFeatures(), this.savedDataStorage.computeIfAbsent(GameRuleMap.TYPE));
gameRules.ifPresent(g -> this.gameRules.setAll(g, null));
this.fixerUpper = fixerUpper;
this.functionManager = new ServerFunctionManager(this, this.resources.managers.getFunctionLibrary());
HolderGetter<Block> blockLookup = this.registries
.compositeAccess()
.lookupOrThrow(Registries.BLOCK)
.filterFeatures(this.worldData.enabledFeatures());
this.structureTemplateManager = new StructureTemplateManager(worldStem.resourceManager(), storageSource, fixerUpper, blockLookup);
this.serverThread = serverThread;
this.executor = Util.backgroundExecutor();
this.potionBrewing = PotionBrewing.bootstrap(this.worldData.enabledFeatures());
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
this.notificationManager = new NotificationManager();
this.serverActivityMonitor = new ServerActivityMonitor(this.notificationManager, 30);
this.packetProcessor = new PacketProcessor(serverThread);
this.clockManager = this.getDataStorage().computeIfAbsent(ServerClockManager.TYPE);
this.clockManager.init(this);
this.customBossEvents = this.savedDataStorage.computeIfAbsent(CustomBossEvents.TYPE);
this.scheduledEvents = this.savedDataStorage.computeIfAbsent(TimerQueue.TYPE);
}
}
protected abstract boolean initServer() throws IOException;
public ChunkLoadStatusView createChunkLoadStatusView(int radius) {
return new ChunkLoadStatusView() {
private @Nullable ChunkMap chunkMap;
private int centerChunkX;
private int centerChunkZ;
{
Objects.requireNonNull(MinecraftServer.this);
}
@Override
public void moveTo(ResourceKey<Level> dimension, ChunkPos centerChunk) {
ServerLevel level = MinecraftServer.this.getLevel(dimension);
this.chunkMap = level != null ? level.getChunkSource().chunkMap : null;
this.centerChunkX = centerChunk.x();
this.centerChunkZ = centerChunk.z();
}
@Override
public @Nullable ChunkStatus get(int x, int z) {
return this.chunkMap == null
? null
: this.chunkMap.getLatestStatus(ChunkPos.pack(x + this.centerChunkX - radius, z + this.centerChunkZ - radius));
}
@Override
public int radius() {
return radius;
}
};
}
protected void loadLevel() {
boolean startedWorldLoadProfiling = !JvmProfiler.INSTANCE.isRunning()
&& SharedConstants.DEBUG_JFR_PROFILING_ENABLE_LEVEL_LOADING
&& JvmProfiler.INSTANCE.start(Environment.from(this));
ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onWorldLoadedStarted();
this.worldData.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
this.createLevels();
this.forceDifficulty();
this.prepareLevels();
if (profiledDuration != null) {
profiledDuration.finish(true);
}
if (startedWorldLoadProfiling) {
try {
JvmProfiler.INSTANCE.stop();
} catch (Throwable var4) {
LOGGER.warn("Failed to stop JFR profiling", var4);
}
}
}
protected void forceDifficulty() {
}
protected void createLevels() {
ServerLevelData levelData = this.worldData.overworldData();
boolean isDebug = this.worldData.isDebugWorld();
Registry<LevelStem> dimensions = this.registries.compositeAccess().lookupOrThrow(Registries.LEVEL_STEM);
WorldOptions worldOptions = this.worldGenSettings.options();
long seed = worldOptions.seed();
long biomeZoomSeed = BiomeManager.obfuscateSeed(seed);
List<CustomSpawner> overworldCustomSpawners = ImmutableList.of(
new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(this.savedDataStorage)
);
LevelStem overworldData = dimensions.getValue(LevelStem.OVERWORLD);
ServerLevel overworld = new ServerLevel(
this, this.executor, this.storageSource, levelData, Level.OVERWORLD, overworldData, isDebug, biomeZoomSeed, overworldCustomSpawners, true
);
this.levels.put(Level.OVERWORLD, overworld);
this.scoreboard.load(this.savedDataStorage.computeIfAbsent(ScoreboardSaveData.TYPE).getData());
this.commandStorage = new CommandStorage(this.savedDataStorage);
this.stopwatches = this.savedDataStorage.computeIfAbsent(Stopwatches.TYPE);
if (!levelData.isInitialized()) {
try {
setInitialSpawn(overworld, levelData, worldOptions.generateBonusChest(), isDebug, this.levelLoadListener);
levelData.setInitialized(true);
if (isDebug) {
this.setupDebugLevel(this.worldData);
}
} catch (Throwable var20) {
CrashReport report = CrashReport.forThrowable(var20, "Exception initializing level");
try {
overworld.fillReportDetails(report);
} catch (Throwable var19) {
}
throw new ReportedException(report);
}
levelData.setInitialized(true);
}
GlobalPos focusPos = this.selectLevelLoadFocusPos();
this.levelLoadListener.updateFocus(focusPos.dimension(), ChunkPos.containing(focusPos.pos()));
for (Entry<ResourceKey<LevelStem>, LevelStem> entry : dimensions.entrySet()) {
ResourceKey<LevelStem> name = entry.getKey();
ServerLevel level;
if (name != LevelStem.OVERWORLD) {
ResourceKey<Level> dimension = ResourceKey.create(Registries.DIMENSION, name.identifier());
DerivedLevelData derivedLevelData = new DerivedLevelData(this.worldData, levelData);
level = new ServerLevel(
this, this.executor, this.storageSource, derivedLevelData, dimension, entry.getValue(), isDebug, biomeZoomSeed, ImmutableList.of(), false
);
this.levels.put(dimension, level);
} else {
level = overworld;
}
level.getWorldBorder().setAbsoluteMaxSize(this.getAbsoluteMaxWorldSize());
this.getPlayerList().addWorldborderListener(level);
}
}
private static void setInitialSpawn(
ServerLevel level, ServerLevelData levelData, boolean spawnBonusChest, boolean isDebug, LevelLoadListener levelLoadListener
) {
if (SharedConstants.DEBUG_ONLY_GENERATE_HALF_THE_WORLD && SharedConstants.DEBUG_WORLD_RECREATE) {
levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), new BlockPos(0, 64, -100), 0.0F, 0.0F));
} else if (isDebug) {
levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), BlockPos.ZERO.above(80), 0.0F, 0.0F));
} else {
ServerChunkCache chunkSource = level.getChunkSource();
ChunkPos spawnChunk = ChunkPos.containing(chunkSource.randomState().sampler().findSpawnPosition());
levelLoadListener.start(LevelLoadListener.Stage.PREPARE_GLOBAL_SPAWN, 0);
levelLoadListener.updateFocus(level.dimension(), spawnChunk);
int height = chunkSource.getGenerator().getSpawnHeight(level);
if (height < level.getMinY()) {
BlockPos worldPosition = spawnChunk.getWorldPosition();
height = level.getHeight(Heightmap.Types.WORLD_SURFACE, worldPosition.getX() + 8, worldPosition.getZ() + 8);
}
levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), spawnChunk.getWorldPosition().offset(8, height, 8), 0.0F, 0.0F));
int xChunkOffset = 0;
int zChunkOffset = 0;
int dXChunk = 0;
int dZChunk = -1;
for (int i = 0; i < Mth.square(11); i++) {
if (xChunkOffset >= -5 && xChunkOffset <= 5 && zChunkOffset >= -5 && zChunkOffset <= 5) {
BlockPos testedPos = PlayerSpawnFinder.getSpawnPosInChunk(level, new ChunkPos(spawnChunk.x() + xChunkOffset, spawnChunk.z() + zChunkOffset));
if (testedPos != null) {
levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), testedPos, 0.0F, 0.0F));
break;
}
}
if (xChunkOffset == zChunkOffset || xChunkOffset < 0 && xChunkOffset == -zChunkOffset || xChunkOffset > 0 && xChunkOffset == 1 - zChunkOffset) {
int olddx = dXChunk;
dXChunk = -dZChunk;
dZChunk = olddx;
}
xChunkOffset += dXChunk;
zChunkOffset += dZChunk;
}
if (spawnBonusChest) {
level.registryAccess()
.lookup(Registries.CONFIGURED_FEATURE)
.flatMap(registry -> registry.get(MiscOverworldFeatures.BONUS_CHEST))
.ifPresent(feature -> feature.value().place(level, chunkSource.getGenerator(), level.getRandom(), levelData.getRespawnData().pos()));
}
levelLoadListener.finish(LevelLoadListener.Stage.PREPARE_GLOBAL_SPAWN);
}
}
private void setupDebugLevel(WorldData worldData) {
worldData.setDifficulty(Difficulty.PEACEFUL);
worldData.setDifficultyLocked(true);
ServerLevelData levelData = worldData.overworldData();
this.getGameRules().set(GameRules.ADVANCE_WEATHER, false, this);
this.clockManager.moveToTimeMarker(this.registryAccess().getOrThrow(WorldClocks.OVERWORLD), ClockTimeMarkers.NOON);
levelData.setGameType(GameType.SPECTATOR);
}
private void prepareLevels() {
ChunkLoadCounter chunkLoadCounter = new ChunkLoadCounter();
for (ServerLevel level : this.levels.values()) {
chunkLoadCounter.track(level, () -> {
TicketStorage savedTickets = level.getDataStorage().get(TicketStorage.TYPE);
if (savedTickets != null) {
savedTickets.activateAllDeactivatedTickets();
}
});
}
this.levelLoadListener.start(LevelLoadListener.Stage.LOAD_INITIAL_CHUNKS, chunkLoadCounter.totalChunks());
do {
this.levelLoadListener.update(LevelLoadListener.Stage.LOAD_INITIAL_CHUNKS, chunkLoadCounter.readyChunks(), chunkLoadCounter.totalChunks());
this.nextTickTimeNanos = Util.getNanos() + PREPARE_LEVELS_DEFAULT_DELAY_NANOS;
this.waitUntilNextTick();
} while (chunkLoadCounter.pendingChunks() > 0);
this.levelLoadListener.finish(LevelLoadListener.Stage.LOAD_INITIAL_CHUNKS);
this.updateMobSpawningFlags();
this.updateEffectiveRespawnData();
}
protected GlobalPos selectLevelLoadFocusPos() {
return this.worldData.overworldData().getRespawnData().globalPos();
}
public GameType getDefaultGameType() {
return this.worldData.getGameType();
}
public boolean isHardcore() {
return this.worldData.isHardcore();
}
public abstract LevelBasedPermissionSet operatorUserPermissions();
public abstract PermissionSet getFunctionCompilationPermissions();
public abstract boolean shouldRconBroadcast();
public boolean saveAllChunks(boolean silent, boolean flush, boolean force) {
this.scoreboard.storeToSaveDataIfDirty(this.getDataStorage().computeIfAbsent(ScoreboardSaveData.TYPE));
boolean result = false;
for (ServerLevel level : this.getAllLevels()) {
if (!silent) {
LOGGER.info("Saving chunks for level '{}'/{}", level, level.dimension().identifier());
}
level.save(null, flush, SharedConstants.DEBUG_DONT_SAVE_WORLD || level.noSave && !force);
result = true;
}
GameProfile singleplayerProfile = this.getSingleplayerProfile();
this.storageSource.saveDataTag(this.worldData, singleplayerProfile == null ? null : singleplayerProfile.id());
if (flush) {
this.savedDataStorage.saveAndJoin();
} else {
this.savedDataStorage.scheduleSave();
}
if (flush) {
for (ServerLevel level : this.getAllLevels()) {
String storageName = level.getChunkSource().chunkMap.getStorageName();
LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", LEGACY_WORLD_NAMES_FOR_REALMS_LOG.getOrDefault(storageName, storageName));
}
LOGGER.info("ThreadedAnvilChunkStorage: All dimensions are saved");
}
return result;
}
public boolean saveEverything(boolean silent, boolean flush, boolean force) {
boolean var5;
try {
this.isSaving = true;
this.getPlayerList().saveAll();
boolean result = this.saveAllChunks(silent, flush, force);
this.warnOnLowDiskSpace();
var5 = result;
} finally {
this.isSaving = false;
}
return var5;
}
@Override
public void close() {
this.stopServer();
}
protected void stopServer() {
this.packetProcessor.close();
if (this.metricsRecorder.isRecording()) {
this.cancelRecordingMetrics();
}
LOGGER.info("Stopping server");
this.getConnection().stop();
this.isSaving = true;
if (this.playerList != null) {
LOGGER.info("Saving players");
this.playerList.saveAll();
this.playerList.removeAll();
}
LOGGER.info("Saving worlds");
for (ServerLevel level : this.getAllLevels()) {
if (level != null) {
level.noSave = false;
}
}
while (this.levels.values().stream().anyMatch(l -> l.getChunkSource().chunkMap.hasWork())) {
this.nextTickTimeNanos = Util.getNanos() + TimeUtil.NANOSECONDS_PER_MILLISECOND;
for (ServerLevel levelx : this.getAllLevels()) {
levelx.getChunkSource().deactivateTicketsOnClosing();
levelx.getChunkSource().tick(() -> true, false);
}
this.waitUntilNextTick();
}
this.saveAllChunks(false, true, false);
for (ServerLevel levelx : this.getAllLevels()) {
if (levelx != null) {
try {
levelx.close();
} catch (IOException var5) {
LOGGER.error("Exception closing the level", (Throwable)var5);
}
}
}
this.isSaving = false;
this.savedDataStorage.close();
this.resources.close();
try {
this.storageSource.close();
} catch (IOException var4) {
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4);
}
}
public String getLocalIp() {
return this.localIp;
}
public void setLocalIp(String ip) {
this.localIp = ip;
}
public boolean isRunning() {
return this.running;
}
public void halt(boolean wait) {
this.running = false;
if (wait) {
try {
this.serverThread.join();
} catch (InterruptedException var3) {
LOGGER.error("Error while shutting down", (Throwable)var3);
}
}
}
protected void runServer() {
try {
if (!this.initServer()) {
throw new IllegalStateException("Failed to initialize server");
}
this.nextTickTimeNanos = Util.getNanos();
this.statusIcon = this.loadStatusIcon().orElse(null);
this.status = this.buildServerStatus();
while (this.running) {
long thisTickNanos;
if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) {
thisTickNanos = 0L;
this.nextTickTimeNanos = Util.getNanos();
this.lastOverloadWarningNanos = this.nextTickTimeNanos;
} else {
thisTickNanos = this.tickRateManager.nanosecondsPerTick();
long behindTimeNanos = Util.getNanos() - this.nextTickTimeNanos;
if (behindTimeNanos > OVERLOADED_THRESHOLD_NANOS + 20L * thisTickNanos
&& this.nextTickTimeNanos - this.lastOverloadWarningNanos >= OVERLOADED_WARNING_INTERVAL_NANOS + 100L * thisTickNanos) {
long ticks = behindTimeNanos / thisTickNanos;
LOGGER.warn(
"Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind",
behindTimeNanos / TimeUtil.NANOSECONDS_PER_MILLISECOND,
ticks
);
this.nextTickTimeNanos += ticks * thisTickNanos;
this.lastOverloadWarningNanos = this.nextTickTimeNanos;
}
}
boolean sprinting = thisTickNanos == 0L;
if (this.debugCommandProfilerDelayStart) {
this.debugCommandProfilerDelayStart = false;
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
}
this.nextTickTimeNanos += thisTickNanos;
try (Profiler.Scope ignored = Profiler.use(this.createProfiler())) {
this.processPacketsAndTick(sprinting);
ProfilerFiller profiler = Profiler.get();
profiler.push("nextTickWait");
this.mayHaveDelayedTasks = true;
this.delayedTasksMaxNextTickTimeNanos = Math.max(Util.getNanos() + thisTickNanos, this.nextTickTimeNanos);
this.startMeasuringTaskExecutionTime();
this.waitUntilNextTick();
this.finishMeasuringTaskExecutionTime();
if (sprinting) {
this.tickRateManager.endTickWork();
}
profiler.pop();
this.logFullTickTime();
} finally {
this.endMetricsRecordingTick();
}
this.isReady = true;
JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis);
}
} catch (Throwable var69) {
LOGGER.error("Encountered an unexpected exception", var69);
CrashReport report = constructOrExtractCrashReport(var69);
this.fillSystemReport(report.getSystemReport());
Path file = this.getServerDirectory().resolve("crash-reports").resolve("crash-" + Util.getFilenameFormattedDateTime() + "-server.txt");
if (report.saveToFile(file, ReportType.CRASH)) {
LOGGER.error("This crash report has been saved to: {}", file.toAbsolutePath());
} else {
LOGGER.error("We were unable to save this crash report to disk.");
}
this.onServerCrash(report);
} finally {
try {
this.stopped = true;
this.stopServer();
} catch (Throwable var64) {
LOGGER.error("Exception stopping the server", var64);
} finally {
this.onServerExit();
}
}
}
private void logFullTickTime() {
long currentTime = Util.getNanos();
if (this.isTickTimeLoggingEnabled()) {
this.getTickTimeLogger().logSample(currentTime - this.lastTickNanos);
}
this.lastTickNanos = currentTime;
}
private void startMeasuringTaskExecutionTime() {
if (this.isTickTimeLoggingEnabled()) {
this.taskExecutionStartNanos = Util.getNanos();
this.idleTimeNanos = 0L;
}
}
private void finishMeasuringTaskExecutionTime() {
if (this.isTickTimeLoggingEnabled()) {
SampleLogger tickTimelogger = this.getTickTimeLogger();
tickTimelogger.logPartialSample(Util.getNanos() - this.taskExecutionStartNanos - this.idleTimeNanos, TpsDebugDimensions.SCHEDULED_TASKS.ordinal());
tickTimelogger.logPartialSample(this.idleTimeNanos, TpsDebugDimensions.IDLE.ordinal());
}
}
private static CrashReport constructOrExtractCrashReport(Throwable t) {
ReportedException firstReported = null;
for (Throwable cause = t; cause != null; cause = cause.getCause()) {
if (cause instanceof ReportedException reportedException) {
firstReported = reportedException;
}
}
CrashReport report;
if (firstReported != null) {
report = firstReported.getReport();
if (firstReported != t) {
report.addCategory("Wrapped in").setDetailError("Wrapping exception", t);
}
} else {
report = new CrashReport("Exception in server tick loop", t);
}
return report;
}
private boolean haveTime() {
return this.runningTask() || Util.getNanos() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTimeNanos : this.nextTickTimeNanos);
}
public NotificationManager notificationManager() {
return this.notificationManager;
}
protected void waitUntilNextTick() {
this.runAllTasks();
this.waitingForNextTick = true;
try {
this.managedBlock(() -> !this.haveTime());
} finally {
this.waitingForNextTick = false;
}
}
@Override
protected void waitForTasks() {
boolean shouldLogTime = this.isTickTimeLoggingEnabled();
long waitStart = shouldLogTime ? Util.getNanos() : 0L;
long waitNanos = this.waitingForNextTick ? this.nextTickTimeNanos - Util.getNanos() : 100000L;
LockSupport.parkNanos("waiting for tasks", waitNanos);
if (shouldLogTime) {
this.idleTimeNanos = this.idleTimeNanos + (Util.getNanos() - waitStart);
}
}
public TickTask wrapRunnable(Runnable runnable) {
return new TickTask(this.tickCount, runnable);
}
protected boolean shouldRun(TickTask task) {
return task.getTick() + 3 < this.tickCount || this.haveTime();
}
@Override
protected boolean pollTask() {
boolean mayHaveMoreTasks = this.pollTaskInternal();
this.mayHaveDelayedTasks = mayHaveMoreTasks;
return mayHaveMoreTasks;
}
private boolean pollTaskInternal() {
if (super.pollTask()) {
return true;
} else {
if (this.tickRateManager.isSprinting() || this.shouldRunAllTasks() || this.haveTime()) {
for (ServerLevel level : this.getAllLevels()) {
if (level.getChunkSource().pollTask()) {
return true;
}
}
}
return false;
}
}
protected void doRunTask(TickTask task) {
Profiler.get().incrementCounter("runTask");
super.doRunTask(task);
}
private Optional<ServerStatus.Favicon> loadStatusIcon() {
Optional<Path> iconPath = Optional.of(this.getFile("server-icon.png"))
.filter(x$0 -> Files.isRegularFile(x$0))
.or(() -> this.storageSource.getIconFile().filter(x$0 -> Files.isRegularFile(x$0)));
return iconPath.flatMap(path -> {
try {
byte[] contents = Files.readAllBytes(path);
PngInfo pngInfo = PngInfo.fromBytes(contents);
if (pngInfo.width() == 64 && pngInfo.height() == 64) {
return Optional.of(new ServerStatus.Favicon(contents));
} else {
throw new IllegalArgumentException("Invalid world icon size [" + pngInfo.width() + ", " + pngInfo.height() + "], but expected [64, 64]");
}
} catch (Exception var3) {
LOGGER.error("Couldn't load server icon", (Throwable)var3);
return Optional.empty();
}
});
}
public Optional<Path> getWorldScreenshotFile() {
return this.storageSource.getIconFile();
}
public Path getServerDirectory() {
return Path.of("");
}
public ServerActivityMonitor getServerActivityMonitor() {
return this.serverActivityMonitor;
}
protected void onServerCrash(CrashReport report) {
}
protected void onServerExit() {
}
public boolean isPaused() {
return false;
}
protected void tickServer(BooleanSupplier haveTime) {
long nano = Util.getNanos();
int emptyTickThreshold = this.pauseWhenEmptySeconds() * 20;
if (emptyTickThreshold > 0) {
if (this.playerList.getPlayerCount() == 0 && !this.tickRateManager.isSprinting()) {
this.emptyTicks++;
} else {
this.emptyTicks = 0;
}
if (this.emptyTicks >= emptyTickThreshold) {
if (this.emptyTicks == emptyTickThreshold) {
LOGGER.info("Server empty for {} seconds, pausing", this.pauseWhenEmptySeconds());
this.autoSave();
}
this.tickConnection();
return;
}
}
this.tickCount++;
this.tickRateManager.tick();
this.tickChildren(haveTime);
if (nano - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) {
this.lastServerStatus = nano;
this.status = this.buildServerStatus();
}
this.ticksUntilAutosave--;
if (this.ticksUntilAutosave <= 0) {
this.autoSave();
}
ProfilerFiller profiler = Profiler.get();
profiler.push("tallying");
long tickTime = Util.getNanos() - nano;
int tickIndex = this.tickCount % 100;
this.aggregatedTickTimesNanos = this.aggregatedTickTimesNanos - this.tickTimesNanos[tickIndex];
this.aggregatedTickTimesNanos += tickTime;
this.tickTimesNanos[tickIndex] = tickTime;
this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)tickTime / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F;
this.logTickMethodTime(nano);
profiler.pop();
}
protected void processPacketsAndTick(boolean sprinting) {
ProfilerFiller profiler = Profiler.get();
profiler.push("tick");
this.tickFrame.start();
profiler.push("scheduledPacketProcessing");
this.packetProcessor.processQueuedPackets();
profiler.pop();
this.tickServer(sprinting ? () -> false : this::haveTime);
this.tickFrame.end();
profiler.pop();
}
private void autoSave() {
this.ticksUntilAutosave = this.computeNextAutosaveInterval();
LOGGER.debug("Autosave started");
ProfilerFiller profiler = Profiler.get();
profiler.push("save");
this.saveEverything(true, false, false);
profiler.pop();
LOGGER.debug("Autosave finished");
}
private void logTickMethodTime(long startTime) {
if (this.isTickTimeLoggingEnabled()) {
this.getTickTimeLogger().logPartialSample(Util.getNanos() - startTime, TpsDebugDimensions.TICK_SERVER_METHOD.ordinal());
}
}
private int computeNextAutosaveInterval() {
float ticksPerSecond;
if (this.tickRateManager.isSprinting()) {
long estimatedTickTimeNanos = this.getAverageTickTimeNanos() + 1L;
ticksPerSecond = (float)TimeUtil.NANOSECONDS_PER_SECOND / (float)estimatedTickTimeNanos;
} else {
ticksPerSecond = this.tickRateManager.tickrate();
}
int intendedIntervalInSeconds = 300;
return Math.max(100, (int)(ticksPerSecond * 300.0F));
}
public void onTickRateChanged() {
int newAutosaveInterval = this.computeNextAutosaveInterval();
if (newAutosaveInterval < this.ticksUntilAutosave) {
this.ticksUntilAutosave = newAutosaveInterval;
}
}
protected abstract SampleLogger getTickTimeLogger();
public abstract boolean isTickTimeLoggingEnabled();
private ServerStatus buildServerStatus() {
ServerStatus.Players players = this.buildPlayerStatus();
return new ServerStatus(
Component.nullToEmpty(this.getMotd()),
Optional.of(players),
Optional.of(ServerStatus.Version.current()),
Optional.ofNullable(this.statusIcon),
this.enforceSecureProfile()
);
}
private ServerStatus.Players buildPlayerStatus() {
List<ServerPlayer> players = this.playerList.getPlayers();
int maxPlayers = this.getMaxPlayers();
if (this.hidesOnlinePlayers()) {
return new ServerStatus.Players(maxPlayers, players.size(), List.of());
} else {
int sampleSize = Math.min(players.size(), 12);
ObjectArrayList<NameAndId> sample = new ObjectArrayList<>(sampleSize);
int offset = Mth.nextInt(this.random, 0, players.size() - sampleSize);
for (int i = 0; i < sampleSize; i++) {
ServerPlayer player = players.get(offset + i);
sample.add(player.allowsListing() ? player.nameAndId() : ANONYMOUS_PLAYER_PROFILE);
}
Util.shuffle(sample, this.random);
return new ServerStatus.Players(maxPlayers, players.size(), sample);
}
}
protected void tickChildren(BooleanSupplier haveTime) {
ProfilerFiller profiler = Profiler.get();
this.getPlayerList().getPlayers().forEach(playerx -> playerx.connection.suspendFlushing());
profiler.push("commandFunctions");
this.getFunctions().tick();
profiler.pop();
if (this.tickRateManager.runsNormally()) {
profiler.push("clocks");
this.clockManager.tick();
profiler.pop();
}
if (this.tickCount % 20 == 0) {
profiler.push("timeSync");
this.forceGameTimeSynchronization();
profiler.pop();
}
profiler.push("levels");
this.updateEffectiveRespawnData();
for (ServerLevel level : this.getAllLevels()) {
profiler.push(() -> level + " " + level.dimension().identifier());
profiler.push("tick");
try {
level.tick(haveTime);
} catch (Throwable var7) {
CrashReport report = CrashReport.forThrowable(var7, "Exception ticking world");
level.fillReportDetails(report);
throw new ReportedException(report);
}
profiler.pop();
profiler.pop();
}
profiler.popPush("connection");
this.tickConnection();
profiler.popPush("players");
this.playerList.tick();
profiler.popPush("debugSubscribers");
this.debugSubscribers.tick();
if (this.tickRateManager.runsNormally()) {
profiler.popPush("gameTests");
GameTestTicker.SINGLETON.tick();
}
profiler.popPush("server gui refresh");
for (Runnable tickable : this.tickables) {
tickable.run();
}
profiler.popPush("send chunks");
for (ServerPlayer player : this.playerList.getPlayers()) {
player.connection.chunkSender.sendNextChunks(player);
player.connection.resumeFlushing();
}
profiler.pop();
this.serverActivityMonitor.tick();
}
private void updateEffectiveRespawnData() {
LevelData.RespawnData respawnData = this.worldData.overworldData().getRespawnData();
ServerLevel respawnLevel = this.findRespawnDimension();
this.effectiveRespawnData = respawnLevel.getWorldBorderAdjustedRespawnData(respawnData);
}
protected void tickConnection() {
this.getConnection().tick();
}
public void forceGameTimeSynchronization() {
ProfilerFiller profiler = Profiler.get();
profiler.push("timeSync");
this.playerList.broadcastAll(new ClientboundSetTimePacket(this.overworld().getGameTime(), Map.of()));
profiler.pop();
}
public void addTickable(Runnable tickable) {
this.tickables.add(tickable);
}
protected void setId(String serverId) {
this.serverId = serverId;
}
public boolean isShutdown() {
return !this.serverThread.isAlive();
}
public Path getFile(String name) {
return this.getServerDirectory().resolve(name);
}
public final ServerLevel overworld() {
return this.levels.get(Level.OVERWORLD);
}
public @Nullable ServerLevel getLevel(ResourceKey<Level> dimension) {
return this.levels.get(dimension);
}
public Set<ResourceKey<Level>> levelKeys() {
return this.levels.keySet();
}
public Iterable<ServerLevel> getAllLevels() {
return this.levels.values();
}
@Override
public String getServerVersion() {
return SharedConstants.getCurrentVersion().name();
}
@Override
public int getPlayerCount() {
return this.playerList.getPlayerCount();
}
public String[] getPlayerNames() {
return this.playerList.getPlayerNamesArray();
}
public String getServerModName() {
return "vanilla";
}
public ServerClockManager clockManager() {
return this.clockManager;
}
public SystemReport fillSystemReport(SystemReport systemReport) {
systemReport.setDetail("Server Running", () -> Boolean.toString(this.running));
if (this.playerList != null) {
systemReport.setDetail(
"Player Count", () -> this.playerList.getPlayerCount() + " / " + this.playerList.getMaxPlayers() + "; " + this.playerList.getPlayers()
);
}
systemReport.setDetail("Active Data Packs", () -> PackRepository.displayPackList(this.packRepository.getSelectedPacks()));
systemReport.setDetail("Available Data Packs", () -> PackRepository.displayPackList(this.packRepository.getAvailablePacks()));
systemReport.setDetail(
"Enabled Feature Flags",
() -> FeatureFlags.REGISTRY.toNames(this.worldData.enabledFeatures()).stream().map(Identifier::toString).collect(Collectors.joining(", "))
);
systemReport.setDetail("World Generation", () -> this.worldData.worldGenSettingsLifecycle().toString());
systemReport.setDetail("World Seed", () -> String.valueOf(this.worldGenSettings.options().seed()));
systemReport.setDetail("Suppressed Exceptions", this.suppressedExceptions::dump);
if (this.serverId != null) {
systemReport.setDetail("Server Id", () -> this.serverId);
}
return this.fillServerSystemReport(systemReport);
}
public abstract SystemReport fillServerSystemReport(final SystemReport systemReport);
public ModCheck getModdedStatus() {
return ModCheck.identify("vanilla", this::getServerModName, "Server", MinecraftServer.class);
}
@Override
public void sendSystemMessage(Component message) {
LOGGER.info(message.getString());
}
public KeyPair getKeyPair() {
return Objects.requireNonNull(this.keyPair);
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
public @Nullable GameProfile getSingleplayerProfile() {
return this.singleplayerProfile;
}
public void setSingleplayerProfile(@Nullable GameProfile singleplayerProfile) {
this.singleplayerProfile = singleplayerProfile;
}
public boolean isSingleplayer() {
return this.singleplayerProfile != null;
}
protected void initializeKeyPair() {
LOGGER.info("Generating keypair");
try {
this.keyPair = Crypt.generateKeyPair();
} catch (CryptException var2) {
throw new IllegalStateException("Failed to generate key pair", var2);
}
}
public void setDifficulty(Difficulty difficulty, boolean ignoreLock) {
if (ignoreLock || !this.worldData.isDifficultyLocked()) {
this.worldData.setDifficulty(this.worldData.isHardcore() ? Difficulty.HARD : difficulty);
this.updateMobSpawningFlags();
this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate);
}
}
public int getScaledTrackingDistance(int baseRange) {
return baseRange;
}
public void updateMobSpawningFlags() {
for (ServerLevel level : this.getAllLevels()) {
level.setSpawnSettings(level.isSpawningMonsters());
}
}
public void setDifficultyLocked(boolean locked) {
this.worldData.setDifficultyLocked(locked);
this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate);
}
private void sendDifficultyUpdate(ServerPlayer player) {
LevelData levelData = player.level().getLevelData();
player.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
}
public boolean isDemo() {
return this.isDemo;
}
public void setDemo(boolean demo) {
this.isDemo = demo;
}
public Map<String, String> getCodeOfConducts() {
return Map.of();
}
public Optional<MinecraftServer.ServerResourcePackInfo> getServerResourcePack() {
return Optional.empty();
}
public boolean isResourcePackRequired() {
return this.getServerResourcePack().filter(MinecraftServer.ServerResourcePackInfo::isRequired).isPresent();
}
public abstract boolean isDedicatedServer();
public abstract int getRateLimitPacketsPerSecond();
public boolean usesAuthentication() {
return this.onlineMode;
}
public void setUsesAuthentication(boolean onlineMode) {
this.onlineMode = onlineMode;
}
public boolean getPreventProxyConnections() {
return this.preventProxyConnections;
}
public void setPreventProxyConnections(boolean preventProxyConnections) {
this.preventProxyConnections = preventProxyConnections;
}
public abstract boolean useNativeTransport();
public boolean allowFlight() {
return true;
}
@Override
public String getMotd() {
return this.motd;
}
public void setMotd(String motd) {
this.motd = motd;
}
public boolean isStopped() {
return this.stopped;
}
public PlayerList getPlayerList() {
return this.playerList;
}
public void setPlayerList(PlayerList players) {
this.playerList = players;
}
public abstract boolean isPublished();
public void setDefaultGameType(GameType gameType) {
this.worldData.setGameType(gameType);
}
public int enforceGameTypeForPlayers(@Nullable GameType gameType) {
if (gameType == null) {
return 0;
} else {
int count = 0;
for (ServerPlayer player : this.getPlayerList().getPlayers()) {
if (player.setGameMode(gameType)) {
count++;
}
}
return count;
}
}
public ServerConnectionListener getConnection() {
return this.connection;
}
public boolean isReady() {
return this.isReady;
}
public boolean publishServer(@Nullable GameType gameMode, boolean allowCommands, int port) {
return false;
}
public int getTickCount() {
return this.tickCount;
}
public boolean isUnderSpawnProtection(ServerLevel level, BlockPos pos, Player player) {
return false;
}
public boolean repliesToStatus() {
return true;
}
public boolean hidesOnlinePlayers() {
return false;
}
public Proxy getProxy() {
return this.proxy;
}
public int playerIdleTimeout() {
return this.playerIdleTimeout;
}
public void setPlayerIdleTimeout(int playerIdleTimeout) {
this.playerIdleTimeout = playerIdleTimeout;
}
public Services services() {
return this.services;
}
public @Nullable ServerStatus getStatus() {
return this.status;
}
public void invalidateStatus() {
this.lastServerStatus = 0L;
}
public int getAbsoluteMaxWorldSize() {
return 29999984;
}
@Override
public boolean scheduleExecutables() {
return super.scheduleExecutables() && !this.isStopped();
}
@Override
public void executeIfPossible(Runnable command) {
if (this.isStopped()) {
throw new RejectedExecutionException("Server already shutting down");
} else {
super.executeIfPossible(command);
}
}
@Override
public Thread getRunningThread() {
return this.serverThread;
}
public int getCompressionThreshold() {
return 256;
}
public boolean enforceSecureProfile() {
return false;
}
public long getNextTickTime() {
return this.nextTickTimeNanos;
}
public DataFixer getFixerUpper() {
return this.fixerUpper;
}
public ServerAdvancementManager getAdvancements() {
return this.resources.managers.getAdvancements();
}
public ServerFunctionManager getFunctions() {
return this.functionManager;
}
public CompletableFuture<Void> reloadResources(Collection<String> packsToEnable) {
CompletableFuture<Void> result = CompletableFuture.<ImmutableList>supplyAsync(
() -> packsToEnable.stream()
.map(this.packRepository::getPack)
.filter(Objects::nonNull)
.map(Pack::open)
.collect(ImmutableList.toImmutableList()),
this
)
.thenCompose(
packsToLoad -> {
CloseableResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, packsToLoad);
List<Registry.PendingTags<?>> postponedTags = TagLoader.loadTagsForExistingRegistries(resources, this.registries.compositeAccess());
return ReloadableServerResources.loadResources(
resources,
this.registries,
postponedTags,
this.worldData.enabledFeatures(),
this.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED,
this.getFunctionCompilationPermissions(),
this.executor,
this
)
.whenComplete((unit, throwable) -> {
if (throwable != null) {
resources.close();
}
})
.thenApply(managers -> new MinecraftServer.ReloadableResources(resources, managers));
}
)
.thenAcceptAsync(newResources -> {
this.resources.close();
this.resources = newResources;
this.packRepository.setSelected(packsToEnable);
WorldDataConfiguration newConfig = new WorldDataConfiguration(getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures());
this.worldData.setDataConfiguration(newConfig);
this.resources.managers.updateComponentsAndStaticRegistryTags();
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
this.getPlayerList().saveAll();
this.getPlayerList().reloadResources();
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
}, this);
if (this.isSameThread()) {
this.managedBlock(result::isDone);
}
return result;
}
public static WorldDataConfiguration configurePackRepository(
PackRepository packRepository, WorldDataConfiguration initialDataConfig, boolean initMode, boolean safeMode
) {
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
FeatureFlagSet forcedFeatures = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
FeatureFlagSet allowedFeatures = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
packRepository.reload();
if (safeMode) {
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), forcedFeatures, false);
} else {
Set<String> selected = Sets.newLinkedHashSet();
for (String id : dataPackConfig.getEnabled()) {
if (packRepository.isAvailable(id)) {
selected.add(id);
} else {
LOGGER.warn("Missing data pack {}", id);
}
}
for (Pack pack : packRepository.getAvailablePacks()) {
String packId = pack.getId();
if (!dataPackConfig.getDisabled().contains(packId)) {
FeatureFlagSet packFeatures = pack.getRequestedFeatures();
boolean isSelected = selected.contains(packId);
if (!isSelected && pack.getPackSource().shouldAddAutomatically()) {
if (packFeatures.isSubsetOf(allowedFeatures)) {
LOGGER.info("Found new data pack {}, loading it automatically", packId);
selected.add(packId);
} else {
LOGGER.info(
"Found new data pack {}, but can't load it due to missing features {}",
packId,
FeatureFlags.printMissingFlags(allowedFeatures, packFeatures)
);
}
}
if (isSelected && !packFeatures.isSubsetOf(allowedFeatures)) {
LOGGER.warn(
"Pack {} requires features {} that are not enabled for this world, disabling pack.",
packId,
FeatureFlags.printMissingFlags(allowedFeatures, packFeatures)
);
selected.remove(packId);
}
}
}
if (selected.isEmpty()) {
LOGGER.info("No datapacks selected, forcing vanilla");
selected.add("vanilla");
}
return configureRepositoryWithSelection(packRepository, selected, forcedFeatures, true);
}
}
private static WorldDataConfiguration configureRepositoryWithSelection(
PackRepository packRepository, Collection<String> selected, FeatureFlagSet forcedFeatures, boolean disableInactive
) {
packRepository.setSelected(selected);
enableForcedFeaturePacks(packRepository, forcedFeatures);
DataPackConfig packConfig = getSelectedPacks(packRepository, disableInactive);
FeatureFlagSet packRequestedFeatures = packRepository.getRequestedFeatureFlags().join(forcedFeatures);
return new WorldDataConfiguration(packConfig, packRequestedFeatures);
}
private static void enableForcedFeaturePacks(PackRepository packRepository, FeatureFlagSet forcedFeatures) {
FeatureFlagSet providedFeatures = packRepository.getRequestedFeatureFlags();
FeatureFlagSet missingFeatures = forcedFeatures.subtract(providedFeatures);
if (!missingFeatures.isEmpty()) {
Set<String> selected = new ObjectArraySet<>(packRepository.getSelectedIds());
for (Pack pack : packRepository.getAvailablePacks()) {
if (missingFeatures.isEmpty()) {
break;
}
if (pack.getPackSource() == PackSource.FEATURE) {
String packId = pack.getId();
FeatureFlagSet packFeatures = pack.getRequestedFeatures();
if (!packFeatures.isEmpty() && packFeatures.intersects(missingFeatures) && packFeatures.isSubsetOf(forcedFeatures)) {
if (!selected.add(packId)) {
throw new IllegalStateException("Tried to force '" + packId + "', but it was already enabled");
}
LOGGER.info("Found feature pack ('{}') for requested feature, forcing to enabled", packId);
missingFeatures = missingFeatures.subtract(packFeatures);
}
}
}
packRepository.setSelected(selected);
}
}
private static DataPackConfig getSelectedPacks(PackRepository packRepository, boolean disableInactive) {
Collection<String> selected = packRepository.getSelectedIds();
List<String> enabled = ImmutableList.copyOf(selected);
List<String> disabled = disableInactive ? packRepository.getAvailableIds().stream().filter(id -> !selected.contains(id)).toList() : List.of();
return new DataPackConfig(enabled, disabled);
}
public void kickUnlistedPlayers() {
if (this.isEnforceWhitelist() && this.isUsingWhitelist()) {
PlayerList playerList = this.getPlayerList();
UserWhiteList whiteList = playerList.getWhiteList();
for (ServerPlayer player : Lists.newArrayList(playerList.getPlayers())) {
if (!whiteList.isWhiteListed(player.nameAndId())) {
player.connection.disconnect(Component.translatable("multiplayer.disconnect.not_whitelisted"));
}
}
}
}
public PackRepository getPackRepository() {
return this.packRepository;
}
public Commands getCommands() {
return this.resources.managers.getCommands();
}
public CommandSourceStack createCommandSourceStack() {
ServerLevel level = this.findRespawnDimension();
return new CommandSourceStack(
this,
Vec3.atLowerCornerOf(this.getRespawnData().pos()),
Vec2.ZERO,
level,
LevelBasedPermissionSet.OWNER,
"Server",
Component.literal("Server"),
this,
null
);
}
public ServerLevel findRespawnDimension() {
LevelData.RespawnData respawnData = this.getWorldData().overworldData().getRespawnData();
ResourceKey<Level> respawnDimension = respawnData.dimension();
ServerLevel respawnLevel = this.getLevel(respawnDimension);
return respawnLevel != null ? respawnLevel : this.overworld();
}
public void setRespawnData(LevelData.RespawnData respawnData) {
ServerLevelData levelData = this.worldData.overworldData();
LevelData.RespawnData oldRespawnData = levelData.getRespawnData();
if (!oldRespawnData.equals(respawnData)) {
levelData.setSpawn(respawnData);
this.getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(respawnData));
this.updateEffectiveRespawnData();
}
}
public LevelData.RespawnData getRespawnData() {
return this.effectiveRespawnData;
}
@Override
public boolean acceptsSuccess() {
return true;
}
@Override
public boolean acceptsFailure() {
return true;
}
@Override
public abstract boolean shouldInformAdmins();
public WorldGenSettings getWorldGenSettings() {
return this.worldGenSettings;
}
public RecipeManager getRecipeManager() {
return this.resources.managers.getRecipeManager();
}
public ServerScoreboard getScoreboard() {
return this.scoreboard;
}
public CommandStorage getCommandStorage() {
if (this.commandStorage == null) {
throw new NullPointerException("Called before server init");
} else {
return this.commandStorage;
}
}
public Stopwatches getStopwatches() {
if (this.stopwatches == null) {
throw new NullPointerException("Called before server init");
} else {
return this.stopwatches;
}
}
public CustomBossEvents getCustomBossEvents() {
return this.customBossEvents;
}
public RandomSource getRandomSequence(Identifier key) {
return this.randomSequences.get(key, this.worldGenSettings.options().seed());
}
public RandomSequences getRandomSequences() {
return this.randomSequences;
}
public void setWeatherParameters(int clearTime, int rainTime, boolean raining, boolean thundering) {
WeatherData weatherData = this.getWeatherData();
weatherData.setClearWeatherTime(clearTime);
weatherData.setRainTime(rainTime);
weatherData.setThunderTime(rainTime);
weatherData.setRaining(raining);
weatherData.setThundering(thundering);
}
public WeatherData getWeatherData() {
return this.weatherData;
}
public boolean isEnforceWhitelist() {
return this.enforceWhitelist;
}
public void setEnforceWhitelist(boolean enforceWhitelist) {
this.enforceWhitelist = enforceWhitelist;
}
public boolean isUsingWhitelist() {
return this.usingWhitelist;
}
public void setUsingWhitelist(boolean usingWhitelist) {
this.usingWhitelist = usingWhitelist;
}
public float getCurrentSmoothedTickTime() {
return this.smoothedTickTimeMillis;
}
public ServerTickRateManager tickRateManager() {
return this.tickRateManager;
}
public long getAverageTickTimeNanos() {
return this.aggregatedTickTimesNanos / Math.min(100, Math.max(this.tickCount, 1));
}
public long[] getTickTimesNanos() {
return this.tickTimesNanos;
}
public LevelBasedPermissionSet getProfilePermissions(NameAndId nameAndId) {
if (this.getPlayerList().isOp(nameAndId)) {
ServerOpListEntry opListEntry = this.getPlayerList().getOps().get(nameAndId);
if (opListEntry != null) {
return opListEntry.permissions();
} else if (this.isSingleplayerOwner(nameAndId)) {
return LevelBasedPermissionSet.OWNER;
} else if (this.isSingleplayer()) {
return this.getPlayerList().isAllowCommandsForAllPlayers() ? LevelBasedPermissionSet.OWNER : LevelBasedPermissionSet.ALL;
} else {
return this.operatorUserPermissions();
}
} else {
return LevelBasedPermissionSet.ALL;
}
}
public abstract boolean isSingleplayerOwner(NameAndId nameAndId);
public void dumpServerProperties(Path path) throws IOException {
}
private void saveDebugReport(Path output) {
Path levelsDir = output.resolve("levels");
try {
for (Entry<ResourceKey<Level>, ServerLevel> level : this.levels.entrySet()) {
Identifier levelId = level.getKey().identifier();
Path levelPath = levelId.resolveAgainst(levelsDir);
Files.createDirectories(levelPath);
level.getValue().saveDebugReport(levelPath);
}
this.dumpGameRules(output.resolve("gamerules.txt"));
this.dumpClasspath(output.resolve("classpath.txt"));
this.dumpMiscStats(output.resolve("stats.txt"));
this.dumpThreads(output.resolve("threads.txt"));
this.dumpServerProperties(output.resolve("server.properties.txt"));
this.dumpNativeModules(output.resolve("modules.txt"));
} catch (IOException var7) {
LOGGER.warn("Failed to save debug report", (Throwable)var7);
}
}
private void dumpMiscStats(Path path) throws IOException {
try (Writer output = Files.newBufferedWriter(path)) {
output.write(String.format(Locale.ROOT, "pending_tasks: %d\n", this.getPendingTasksCount()));
output.write(String.format(Locale.ROOT, "average_tick_time: %f\n", this.getCurrentSmoothedTickTime()));
output.write(String.format(Locale.ROOT, "tick_times: %s\n", Arrays.toString(this.tickTimesNanos)));
output.write(String.format(Locale.ROOT, "queue: %s\n", Util.backgroundExecutor()));
}
}
private void dumpGameRules(Path path) throws IOException {
try (Writer output = Files.newBufferedWriter(path)) {
final List<String> entries = Lists.newArrayList();
final GameRules gameRules = this.getGameRules();
gameRules.visitGameRuleTypes(new GameRuleTypeVisitor() {
{
Objects.requireNonNull(MinecraftServer.this);
}
@Override
public <T> void visit(GameRule<T> gameRule) {
entries.add(String.format(Locale.ROOT, "%s=%s\n", gameRule.getIdentifier(), gameRules.getAsString(gameRule)));
}
});
for (String entry : entries) {
output.write(entry);
}
}
}
private void dumpClasspath(Path path) throws IOException {
try (Writer output = Files.newBufferedWriter(path)) {
String classpath = System.getProperty("java.class.path");
String separator = File.pathSeparator;
for (String s : Splitter.on(separator).split(classpath)) {
output.write(s);
output.write("\n");
}
}
}
private void dumpThreads(Path path) throws IOException {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
Arrays.sort(threadInfos, Comparator.comparing(ThreadInfo::getThreadName));
try (Writer output = Files.newBufferedWriter(path)) {
for (ThreadInfo threadInfo : threadInfos) {
output.write(threadInfo.toString());
output.write(10);
}
}
}
private void dumpNativeModules(Path path) throws IOException {
try (Writer output = Files.newBufferedWriter(path)) {
List<NativeModuleLister.NativeModuleInfo> modules;
try {
modules = Lists.newArrayList(NativeModuleLister.listModules());
} catch (Throwable var7) {
LOGGER.warn("Failed to list native modules", var7);
return;
}
modules.sort(Comparator.comparing(modulex -> modulex.name));
for (NativeModuleLister.NativeModuleInfo module : modules) {
output.write(module.toString());
output.write(10);
}
}
}
private ProfilerFiller createProfiler() {
if (this.willStartRecordingMetrics) {
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
new ServerMetricsSamplersProvider(Util.timeSource, this.isDedicatedServer()),
Util.timeSource,
Util.ioPool(),
new MetricsPersister("server"),
this.onMetricsRecordingStopped,
reportPath -> {
this.executeBlocking(() -> this.saveDebugReport(reportPath.resolve("server")));
this.onMetricsRecordingFinished.accept(reportPath);
}
);
this.willStartRecordingMetrics = false;
}
this.metricsRecorder.startTick();
return SingleTickProfiler.decorateFiller(this.metricsRecorder.getProfiler(), SingleTickProfiler.createTickProfiler("Server"));
}
protected void endMetricsRecordingTick() {
this.metricsRecorder.endTick();
}
public boolean isRecordingMetrics() {
return this.metricsRecorder.isRecording();
}
public void startRecordingMetrics(Consumer<ProfileResults> onStopped, Consumer<Path> onFinished) {
this.onMetricsRecordingStopped = report -> {
this.stopRecordingMetrics();
onStopped.accept(report);
};
this.onMetricsRecordingFinished = onFinished;
this.willStartRecordingMetrics = true;
}
public void stopRecordingMetrics() {
this.metricsRecorder = InactiveMetricsRecorder.INSTANCE;
}
public void finishRecordingMetrics() {
this.metricsRecorder.end();
}
public void cancelRecordingMetrics() {
this.metricsRecorder.cancel();
}
public Path getWorldPath(LevelResource resource) {
return this.storageSource.getLevelPath(resource);
}
public boolean forceSynchronousWrites() {
return true;
}
public StructureTemplateManager getStructureManager() {
return this.structureTemplateManager;
}
public WorldData getWorldData() {
return this.worldData;
}
public RegistryAccess.Frozen registryAccess() {
return this.registries.compositeAccess();
}
public LayeredRegistryAccess<RegistryLayer> registries() {
return this.registries;
}
public ReloadableServerRegistries.Holder reloadableRegistries() {
return this.resources.managers.fullRegistries();
}
public TextFilter createTextFilterForPlayer(ServerPlayer player) {
return TextFilter.DUMMY;
}
public ServerPlayerGameMode createGameModeForPlayer(ServerPlayer player) {
return (ServerPlayerGameMode)(this.isDemo() ? new DemoMode(player) : new ServerPlayerGameMode(player));
}
public @Nullable GameType getForcedGameType() {
return null;
}
public ResourceManager getResourceManager() {
return this.resources.resourceManager;
}
public boolean isCurrentlySaving() {
return this.isSaving;
}
public boolean isTimeProfilerRunning() {
return this.debugCommandProfilerDelayStart || this.debugCommandProfiler != null;
}
public void startTimeProfiler() {
this.debugCommandProfilerDelayStart = true;
}
public ProfileResults stopTimeProfiler() {
if (this.debugCommandProfiler == null) {
return EmptyProfileResults.EMPTY;
} else {
ProfileResults results = this.debugCommandProfiler.stop(Util.getNanos(), this.tickCount);
this.debugCommandProfiler = null;
return results;
}
}
public int getMaxChainedNeighborUpdates() {
return 1000000;
}
public void logChatMessage(Component message, ChatType.Bound chatType, @Nullable String tag) {
String decoratedMessage = chatType.decorate(message).getString();
if (tag != null) {
LOGGER.info("[{}] {}", tag, decoratedMessage);
} else {
LOGGER.info("{}", decoratedMessage);
}
}
public ChatDecorator getChatDecorator() {
return ChatDecorator.PLAIN;
}
public boolean logIPs() {
return true;
}
public void handleCustomClickAction(Identifier id, Optional<Tag> payload) {
LOGGER.debug("Received custom click action {} with payload {}", id, payload.orElse(null));
}
public LevelLoadListener getLevelLoadListener() {
return this.levelLoadListener;
}
public boolean setAutoSave(boolean enable) {
boolean success = false;
for (ServerLevel level : this.getAllLevels()) {
if (level != null && level.noSave == enable) {
level.noSave = !enable;
success = true;
}
}
return success;
}
public boolean isAutoSave() {
for (ServerLevel level : this.getAllLevels()) {
if (level != null && !level.noSave) {
return true;
}
}
return false;
}
public <T> void onGameRuleChanged(GameRule<T> rule, T value) {
this.notificationManager().onGameRuleChanged(rule, value);
if (rule == GameRules.REDUCED_DEBUG_INFO) {
byte event = (byte)((Boolean)value ? 22 : 23);
for (ServerPlayer player : this.getPlayerList().getPlayers()) {
player.connection.send(new ClientboundEntityEventPacket(player, event));
}
} else if (rule == GameRules.LIMITED_CRAFTING || rule == GameRules.IMMEDIATE_RESPAWN) {
ClientboundGameEventPacket.Type eventType = rule == GameRules.LIMITED_CRAFTING
? ClientboundGameEventPacket.LIMITED_CRAFTING
: ClientboundGameEventPacket.IMMEDIATE_RESPAWN;
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(eventType, (Boolean)value ? 1.0F : 0.0F);
this.getPlayerList().getPlayers().forEach(playerx -> playerx.connection.send(packet));
} else if (rule == GameRules.LOCATOR_BAR) {
this.getAllLevels().forEach(level -> {
ServerWaypointManager waypointManager = level.getWaypointManager();
if ((Boolean)value) {
level.players().forEach(waypointManager::updatePlayer);
} else {
waypointManager.breakAllConnections();
}
});
} else if (rule == GameRules.SPAWN_MONSTERS) {
this.updateMobSpawningFlags();
} else if (rule == GameRules.ADVANCE_TIME) {
this.getPlayerList().broadcastAll(this.clockManager().createFullSyncPacket());
}
}
@Deprecated
public GameRules getGlobalGameRules() {
return this.overworld().getGameRules();
}
public SavedDataStorage getDataStorage() {
return this.savedDataStorage;
}
public TimerQueue<MinecraftServer> getScheduledEvents() {
return this.scheduledEvents;
}
public GameRules getGameRules() {
return this.gameRules;
}
public boolean acceptsTransfers() {
return false;
}
private void storeChunkIoError(CrashReport report, ChunkPos pos, RegionStorageInfo storageInfo) {
Util.ioPool().execute(() -> {
try {
Path debugDir = this.getFile("debug");
FileUtil.createDirectoriesSafe(debugDir);
String sanitizedLevelName = FileUtil.sanitizeName(storageInfo.level());
Path reportFile = debugDir.resolve("chunk-" + sanitizedLevelName + "-" + Util.getFilenameFormattedDateTime() + "-server.txt");
FileStore fileStore = Files.getFileStore(debugDir);
long remainingSpace = fileStore.getUsableSpace();
if (remainingSpace < 8192L) {
LOGGER.warn("Not storing chunk IO report due to low space on drive {}", fileStore.name());
return;
}
CrashReportCategory category = report.addCategory("Chunk Info");
category.setDetail("Level", storageInfo::level);
category.setDetail("Dimension", () -> storageInfo.dimension().identifier().toString());
category.setDetail("Storage", storageInfo::type);
category.setDetail("Position", pos::toString);
report.saveToFile(reportFile, ReportType.CHUNK_IO_ERROR);
LOGGER.info("Saved details to {}", report.getSaveFile());
} catch (Exception var11) {
LOGGER.warn("Failed to store chunk IO exception", (Throwable)var11);
}
});
}
@Override
public void reportChunkLoadFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) {
LOGGER.error("Failed to load chunk {},{}", pos.x(), pos.z(), throwable);
this.suppressedExceptions.addEntry("chunk/load", throwable);
this.storeChunkIoError(CrashReport.forThrowable(throwable, "Chunk load failure"), pos, storageInfo);
this.warnOnLowDiskSpace();
}
@Override
public void reportChunkSaveFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) {
LOGGER.error("Failed to save chunk {},{}", pos.x(), pos.z(), throwable);
this.suppressedExceptions.addEntry("chunk/save", throwable);
this.storeChunkIoError(CrashReport.forThrowable(throwable, "Chunk save failure"), pos, storageInfo);
this.warnOnLowDiskSpace();
}
protected void warnOnLowDiskSpace() {
if (this.storageSource.checkForLowDiskSpace()) {
this.sendLowDiskSpaceWarning();
}
}
public void sendLowDiskSpaceWarning() {
LOGGER.warn("Low disk space! Might not be able to save the world.");
}
public void reportPacketHandlingException(Throwable throwable, PacketType<?> packetType) {
this.suppressedExceptions.addEntry("packet/" + packetType, throwable);
}
public PotionBrewing potionBrewing() {
return this.potionBrewing;
}
public FuelValues fuelValues() {
return this.fuelValues;
}
public ServerLinks serverLinks() {
return ServerLinks.EMPTY;
}
protected int pauseWhenEmptySeconds() {
return 0;
}
public PacketProcessor packetProcessor() {
return this.packetProcessor;
}
public ServerDebugSubscribers debugSubscribers() {
return this.debugSubscribers;
}
private record ReloadableResources(CloseableResourceManager resourceManager, ReloadableServerResources managers) implements AutoCloseable {
@Override
public void close() {
this.resourceManager.close();
}
}
public record ServerResourcePackInfo(UUID id, String url, String hash, boolean isRequired, @Nullable Component prompt) {
}
private static class TimeProfiler {
private final long startNanos;
private final int startTick;
private TimeProfiler(long startNanos, int startTick) {
this.startNanos = startNanos;
this.startTick = startTick;
}
private ProfileResults stop(long stopNanos, int stopTick) {
return new ProfileResults() {
{
Objects.requireNonNull(TimeProfiler.this);
}
@Override
public List<ResultField> getTimes(String path) {
return Collections.emptyList();
}
@Override
public boolean saveResults(Path file) {
return false;
}
@Override
public long getStartTimeNano() {
return TimeProfiler.this.startNanos;
}
@Override
public int getStartTimeTicks() {
return TimeProfiler.this.startTick;
}
@Override
public long getEndTimeNano() {
return stopNanos;
}
@Override
public int getEndTimeTicks() {
return stopTick;
}
@Override
public String getProfilerResults() {
return "";
}
};
}
}
}引用的其他类
-
- 引用位置:
参数/方法调用/构造调用/返回值 - 关联成员:
CrashReport(), CrashReport.forThrowable()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ReportedException()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SharedConstants.getCurrentVersion()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
System.getProperty()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
CommandSourceStack()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
BlockPos()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
PacketProcessor()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Component.literal(), Component.nullToEmpty(), Component.translatable()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
ClientboundChangeDifficultyPacket
- 引用位置:
构造调用 - 关联成员:
ClientboundChangeDifficultyPacket()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ClientboundEntityEventPacket()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ClientboundGameEventPacket()
- 引用位置:
-
ClientboundSetDefaultSpawnPositionPacket
- 引用位置:
构造调用 - 关联成员:
ClientboundSetDefaultSpawnPositionPacket()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ClientboundSetTimePacket()
- 引用位置:
-
- 引用位置:
字段/方法调用/构造调用/返回值 - 关联成员:
Favicon(), Players(), ServerStatus(), ServerStatus.Favicon(), ServerStatus.Players(), ServerStatus.Version.current()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
ResourceKey.create()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ReloadableServerResources.loadResources()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerFunctionManager()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerScoreboard()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerTickRateManager()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
SuppressedExceptionCollector()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
TickTask()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ChunkLoadCounter()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
DemoMode()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
PlayerSpawnFinder.getSpawnPosInChunk()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
ServerLevel()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
ServerPlayerGameMode()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
ChunkLoadStatusView()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerConnectionListener()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
NotificationManager()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerActivityMonitor()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
PackRepository.displayPackList()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
MultiPackResourceManager()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段/构造调用 - 关联成员:
NameAndId()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
TagLoader.loadTagsForExistingRegistries()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Crypt.generateKeyPair()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FileUtil.createDirectoriesSafe(), FileUtil.sanitizeName()
- 引用位置:
-
- 引用位置:
方法调用/返回值 - 关联成员:
ModCheck.identify()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.nextInt(), Mth.square()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
NativeModuleLister.listModules()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
PngInfo.fromBytes()
- 引用位置:
-
- 引用位置:
字段/方法调用/返回值 - 关联成员:
RandomSource.create()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.backgroundExecutor(), Util.getFilenameFormattedDateTime(), Util.getNanos(), Util.ioPool(), Util.shuffle()
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
ServerDebugSubscribers()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
ProfileResults()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Profiler.get(), Profiler.use()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SingleTickProfiler.createTickProfiler(), SingleTickProfiler.decorateFiller()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Environment.from()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ActiveMetricsRecorder.createStarted()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ServerMetricsSamplersProvider()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
MetricsPersister()
- 引用位置:
-
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
VillageSiege()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
CatSpawner()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
WanderingTraderSpawner()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
FeatureFlagSet.of()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FeatureFlags.printMissingFlags()
- 引用位置:
-
- 引用位置:
字段/方法调用/返回值 - 关联成员:
PotionBrewing.bootstrap()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
ChunkPos(), ChunkPos.containing(), ChunkPos.pack()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
DataPackConfig()
- 引用位置:
-
- 引用位置:
参数/返回值
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
LevelSettings()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
WorldDataConfiguration()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
BiomeManager.obfuscateSeed()
- 引用位置:
-
- 引用位置:
字段/方法调用/返回值 - 关联成员:
FuelValues.vanillaBurnTimes()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameRuleTypeVisitor()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
GameRules()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
PatrolSpawner()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
PhantomSpawner()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
StructureTemplateManager()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
CommandStorage()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
DerivedLevelData()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/返回值 - 关联成员:
LevelData.RespawnData.of()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
SavedDataStorage()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Vec3.atLowerCornerOf()
- 引用位置: