Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Refactor mouse controls, fixing all false entity/item interaction issues #286

Merged
merged 11 commits into from
Feb 27, 2025

Conversation

zardoy
Copy link
Owner

@zardoy zardoy commented Feb 22, 2025

PR Type

Enhancement, Bug fix


Description

  • Refactored sound system to improve sound handling.

    • Added soundsIdToName mapping for better sound identification.
    • Simplified sound key resolution logic.
  • Enhanced block sound alias mappings for better categorization.

    • Added new categories for dirt, crops, and other blocks.
  • Removed redundant or unused code for optimization.

  • Commented out unused sounds bundling in makeOptimizedMcData.mjs.


Changes walkthrough 📝

Relevant files
Enhancement
botSoundSystem.ts
Refactored sound handling logic in bot sound system           

src/sounds/botSoundSystem.ts

  • Simplified sound key resolution logic.
  • Removed unnecessary offset adjustment for sound IDs.
  • Adjusted game load logic to exclude redundant checks.
  • +2/-3     
    soundsMap.ts
    Improved sound mapping and block sound alias handling       

    src/sounds/soundsMap.ts

  • Added soundsIdToName mapping for sound identification.
  • Refactored sound mapping initialization for clarity.
  • Enhanced block sound alias mappings with new categories.
  • Removed redundant block sound alias entries.
  • +44/-19 
    Configuration changes
    makeOptimizedMcData.mjs
    Removed unused sounds bundling configuration                         

    scripts/makeOptimizedMcData.mjs

  • Commented out unused sounds bundling configuration.
  • Improved clarity by removing redundant code.
  • +3/-3     

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Summary by CodeRabbit

    • New Features

      • Enhanced mouse interactions for smoother gameplay, including improved block highlighting and break animations.
      • Added an option for precise mouse input, providing users with finer control.
    • Bug Fixes

      • Improved error handling by ensuring actions are only executed when a valid bot instance is present.
    • Refactor

      • Streamlined mouse event handling and state management.
      • Transitioned from older interaction systems to a more responsive and robust solution.
      • Simplified cursor entity handling with a new method for retrieving cursor state.
      • Removed deprecated worldInteractions module to focus on the mouse plugin.
      • Updated method signatures for better type safety.
      • Removed unnecessary constants and functions related to motion handling.

    Copy link

    codesandbox bot commented Feb 22, 2025

    Review or Edit in CodeSandbox

    Open the branch in Web EditorVS CodeInsiders

    Open Preview

    Copy link

    coderabbitai bot commented Feb 22, 2025

    Caution

    Review failed

    The pull request is closed.

    Walkthrough

    The pull request introduces a new dependency, transitions mouse interaction logic from legacy world interactions to a dedicated mouse plugin, and updates various event handlers to utilize the new functionality. Modifications include the removal of obsolete constants and functions, refinement of type declarations, addition of null checks, and support for a new configuration option for precise mouse input. A new file implements a display manager and event listeners for enhanced mouse interactions, while the outdated world interactions file has been removed.

    Changes

    File(s) Change Summary
    package.json, src/optionsStorage.ts Added new dependency "mineflayer-mouse": "^0.0.4" and introduced the preciseMouseInput: false option for configuration.
    src/cameraRotationControls.ts Removed motion handling constants and updateCursor; updated onCameraMove to use bot.mouse.update() with a conditional check using !options.preciseMouseInput.
    src/devtools.ts, src/react/GameInteractionOverlay.tsx, src/react/TouchAreasControls.tsx, src/index.ts Removed worldInteractions references by replacing window.cursorEntity with window.entityCursor, eliminating world interaction imports/initialization, and updating pointer/touch event handlers to use bot.mouse.update().
    src/mineflayer/plugins/mouse.ts Introduced a new mouse plugin that sets up a display manager, DOM event listeners, and handles mouse interactions and block break animations.
    src/worldInteractions.ts Removed legacy world interactions code including the WorldInteraction class and related functions.
    src/globals.d.ts Updated the digStart() method signature in customEvents to explicitly return void.

    Sequence Diagram(s)

    sequenceDiagram
        participant U as User
        participant CI as Controller (Camera/GameOverlay/Touch)
        participant B as Bot
        participant MP as Mouse Plugin
        participant DM as Display Manager
    
        U->>CI: Initiates mouse/touch event
        CI->>B: Calls bot.mouse.update()
        B->>MP: Forwards update event
        MP->>DM: Updates cursor state and animations
        DM-->>U: Renders visual feedback
    

    Poem

    I'm a rabbit, quick on my feet,
    Hopping through code with a happy beat,
    Old paths are gone, a new trail shines bright,
    With mouse magic leading our digital flight!
    In fields of code where bugs take retreat,
    I cheer our changes with a joyful tweet! 🐇✨


    📜 Recent review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 560f82a and cbf43f2.

    📒 Files selected for processing (1)
    • src/devtools.ts (1 hunks)

    🪧 Tips

    Chat

    There are 3 ways to chat with CodeRabbit:

    • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
      • I pushed a fix in commit <commit_id>, please review it.
      • Generate unit testing code for this file.
      • Open a follow-up GitHub issue for this discussion.
    • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
      • @coderabbitai generate unit testing code for this file.
      • @coderabbitai modularize this function.
    • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
      • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
      • @coderabbitai read src/utils.ts and generate unit testing code.
      • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
      • @coderabbitai help me debug CodeRabbit configuration file.

    Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

    CodeRabbit Commands (Invoked using PR comments)

    • @coderabbitai pause to pause the reviews on a PR.
    • @coderabbitai resume to resume the paused reviews.
    • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
    • @coderabbitai full review to do a full review from scratch and review all the files again.
    • @coderabbitai summary to regenerate the summary of the PR.
    • @coderabbitai generate docstrings to generate docstrings for this PR.
    • @coderabbitai resolve resolve all the CodeRabbit review comments.
    • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
    • @coderabbitai help to get help.

    Other keywords and placeholders

    • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
    • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
    • Add @coderabbitai anywhere in the PR title to generate the title automatically.

    CodeRabbit Configuration File (.coderabbit.yaml)

    • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
    • Please see the configuration documentation for more information.
    • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

    Documentation and Community

    • Visit our Documentation for detailed information on how to use CodeRabbit.
    • Join our Discord Community to get help, request features, and share feedback.
    • Follow us on X/Twitter for updates and announcements.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Null Safety

    The code uses non-null assertion operator (!) on soundMap when accessing soundsIdToName. This could cause runtime errors if soundMap is null.

    const soundKey = soundMap!.soundsIdToName[soundIdNum]
    Error Handling

    The sound mapping initialization lacks error handling for malformed sound data. Invalid sound entries could crash the application.

    for (const [id, soundsStr] of Object.entries(soundsMap)) {
      const sounds = soundsStr.split(',').map(s => {
        const [volume, name, weight] = s.split(';')
        if (isNaN(Number(volume))) throw new Error('volume is not a number')
        if (isNaN(Number(weight))) throw new TypeError('weight is not a number')
        return {
          file: name,
          weight: Number(weight),
          volume: Number(volume)
        }
      })
    
      const [idPart, namePart] = id.split(';')
      this.soundsIdToName[idPart] = namePart
    
      this.soundsPerName[namePart] = sounds
    }

    Copy link

    qodo-merge-pro-for-open-source bot commented Feb 22, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Add missing null check

    Add null check for soundMap before accessing soundsIdToName to prevent potential
    runtime errors.

    src/sounds/botSoundSystem.ts [111-112]

    -const soundKey = soundMap!.soundsIdToName[soundIdNum]
    +if (!soundMap) return
    +const soundKey = soundMap.soundsIdToName[soundIdNum]
     if (soundKey === undefined) return
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion addresses a potential runtime error by adding a crucial null check before accessing soundMap.soundsIdToName. This is important for preventing crashes when soundMap is null.

    Medium
    General
    Initialize object properties properly

    Initialize soundsIdToName and soundsPerName as empty objects in the class
    declaration to ensure type safety and prevent potential undefined access.

    src/sounds/soundsMap.ts [50-51]

    -private readonly soundsPerName: Record<string, SoundEntry[]>
    -soundsIdToName: Record<string, string>
    +private readonly soundsPerName: Record<string, SoundEntry[]> = {}
    +soundsIdToName: Record<string, string> = {}
    • Apply this suggestion
    Suggestion importance[1-10]: 2

    __

    Why: While the suggestion proposes initializing objects at declaration, it's unnecessary as the constructor already properly initializes these objects on lines 64-65. The current implementation is already safe.

    Low
    • Update

    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 1

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 78d923d and 16dd4fc.

    📒 Files selected for processing (3)
    • scripts/makeOptimizedMcData.mjs (1 hunks)
    • src/sounds/botSoundSystem.ts (2 hunks)
    • src/sounds/soundsMap.ts (3 hunks)
    ✅ Files skipped from review due to trivial changes (1)
    • scripts/makeOptimizedMcData.mjs
    ⏰ Context from checks skipped due to timeout of 90000ms (1)
    • GitHub Check: build-and-deploy
    🔇 Additional comments (4)
    src/sounds/botSoundSystem.ts (1)

    24-24:

    ❓ Verification inconclusive

    Verify the safety of removing the sounds data check.

    The condition has been simplified to only check miscUiState.gameLoaded. Please verify that removing the loadedData.sounds check won't cause issues if sound data isn't loaded when this executes.


    🏁 Script executed:

    #!/bin/bash
    # Description: Check if loadedData.sounds is used elsewhere in the codebase
    # to understand potential dependencies
    
    rg "loadedData\.sounds" -A 5

    Length of output: 30


    Ensure sound data is safely decoupled from the game loading check.

    The updated condition now only verifies whether miscUiState.gameLoaded is true. An initial search for references to loadedData.sounds returned no results, which suggests that there aren’t any explicit dependencies on that check elsewhere in the codebase. However, since the automated search output was inconclusive, please perform a manual verification to confirm that this change won’t lead to scenarios where sound data is needed but remains uninitialized.

    src/sounds/soundsMap.ts (3)

    51-51: Well-structured sound mapping implementation!

    The new implementation provides better organization and explicit error handling:

    • Separates ID-to-name and name-to-sounds mappings
    • Adds proper type checking for volume and weight
    • Uses clear variable names for ID parts

    Also applies to: 64-83


    264-284: Improved block categorization!

    The changes enhance the organization and accuracy of block sound mappings:

    • Added logical grouping for dirt and ground blocks
    • Added proper categorization for crop blocks
    • Fixed nether_wart categorization by moving it to crop blocks

    1-426:

    ❓ Verification inconclusive

    Verify PR title accuracy.

    The PR title mentions "Refactor mouse controls, fixing all false entity interaction issues" but the changes appear to focus on sound handling improvements. Please verify if this PR description accurately reflects the changes or if there are missing files related to mouse controls.


    🏁 Script executed:

    #!/bin/bash
    # Description: Look for related mouse control changes
    # that might be missing from this PR
    
    rg -g '!*.md' -i "mouse.*control" -A 5

    Length of output: 40


    PR Title Mismatch: Mouse Control Changes Not Evident

    The changes in src/sounds/soundsMap.ts are focused solely on sound handling improvements, yet the PR title references "Refactor mouse controls, fixing all false entity interaction issues." Our initial search did not reveal any modifications related to mouse control functionality. Please verify whether (a) the PR title accurately reflects the changes in this commit or (b) additional files related to mouse controls should be included.

    @@ -108,8 +108,7 @@ subscribeKey(miscUiState, 'gameLoaded', async () => {
    })

    bot.on('hardcodedSoundEffectHeard', async (soundIdNum, soundCategory, position, volume, pitch) => {
    const fixOffset = versionToNumber('1.20.4') === versionToNumber(bot.version) ? -1 : 0
    const soundKey = loadedData.sounds[soundIdNum + fixOffset]?.name
    const soundKey = soundMap!.soundsIdToName[soundIdNum]
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Replace non-null assertion with proper null check.

    Using the non-null assertion operator (!) is unsafe as it assumes soundMap will always be defined. Consider adding a proper null check.

    -    const soundKey = soundMap!.soundsIdToName[soundIdNum]
    +    if (!soundMap) return
    +    const soundKey = soundMap.soundsIdToName[soundIdNum]
    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    const soundKey = soundMap!.soundsIdToName[soundIdNum]
    if (!soundMap) return
    const soundKey = soundMap.soundsIdToName[soundIdNum]

    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 2

    🧹 Nitpick comments (3)
    src/mineflayer/plugins/mouse.ts (3)

    10-20: Consider consolidating block destruction textures into a single atlas.
    Loading each stage texture individually may impact performance. If possible, creating an atlas could reduce texture load requests and streamline rendering.


    117-120: Avoid using @ts-expect-error unless strictly necessary.
    Relying on @ts-expect-error suppresses type safety, making it harder to catch subtle bugs. Consider casting or refining the underlying types for material.map and material.needsUpdate.


    140-147: Implement highlight logic for null cursor data.
    Currently, if data is not provided, there's no fallback or clearing logic for cursor highlights. Implement appropriate handling to ensure the UI state remains consistent.

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 16dd4fc and db52e20.

    ⛔ Files ignored due to path filters (1)
    • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
    📒 Files selected for processing (9)
    • package.json (1 hunks)
    • src/cameraRotationControls.ts (1 hunks)
    • src/devtools.ts (1 hunks)
    • src/index.ts (2 hunks)
    • src/mineflayer/plugins/mouse.ts (1 hunks)
    • src/optionsStorage.ts (1 hunks)
    • src/react/GameInteractionOverlay.tsx (1 hunks)
    • src/react/TouchAreasControls.tsx (3 hunks)
    • src/worldInteractions.ts (0 hunks)
    💤 Files with no reviewable changes (1)
    • src/worldInteractions.ts
    🔇 Additional comments (10)
    src/mineflayer/plugins/mouse.ts (2)

    28-34: Verify external declarations.
    beforeRenderFrame and viewer references are used but not declared or imported in this file. Ensure they are globally available or imported to avoid runtime reference errors.


    178-192: Recheck mouse button usage.
    Standard HTML button codes are 0 for left click, 1 for middle click, and 2 for right click. Here, button === 0 triggers rightClickStart(), which seems reversed. Confirm the intended mouse handling, as this may confuse users.

    src/cameraRotationControls.ts (1)

    23-23: Potential unintended camera update skip.
    if (now - lastMouseMove < 4 && !options.preciseMouseInput) return may skip CPU frames when the user moves the mouse rapidly. Confirm that skipping these frames won't introduce jitter or sluggish controls.

    src/optionsStorage.ts (1)

    61-61:

    ❓ Verification inconclusive

    Verify the integration of the new mouse input option.

    The new preciseMouseInput option is well-placed among other mouse-related settings. Please ensure that:

    1. The option is properly handled in the mouse control logic.
    2. The UI includes a toggle for this setting.
    3. Documentation is updated to explain this feature.

    🏁 Script executed:

    #!/bin/bash
    # Description: Check if the option is used in mouse control logic and UI components.
    
    # Check mouse control logic
    rg -A 5 "preciseMouseInput"
    
    # Check UI components
    rg -A 5 "preciseMouseInput.*checkbox|toggle"

    Length of output: 22744


    Integration of preciseMouseInput Option: Verify UI and Documentation

    The new preciseMouseInput option is clearly used in the mouse control logic (see its use in src/cameraRotationControls.ts), and it’s correctly added in the default options (src/optionsStorage.ts). However, our search did not reveal any explicit UI component (e.g., a checkbox or toggle) tied to this setting. Please confirm that one of the following is true:

    • The options UI automatically renders a toggle for boolean settings like preciseMouseInput, or
    • A specific UI control for this option is implemented.

    Also, ensure that the documentation is updated to explain how this setting affects mouse behavior.

    src/react/TouchAreasControls.tsx (3)

    75-77: LGTM! Added null check and mouse state update.

    The null check for bot prevents potential runtime errors, and the mouse state is properly updated after the action.


    87-89: LGTM! Added null check and mouse state update.

    The null check for bot prevents potential runtime errors, and the mouse state is properly updated after the action.


    112-114: LGTM! Added null check and mouse state update.

    The null check for bot prevents potential runtime errors, and the mouse state is properly updated after the action.

    src/react/GameInteractionOverlay.tsx (1)

    154-154: LGTM! Updated mouse state handling.

    The change aligns with the refactor to use the new mouse plugin for handling mouse state updates.

    src/index.ts (1)

    110-110: LGTM! Added mouse plugin integration.

    The mouse plugin is properly imported and loaded after bot creation, replacing the old worldInteractions module.

    Also applies to: 669-669

    package.json (1)

    149-149: New Dependency Addition – "mineflayer-mouse": "^0.0.1"

    The new dependency has been correctly added as per the PR objectives to enable enhanced mouse interaction support. Please verify that:

    • The version "^0.0.1" meets your integration requirements.
    • There are no conflicts or breaking changes introduced by this dependency with other parts of the codebase (e.g., the current mineflayer integration).

    src/devtools.ts Outdated
    Comment on lines 13 to 14
    window.entityCursor = () => {
    return bot.mouse.getCursorState
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Invoke getCursorState rather than returning the reference.
    return bot.mouse.getCursorState yields the function reference, not the actual state. Use getCursorState() if you intend to retrieve the cursor information immediately.

    @zardoy
    Copy link
    Owner Author

    zardoy commented Feb 23, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-ps561jtft-zaro.vercel.app
    Playground
    Storybook

    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 1

    🧹 Nitpick comments (3)
    src/mineflayer/plugins/mouse.ts (3)

    11-22: Consider using a texture atlas for destroy stage textures.

    Loading individual textures for each destroy stage could impact performance. Using a texture atlas would be more efficient.

    Consider creating a single texture atlas containing all destroy stage textures to reduce texture switches and improve performance.


    164-164: Fix TODO comment about entity attack workaround.

    The TODO comment indicates a workaround for entity attacks that needs to be addressed.

    Would you like me to help implement a proper solution for the entity attack functionality instead of using a workaround?


    188-193: Consider adding debounce to focus check.

    The focus check in beforeUpdateChecks might be called frequently. Consider adding debounce to improve performance.

    +let lastFocusCheck = 0
    +const FOCUS_CHECK_INTERVAL = 100 // ms
     bot.mouse.beforeUpdateChecks = () => {
    +  const now = Date.now()
    +  if (now - lastFocusCheck < FOCUS_CHECK_INTERVAL) return
    +  lastFocusCheck = now
       if (!document.hasFocus()) {
         // deactive all buttons
         bot.mouse.buttons.fill(false)
       }
     }
    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between db52e20 and af0245d.

    ⛔ Files ignored due to path filters (1)
    • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
    📒 Files selected for processing (5)
    • package.json (1 hunks)
    • src/globals.d.ts (1 hunks)
    • src/index.ts (2 hunks)
    • src/mineflayer/plugins/mouse.ts (1 hunks)
    • src/react/GameInteractionOverlay.tsx (1 hunks)
    🚧 Files skipped from review as they are similar to previous changes (2)
    • package.json
    • src/react/GameInteractionOverlay.tsx
    ⏰ Context from checks skipped due to timeout of 90000ms (1)
    • GitHub Check: build-and-deploy
    🔇 Additional comments (2)
    src/globals.d.ts (1)

    24-24: LGTM! Improved type safety.

    The addition of the void return type to digStart enhances type safety and documentation.

    src/index.ts (1)

    110-110: LGTM! Clean integration of mouse plugin.

    The mouse plugin is properly imported and loaded, aligning with the PR's objective of shifting mouse interaction logic to a dedicated plugin.

    Also applies to: 691-691

    Comment on lines +106 to +109
    //@ts-expect-error
    state.blockBreakMesh.material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    //@ts-expect-error
    state.blockBreakMesh.material.needsUpdate = true
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Remove @ts-expect-error and fix type issues.

    Using @ts-expect-error suppresses type checking which could lead to runtime errors. The material property should be properly typed.

    Fix the type issues by properly typing the material property:

    -//@ts-expect-error
    -state.blockBreakMesh.material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    -//@ts-expect-error
    -state.blockBreakMesh.material.needsUpdate = true
    +const material = state.blockBreakMesh.material as THREE.MeshBasicMaterial
    +material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    +material.needsUpdate = true
    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    //@ts-expect-error
    state.blockBreakMesh.material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    //@ts-expect-error
    state.blockBreakMesh.material.needsUpdate = true
    const material = state.blockBreakMesh.material as THREE.MeshBasicMaterial
    material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    material.needsUpdate = true

    @zardoy
    Copy link
    Owner Author

    zardoy commented Feb 23, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-hkb72gbof-zaro.vercel.app
    Playground
    Storybook

    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 2

    🧹 Nitpick comments (2)
    src/mineflayer/plugins/mouse.ts (2)

    11-22: Consider using a texture atlas for destroy stage textures.

    Loading individual textures for each destroy stage increases HTTP requests and memory usage. Consider combining these textures into a single atlas texture for better performance.


    186-191: Address TODO comment about entity attack handling.

    The current implementation uses a workaround for entity attacks. This should be replaced with a proper implementation.

    Would you like me to help implement a proper entity attack handler that doesn't require the workaround?

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between af0245d and ec4faa4.

    📒 Files selected for processing (1)
    • src/mineflayer/plugins/mouse.ts (1 hunks)
    🔇 Additional comments (3)
    src/mineflayer/plugins/mouse.ts (3)

    26-57: LGTM! Well-structured display manager initialization.

    The implementation properly initializes textures with appropriate filtering and sets up the break mesh with correct blending and render order settings.


    107-110: Remove @ts-expect-error and fix type issues.

    Using @ts-expect-error suppresses type checking which could lead to runtime errors. The material property should be properly typed.


    142-149: LGTM! Clean plugin setup implementation.

    The plugin setup follows a logical flow, properly initializing the mouse plugin and setting up necessary listeners and display manager.

    Comment on lines +135 to +139
    bot.on('end', () => {
    disposeObject(state.blockBreakMesh!, true)
    scene.remove(state.blockBreakMesh!)
    viewer.world.setHighlightCursorBlock(null)
    })
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Replace non-null assertions with safe null checks.

    Using non-null assertions (!) could lead to runtime errors. Consider adding explicit null checks.

    -    disposeObject(state.blockBreakMesh!, true)
    -    scene.remove(state.blockBreakMesh!)
    +    if (state.blockBreakMesh) {
    +      disposeObject(state.blockBreakMesh, true)
    +      scene.remove(state.blockBreakMesh)
    +    }
    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    bot.on('end', () => {
    disposeObject(state.blockBreakMesh!, true)
    scene.remove(state.blockBreakMesh!)
    viewer.world.setHighlightCursorBlock(null)
    })
    bot.on('end', () => {
    if (state.blockBreakMesh) {
    disposeObject(state.blockBreakMesh, true)
    scene.remove(state.blockBreakMesh)
    }
    viewer.world.setHighlightCursorBlock(null)
    })

    Comment on lines +58 to +93
    // Update functions
    function updateLineMaterial () {
    const inCreative = bot.game.gameMode === 'creative'
    const pixelRatio = viewer.renderer.getPixelRatio()

    viewer.world.threejsCursorLineMaterial = new LineMaterial({
    color: (() => {
    switch (options.highlightBlockColor) {
    case 'blue':
    return 0x40_80_ff
    case 'classic':
    return 0x00_00_00
    default:
    return inCreative ? 0x40_80_ff : 0x00_00_00
    }
    })(),
    linewidth: Math.max(pixelRatio * 0.7, 1) * 2,
    // dashed: true,
    // dashSize: 5,
    })
    }

    function updateDisplay () {
    if (viewer.world.threejsCursorLineMaterial) {
    const { renderer } = viewer
    viewer.world.threejsCursorLineMaterial.resolution.set(renderer.domElement.width, renderer.domElement.height)
    viewer.world.threejsCursorLineMaterial.dashOffset = performance.now() / 750
    }
    }
    beforeRenderFrame.push(updateDisplay)

    // Update cursor line material on game mode change
    bot.on('game', updateLineMaterial)
    // Update material when highlight color setting changes
    subscribeKey(options, 'highlightBlockColor', updateLineMaterial)

    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ⚠️ Potential issue

    Add missing imports for viewer and beforeRenderFrame.

    The code references viewer and beforeRenderFrame which are not imported or defined in the current scope.

    Add the following imports at the top of the file:

    +import { viewer, beforeRenderFrame } from '../../viewer'
    📝 Committable suggestion

    ‼️ IMPORTANT
    Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    Suggested change
    // Update functions
    function updateLineMaterial () {
    const inCreative = bot.game.gameMode === 'creative'
    const pixelRatio = viewer.renderer.getPixelRatio()
    viewer.world.threejsCursorLineMaterial = new LineMaterial({
    color: (() => {
    switch (options.highlightBlockColor) {
    case 'blue':
    return 0x40_80_ff
    case 'classic':
    return 0x00_00_00
    default:
    return inCreative ? 0x40_80_ff : 0x00_00_00
    }
    })(),
    linewidth: Math.max(pixelRatio * 0.7, 1) * 2,
    // dashed: true,
    // dashSize: 5,
    })
    }
    function updateDisplay () {
    if (viewer.world.threejsCursorLineMaterial) {
    const { renderer } = viewer
    viewer.world.threejsCursorLineMaterial.resolution.set(renderer.domElement.width, renderer.domElement.height)
    viewer.world.threejsCursorLineMaterial.dashOffset = performance.now() / 750
    }
    }
    beforeRenderFrame.push(updateDisplay)
    // Update cursor line material on game mode change
    bot.on('game', updateLineMaterial)
    // Update material when highlight color setting changes
    subscribeKey(options, 'highlightBlockColor', updateLineMaterial)
    import { viewer, beforeRenderFrame } from '../../viewer'
    // Update functions
    function updateLineMaterial () {
    const inCreative = bot.game.gameMode === 'creative'
    const pixelRatio = viewer.renderer.getPixelRatio()
    viewer.world.threejsCursorLineMaterial = new LineMaterial({
    color: (() => {
    switch (options.highlightBlockColor) {
    case 'blue':
    return 0x40_80_ff
    case 'classic':
    return 0x00_00_00
    default:
    return inCreative ? 0x40_80_ff : 0x00_00_00
    }
    })(),
    linewidth: Math.max(pixelRatio * 0.7, 1) * 2,
    // dashed: true,
    // dashSize: 5,
    })
    }
    function updateDisplay () {
    if (viewer.world.threejsCursorLineMaterial) {
    const { renderer } = viewer
    viewer.world.threejsCursorLineMaterial.resolution.set(renderer.domElement.width, renderer.domElement.height)
    viewer.world.threejsCursorLineMaterial.dashOffset = performance.now() / 750
    }
    }
    beforeRenderFrame.push(updateDisplay)
    // Update cursor line material on game mode change
    bot.on('game', updateLineMaterial)
    // Update material when highlight color setting changes
    subscribeKey(options, 'highlightBlockColor', updateLineMaterial)

    @zardoy
    Copy link
    Owner Author

    zardoy commented Feb 26, 2025

    /deploy

    Copy link

    Deployed to Vercel Preview: https://prismarine-p6981j2xl-zaro.vercel.app
    Playground
    Storybook

    @zardoy zardoy changed the title feat: Refactor mouse controls, fixing all false entity interaction issues feat: Refactor mouse controls, fixing all false entity/item interaction issues Feb 27, 2025
    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 2

    ♻️ Duplicate comments (4)
    src/cameraRotationControls.ts (1)

    31-31: ⚠️ Potential issue

    Check for null or undefined 'bot'.

    bot.mouse.update() is called but bot isn't declared locally. Ensure bot is always initialized before this point to prevent runtime errors.

    Add null checks before accessing bot.mouse:

    -  bot.mouse.update()
    +  if (bot?.mouse) {
    +    bot.mouse.update()
    +  }
    src/mineflayer/plugins/mouse.ts (3)

    58-93: ⚠️ Potential issue

    Add missing imports for viewer and beforeRenderFrame.

    The code references viewer and beforeRenderFrame which are not imported or defined in the current scope.

    Add the following imports at the top of the file:

    import { createMouse } from 'mineflayer-mouse'
    import * as THREE from 'three'
    import { Bot } from 'mineflayer'
    import { Block } from 'prismarine-block'
    import { Vec3 } from 'vec3'
    import { LineMaterial } from 'three-stdlib'
    import { subscribeKey } from 'valtio/utils'
    import { disposeObject } from 'renderer/viewer/lib/threeJsUtils'
    import { isGameActive, showModal } from '../../globalState'
    +import { viewer } from '../../globals'
    +import { beforeRenderFrame } from '../../index'

    107-110: 🛠️ Refactor suggestion

    Remove @ts-expect-error and fix type issues.

    Using @ts-expect-error suppresses type checking which could lead to runtime errors. The material property should be properly typed.

    Fix the type issues by properly typing the material property:

    -//@ts-expect-error
    -state.blockBreakMesh.material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    -//@ts-expect-error
    -state.blockBreakMesh.material.needsUpdate = true
    +const material = state.blockBreakMesh.material as THREE.MeshBasicMaterial
    +material.map = state.breakTextures[stage] ?? state.breakTextures.at(-1)
    +material.needsUpdate = true

    135-139: 🛠️ Refactor suggestion

    Replace non-null assertions with safe null checks.

    Using non-null assertions (!) could lead to runtime errors. Consider adding explicit null checks.

    -    disposeObject(state.blockBreakMesh!, true)
    -    scene.remove(state.blockBreakMesh!)
    +    if (state.blockBreakMesh) {
    +      disposeObject(state.blockBreakMesh, true)
    +      scene.remove(state.blockBreakMesh)
    +    }
    🧹 Nitpick comments (2)
    src/mineflayer/plugins/mouse.ts (2)

    40-45: Add texture disposal to prevent memory leaks.

    The textures loaded for break animations are never disposed, which could lead to memory leaks when the plugin is unloaded.

    Add texture disposal in the bot's end event handler:

      bot.on('end', () => {
        if (state.blockBreakMesh) {
          disposeObject(state.blockBreakMesh, true)
          scene.remove(state.blockBreakMesh)
        }
        viewer.world.setHighlightCursorBlock(null)
    +   // Dispose textures to prevent memory leaks
    +   state.breakTextures.forEach(texture => {
    +     texture.dispose()
    +   })
    +   state.breakTextures = []
      })

    142-149: Add proper module exports and type interfaces.

    The mouse plugin implementation would benefit from clearer exports and interfaces for better code organization.

    Consider extracting the display manager and listeners into named exports with proper interfaces:

    interface MouseDisplayManager {
      updateBreakAnimation: (block?: Block, stage?: number | null) => void
      hideBreakAnimation: () => void
      updateCursorBlock: (data?: { block: Block }) => void
      dispose: () => void
    }
    
    export function createMouseDisplayManager(bot: Bot, scene: THREE.Scene, renderer: THREE.WebGLRenderer): MouseDisplayManager {
      // Implementation
    }
    
    export default function(bot: Bot) {
      // Plugin setup
    }
    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 06c06de and eb712ff.

    ⛔ Files ignored due to path filters (1)
    • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
    📒 Files selected for processing (4)
    • package.json (1 hunks)
    • src/cameraRotationControls.ts (1 hunks)
    • src/index.ts (2 hunks)
    • src/mineflayer/plugins/mouse.ts (1 hunks)
    🚧 Files skipped from review as they are similar to previous changes (1)
    • package.json
    🔇 Additional comments (3)
    src/index.ts (2)

    110-110: Clean and appropriate import added.

    The mouse plugin import is added correctly, which aligns with the PR objective of refactoring mouse controls.


    692-692: Plugin loading looks good.

    The mouse plugin is properly loaded into the bot instance, replacing the previous worldInteractions functionality.

    src/cameraRotationControls.ts (1)

    23-23: Improved mouse input control with new option.

    Adding the preciseMouseInput condition provides more granular control over mouse sensitivity and movement.

    @zardoy zardoy merged commit ceb4cb0 into next Feb 27, 2025
    2 of 3 checks passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant