KeyboardHandler.java

net.minecraft.client.KeyboardHandler

信息

  • 全限定名:net.minecraft.client.KeyboardHandler
  • 类型:public class
  • 包:net.minecraft.client
  • 源码路径:src/main/java/net/minecraft/client/KeyboardHandler.java
  • 起始行号:L65
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • DEBUG_CRASH_TIME

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

      TODO

  • minecraft

    • 类型: Minecraft
    • 修饰符: private final
    • 源码定位: L68
    • 说明:

      TODO

  • clipboardManager

    • 类型: ClipboardManager
    • 修饰符: private final
    • 源码定位: L69
    • 说明:

      TODO

  • debugCrashKeyTime

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

      TODO

  • debugCrashKeyReportedTime

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

      TODO

  • debugCrashKeyReportedCount

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

      TODO

  • usedDebugKeyAsModifier

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

      TODO

  • lastPreeditEvent

    • 类型: PreeditEvent
    • 修饰符: private
    • 源码定位: L74
    • 说明:

      TODO

内部类/嵌套类型

构造器

public KeyboardHandler(Minecraft minecraft) @ L76

  • 构造器名:KeyboardHandler
  • 源码定位:L76
  • 修饰符:public

参数:

  • minecraft: Minecraft

说明:

TODO

方法

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

private boolean handleChunkDebugKeys(KeyEvent event) @ L80

  • 方法名:handleChunkDebugKeys
  • 源码定位:L80
  • 返回类型:boolean
  • 修饰符:private

参数:

  • event: KeyEvent

说明:

TODO

private void debugFeedbackEnabledStatus(String prefix, boolean isEnabled) @ L145

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

参数:

  • prefix: String
  • isEnabled: boolean

说明:

TODO

private void showDebugChat(Component message) @ L149

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

参数:

  • message: Component

说明:

TODO

private static Component decorateDebugComponent(ChatFormatting formatting, Component component) @ L154

  • 方法名:decorateDebugComponent
  • 源码定位:L154
  • 返回类型:Component
  • 修饰符:private static

参数:

  • formatting: ChatFormatting
  • component: Component

说明:

TODO

private void debugWarningComponent(Component component) @ L161

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

参数:

  • component: Component

说明:

TODO

private void debugFeedbackComponent(Component component) @ L165

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

参数:

  • component: Component

说明:

TODO

private void debugFeedbackTranslated(String pattern, Object... args) @ L169

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

参数:

  • pattern: String
  • args: Object…

说明:

TODO

private void debugFeedback(String message) @ L173

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

参数:

  • message: String

说明:

TODO

private boolean handleDebugKeys(KeyEvent event) @ L177

  • 方法名:handleDebugKeys
  • 源码定位:L177
  • 返回类型:boolean
  • 修饰符:private

参数:

  • event: KeyEvent

说明:

TODO

private void copyRecreateCommand(boolean addNbt, boolean pullFromServer) @ L357

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

参数:

  • addNbt: boolean
  • pullFromServer: boolean

说明:

TODO

private void copyCreateBlockCommand(BlockState state, BlockPos blockPos, CompoundTag entityTag) @ L408

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

参数:

  • state: BlockState
  • blockPos: BlockPos
  • entityTag: CompoundTag

说明:

TODO

private void copyCreateEntityCommand(Identifier id, Vec3 pos, CompoundTag entityTag) @ L418

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

参数:

  • id: Identifier
  • pos: Vec3
  • entityTag: CompoundTag

说明:

TODO

private void keyPress(long handle, int action, KeyEvent event) @ L432

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

参数:

  • handle: long
  • action: int
  • event: KeyEvent

说明:

TODO

private void charTyped(long handle, CharacterEvent event) @ L601

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

参数:

  • handle: long
  • event: CharacterEvent

说明:

TODO

private void preeditCallback(long handle, PreeditEvent event) @ L618

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

参数:

  • handle: long
  • event: PreeditEvent

说明:

TODO

public void resubmitLastPreeditEvent(GuiEventListener screen) @ L628

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

参数:

  • screen: GuiEventListener

说明:

TODO

public static void submitPreeditEvent(GuiEventListener element, PreeditEvent event) @ L632

  • 方法名:submitPreeditEvent
  • 源码定位:L632
  • 返回类型:void
  • 修饰符:public static

参数:

  • element: GuiEventListener
  • event: PreeditEvent

说明:

TODO

public void setup(Window window) @ L647

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

参数:

  • window: Window

说明:

TODO

public String getClipboard() @ L660

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

参数:

说明:

TODO

public void setClipboard(String clipboard) @ L668

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

参数:

  • clipboard: String

说明:

TODO

public void tick() @ L674

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

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class KeyboardHandler {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final int DEBUG_CRASH_TIME = 10000;
    private final Minecraft minecraft;
    private final ClipboardManager clipboardManager = new ClipboardManager();
    private long debugCrashKeyTime = -1L;
    private long debugCrashKeyReportedTime = -1L;
    private long debugCrashKeyReportedCount = -1L;
    private boolean usedDebugKeyAsModifier;
    private @Nullable PreeditEvent lastPreeditEvent;
 
    public KeyboardHandler(Minecraft minecraft) {
        this.minecraft = minecraft;
    }
 
    private boolean handleChunkDebugKeys(KeyEvent event) {
        switch (event.key()) {
            case 69:
                if (this.minecraft.player == null) {
                    return false;
                }
 
                boolean chunkSectionPaths = this.minecraft.debugEntries.toggleStatus(DebugScreenEntries.CHUNK_SECTION_PATHS);
                this.debugFeedback("SectionPath: " + (chunkSectionPaths ? "shown" : "hidden"));
                return true;
            case 70:
                boolean fogEnabled = FogRenderer.toggleFog();
                this.debugFeedbackEnabledStatus("Fog: ", fogEnabled);
                return true;
            case 71:
            case 72:
            case 73:
            case 74:
            case 75:
            case 77:
            case 78:
            case 80:
            case 81:
            case 82:
            case 83:
            case 84:
            default:
                return false;
            case 76:
                this.minecraft.smartCull = !this.minecraft.smartCull;
                this.debugFeedbackEnabledStatus("SmartCull: ", this.minecraft.smartCull);
                return true;
            case 79:
                if (this.minecraft.player == null) {
                    return false;
                }
 
                boolean renderOctree = this.minecraft.debugEntries.toggleStatus(DebugScreenEntries.CHUNK_SECTION_OCTREE);
                this.debugFeedbackEnabledStatus("Frustum culling Octree: ", renderOctree);
                return true;
            case 85:
                if (event.hasShiftDown()) {
                    this.minecraft.gameRenderer.getMainCamera().killFrustum();
                    this.debugFeedback("Killed frustum");
                } else {
                    this.minecraft.gameRenderer.getMainCamera().captureFrustum();
                    this.debugFeedback("Captured frustum");
                }
 
                return true;
            case 86:
                if (this.minecraft.player == null) {
                    return false;
                }
 
                boolean sectionVisibility = this.minecraft.debugEntries.toggleStatus(DebugScreenEntries.CHUNK_SECTION_VISIBILITY);
                this.debugFeedbackEnabledStatus("SectionVisibility: ", sectionVisibility);
                return true;
            case 87:
                this.minecraft.wireframe = !this.minecraft.wireframe;
                this.debugFeedbackEnabledStatus("WireFrame: ", this.minecraft.wireframe);
                return true;
        }
    }
 
    private void debugFeedbackEnabledStatus(String prefix, boolean isEnabled) {
        this.debugFeedback(prefix + (isEnabled ? "enabled" : "disabled"));
    }
 
    private void showDebugChat(Component message) {
        this.minecraft.gui.getChat().addClientSystemMessage(message);
        this.minecraft.getNarrator().saySystemQueued(message);
    }
 
    private static Component decorateDebugComponent(ChatFormatting formatting, Component component) {
        return Component.empty()
            .append(Component.translatable("debug.prefix").withStyle(formatting, ChatFormatting.BOLD))
            .append(CommonComponents.SPACE)
            .append(component);
    }
 
    private void debugWarningComponent(Component component) {
        this.showDebugChat(decorateDebugComponent(ChatFormatting.RED, component));
    }
 
    private void debugFeedbackComponent(Component component) {
        this.showDebugChat(decorateDebugComponent(ChatFormatting.YELLOW, component));
    }
 
    private void debugFeedbackTranslated(String pattern, Object... args) {
        this.debugFeedbackComponent(Component.translatable(pattern, args));
    }
 
    private void debugFeedback(String message) {
        this.debugFeedbackComponent(Component.literal(message));
    }
 
    private boolean handleDebugKeys(KeyEvent event) {
        if (this.debugCrashKeyTime > 0L && this.debugCrashKeyTime < Util.getMillis() - 100L) {
            return true;
        } else if (SharedConstants.DEBUG_HOTKEYS && this.handleChunkDebugKeys(event)) {
            return true;
        } else {
            if (SharedConstants.DEBUG_FEATURE_COUNT) {
                switch (event.key()) {
                    case 76:
                        FeatureCountTracker.logCounts();
                        return true;
                    case 82:
                        FeatureCountTracker.clearCounts();
                        return true;
                }
            }
 
            Options options = this.minecraft.options;
            boolean debugAction = false;
            if (options.keyDebugReloadChunk.matches(event)) {
                this.minecraft.levelRenderer.allChanged();
                this.debugFeedbackTranslated("debug.reload_chunks.message");
                debugAction = true;
            }
 
            if (options.keyDebugShowHitboxes.matches(event) && this.minecraft.player != null && !this.minecraft.player.isReducedDebugInfo()) {
                boolean renderHitBoxes = this.minecraft.debugEntries.toggleStatus(DebugScreenEntries.ENTITY_HITBOXES);
                this.debugFeedbackTranslated(renderHitBoxes ? "debug.show_hitboxes.on" : "debug.show_hitboxes.off");
                debugAction = true;
            }
 
            if (options.keyDebugClearChat.matches(event)) {
                this.minecraft.gui.getChat().clearMessages(false);
                debugAction = true;
            }
 
            if (options.keyDebugShowChunkBorders.matches(event) && this.minecraft.player != null && !this.minecraft.player.isReducedDebugInfo()) {
                boolean displayChunkborder = this.minecraft.debugEntries.toggleStatus(DebugScreenEntries.CHUNK_BORDERS);
                this.debugFeedbackTranslated(displayChunkborder ? "debug.chunk_boundaries.on" : "debug.chunk_boundaries.off");
                debugAction = true;
            }
 
            if (options.keyDebugShowAdvancedTooltips.matches(event)) {
                options.advancedItemTooltips = !options.advancedItemTooltips;
                this.debugFeedbackTranslated(options.advancedItemTooltips ? "debug.advanced_tooltips.on" : "debug.advanced_tooltips.off");
                options.save();
                debugAction = true;
            }
 
            if (options.keyDebugCopyRecreateCommand.matches(event)) {
                if (this.minecraft.player != null && !this.minecraft.player.isReducedDebugInfo()) {
                    this.copyRecreateCommand(this.minecraft.player.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER), !event.hasShiftDown());
                }
 
                debugAction = true;
            }
 
            if (options.keyDebugSpectate.matches(event)) {
                if (this.minecraft.player == null || !GameModeCommand.PERMISSION_CHECK.check(this.minecraft.player.permissions())) {
                    this.debugFeedbackTranslated("debug.creative_spectator.error");
                } else if (!this.minecraft.player.isSpectator()) {
                    this.minecraft.player.connection.send(new ServerboundChangeGameModePacket(GameType.SPECTATOR));
                } else {
                    GameType newGameType = MoreObjects.firstNonNull(this.minecraft.gameMode.getPreviousPlayerMode(), GameType.CREATIVE);
                    this.minecraft.player.connection.send(new ServerboundChangeGameModePacket(newGameType));
                }
 
                debugAction = true;
            }
 
            if (options.keyDebugSwitchGameMode.matches(event) && this.minecraft.level != null && this.minecraft.screen == null) {
                if (this.minecraft.canSwitchGameMode() && GameModeCommand.PERMISSION_CHECK.check(this.minecraft.player.permissions())) {
                    this.minecraft.setScreen(new GameModeSwitcherScreen());
                } else {
                    this.debugFeedbackTranslated("debug.gamemodes.error");
                }
 
                debugAction = true;
            }
 
            if (options.keyDebugDebugOptions.matches(event)) {
                if (this.minecraft.screen instanceof DebugOptionsScreen) {
                    this.minecraft.screen.onClose();
                } else if (this.minecraft.canInterruptScreen()) {
                    if (this.minecraft.screen != null) {
                        this.minecraft.screen.onClose();
                    }
 
                    this.minecraft.setScreen(new DebugOptionsScreen());
                }
 
                debugAction = true;
            }
 
            if (options.keyDebugFocusPause.matches(event)) {
                options.pauseOnLostFocus = !options.pauseOnLostFocus;
                options.save();
                this.debugFeedbackTranslated(options.pauseOnLostFocus ? "debug.pause_focus.on" : "debug.pause_focus.off");
                debugAction = true;
            }
 
            if (options.keyDebugDumpDynamicTextures.matches(event)) {
                Path gameDirectory = this.minecraft.gameDirectory.toPath().toAbsolutePath();
                Path debugTexturePath = TextureUtil.getDebugTexturePath(gameDirectory);
                this.minecraft.getTextureManager().dumpAllSheets(debugTexturePath);
                Component pathComponent = Component.literal(gameDirectory.relativize(debugTexturePath).toString())
                    .withStyle(ChatFormatting.UNDERLINE)
                    .withStyle(s -> s.withClickEvent(new ClickEvent.OpenFile(debugTexturePath)));
                this.debugFeedbackComponent(Component.translatable("debug.dump_dynamic_textures", pathComponent));
                debugAction = true;
            }
 
            if (options.keyDebugReloadResourcePacks.matches(event)) {
                this.debugFeedbackTranslated("debug.reload_resourcepacks.message");
                this.minecraft.reloadResourcePacks();
                debugAction = true;
            }
 
            if (options.keyDebugProfiling.matches(event)) {
                if (this.minecraft.debugClientMetricsStart(this::debugFeedbackComponent)) {
                    this.debugFeedbackComponent(
                        Component.translatable(
                            "debug.profiling.start",
                            10,
                            options.keyDebugModifier.getTranslatedKeyMessage(),
                            options.keyDebugProfiling.getTranslatedKeyMessage()
                        )
                    );
                }
 
                debugAction = true;
            }
 
            if (options.keyDebugCopyLocation.matches(event) && this.minecraft.player != null && !this.minecraft.player.isReducedDebugInfo()) {
                this.debugFeedbackTranslated("debug.copy_location.message");
                this.setClipboard(
                    String.format(
                        Locale.ROOT,
                        "/execute in %s run tp @s %.2f %.2f %.2f %.2f %.2f",
                        this.minecraft.player.level().dimension().identifier(),
                        this.minecraft.player.getX(),
                        this.minecraft.player.getY(),
                        this.minecraft.player.getZ(),
                        this.minecraft.player.getYRot(),
                        this.minecraft.player.getXRot()
                    )
                );
                debugAction = true;
            }
 
            if (options.keyDebugDumpVersion.matches(event)) {
                this.debugFeedbackTranslated("debug.version.header");
                VersionCommand.dumpVersion(this::showDebugChat);
                debugAction = true;
            }
 
            if (options.keyDebugPofilingChart.matches(event)) {
                this.minecraft.getDebugOverlay().toggleProfilerChart();
                debugAction = true;
            }
 
            if (options.keyDebugFpsCharts.matches(event)) {
                this.minecraft.getDebugOverlay().toggleFpsCharts();
                debugAction = true;
            }
 
            if (options.keyDebugNetworkCharts.matches(event)) {
                this.minecraft.getDebugOverlay().toggleNetworkCharts();
                debugAction = true;
            }
 
            if (options.keyDebugLightmapTexture.matches(event)) {
                this.minecraft.getDebugOverlay().toggleLightmapTexture();
                debugAction = true;
            }
 
            return debugAction;
        }
    }
 
    private void copyRecreateCommand(boolean addNbt, boolean pullFromServer) {
        HitResult hitResult = this.minecraft.hitResult;
        if (hitResult != null) {
            switch (hitResult.getType()) {
                case BLOCK:
                    BlockPos blockPos = ((BlockHitResult)hitResult).getBlockPos();
                    Level level = this.minecraft.player.level();
                    BlockState state = level.getBlockState(blockPos);
                    if (addNbt) {
                        if (pullFromServer) {
                            this.minecraft.player.connection.getDebugQueryHandler().queryBlockEntityTag(blockPos, tagx -> {
                                this.copyCreateBlockCommand(state, blockPos, tagx);
                                this.debugFeedbackTranslated("debug.inspect.server.block");
                            });
                        } else {
                            BlockEntity blockEntity = level.getBlockEntity(blockPos);
                            CompoundTag tag = blockEntity != null ? blockEntity.saveWithoutMetadata(level.registryAccess()) : null;
                            this.copyCreateBlockCommand(state, blockPos, tag);
                            this.debugFeedbackTranslated("debug.inspect.client.block");
                        }
                    } else {
                        this.copyCreateBlockCommand(state, blockPos, null);
                        this.debugFeedbackTranslated("debug.inspect.client.block");
                    }
                    break;
                case ENTITY:
                    Entity entity = ((EntityHitResult)hitResult).getEntity();
                    Identifier id = BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType());
                    if (addNbt) {
                        if (pullFromServer) {
                            this.minecraft.player.connection.getDebugQueryHandler().queryEntityTag(entity.getId(), tagx -> {
                                this.copyCreateEntityCommand(id, entity.position(), tagx);
                                this.debugFeedbackTranslated("debug.inspect.server.entity");
                            });
                        } else {
                            try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(entity.problemPath(), LOGGER)) {
                                TagValueOutput output = TagValueOutput.createWithContext(reporter, entity.registryAccess());
                                entity.saveWithoutId(output);
                                this.copyCreateEntityCommand(id, entity.position(), output.buildResult());
                            }
 
                            this.debugFeedbackTranslated("debug.inspect.client.entity");
                        }
                    } else {
                        this.copyCreateEntityCommand(id, entity.position(), null);
                        this.debugFeedbackTranslated("debug.inspect.client.entity");
                    }
            }
        }
    }
 
    private void copyCreateBlockCommand(BlockState state, BlockPos blockPos, @Nullable CompoundTag entityTag) {
        StringBuilder description = new StringBuilder(BlockStateParser.serialize(state));
        if (entityTag != null) {
            description.append(entityTag);
        }
 
        String command = String.format(Locale.ROOT, "/setblock %d %d %d %s", blockPos.getX(), blockPos.getY(), blockPos.getZ(), description);
        this.setClipboard(command);
    }
 
    private void copyCreateEntityCommand(Identifier id, Vec3 pos, @Nullable CompoundTag entityTag) {
        String command;
        if (entityTag != null) {
            entityTag.remove("UUID");
            entityTag.remove("Pos");
            String snbt = NbtUtils.toPrettyComponent(entityTag).getString();
            command = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f %s", id, pos.x, pos.y, pos.z, snbt);
        } else {
            command = String.format(Locale.ROOT, "/summon %s %.2f %.2f %.2f", id, pos.x, pos.y, pos.z);
        }
 
        this.setClipboard(command);
    }
 
    private void keyPress(long handle, @KeyEvent.Action int action, KeyEvent event) {
        Window window = this.minecraft.getWindow();
        if (handle == window.handle()) {
            this.minecraft.getFramerateLimitTracker().onInputReceived();
            Options options = this.minecraft.options;
            boolean modifierAndOverlayIsSame = options.keyDebugModifier.key.getValue() == options.keyDebugOverlay.key.getValue();
            boolean debugModifierDown = options.keyDebugModifier.isDown();
            boolean debugCrash = !options.keyDebugCrash.isUnbound()
                && InputConstants.isKeyDown(this.minecraft.getWindow(), options.keyDebugCrash.key.getValue());
            if (this.debugCrashKeyTime > 0L) {
                if (!debugCrash || !debugModifierDown) {
                    this.debugCrashKeyTime = -1L;
                }
            } else if (debugCrash && debugModifierDown) {
                this.usedDebugKeyAsModifier = modifierAndOverlayIsSame;
                this.debugCrashKeyTime = Util.getMillis();
                this.debugCrashKeyReportedTime = Util.getMillis();
                this.debugCrashKeyReportedCount = 0L;
            }
 
            Screen screen = this.minecraft.screen;
            if (screen != null) {
                switch (event.key()) {
                    case 258:
                        this.minecraft.setLastInputType(InputType.KEYBOARD_TAB);
                    case 259:
                    case 260:
                    case 261:
                    default:
                        break;
                    case 262:
                    case 263:
                    case 264:
                    case 265:
                        this.minecraft.setLastInputType(InputType.KEYBOARD_ARROW);
                }
            }
 
            if (action == 1 && (!(this.minecraft.screen instanceof KeyBindsScreen) || ((KeyBindsScreen)screen).lastKeySelection <= Util.getMillis() - 20L)) {
                if (options.keyFullscreen.matches(event)) {
                    window.toggleFullScreen();
                    boolean fullscreen = window.isFullscreen();
                    options.fullscreen().set(fullscreen);
                    options.save();
                    if (this.minecraft.screen instanceof VideoSettingsScreen videoSettingsScreen) {
                        videoSettingsScreen.updateFullscreenButton(fullscreen);
                    }
 
                    return;
                }
 
                if (options.keyScreenshot.matches(event)) {
                    if (event.hasControlDownWithQuirk() && SharedConstants.DEBUG_PANORAMA_SCREENSHOT) {
                        this.showDebugChat(this.minecraft.grabPanoramixScreenshot(this.minecraft.gameDirectory));
                    } else {
                        Screenshot.grab(
                            this.minecraft.gameDirectory,
                            this.minecraft.getMainRenderTarget(),
                            message -> this.minecraft.execute(() -> this.showDebugChat(message))
                        );
                    }
 
                    return;
                }
            }
 
            if (action != 0) {
                boolean hasNoEditboxFocused = screen == null || !(screen.getFocused() instanceof EditBox) || !((EditBox)screen.getFocused()).canConsumeInput();
                if (hasNoEditboxFocused) {
                    if (event.hasControlDownWithQuirk() && event.key() == 66 && this.minecraft.getNarrator().isActive() && options.narratorHotkey().get()) {
                        boolean wasDisabled = options.narrator().get() == NarratorStatus.OFF;
                        options.narrator().set(NarratorStatus.byId(options.narrator().get().getId() + 1));
                        options.save();
                        if (screen != null) {
                            screen.updateNarratorStatus(wasDisabled);
                        }
                    }
 
                    LocalPlayer var21 = this.minecraft.player;
                }
            }
 
            if (screen != null) {
                try {
                    if (action != 1 && action != 2) {
                        if (action == 0 && screen.keyReleased(event)) {
                            if (options.keyDebugModifier.matches(event)) {
                                this.usedDebugKeyAsModifier = false;
                            }
 
                            return;
                        }
                    } else {
                        screen.afterKeyboardAction();
                        if (screen.keyPressed(event)) {
                            if (this.minecraft.screen == null) {
                                InputConstants.Key key = InputConstants.getKey(event);
                                KeyMapping.set(key, false);
                            }
 
                            return;
                        }
                    }
                } catch (Throwable var17) {
                    CrashReport report = CrashReport.forThrowable(var17, "keyPressed event handler");
                    screen.fillCrashDetails(report);
                    CrashReportCategory keyDetails = report.addCategory("Key");
                    keyDetails.setDetail("Key", event.key());
                    keyDetails.setDetail("Scancode", event.scancode());
                    keyDetails.setDetail("Mods", event.modifiers());
                    throw new ReportedException(report);
                }
            }
 
            InputConstants.Key key = InputConstants.getKey(event);
            boolean handlesGameInput = this.minecraft.screen == null;
            boolean handlesGlobalInput = handlesGameInput
                || this.minecraft.screen instanceof PauseScreen pauseScreen && !pauseScreen.showsPauseMenu()
                || this.minecraft.screen instanceof GameModeSwitcherScreen;
            if (modifierAndOverlayIsSame && options.keyDebugModifier.matches(event) && action == 0) {
                if (this.usedDebugKeyAsModifier) {
                    this.usedDebugKeyAsModifier = false;
                } else {
                    this.minecraft.debugEntries.toggleDebugOverlay();
                }
            } else if (!modifierAndOverlayIsSame && options.keyDebugOverlay.matches(event) && action == 1) {
                this.minecraft.debugEntries.toggleDebugOverlay();
            }
 
            if (action == 0) {
                KeyMapping.set(key, false);
            } else {
                boolean didDebugAction = false;
                if (handlesGlobalInput && event.isEscape()) {
                    this.minecraft.pauseGame(debugModifierDown);
                    didDebugAction = debugModifierDown;
                } else if (debugModifierDown) {
                    didDebugAction = this.handleDebugKeys(event);
                    if (didDebugAction && screen instanceof DebugOptionsScreen debugOptionsScreen) {
                        DebugOptionsScreen.OptionList optionList = debugOptionsScreen.getOptionList();
                        if (optionList != null) {
                            optionList.children().forEach(DebugOptionsScreen.AbstractOptionEntry::refreshEntry);
                        }
                    }
                }
 
                if (modifierAndOverlayIsSame) {
                    this.usedDebugKeyAsModifier |= didDebugAction;
                }
 
                if (this.minecraft.getDebugOverlay().showProfilerChart() && !debugModifierDown) {
                    int digit = event.getDigit();
                    if (digit != -1) {
                        this.minecraft.getDebugOverlay().getProfilerPieChart().profilerPieChartKeyPress(digit);
                    }
                }
 
                if (handlesGameInput || key == options.keyDebugModifier.key) {
                    if (didDebugAction) {
                        KeyMapping.set(key, false);
                    } else {
                        KeyMapping.set(key, true);
                        KeyMapping.click(key);
                    }
                }
            }
        }
    }
 
    private void charTyped(long handle, CharacterEvent event) {
        if (handle == this.minecraft.getWindow().handle()) {
            Screen screen = this.minecraft.screen;
            if (screen != null && this.minecraft.getOverlay() == null) {
                try {
                    screen.charTyped(event);
                } catch (Throwable var8) {
                    CrashReport report = CrashReport.forThrowable(var8, "charTyped event handler");
                    screen.fillCrashDetails(report);
                    CrashReportCategory keyDetails = report.addCategory("Key");
                    keyDetails.setDetail("Codepoint", event.codepoint());
                    throw new ReportedException(report);
                }
            }
        }
    }
 
    private void preeditCallback(long handle, @Nullable PreeditEvent event) {
        if (handle == this.minecraft.getWindow().handle()) {
            this.lastPreeditEvent = event;
            Screen screen = this.minecraft.screen;
            if (screen != null && this.minecraft.getOverlay() == null) {
                submitPreeditEvent(screen, event);
            }
        }
    }
 
    public void resubmitLastPreeditEvent(GuiEventListener screen) {
        submitPreeditEvent(screen, this.lastPreeditEvent);
    }
 
    public static void submitPreeditEvent(GuiEventListener element, @Nullable PreeditEvent event) {
        try {
            element.preeditUpdated(event);
        } catch (Throwable var5) {
            CrashReport report = CrashReport.forThrowable(var5, "IME pre-edit event handler");
            if (element instanceof Screen screen) {
                screen.fillCrashDetails(report);
            }
 
            CrashReportCategory keyDetails = report.addCategory("Event");
            keyDetails.setDetail("Contents", () -> String.valueOf(event));
            throw new ReportedException(report);
        }
    }
 
    public void setup(Window window) {
        InputConstants.setupKeyboardCallbacks(window, (window1, keysym, scancode, action, mods) -> {
            KeyEvent event = new KeyEvent(keysym, scancode, mods);
            this.minecraft.execute(() -> this.keyPress(window1, action, event));
        }, (window1, codepoint) -> {
            CharacterEvent event = new CharacterEvent(codepoint);
            this.minecraft.execute(() -> this.charTyped(window1, event));
        }, (window1, preeditSize, preeditPtr, blockCount, blockSizesPtr, focusedBlock, caret) -> {
            PreeditEvent event = PreeditEvent.createFromCallback(preeditSize, preeditPtr, blockCount, blockSizesPtr, focusedBlock, caret);
            this.minecraft.execute(() -> this.preeditCallback(window1, event));
        }, window1 -> this.minecraft.textInputManager().notifyIMEChanged());
    }
 
    public String getClipboard() {
        return this.clipboardManager.getClipboard(this.minecraft.getWindow(), (error, description) -> {
            if (error != 65545) {
                this.minecraft.getWindow().defaultErrorCallback(error, description);
            }
        });
    }
 
    public void setClipboard(String clipboard) {
        if (!clipboard.isEmpty()) {
            this.clipboardManager.setClipboard(this.minecraft.getWindow(), clipboard);
        }
    }
 
    public void tick() {
        if (this.debugCrashKeyTime > 0L) {
            long now = Util.getMillis();
            long remainingTime = 10000L - (now - this.debugCrashKeyTime);
            long reportedTime = now - this.debugCrashKeyReportedTime;
            if (remainingTime < 0L) {
                if (this.minecraft.hasControlDown()) {
                    Blaze3D.youJustLostTheGame();
                }
 
                String message = "Manually triggered debug crash";
                CrashReport report = new CrashReport("Manually triggered debug crash", new Throwable("Manually triggered debug crash"));
                CrashReportCategory manualCrashDetails = report.addCategory("Manual crash details");
                NativeModuleLister.addCrashSection(manualCrashDetails);
                throw new ReportedException(report);
            }
 
            if (reportedTime >= 1000L) {
                if (this.debugCrashKeyReportedCount == 0L) {
                    this.debugFeedbackTranslated(
                        "debug.crash.message",
                        this.minecraft.options.keyDebugModifier.getTranslatedKeyMessage().getString(),
                        this.minecraft.options.keyDebugCrash.getTranslatedKeyMessage().getString()
                    );
                } else {
                    this.debugWarningComponent(Component.translatable("debug.crash.warning", Mth.ceil((float)remainingTime / 1000.0F)));
                }
 
                this.debugCrashKeyReportedTime = now;
                this.debugCrashKeyReportedCount++;
            }
        }
    }
}

引用的其他类

  • Blaze3D

    • 引用位置: 方法调用
    • 关联成员: Blaze3D.youJustLostTheGame()
  • ClipboardManager

    • 引用位置: 字段/构造调用
    • 关联成员: ClipboardManager()
  • InputConstants

    • 引用位置: 方法调用
    • 关联成员: InputConstants.getKey(), InputConstants.isKeyDown(), InputConstants.setupKeyboardCallbacks()
  • TextureUtil

    • 引用位置: 方法调用
    • 关联成员: TextureUtil.getDebugTexturePath()
  • Window

    • 引用位置: 参数
  • ChatFormatting

    • 引用位置: 参数
  • CrashReport

    • 引用位置: 方法调用/构造调用
    • 关联成员: CrashReport(), CrashReport.forThrowable()
  • ReportedException

    • 引用位置: 构造调用
    • 关联成员: ReportedException()
  • KeyMapping

    • 引用位置: 方法调用
    • 关联成员: KeyMapping.click(), KeyMapping.set()
  • Minecraft

    • 引用位置: 参数/字段
  • NarratorStatus

    • 引用位置: 方法调用
    • 关联成员: NarratorStatus.byId()
  • Screenshot

    • 引用位置: 方法调用
    • 关联成员: Screenshot.grab()
  • GuiEventListener

    • 引用位置: 参数
  • DebugOptionsScreen

    • 引用位置: 构造调用
    • 关联成员: DebugOptionsScreen()
  • GameModeSwitcherScreen

    • 引用位置: 构造调用
    • 关联成员: GameModeSwitcherScreen()
  • CharacterEvent

    • 引用位置: 参数/构造调用
    • 关联成员: CharacterEvent()
  • KeyEvent

    • 引用位置: 参数/构造调用
    • 关联成员: KeyEvent()
  • PreeditEvent

    • 引用位置: 参数/字段/方法调用
    • 关联成员: PreeditEvent.createFromCallback()
  • FogRenderer

    • 引用位置: 方法调用
    • 关联成员: FogRenderer.toggleFog()
  • BlockStateParser

    • 引用位置: 方法调用
    • 关联成员: BlockStateParser.serialize()
  • BlockPos

    • 引用位置: 参数
  • CompoundTag

    • 引用位置: 参数
  • NbtUtils

    • 引用位置: 方法调用
    • 关联成员: NbtUtils.toPrettyComponent()
  • ClickEvent

    • 引用位置: 方法调用/构造调用
    • 关联成员: ClickEvent.OpenFile(), OpenFile()
  • Component

    • 引用位置: 参数/方法调用/返回值
    • 关联成员: Component.empty(), Component.literal(), Component.translatable()
  • ServerboundChangeGameModePacket

    • 引用位置: 构造调用
    • 关联成员: ServerboundChangeGameModePacket()
  • Identifier

    • 引用位置: 参数
  • VersionCommand

    • 引用位置: 方法调用
    • 关联成员: VersionCommand.dumpVersion()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.ceil()
  • NativeModuleLister

    • 引用位置: 方法调用
    • 关联成员: NativeModuleLister.addCrashSection()
  • ProblemReporter

    • 引用位置: 方法调用/构造调用
    • 关联成员: ProblemReporter.ScopedCollector(), ScopedCollector()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.getMillis()
  • BlockState

    • 引用位置: 参数
  • FeatureCountTracker

    • 引用位置: 方法调用
    • 关联成员: FeatureCountTracker.clearCounts(), FeatureCountTracker.logCounts()
  • TagValueOutput

    • 引用位置: 方法调用
    • 关联成员: TagValueOutput.createWithContext()
  • Vec3

    • 引用位置: 参数