Class RotationManager

java.lang.Object
me.hackware.api.RotationManager

public final class RotationManager extends Object
Single-slot rotation manager.

Modules submit a rotation each tick they want to be active. Higher priority replaces a lower-priority active request. The active request lives for one tick — the owner must re-submit each tick to keep it active. There is no queue, no suppliers, no instant flag.

Three submission entry points:

  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Runs at the very start of every tick — before any module's tick handler has had a chance to (re)submit.
    get()
     
    The id of the active request, or null.
    double
    The priority of the active request, or Double.NEGATIVE_INFINITY.
    boolean
     
    float
     
    double
     
    double
     
    float
     
    double
     
    float
    Current rotation target pitch — clamped to [-90, 90].
    float
    The player's real (un-spoofed) pitch at the start of this tick.
    float
    The player's real (un-spoofed) yaw at the start of this tick.
    float
    The pitch the server most recently saw.
    float
    The yaw the server most recently saw.
    float
    Current rotation target yaw — the angle that gets sent in the next packet.
    void
     
    boolean
    Whether the active request is a look on the tick's flying packet (requestSilentRotation(java.lang.String, double, float, float) on these wires).
    boolean
    Whether the active request is in MOTION mode.
    boolean
    Whether any rotation request is currently active.
    boolean
    Whether the packet being sent right now is our own silent-aim PosRot (for SEND listeners).
    boolean
    Whether the active request is in SILENT mode.
    boolean
    justTeleported(int withinTicks)
    True within withinTicks client ticks of the last server teleport.
    static boolean
    Whether silent looks ride the tick's flying packet here (see requestSilentRotation(java.lang.String, double, float, float)): on a wire where a look of its own is a Grim tick, on foot.
    void
    The tick's flying packet is sent: a look claimed for it has been carried and ends here.
    void
    sendPosition is starting: the window for claiming this tick's look is over.
    void
    travel() is starting this tick: a look claimed from here on could not steer the movement.
    boolean
    pulseSilentRotation(double priority, float yaw, float pitch)
    One-shot silent look that does NOT take the rotation slot: the extra PosRot goes out now and whoever owns the slot keeps it.
    void
    Explicitly release the active request if it is owned by id.
    boolean
    requestMotionRotation(String id, double priority, float yaw, float pitch)
    Force MOTION mode — rotation is applied via vanilla sendPosition.
    boolean
    requestMotionRotationCameraAnchored(String id, double priority, float yaw, float pitch)
    Force MOTION mode, anchoring the sent yaw to the real CAMERA yaw instead of the last-sent yaw.
    boolean
    requestMotionRotationExact(String id, double priority, float yaw, float pitch)
    Force MOTION mode, sending the yaw and pitch bit for bit as given: no re-basing onto the last-sent or camera yaw, whose float arithmetic can land an ulp off.
    boolean
    requestRotation(String id, double priority, float yaw, float pitch)
    Submit a rotation using the global mode from the Rotations settings module (defaults to MOTION if the module is missing).
    boolean
    requestSilentRotation(String id, double priority, float yaw, float pitch)
    Force SILENT mode — an extra PosRot packet is sent immediately so following action packets validate against the spoofed angles.
    boolean
    requestSilentRotation(String id, double priority, float yaw, float pitch, net.minecraft.world.phys.AABB target)
    requestSilentRotation(String, double, float, float) for an action aimed at target (a clicked block's box, an attacked entity's): where the look rides the flying packet and the tick's look is claimed already, the request is served by that look if its ray hits target, so a second action on the same spot needs no look of its own.
    void
    Makes the next flying packet carry the motion look even if vanilla would leave it out: it sends a look only when it differs from the last one sendPosition sent, which a packet sent around it (a teleport's confirm, a silent look) can leave stale, so a held look never reaches the server.
    static boolean
    Whether a look sent in a packet of its own, beside the tick's flying packet, is free with Grim on this wire.
    static void
    setContainerScreenClientOnly(boolean clientOnly)
    Declares that the container GUI currently drawn has no menu behind it on the server — the caller closed the container server-side and is keeping the screen up only so the player does not see it blink.
    boolean
    Whether this tick's flying packet must carry a look whatever vanilla thinks: one a packet the server may have dropped after a teleport carried (see mirrorMove).
    int
    How many server teleports have arrived; compare two reads to tell whether one came in between.
    float
    usePitch(float pitch)
    The pitch counterpart of useYaw(float).
    float
    useYaw(float yaw)
    The yaw a use-item packet sent under the active request must carry: on a wire where silent looks ride the flying packet, exactly the one it will carry (Grim's BadPacketsJ compares the two bit for bit); elsewhere yaw as given.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • get

      public static RotationManager get()
    • init

      public void init()
    • teleportCount

      public int teleportCount()
      How many server teleports have arrived; compare two reads to tell whether one came in between.
    • justTeleported

      public boolean justTeleported(int withinTicks)
      True within withinTicks client ticks of the last server teleport. Used by ClientInputMixin to suppress a frame-perfect jump on the ack tick: Grim resets its sim to the teleport position and doesn't know the client's ground state there yet, so a jump (or a KB verified) on that exact tick is unpredictable — the one-off Simulation .42 (unpredicted jump) and AntiKB .078 / A: 0.0 (airborne-vs-grounded phase mismatch) flags while jump-spamming through pearl teleports. No human times a jump onto the ack tick, so a one-tick suppression is vanilla-invisible.
    • requestRotation

      public boolean requestRotation(String id, double priority, float yaw, float pitch)
      Submit a rotation using the global mode from the Rotations settings module (defaults to MOTION if the module is missing).
      Returns:
      true if accepted (took the active slot), false if a higher-priority request already owns the slot this tick.
    • requestMotionRotation

      public boolean requestMotionRotation(String id, double priority, float yaw, float pitch)
      Force MOTION mode — rotation is applied via vanilla sendPosition.
    • requestMotionRotationCameraAnchored

      public boolean requestMotionRotationCameraAnchored(String id, double priority, float yaw, float pitch)
      Force MOTION mode, anchoring the sent yaw to the real CAMERA yaw instead of the last-sent yaw. For movement rotations (Sprint) whose target oscillates ~180° via WASD flips: serverYaw-anchoring resolves every 180° flip the same way (−180) and spirals the sent yaw unbounded (−298→−478→−658…). Camera-anchoring keeps it oscillating around the stable camera yaw. Do NOT use for combat aim — an aim target hovering exactly 180° from the camera would flip 360° on tiny changes (AimModulo360).
    • requestMotionRotationExact

      public boolean requestMotionRotationExact(String id, double priority, float yaw, float pitch)
      Force MOTION mode, sending the yaw and pitch bit for bit as given: no re-basing onto the last-sent or camera yaw, whose float arithmetic can land an ulp off. For a look a packet already carried, which the flying packet must repeat exactly (Grim's BadPacketsJ compares a use's look with the tick's by float equality). The caller keeps the yaw within 180° of the last one sent.
    • requestSilentRotation

      public boolean requestSilentRotation(String id, double priority, float yaw, float pitch)
      Force SILENT mode — an extra PosRot packet is sent immediately so following action packets validate against the spoofed angles. The next vanilla sendPosition restores the real yaw.

      Where that packet is a Grim tick of its own (looksRideFlying()), nothing is sent: the look is claimed for the tick's flying packet, and the action packets sent before it are judged against it. The caller sends them right away, as on any wire. One look per flying packet: once a tick's look is claimed, a request for another one is refused (unless within SAME_LOOK), and so is one made after travel(), or between ticks, where the movement can no longer follow it. A refused caller sends no action this tick. release(java.lang.String) keeps a claimed look until the flying packet has carried it.

    • requestSilentRotation

      public boolean requestSilentRotation(String id, double priority, float yaw, float pitch, net.minecraft.world.phys.AABB target)
      requestSilentRotation(String, double, float, float) for an action aimed at target (a clicked block's box, an attacked entity's): where the look rides the flying packet and the tick's look is claimed already, the request is served by that look if its ray hits target, so a second action on the same spot needs no look of its own.
    • looksRideFlying

      public static boolean looksRideFlying()
      Whether silent looks ride the tick's flying packet here (see requestSilentRotation(java.lang.String, double, float, float)): on a wire where a look of its own is a Grim tick, on foot. Gliding the look steers the glide and the movement module's travel() overrides the physics, and riding the vehicle moves the player, so there a silent look is still sent as a packet of its own (a TickTimer setback on these wires: the accepted price of acting in flight).
    • isFlyingLook

      public boolean isFlyingLook()
      Whether the active request is a look on the tick's flying packet (requestSilentRotation(java.lang.String, double, float, float) on these wires).
    • useYaw

      public float useYaw(float yaw)
      The yaw a use-item packet sent under the active request must carry: on a wire where silent looks ride the flying packet, exactly the one it will carry (Grim's BadPacketsJ compares the two bit for bit); elsewhere yaw as given.
    • usePitch

      public float usePitch(float pitch)
      The pitch counterpart of useYaw(float).
    • separateLooksFree

      public static boolean separateLooksFree()
      Whether a look sent in a packet of its own, beside the tick's flying packet, is free with Grim on this wire. Only a 1.17-1.20.x client has the 1.17 duplicate: a PosRot at the last position Grim neither counts (Timer) nor simulates. From 1.21 every flying packet is a tick to it (Timer, and the start of Post's window), and on 1.21.2+ TickTimer sets back a second one before the tick's end. There a look has to ride the tick's own flying packet, as a motion rotation.
    • resendMotionLook

      public void resendMotionLook()
      Makes the next flying packet carry the motion look even if vanilla would leave it out: it sends a look only when it differs from the last one sendPosition sent, which a packet sent around it (a teleport's confirm, a silent look) can leave stale, so a held look never reaches the server.
    • pulseSilentRotation

      public boolean pulseSilentRotation(double priority, float yaw, float pitch)
      One-shot silent look that does NOT take the rotation slot: the extra PosRot goes out now and whoever owns the slot keeps it. For a caller that fires right before the tick's flying packet, where taking and releasing the slot would strip a motion rotation off that packet. The caller is responsible for not pulsing with a container screen open.
      Returns:
      false if a higher-priority request owns the slot (nothing is sent)
    • release

      public void release(String id)
      Explicitly release the active request if it is owned by id. Modules normally don't need this — just stop re-submitting. A look claimed for this tick's flying packet stays until that packet has carried it (the actions sent under it are judged against it there).
    • onTravel

      public void onTravel()
      travel() is starting this tick: a look claimed from here on could not steer the movement.
    • takeLookResend

      public boolean takeLookResend()
      Whether this tick's flying packet must carry a look whatever vanilla thinks: one a packet the server may have dropped after a teleport carried (see mirrorMove). Asked once, by sendPosition.
    • onPreSendPosition

      public void onPreSendPosition()
      sendPosition is starting: the window for claiming this tick's look is over.
    • onFlyingSent

      public void onFlyingSent()
      The tick's flying packet is sent: a look claimed for it has been carried and ends here.
    • isRotating

      public boolean isRotating()
      Whether any rotation request is currently active.
    • isMotionActive

      public boolean isMotionActive()
      Whether the active request is in MOTION mode.
    • isSilentActive

      public boolean isSilentActive()
      Whether the active request is in SILENT mode.
    • getActiveId

      public String getActiveId()
      The id of the active request, or null.
    • getActivePriority

      public double getActivePriority()
      The priority of the active request, or Double.NEGATIVE_INFINITY.
    • getYaw

      public float getYaw()
      Current rotation target yaw — the angle that gets sent in the next packet. Returns the real client yaw when no request is active.
    • getPitch

      public float getPitch()
      Current rotation target pitch — clamped to [-90, 90]. Returns the real client pitch when no request is active.
    • getRealYaw

      public float getRealYaw()
      The player's real (un-spoofed) yaw at the start of this tick.
    • getRealPitch

      public float getRealPitch()
      The player's real (un-spoofed) pitch at the start of this tick.
    • getServerYaw

      public float getServerYaw()
      The yaw the server most recently saw.
    • getServerPitch

      public float getServerPitch()
      The pitch the server most recently saw.
    • getLastSentX

      public double getLastSentX()
    • getLastSentY

      public double getLastSentY()
    • getLastSentZ

      public double getLastSentZ()
    • getLastSentYaw

      public float getLastSentYaw()
    • getLastSentPitch

      public float getLastSentPitch()
    • getLastSentOnGround

      public boolean getLastSentOnGround()
    • isSendingSilent

      public boolean isSendingSilent()
      Whether the packet being sent right now is our own silent-aim PosRot (for SEND listeners).
    • beginTick

      public void beginTick()
      Runs at the very start of every tick — before any module's tick handler has had a chance to (re)submit. We snapshot the real rotation here so getRealYaw() reflects the user's current intent, and we expire any active request that was submitted in a previous tick (the owner failed to re-submit). Called from Minecraft.tick's head right before TickStartEvent is posted, so that no listener of it, whatever its priority, requests before the tick has begun here.
    • setContainerScreenClientOnly

      public static void setContainerScreenClientOnly(boolean clientOnly)
      Declares that the container GUI currently drawn has no menu behind it on the server — the caller closed the container server-side and is keeping the screen up only so the player does not see it blink. While set, a rotation request does not dismiss the screen: from the server's point of view no container is open, so the look change is vanilla-legal. Callers set it around the rotation and clear it in a finally.