Skip to content

feat(ruby): make JSON status protocol configurable and expose mismatch metadata#2

Open
ryush00 wants to merge 1 commit intomasterfrom
codex/ruby-status-protocol-config
Open

feat(ruby): make JSON status protocol configurable and expose mismatch metadata#2
ryush00 wants to merge 1 commit intomasterfrom
codex/ruby-status-protocol-config

Conversation

@ryush00
Copy link
Member

@ryush00 ryush00 commented Feb 24, 2026

Summary

This PR removes the hardcoded JSON status handshake protocol (760) in Ruby MineStat and introduces configurable protocol selection while preserving backward-compatible default behavior.

What changed

  • Replaced fixed pack_varint(760) with dynamic handshake protocol resolution.
  • Added status_protocol option support:
    • Integer: use explicit protocol
    • :auto or nil: use default auto mode
  • Added metadata fields:
    • requested_protocol
    • response_protocol
    • protocol_mismatch
  • Kept existing public API behavior intact.
  • Added docs clarifying that response_protocol is not always backend server version in proxy stacks (Velocity/Bungee/ViaVersion).
  • Added tests for:
    • explicit protocol injection
    • auto mode default behavior
    • mismatch recorded as metadata (no error)

Why

In proxy/ViaVersion environments, status responses may be shaped by requester protocol and version.protocol may be rewritten. A fixed handshake protocol can produce misleading observations and false version assumptions.

Validation

  • ruby -I Ruby/lib Ruby/test/test_status_protocol.rb
  • Live checks against real servers with low/in-range/high protocol inputs confirmed mismatch metadata behavior.

…h metadata

- remove hardcoded JSON handshake protocol varint (760)

- add status_protocol option (Integer, :auto, nil)

- keep backward-compatible auto behavior via DEFAULT_JSON_STATUS_PROTOCOL (760)

- expose requested_protocol, response_protocol, protocol_mismatch

- record protocol mismatch as metadata without raising errors

- document proxy rewrite caveat (Velocity/Bungee/ViaVersion)

- add tests for explicit protocol injection, auto mode, and mismatch handling
@gemini-code-assist
Copy link

Summary of Changes

Hello @ryush00, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the Ruby MineStat library by introducing a configurable JSON status handshake protocol, moving away from a hardcoded value. This change, along with the exposure of detailed protocol mismatch metadata, aims to provide more accurate and transparent server status observations, especially in complex proxy environments where protocol versions might be manipulated or differ between request and response.

Highlights

  • Configurable JSON Status Protocol: The hardcoded JSON status handshake protocol (760) has been replaced with a configurable option, allowing users to specify an integer protocol or use an auto mode.
  • Exposure of Mismatch Metadata: New metadata fields (requested_protocol, response_protocol, protocol_mismatch) are now exposed to provide insight into the protocol used for the request and received in the response, and whether they differ.
  • Documentation and Tests: The ReadMe.md has been updated with usage examples and clarifications, and new tests have been added to validate the explicit protocol injection, auto mode, and mismatch recording.
Changelog
  • Ruby/ReadMe.md
    • Added a new section "JSON status protocol selection" with examples for explicit and auto protocol modes.
    • Documented the new requested_protocol, response_protocol, and protocol_mismatch attributes.
    • Included a note clarifying response_protocol behavior in proxy stacks.
  • Ruby/lib/minestat.rb
    • Defined DEFAULT_JSON_STATUS_PROTOCOL constant.
    • Updated initialize method to accept status_protocol option and initialize new metadata instance variables.
    • Modified json_request to use the selected_status_protocol for the handshake and to populate requested_protocol, response_protocol, and protocol_mismatch based on the response.
    • Added normalize_status_protocol and selected_status_protocol private helper methods for managing protocol selection.
    • Added attr_reader for requested_protocol, response_protocol, and protocol_mismatch.
    • Added documentation to json_request regarding proxy environments.
  • Ruby/test/test_status_protocol.rb
    • Added a new test file containing FakeJsonSocket and MineStatProtocolHarness for mocking network interactions.
    • Included tests to verify explicit status protocol sending, auto mode behavior, and correct recording of protocol mismatch metadata.
Activity
  • No human activity (comments, reviews, approvals) has occurred on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ryush00
Copy link
Member Author

ryush00 commented Feb 24, 2026

/gemini review

@ryush00
Copy link
Member Author

ryush00 commented Feb 24, 2026

@codex review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request introduces configurable JSON status protocol selection and exposes metadata about the requested and response protocols, which is a valuable enhancement for environments with proxy servers. The changes are well-documented in the ReadMe.md and include new tests to cover the added functionality. The code appears to be correct and follows good practices for Ruby development.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request introduces configurable JSON status protocol selection and exposes mismatch metadata, which is a valuable enhancement for environments with proxy stacks. The changes are well-documented in the ReadMe.md and the new functionality is covered by comprehensive tests. The code is generally clean and follows good practices. I've provided some minor suggestions for clarity and consistency.

ms = MineStat.new("minecraft.frag.land", 25565, 3, MineStat::Request::SLP, false, false)
```

### JSON status protocol selection

Choose a reason for hiding this comment

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

medium

The heading "JSON status protocol selection" is a bit verbose. Consider shortening it to "JSON Protocol Selection" or similar for conciseness.

- `response_protocol`: protocol from `version.protocol` in response JSON (if present)
- `protocol_mismatch`: whether request/response protocol values differ

In proxy stacks (Velocity/Bungee) and ViaVersion setups, `version.protocol` may be rewritten or shaped by requester protocol. Do not assume `response_protocol` is always the backend server's real version.

Choose a reason for hiding this comment

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

medium

This note is very important and is also present in the code comments. Consider making it more prominent, perhaps with a warning icon or a bolded "Important Note:" prefix, to draw more attention to it.

Comment on lines +53 to +55
# Default protocol version used for JSON status handshakes in auto mode.
# This preserves the current behavior while keeping future protocol bumps centralized.
DEFAULT_JSON_STATUS_PROTOCOL = 760

Choose a reason for hiding this comment

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

medium

The comment for DEFAULT_JSON_STATUS_PROTOCOL is good, but it could be slightly more concise. The phrase "This preserves the current behavior while keeping future protocol bumps centralized" is a bit long for a constant's comment.

  # Default protocol version used for JSON status handshakes in auto mode.
  # Centralizes protocol version for future updates while maintaining backward compatibility.

Comment on lines +168 to +170
@requested_protocol # protocol used in JSON status handshake
@response_protocol # protocol returned by JSON status response
@protocol_mismatch # protocol mismatch between request and response?

Choose a reason for hiding this comment

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

medium

The comments for @requested_protocol, @response_protocol, and @protocol_mismatch are good, but they could be aligned for better readability, similar to other instance variables above.

    @protocol                  # protocol level
    @requested_protocol        # protocol used in JSON status handshake
    @response_protocol         # protocol returned by JSON status response
    @protocol_mismatch         # protocol mismatch between request and response?

Comment on lines +622 to +625
#
# The response protocol is not always the real backend server protocol.
# Proxy stacks such as Velocity/Bungee may shape status responses from the
# requester protocol, and ViaVersion may rewrite `version.protocol`.

Choose a reason for hiding this comment

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

medium

This comment block is very important for understanding the response_protocol behavior. It's good that it's included here and in the README. Consider using a consistent phrasing for this note across both locations.

Comment on lines +752 to +754
def normalize_status_protocol(protocol)
return :auto if protocol.nil? || protocol == :auto
return protocol if protocol.is_a?(Integer)

Choose a reason for hiding this comment

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

medium

The normalize_status_protocol method's logic is clear. However, the return protocol if protocol.is_a?(Integer) line could be combined with the raise ArgumentError to make the intent of the if statement clearer: if it's not nil or :auto, it must be an Integer.

    return :auto if protocol.nil? || protocol == :auto
    raise ArgumentError, "status_protocol must be an Integer, :auto, or nil" unless protocol.is_a?(Integer)
    protocol

Comment on lines +953 to +962
# Protocol used in the JSON status handshake request
# @note `:auto`/`nil` mode uses {DEFAULT_JSON_STATUS_PROTOCOL}
attr_reader :requested_protocol

# Protocol observed in JSON status response (`version.protocol`)
# @note In proxy environments (Velocity/Bungee/ViaVersion), this may not match backend server protocol
attr_reader :response_protocol

# Whether requested and response protocols are different
attr_reader :protocol_mismatch

Choose a reason for hiding this comment

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

medium

The attr_reader comments for requested_protocol, response_protocol, and protocol_mismatch are well-written and provide good context. Ensure that the spacing for these new attr_reader definitions is consistent with the existing ones for better readability.

  attr_reader :protocol

  # Protocol used in the JSON status handshake request
  # @note `:auto`/`nil` mode uses {DEFAULT_JSON_STATUS_PROTOCOL}
  attr_reader :requested_protocol

  # Protocol observed in JSON status response (`version.protocol`)
  # @note In proxy environments (Velocity/Bungee/ViaVersion), this may not match backend server protocol
  attr_reader :response_protocol

  # Whether requested and response protocols are different
  attr_reader :protocol_mismatch

end

class MineStatStatusProtocolTest < Minitest::Test
def decode_varint(data, offset = 0)

Choose a reason for hiding this comment

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

medium

The test class name MineStatStatusProtocolTest is descriptive. However, for consistency with Ruby's naming conventions, it's common to use TestMineStatStatusProtocol or MineStat::StatusProtocolTest.

Comment on lines +123 to +124
packet_id = handshake_packet.getbyte(packet_len_size)
raise "Unexpected packet id: #{packet_id}" unless packet_id == 0

Choose a reason for hiding this comment

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

medium

The raise statement here is good for ensuring the packet ID is as expected. However, in a test helper, it might be more robust to return nil or raise a more specific test-related error, or even assert the packet ID directly in the test method if it's critical for the test's premise.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b25d745f53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# @return [Integer, Symbol] Integer protocol or :auto
def normalize_status_protocol(protocol)
return :auto if protocol.nil? || protocol == :auto
return protocol if protocol.is_a?(Integer)

Choose a reason for hiding this comment

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

P2 Badge Reject out-of-range status_protocol values

normalize_status_protocol currently accepts any Integer, but pack_varint later truncates to 32 bits (value &= 0xFFFFFFFF), so large values are silently rewritten on the wire while requested_protocol still exposes the original input. In practice, passing something like 1 << 40 sends protocol 0, which can produce incorrect status responses and misleading mismatch metadata instead of honoring the caller’s explicit protocol request.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant