Skip to content

Commit

Permalink
Throw Physics::MovementStuck upon stuck movement
Browse files Browse the repository at this point in the history
This allows the exception to be caught directly in bots
  • Loading branch information
grepsedawk committed Jun 14, 2023
1 parent d94f35c commit 9a205f6
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
28 changes: 18 additions & 10 deletions spec/integration/bot_spec.cr → spec/integration/movement_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,24 @@ Spectator.describe Rosegold::Bot do
end
end

it "should select a different hotbar slot" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/tp 1 -60 1"

bot.hotbar_selection = 4
expect(bot.hotbar_selection).to eq 4

bot.hotbar_selection = 7
expect(bot.hotbar_selection).to eq 7
describe "#move_to" do
context "when movement is stuck" do
it "throws Physics::MovementStuck" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
sleep 2 # load chunks
bot.chat "/fill 1 -60 2 1 -60 2 minecraft:stone"
bot.chat "/tp 1 -60 1"
sleep 1 # teleport

expect {
bot.move_to 1, 2
}.to raise_error(Rosegold::Physics::MovementStuck)

bot.chat "/fill 1 -60 2 1 -60 2 minecraft:air"
sleep 1
end
end
end
end
end
Expand Down
15 changes: 8 additions & 7 deletions src/rosegold/control/action.cr
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
class Rosegold::Action(T)
SUCCESS = "" # TODO use unique symbol

# TODO try channel size 1 so #succeed/#fail aren't rendezvous
getter channel : Channel(String) = Channel(String).new
getter channel : Channel(Exception | Nil) = Channel(Exception | Nil).new
getter target : T

def initialize(@target : T); end

def succeed
@channel.send(SUCCESS)
@channel.send nil
end

def fail(msg : String)
@channel.send(msg)
@channel.send Exception.new msg
end

def fail(exception : Exception)
@channel.send exception
end

# Throw error if it failed
def join
result = channel.receive
raise Exception.new(result) if result != Action::SUCCESS
raise result if result
end
end
7 changes: 6 additions & 1 deletion src/rosegold/control/physics.cr
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ class Rosegold::Physics
# TODO: this only works with gravity on
on_ground = movement.y > input_velocity.y

@movement_action.try &.fail "Stuck at #{feet}" unless feet != player.feet
unless feet != player.feet
@movement_action.try &.fail MovementStuck.new "Stuck at #{feet}"
@movement_action = nil
end

send_movement_packet feet, look, on_ground
player.velocity = next_velocity
Expand All @@ -185,6 +188,8 @@ class Rosegold::Physics
client.emit_event Event::PhysicsTick.new movement
end

class MovementStuck < Exception; end

private def send_movement_packet(feet : Vec3d, look : Look, on_ground : Bool)
# anticheat requires sending these different packets
if feet != player.feet
Expand Down

0 comments on commit 9a205f6

Please sign in to comment.