mirror of
https://github.com/neoforged/NeoForge.git
synced 2026-10-12 02:19:42 +00:00
Co-Authored-By: Dennis C <[email protected]> Co-Authored-By: RogueLogix <[email protected]>
422 lines
21 KiB
Diff
422 lines
21 KiB
Diff
--- a/net/minecraft/client/Minecraft.java
|
|
+++ b/net/minecraft/client/Minecraft.java
|
|
@@ -274,6 +_,7 @@
|
|
public final LevelExtractor levelExtractor;
|
|
public final LevelRenderer levelRenderer;
|
|
private final EntityRenderDispatcher entityRenderDispatcher;
|
|
+ private final BlockModelResolver blockModelResolver;
|
|
private final ItemModelResolver itemModelResolver;
|
|
private final MapRenderer mapRenderer;
|
|
public final ParticleEngine particleEngine;
|
|
@@ -404,7 +_,6 @@
|
|
}
|
|
}, Util.nonCriticalIoPool());
|
|
LOGGER.info("Setting user: {}", this.user.getName());
|
|
- LOGGER.debug("(Session ID is {})", this.user.getSessionId());
|
|
this.demo = gameConfig.game.demo;
|
|
this.allowsMultiplayer = !gameConfig.game.disableMultiplayer;
|
|
this.allowsChat = !gameConfig.game.disableChat;
|
|
@@ -436,6 +_,7 @@
|
|
StringBuilder errorMsgBuilder = new StringBuilder("No supported graphics backend was found.");
|
|
Window windowCandidate = null;
|
|
GpuDevice device = null;
|
|
+
|
|
PreferredGraphicsApi forcedGraphicsApi = gameConfig.game.forcedGraphicsApi;
|
|
if (forcedGraphicsApi != null) {
|
|
LOGGER.warn(
|
|
@@ -446,6 +_,9 @@
|
|
|
|
PreferredGraphicsApi preferredGraphicsBackend = forcedGraphicsApi == null ? this.options.preferredGraphicsBackend().get() : forcedGraphicsApi;
|
|
|
|
+ // Neo: Enable GL debug labels and synchronous GL debug output via FML config
|
|
+ boolean enableGlDebug = net.neoforged.fml.loading.FMLConfig.getBoolConfigValue(net.neoforged.fml.loading.FMLConfig.ConfigValue.DEBUG_OPENGL);
|
|
+
|
|
for (GpuBackend backend : preferredGraphicsBackend.getBackendsToTry()) {
|
|
try {
|
|
GLFW.glfwDefaultWindowHints();
|
|
@@ -457,8 +_,8 @@
|
|
(id, type) -> this.getShaderManager().getShader(id, type),
|
|
new GpuDebugOptions(
|
|
this.options.glDebugVerbosity,
|
|
- SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS,
|
|
- gameConfig.game.renderDebugLabels,
|
|
+ SharedConstants.DEBUG_SYNCHRONOUS_GL_LOGS || enableGlDebug,
|
|
+ gameConfig.game.renderDebugLabels || enableGlDebug,
|
|
gameConfig.game.vulkanValidation
|
|
),
|
|
this::loadCriticalShaders
|
|
@@ -522,12 +_,14 @@
|
|
LOGGER.error("Couldn't set icon", e);
|
|
}
|
|
|
|
+ // Neo: Move mouse and keyboard handler setup further below
|
|
this.mouseHandler = new MouseHandler(this);
|
|
- this.mouseHandler.setup(this.window);
|
|
this.keyboardHandler = new KeyboardHandler(this);
|
|
- this.keyboardHandler.setup(this.window);
|
|
this.options.applyGraphicsPreset(this.options.graphicsPreset().get());
|
|
this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
|
|
+ net.neoforged.neoforge.client.loading.ClientModLoader.setupModResourcePacks(this.resourcePackRepository);
|
|
+ //Move client bootstrap to after mod loading so that events can be fired for it.
|
|
+ ClientBootstrap.bootstrap();
|
|
this.resourcePackRepository.reload();
|
|
this.options.loadSelectedResourcePacks(this.resourcePackRepository);
|
|
this.languageManager = new LanguageManager(this.options.languageCode, var1 -> {
|
|
@@ -563,11 +_,13 @@
|
|
RenderSystem.setupDefaultState();
|
|
this.window.setErrorSection("Post startup");
|
|
this.blockColors = BlockColors.createDefault();
|
|
+ net.neoforged.neoforge.client.model.UnbakedModelParser.init();
|
|
this.modelManager = new ModelManager(this.blockColors, this.atlasManager, this.playerSkinRenderCache);
|
|
this.resourceManager.registerReloadListener(this.modelManager);
|
|
EquipmentAssetManager equipmentAssets = new EquipmentAssetManager();
|
|
this.resourceManager.registerReloadListener(equipmentAssets);
|
|
BlockModelResolver blockModelResolver = new BlockModelResolver(this.modelManager);
|
|
+ this.blockModelResolver = blockModelResolver;
|
|
this.itemModelResolver = new ItemModelResolver(this.modelManager);
|
|
this.mapTextureManager = new MapTextureManager(this.textureManager);
|
|
this.mapRenderer = new MapRenderer(this.atlasManager, this.mapTextureManager);
|
|
@@ -606,6 +_,7 @@
|
|
this.resourceManager.registerReloadListener(particleResources);
|
|
this.particleEngine = new ParticleEngine(this.level, particleResources);
|
|
particleResources.onReload(this.particleEngine::clearParticles);
|
|
+ net.neoforged.neoforge.client.ClientHooks.onRegisterParticleProviders(particleResources);
|
|
this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.modelManager);
|
|
WindowRenderState windowRenderState = this.gameRenderer.gameRenderState().windowRenderState;
|
|
windowRenderState.width = this.window.getWidth();
|
|
@@ -627,6 +_,9 @@
|
|
this.gpuWarnlistManager = new GpuWarnlistManager();
|
|
this.resourceManager.registerReloadListener(this.gpuWarnlistManager);
|
|
this.resourceManager.registerReloadListener(this.regionalCompliancies);
|
|
+ // NEO: Moved keyboard and mouse handler setup below ingame gui creation to prevent NPEs in them.
|
|
+ this.mouseHandler.setup(this.window);
|
|
+ this.keyboardHandler.setup(this.window);
|
|
this.gui = new Gui(this, new Hud(this), this.gameRenderer.gameRenderState().guiRenderState);
|
|
this.gui.registerReloadListeners(this.resourceManager);
|
|
RealmsClient realmsClient = RealmsClient.getOrCreate(this);
|
|
@@ -661,6 +_,7 @@
|
|
}
|
|
}
|
|
|
|
+ net.neoforged.neoforge.client.ClientHooks.initClientHooks(this, this.resourceManager);
|
|
this.window.updateRawMouseInput(this.options.rawMouseInput().get());
|
|
this.window.setAllowCursorChanges(this.options.allowCursorChanges().get());
|
|
this.window.setDefaultErrorCallback();
|
|
@@ -677,6 +_,7 @@
|
|
TitleScreen.registerTextures(this.textureManager);
|
|
LoadingOverlay.registerTextures(this.textureManager);
|
|
this.gameRenderer.registerPanoramaTextures(this.textureManager);
|
|
+ net.neoforged.neoforge.client.loading.ClientModLoader.finish();
|
|
this.timerQuery = new TimerQuery();
|
|
this.gui.setScreen(new GenericMessageScreen(Component.translatable("gui.loadingMinecraft")));
|
|
List<PackResources> packs = this.resourcePackRepository.openAllSelected();
|
|
@@ -686,7 +_,7 @@
|
|
GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS);
|
|
GameLoadCookie loadCookie = new GameLoadCookie(realmsClient, gameConfig.quickPlay);
|
|
this.gui.setOverlay(new LoadingOverlay(this, reloadInstance, maybeT -> Util.ifElse(maybeT, t -> this.rollbackResourcePacks(t, loadCookie), () -> {
|
|
- if (SharedConstants.IS_RUNNING_IN_IDE) {
|
|
+ if (SharedConstants.IS_RUNNING_IN_IDE && false /* Neo: Disable self-test */) {
|
|
this.selfTest();
|
|
}
|
|
|
|
@@ -740,6 +_,7 @@
|
|
}
|
|
|
|
private void onResourceLoadFinished(@Nullable GameLoadCookie loadCookie) {
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireResourceLoadFinishedEvent(!this.gameLoadFinished);
|
|
if (!this.gameLoadFinished) {
|
|
this.gameLoadFinished = true;
|
|
this.onGameLoadFinished(loadCookie);
|
|
@@ -775,7 +_,7 @@
|
|
private String createTitle() {
|
|
StringBuilder builder = new StringBuilder("Minecraft");
|
|
if (checkModStatus().shouldReportAsModified()) {
|
|
- builder.append("*");
|
|
+ builder.append(' ').append(net.neoforged.neoforge.internal.BrandingControl.BRANDING_NAME).append('*');
|
|
}
|
|
|
|
builder.append(" ");
|
|
@@ -815,7 +_,7 @@
|
|
}
|
|
|
|
private void rollbackResourcePacks(Throwable t, @Nullable GameLoadCookie loadCookie) {
|
|
- if (this.resourcePackRepository.getSelectedIds().size() > 1) {
|
|
+ if (this.resourcePackRepository.getSelectedPacks().stream().anyMatch(e -> !e.isRequired())) { //Forge: This caused infinite loop if any resource packs are forced. Such as mod resources. So check if we can disable any.
|
|
this.clearResourcePacksOnError(t, null, loadCookie);
|
|
} else {
|
|
Util.throwAsRuntime(t);
|
|
@@ -871,6 +_,8 @@
|
|
DiscontinuousFrame tickFrame = TracyClient.createDiscontinuousFrame("Client Tick");
|
|
|
|
try {
|
|
+ net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStarted(this);
|
|
+
|
|
boolean oomRecovery = false;
|
|
|
|
while (this.running) {
|
|
@@ -932,7 +_,7 @@
|
|
CrashReport finalReport = this.fillReport(partialReport);
|
|
int exitCode = saveReportAndShutdownSoundManager(this, this.gameDirectory, finalReport, -1);
|
|
this.emergencySave();
|
|
- System.exit(exitCode);
|
|
+ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(exitCode);
|
|
}
|
|
|
|
public static void saveReport(File gameDirectory, CrashReport crash) {
|
|
@@ -969,7 +_,7 @@
|
|
|
|
public static void crash(@Nullable Minecraft minecraft, File gameDirectory, CrashReport crash, int exitCode) {
|
|
int actualExitCode = saveReportAndShutdownSoundManager(minecraft, gameDirectory, crash, exitCode);
|
|
- System.exit(actualExitCode);
|
|
+ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(actualExitCode);
|
|
}
|
|
|
|
public static int saveReportAndShutdownSoundManager(@Nullable Minecraft minecraft, File gameDirectory, CrashReport crash, int exitCode) {
|
|
@@ -1073,6 +_,7 @@
|
|
|
|
public void exitWorldAndClose() {
|
|
try {
|
|
+ net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStopping(this);
|
|
LOGGER.info("Stopping!");
|
|
if (this.level != null) {
|
|
this.level.disconnect(ClientLevel.DEFAULT_QUIT_MESSAGE);
|
|
@@ -1114,6 +_,8 @@
|
|
Util.shutdownExecutors();
|
|
this.windowSurface.close();
|
|
RenderSystem.shutdownRenderer();
|
|
+
|
|
+ net.neoforged.neoforge.client.ClientLifecycleHooks.handleClientStopped(this);
|
|
} catch (Throwable t) {
|
|
LOGGER.error("Shutdown failure!", t);
|
|
throw t;
|
|
@@ -1192,7 +_,11 @@
|
|
|
|
this.window.setErrorSection("Post render");
|
|
boolean var28 = this.pause;
|
|
- this.pause = this.hasSingleplayerServer() && this.gui.isPausing() && !this.singleplayerServer.isPublished();
|
|
+ boolean pause = this.hasSingleplayerServer() && this.gui.isPausing() && !this.singleplayerServer.isPublished();
|
|
+ if (pause != this.pause && !net.neoforged.neoforge.client.ClientHooks.onClientPauseChangePre(pause)) {
|
|
+ this.pause = pause;
|
|
+ net.neoforged.neoforge.client.ClientHooks.onClientPauseChangePost(pause);
|
|
+ }
|
|
if (!var28 && this.pause) {
|
|
this.soundManager.pauseAllExcept(SoundSource.MUSIC, SoundSource.UI);
|
|
}
|
|
@@ -1273,7 +_,9 @@
|
|
profiler.popPush("gpuAsync");
|
|
RenderSystem.executePendingTasks();
|
|
profiler.pop();
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.deltaTracker);
|
|
this.gameRenderer.render(this.deltaTracker, advanceGameTime);
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.deltaTracker);
|
|
}
|
|
|
|
profiler.push("present");
|
|
@@ -1395,8 +_,10 @@
|
|
public void resizeGui() {
|
|
int guiScale = this.window.calculateScale(this.options.guiScale().get(), this.isEnforceUnicode());
|
|
this.window.setGuiScale(guiScale);
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireWindowResize(this.window);
|
|
if (this.gui.screen() != null) {
|
|
this.gui.screen().resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
|
+ net.neoforged.neoforge.client.ClientHooks.resizeGuiLayers(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight());
|
|
}
|
|
|
|
this.mouseHandler.setIgnoreFirstMove();
|
|
@@ -1548,6 +_,7 @@
|
|
}
|
|
|
|
public void stop() {
|
|
+ if (this.isRunning()) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.GameShuttingDownEvent());
|
|
this.running = false;
|
|
}
|
|
|
|
@@ -1573,8 +_,16 @@
|
|
BlockPos pos = blockHit.getBlockPos();
|
|
if (!this.level.getBlockState(pos).isAir()) {
|
|
Direction direction = blockHit.getDirection();
|
|
- if (this.gameMode.continueDestroyBlock(pos, direction)) {
|
|
- this.level.addBreakingBlockEffect(pos, direction);
|
|
+ var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
|
|
+ if (inputEvent.isCanceled()) {
|
|
+ if (inputEvent.shouldSwingHand()) {
|
|
+ this.level.addBreakingBlockEffect(pos, direction, blockHit);
|
|
+ this.player.swing(InteractionHand.MAIN_HAND);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ if (this.gameMode.continueDestroyBlock(pos, direction) && inputEvent.shouldSwingHand()) {
|
|
+ this.level.addBreakingBlockEffect(pos, direction, blockHit);
|
|
this.player.swing(InteractionHand.MAIN_HAND);
|
|
}
|
|
}
|
|
@@ -1621,9 +_,16 @@
|
|
}
|
|
|
|
boolean endAttack = false;
|
|
+ var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(0, this.options.keyAttack, InteractionHand.MAIN_HAND);
|
|
+ if (inputEvent.isCanceled()) {
|
|
+ if (inputEvent.shouldSwingHand())
|
|
+ this.player.swing(InteractionHand.MAIN_HAND);
|
|
+ return endAttack;
|
|
+ }
|
|
PiercingWeapon piercingWeapon = heldItem.get(DataComponents.PIERCING_WEAPON);
|
|
if (piercingWeapon != null) {
|
|
this.gameMode.piercingAttack(piercingWeapon);
|
|
+ if (inputEvent.shouldSwingHand())
|
|
this.player.swing(InteractionHand.MAIN_HAND);
|
|
return true;
|
|
}
|
|
@@ -1651,8 +_,10 @@
|
|
}
|
|
|
|
this.player.resetAttackStrengthTicker();
|
|
+ net.neoforged.neoforge.common.CommonHooks.onEmptyLeftClick(this.player);
|
|
}
|
|
|
|
+ if (inputEvent.shouldSwingHand())
|
|
this.player.swing(InteractionHand.MAIN_HAND);
|
|
return endAttack;
|
|
}
|
|
@@ -1668,6 +_,11 @@
|
|
}
|
|
|
|
for (InteractionHand hand : InteractionHand.values()) {
|
|
+ var inputEvent = net.neoforged.neoforge.client.ClientHooks.onClickInput(1, this.options.keyUse, hand);
|
|
+ if (inputEvent.isCanceled()) {
|
|
+ if (inputEvent.shouldSwingHand()) this.player.swing(hand);
|
|
+ return;
|
|
+ }
|
|
ItemStack heldItem = this.player.getItemInHand(hand);
|
|
if (!heldItem.isItemEnabled(this.level.enabledFeatures())) {
|
|
return;
|
|
@@ -1684,7 +_,7 @@
|
|
|
|
if (this.player.isWithinEntityInteractionRange(entity, 0.0)
|
|
&& this.gameMode.interact(this.player, entity, entityHit, hand) instanceof InteractionResult.Success success) {
|
|
- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
|
+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
|
|
this.player.swing(hand);
|
|
}
|
|
|
|
@@ -1696,7 +_,7 @@
|
|
int oldCount = heldItem.getCount();
|
|
InteractionResult useResult = this.gameMode.useItemOn(this.player, hand, blockHit);
|
|
if (useResult instanceof InteractionResult.Success success) {
|
|
- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
|
+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
|
|
this.player.swing(hand);
|
|
if (!heldItem.isEmpty() && (heldItem.getCount() != oldCount || this.player.hasInfiniteMaterials())) {
|
|
this.gameRenderer.itemInHandRenderer.itemUsed(hand);
|
|
@@ -1712,8 +_,11 @@
|
|
}
|
|
}
|
|
|
|
+ if (heldItem.isEmpty() && (this.hitResult == null || this.hitResult.getType() == HitResult.Type.MISS))
|
|
+ net.neoforged.neoforge.common.CommonHooks.onEmptyClick(this.player, hand);
|
|
+
|
|
if (!heldItem.isEmpty() && this.gameMode.useItem(this.player, hand) instanceof InteractionResult.Success success) {
|
|
- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) {
|
|
+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) {
|
|
this.player.swing(hand);
|
|
}
|
|
|
|
@@ -1731,6 +_,10 @@
|
|
|
|
public void tick() {
|
|
this.clientTickCount++;
|
|
+ if (this.gameLoadFinished) {
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireClientTickPre();
|
|
+ }
|
|
+
|
|
if (this.level != null && !this.pause) {
|
|
this.level.tickRateManager().tick();
|
|
}
|
|
@@ -1793,6 +_,7 @@
|
|
|
|
this.tutorial.tick();
|
|
|
|
+ net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(this.level, () -> true);
|
|
try {
|
|
this.level.tick(() -> true);
|
|
} catch (Throwable t) {
|
|
@@ -1806,6 +_,7 @@
|
|
|
|
throw new ReportedException(report);
|
|
}
|
|
+ net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(this.level, () -> true);
|
|
}
|
|
|
|
profiler.popPush("animateTick");
|
|
@@ -1830,6 +_,10 @@
|
|
profiler.popPush("keyboard");
|
|
this.keyboardHandler.tick();
|
|
profiler.pop();
|
|
+
|
|
+ if (this.gameLoadFinished) {
|
|
+ net.neoforged.neoforge.client.ClientHooks.fireClientTickPost();
|
|
+ }
|
|
}
|
|
|
|
private boolean isLevelRunningNormally() {
|
|
@@ -2035,6 +_,7 @@
|
|
}
|
|
|
|
public void setLevel(ClientLevel level) {
|
|
+ if (this.level != null) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level));
|
|
this.level = level;
|
|
this.updateLevelInEngines(level);
|
|
}
|
|
@@ -2096,13 +_,16 @@
|
|
IntegratedServer server = this.singleplayerServer;
|
|
this.singleplayerServer = null;
|
|
this.gameRenderer.resetData();
|
|
+ net.neoforged.neoforge.client.ClientHooks.firePlayerLogout(this.gameMode, this.player);
|
|
this.gameMode = null;
|
|
this.narrator.clear();
|
|
this.gui.setClientLevelTeardownInProgress(true);
|
|
|
|
+ var shouldRevertRegistriesToFrozen = this.getConnection() != null && this.getConnection().getConnection() != null; // Neo: Track whether to revert registries after disconnect
|
|
try {
|
|
if (this.level != null) {
|
|
this.gui.hud.onDisconnected();
|
|
+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level));
|
|
}
|
|
|
|
this.level = null;
|
|
@@ -2126,6 +_,7 @@
|
|
} finally {
|
|
this.gui.setClientLevelTeardownInProgress(false);
|
|
}
|
|
+ if (shouldRevertRegistriesToFrozen) net.neoforged.neoforge.registries.RegistryManager.revertToFrozen(); // Neo: Revert registries to frozen on disconnect
|
|
}
|
|
|
|
public void clearDownloadedResourcePacks() {
|
|
@@ -2151,6 +_,7 @@
|
|
try {
|
|
this.setScreenAndShow(screen);
|
|
this.gui.hud.onDisconnected();
|
|
+ if (this.level != null) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level));
|
|
this.level = null;
|
|
this.updateLevelInEngines(null);
|
|
this.player = null;
|
|
@@ -2283,6 +_,7 @@
|
|
|
|
private void pickBlockOrEntity() {
|
|
if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) {
|
|
+ if (net.neoforged.neoforge.client.ClientHooks.onClickInput(2, this.options.keyPickItem, InteractionHand.MAIN_HAND).isCanceled()) return;
|
|
boolean includeData = this.hasControlDown();
|
|
switch (this.hitResult) {
|
|
case BlockHitResult blockHitResult:
|
|
@@ -2832,6 +_,10 @@
|
|
}
|
|
|
|
return defaultTickTargetMillis;
|
|
+ }
|
|
+
|
|
+ public BlockModelResolver getBlockModelResolver() {
|
|
+ return this.blockModelResolver;
|
|
}
|
|
|
|
public ItemModelResolver getItemModelResolver() {
|