"Client thread@1" prio=5 tid=0x1 nid=NA runnable
java.lang.Thread.State: RUNNABLE
在 org.lwjgl.opengl.WindowsContextImplementation.nSwapBuffers(WindowsContextImplementation.java:-1)
在 org.lwjgl.opengl.WindowsContextImplementation.swapBuffers(WindowsContextImplementation.java:70)
- 锁 <0x411c> (a org.lwjgl.opengl.ContextGL)
在 org.lwjgl.opengl.ContextGL.swapBuffers(ContextGL.java:175)
在 org.lwjgl.opengl.DrawableGL.swapBuffers(DrawableGL.java:90)
在 org.lwjgl.opengl.Display.swapBuffers(Display.java:618)
- 锁 <0x411d> (a java.lang.Object)
在 org.lwjgl.opengl.Display.update(Display.java:646)
在 org.lwjgl.opengl.Display.update(Display.java:628)
在 net.minecraft.client.Minecraft.updateDisplay(Minecraft.java:1295)
在 net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1243)
在 net.minecraft.client.Minecraft.run(Minecraft.java:442)
在 net.minecraft.client.main.Main.main(Main.java:118)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 java.lang.reflect.Method.invoke(Method.java:498)
在 net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
在 net.minecraft.launchwrapper.Launch.main(Launch.java:28)
在 sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在 java.lang.reflect.Method.invoke(Method.java:498)
在 net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
在 GradleStart.main(GradleStart.java:25)
"Server thread@16580" prio=5 tid=0x42 nid=NA runnable
java.lang.Thread.State: RUNNABLE
在 net.minecraft.nbt.NBTTagCompound.writeEntry(NBTTagCompound.java:577)
在 net.minecraft.nbt.NBTTagCompound.write(NBTTagCompound.java:39)
在 net.minecraft.nbt.NBTTagCompound.writeEntry(NBTTagCompound.java:582)
在 net.minecraft.nbt.NBTTagCompound.write(NBTTagCompound.java:39)
在 net.minecraft.nbt.CompressedStreamTools.writeTag(CompressedStreamTools.java:124)
在 net.minecraft.nbt.CompressedStreamTools.write(CompressedStreamTools.java:114)
在 net.minecraft.nbt.CompressedStreamTools.writeCompressed(CompressedStreamTools.java:53)
在 net.minecraft.world.storage.SaveHandler.saveWorldInfoWithPlayer(SaveHandler.java:170)
在 net.minecraft.world.chunk.storage.AnvilSaveHandler.saveWorldInfoWithPlayer(AnvilSaveHandler.java:46)
在 net.minecraft.world.WorldServer.saveLevel(WorldServer.java:1111)
在 net.minecraft.world.WorldServer.saveAllChunks(WorldServer.java:1054)
在 net.minecraft.server.MinecraftServer.saveAllWorlds(MinecraftServer.java:468)
在 net.minecraft.server.integrated.IntegratedServer.saveAllWorlds(IntegratedServer.java:274)
在 net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:766)
在 net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
在 net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592)
在 java.lang.Thread.run(Thread.java:748)
MinecraftServer 里的run
public void run()
{
try
{
if (this.init())
{
net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStarted();
this.currentTime = getCurrentTimeMillis();
long i = 0L;
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.12.2", 340));
this.applyServerIconToResponse(this.statusResponse);
while (this.serverRunning)
{
long k = getCurrentTimeMillis();
long j = k - this.currentTime;
if (j > 2000L && this.currentTime - this.timeOfLastWarning >= 15000L)
{
LOGGER.warn("Can't keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", Long.valueOf(j), Long.valueOf(j / 50L));
j = 2000L;
this.timeOfLastWarning = this.currentTime;
}
if (j < 0L)
{
LOGGER.warn("Time ran backwards! Did the system time change?");
j = 0L;
}
i += j;
this.currentTime = k;
if (this.worlds[0].areAllPlayersAsleep())
{
this.tick();
i = 0L;
}
else
{
while (i > 50L)
{
i -= 50L;
this.tick();
}
}
Thread.sleep(Math.max(1L, 50L - i));
this.serverIsRunning = true;
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopping();
net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
}
else
{
net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
this.finalTick((CrashReport)null);
}
}
catch (net.minecraftforge.fml.common.StartupQuery.AbortedException e)
{
// ignore silently
net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
}
catch (Throwable throwable1)
{
LOGGER.error("Encountered an unexpected exception", throwable1);
CrashReport crashreport = null;
if (throwable1 instanceof ReportedException)
{
crashreport = this.addServerInfoToCrashReport(((ReportedException)throwable1).getCrashReport());
}
else
{
crashreport = this.addServerInfoToCrashReport(new CrashReport("Exception in server tick loop", throwable1));
}
File file1 = new File(new File(this.getDataDirectory(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
if (crashreport.saveToFile(file1))
{
LOGGER.error("This crash report has been saved to: {}", (Object)file1.getAbsolutePath());
}
else
{
LOGGER.error("We were unable to save this crash report to disk.");
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
this.finalTick(crashreport);
}
finally
{
try
{
this.stopServer();
}
catch (Throwable throwable)
{
LOGGER.error("Exception stopping the server", throwable);
}
finally
{
net.minecraftforge.fml.common.FMLCommonHandler.instance().handleServerStopped();
this.serverStopped = true;
this.systemExitNow();
}
}
}
控制每秒20tick的逻辑
net.minecraft.server.MinecraftServer
while (this.serverRunning)
{
long k = getCurrentTimeMillis();
//新时间 - 老时间 = 经过的时间.
long j = k - this.currentTime;
//时间隔得太长.
if (j > 2000L && this.currentTime - this.timeOfLastWarning >= 15000L)
{
LOGGER.warn("Can't keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", Long.valueOf(j), Long.valueOf(j / 50L));
j = 2000L;
this.timeOfLastWarning = this.currentTime;
}
//时间为负
if (j < 0L)
{
LOGGER.warn("Time ran backwards! Did the system time change?");
j = 0L;
}
//i 初始化为0,每次累加.
i += j;
this.currentTime = k;
//判断是不是所有的玩家都躺床上了.
if (this.worlds[0].areAllPlayersAsleep())
{ //立即执行
this.tick();
i = 0L;
}
else
{ //50ms运行一次,这里是看有几个50ms
while (i > 50L)
{
i -= 50L;
this.tick();
}
}
//休眠到该下一次tick的时候.
Thread.sleep(Math.max(1L, 50L - i));
this.serverIsRunning = true;
}
net.minecraft.server.integrated.IntegratedServer 集成服务端 的 代码
public void tick()
{
boolean flag = this.isGamePaused;
this.isGamePaused = Minecraft.getMinecraft().getConnection() != null && Minecraft.getMinecraft().isGamePaused();
//判断是不是刚暂停
if (!flag && this.isGamePaused)
{
LOGGER.info("Saving and pausing game...");
this.getPlayerList().saveAllPlayerData();
this.saveAllWorlds(false);
}
if (this.isGamePaused)
{ //把所有任务都处理完
synchronized (this.futureTaskQueue)
{
while (!this.futureTaskQueue.isEmpty())
{
Util.runTask(this.futureTaskQueue.poll(), LOGGER);
}
}
}
else
{
super.tick();
if (this.mc.gameSettings.renderDistanceChunks != this.getPlayerList().getViewDistance())
{
LOGGER.info("Changing view distance to {}, from {}", Integer.valueOf(this.mc.gameSettings.renderDistanceChunks), Integer.valueOf(this.getPlayerList().getViewDistance()));
this.getPlayerList().setViewDistance(this.mc.gameSettings.renderDistanceChunks);
}
if (this.mc.world != null)
{
WorldInfo worldinfo1 = this.worlds[0].getWorldInfo();
WorldInfo worldinfo = this.mc.world.getWorldInfo();
if (!worldinfo1.isDifficultyLocked() && worldinfo.getDifficulty() != worldinfo1.getDifficulty())
{
LOGGER.info("Changing difficulty to {}, from {}", worldinfo.getDifficulty(), worldinfo1.getDifficulty());
this.setDifficultyForAllWorlds(worldinfo.getDifficulty());
}
else if (worldinfo.isDifficultyLocked() && !worldinfo1.isDifficultyLocked())
{
LOGGER.info("Locking difficulty to {}", (Object)worldinfo.getDifficulty());
for (WorldServer worldserver : this.worlds)
{
if (worldserver != null)
{
worldserver.getWorldInfo().setDifficultyLocked(true);
}
}
}
}
}
}
net.minecraft.server.MinecraftServer 父类
public void tick()
{
long i = System.nanoTime();
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreServerTick();
++this.tickCounter;
if (this.startProfiling)
{
this.startProfiling = false;
this.profiler.profilingEnabled = true;
this.profiler.clearProfiling();
}
this.profiler.startSection("root");
//主要方法 核心 核心 核心
this.updateTimeLightAndEntities();
if (i - this.nanoTimeSinceStatusRefresh >= 5000000000L)
{
this.nanoTimeSinceStatusRefresh = i;
this.statusResponse.setPlayers(new ServerStatusResponse.Players(this.getMaxPlayers(), this.getCurrentPlayerCount()));
GameProfile[] agameprofile = new GameProfile[Math.min(this.getCurrentPlayerCount(), 12)];
int j = MathHelper.getInt(this.random, 0, this.getCurrentPlayerCount() - agameprofile.length);
for (int k = 0; k < agameprofile.length; ++k)
{
agameprofile[k] = ((EntityPlayerMP)this.playerList.getPlayers().get(j + k)).getGameProfile();
}
Collections.shuffle(Arrays.asList(agameprofile));
this.statusResponse.getPlayers().setPlayers(agameprofile);
this.statusResponse.invalidateJson();
}
//45s保存一次?
if (this.tickCounter % 900 == 0)
{
this.profiler.startSection("save");
this.playerList.saveAllPlayerData();
this.saveAllWorlds(true);
this.profiler.endSection();
}
this.profiler.startSection("tallying");
this.tickTimeArray[this.tickCounter % 100] = System.nanoTime() - i;
this.profiler.endSection();
this.profiler.startSection("snooper");
if (!this.usageSnooper.isSnooperRunning() && this.tickCounter > 100)
{
this.usageSnooper.startSnooper();
}
if (this.tickCounter % 6000 == 0)
{
this.usageSnooper.addMemoryStatsToSnooper();
}
this.profiler.endSection();
this.profiler.endSection();
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostServerTick();
}
net.minecraft.server.MinecraftServer 主要方法
public void updateTimeLightAndEntities()
{
this.profiler.startSection("jobs");
//运行任务,把任务运行完.可能会导致这一tick时间超标.
synchronized (this.futureTaskQueue)
{
while (!this.futureTaskQueue.isEmpty())
{
Util.runTask(this.futureTaskQueue.poll(), LOGGER);
}
}
this.profiler.endStartSection("levels");
net.minecraftforge.common.chunkio.ChunkIOExecutor.tick();
//获取所有世界id
Integer[] ids = net.minecraftforge.common.DimensionManager.getIDs(this.tickCounter % 200 == 0);
//遍历所有世界
for (int x = 0; x < ids.length; x++)
{
int id = ids[x];
long i = System.nanoTime();
if (id == 0 || this.getAllowNether())
{ //根据id 获取世界
WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
this.profiler.func_194340_a(() ->
{
return worldserver.getWorldInfo().getWorldName();
});
if (this.tickCounter % 20 == 0)
{
this.profiler.startSection("timeSync");
//发送给此世界所有玩家:时间更新, 玩家客户端以此更新各种东西.
this.playerList.sendPacketToAllPlayersInDimension(new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.provider.getDimension());
this.profiler.endSection();
}
this.profiler.startSection("tick");
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPreWorldTick(worldserver);
try
{
//世界 的 tick
worldserver.tick();
}
catch (Throwable throwable1)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world");
worldserver.addWorldInfoToCrashReport(crashreport);
throw new ReportedException(crashreport);
}
try
{
//更新 实体
worldserver.updateEntities();
}
catch (Throwable throwable)
{
CrashReport crashreport1 = CrashReport.makeCrashReport(throwable, "Exception ticking world entities");
worldserver.addWorldInfoToCrashReport(crashreport1);
throw new ReportedException(crashreport1);
}
net.minecraftforge.fml.common.FMLCommonHandler.instance().onPostWorldTick(worldserver);
this.profiler.endSection();
this.profiler.startSection("tracker");
//好像是更新 entity位置,根据速度.
worldserver.getEntityTracker().tick();
this.profiler.endSection();
this.profiler.endSection();
}
worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - i;
}
评论区