Skip to content

Commit

Permalink
Rewrite client to use a global tick loop
Browse files Browse the repository at this point in the history
Only digging, use hand, change hotbar slot, and physics are part of this
loops sofar

Speed up the specs greatly using event emitter callbacks

Add apple to eating

Fix a ton of random anti-cheat issues

Fix a few inventory desync issues

Resolves #98
Resolves #97
  • Loading branch information
grepsedawk committed Aug 1, 2023
1 parent 7c2addd commit 4f248c6
Show file tree
Hide file tree
Showing 20 changed files with 282 additions and 190 deletions.
39 changes: 7 additions & 32 deletions spec/integration/attack_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,8 @@ Spectator.describe Rosegold::Bot do
Rosegold::Bot.new(client).try do |bot|
bot.chat "/kill @e[type=!minecraft:player]"
bot.chat "/fill -10 -60 -10 10 0 10 minecraft:air"
sleep 1
end
end
end

it "should be able to attack" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/tp @p -9 -60 9"
bot.chat "/time set 13000"
bot.chat "/kill @e[type=!minecraft:player]"
bot.chat "/clear"
sleep 1
bot.chat "/give #{bot.username} minecraft:diamond_sword"
bot.chat "/summon minecraft:zombie -9 -60 8 {NoAI:1}"
sleep 1
bot.inventory.pick! "diamond_sword"
bot.yaw = 180
bot.pitch = 0
20.times do
break if client.dimension.entities.select { |_, e| e.entity_type == 107 }.empty?
bot.chat "attack!"
bot.attack
bot.wait_ticks 20
end
# no zombies left
expect(client.dimension.entities.select { |_, e| e.entity_type == 107 }).to be_empty
bot.chat "/fill -10 -61 -10 10 -61 10 minecraft:bedrock"
bot.wait_tick
end
end
end
Expand All @@ -44,27 +19,27 @@ Spectator.describe Rosegold::Bot do
bot.chat "/time set 13000"
bot.chat "/kill @e[type=!minecraft:player]"
bot.chat "/clear"
bot.wait_ticks 5
bot.wait_for Rosegold::Clientbound::SetSlot

bot.chat "/give #{bot.username} minecraft:diamond_sword"
bot.wait_tick
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/fill -10 -60 8 0 -58 6 minecraft:dirt"
bot.wait_tick
bot.chat "/fill -9 -60 7 0 -58 7 minecraft:air"
bot.wait_tick
bot.chat "/fill -6 -60 7 -6 -60 7 minecraft:water"
bot.wait_tick
bot.chat "/fill -9 -59 8 -9 -59 8 minecraft:air"
bot.wait_tick
bot.chat "/summon minecraft:zombie -7 -60 7"
sleep 1

bot.inventory.pick! "diamond_sword"
bot.yaw = 180
bot.pitch = 0
20.times do
break if client.dimension.entities.select { |_, e| e.entity_type == 107 }.empty?
bot.chat "attack!"
bot.attack
bot.wait_ticks 20
bot.wait_ticks 13
end
# no zombies left
expect(client.dimension.entities.select { |_, e| e.entity_type == 107 }).to be_empty
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
require "../spec_helper"

Spectator.describe Rosegold::Bot do
before_all do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill 8 -60 8 8 0 8 minecraft:air"
bot.wait_tick
end
end
end

it "should be able to dig" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill 8 -60 8 8 -57 8 minecraft:dirt"
sleep 2 # load chunks
bot.chat "/tp 8 -56 8"
sleep 1 # teleport
bot.wait_tick

bot.look &.down
bot.start_digging
Expand All @@ -26,9 +34,8 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill 8 -60 8 8 -57 8 minecraft:dirt"
sleep 2 # load chunks
bot.chat "/tp 8 -56 8"
sleep 1 # teleport
bot.wait_tick

bot.look &.down
bot.start_digging
Expand All @@ -40,4 +47,24 @@ Spectator.describe Rosegold::Bot do
end
end
end

it "should be able to place blocks" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/give #{bot.username} dirt 64"
bot.wait_for Rosegold::Clientbound::SetSlot
starting_y = bot.feet.y

bot.pitch = 90
bot.inventory.pick! "dirt"
bot.start_using_hand
2.times do
bot.start_jump
bot.wait_ticks 20
end

expect(starting_y).to be < bot.feet.y
end
end
end
end
64 changes: 34 additions & 30 deletions spec/integration/inventory_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.count("bucket")).to eq 0
end
Expand All @@ -20,7 +20,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.chat "/give #{bot.username} minecraft:bucket 16"
bot.chat "/give #{bot.username} minecraft:bucket 1"
Expand All @@ -38,10 +38,10 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.chat "/give #{bot.username} minecraft:bucket 513"
sleep 1
bot.wait_ticks 5

expect(bot.inventory.count("bucket")).to eq 513
end
Expand All @@ -56,8 +56,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"

sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("diamond_pickaxe")).to eq false
expect(bot.inventory.pick("stone")).to eq false
Expand All @@ -72,9 +71,11 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone 42"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:grass_block 43"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("stone")).to eq true
expect(bot.inventory.main_hand.item_id).to eq "stone"
Expand All @@ -90,9 +91,11 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone #{64*9}"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:grass_block 1"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

expect(bot.inventory.pick("grass_block")).to eq true
expect(bot.inventory.main_hand.item_id).to eq "grass_block"
Expand All @@ -108,7 +111,7 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
expect { bot.inventory.pick!("diamond_pickaxe") }.to raise_error(Rosegold::Inventory::ItemNotFoundError)
end
end
Expand All @@ -120,7 +123,9 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_pickaxe{Damage:1550,Enchantments:[{id:efficiency,lvl:1}]} 1"
bot.wait_for Rosegold::Clientbound::SetSlot
expect { bot.inventory.pick!("diamond_pickaxe") }.to raise_error(Rosegold::Inventory::ItemNotFoundError)
end
end
Expand All @@ -133,17 +138,17 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[{Slot:7b, id: \"minecraft:diamond_sword\",Count:1b}]}"
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
bot.wait_tick

bot.pitch = 90
bot.use_hand
sleep 1
expect(bot.inventory.withdraw_at_least(1, "diamond_sword")).to eq 1
bot.wait_for Rosegold::Clientbound::WindowItems

sleep 1
expect(bot.inventory.withdraw_at_least(1, "diamond_sword")).to eq 1

local_inventory = bot.inventory.inventory.map &.dup
local_hotbar = bot.inventory.hotbar.map &.dup
Expand All @@ -152,9 +157,9 @@ Spectator.describe Rosegold::Bot do
expect((local_inventory + local_hotbar).map(&.item_id)).to contain "diamond_sword"
expect(local_content.map(&.item_id)).not_to contain "diamond_sword"

sleep 1
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems
bot.wait_tick

expect(local_inventory.map(&.item_id)).to match_array bot.inventory.inventory.map(&.item_id)
expect(local_hotbar.map(&.item_id)).to match_array bot.inventory.hotbar.map(&.item_id)
Expand All @@ -172,16 +177,16 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[]}"
bot.chat "/clear"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_sword 1"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.pitch = 90
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems

expect(bot.inventory.deposit_at_least(1, "diamond_sword")).to eq 1

Expand All @@ -192,9 +197,8 @@ Spectator.describe Rosegold::Bot do
expect((local_inventory + local_hotbar).map(&.item_id)).not_to contain "diamond_sword"
expect(local_content.map(&.item_id)).to contain "diamond_sword"

sleep 1
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems

expect(local_inventory.map(&.item_id)).to match_array bot.inventory.inventory.map(&.item_id)
expect(local_hotbar.map(&.item_id)).to match_array bot.inventory.hotbar.map(&.item_id)
Expand All @@ -213,21 +217,18 @@ Spectator.describe Rosegold::Bot do
Rosegold::Bot.new(client).try do |bot|
bot.chat "/tp #{bot.username} -10 -60 -10"
bot.chat "/fill ~ ~ ~ ~ ~ ~ minecraft:air"
sleep 1
bot.wait_tick
bot.chat "/setblock ~ ~ ~ minecraft:chest{Items:[{Slot:7b, id: \"minecraft:diamond_sword\",Count:1b}]}"
bot.chat "/clear"
sleep 1

bot.pitch = 90
bot.use_hand
sleep 1
bot.wait_for Rosegold::Clientbound::WindowItems
bot.inventory.withdraw_at_least(1, "diamond_sword")

sleep 1

bot.inventory.close

sleep 1
bot.wait_tick

slots_before_reload = bot.inventory.slots

Expand All @@ -251,14 +252,17 @@ Spectator.describe Rosegold::Bot do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/clear"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:diamond_sword 4"
bot.wait_for Rosegold::Clientbound::SetSlot
bot.chat "/give #{bot.username} minecraft:stone 200"
sleep 1
bot.wait_for Rosegold::Clientbound::SetSlot

bot.look = Rosegold::Look.new 0, 0
expect(bot.inventory.throw_all_of "diamond_sword").to eq 4
expect(bot.inventory.throw_all_of "stone").to eq 200

sleep 1
bot.wait_tick

expect(bot.inventory.inventory.map(&.item_id)).not_to contain "diamond_sword"
expect(bot.inventory.hotbar.map(&.item_id)).not_to contain "diamond_sword"
Expand Down
25 changes: 16 additions & 9 deletions spec/integration/movement_spec.cr
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
require "../spec_helper"

Spectator.describe Rosegold::Bot do
before_all do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
bot.chat "/kill @e[type=!minecraft:player]"
bot.chat "/fill -10 -60 -10 10 0 10 minecraft:air"
bot.chat "/fill -10 -61 -10 10 -61 10 minecraft:bedrock"
bot.wait_tick
end
end
end

it "should fall due to gravity" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
sleep 2 # load chunks
bot.chat "/tp 1 -58 1"
sleep 1 # teleport
bot.wait_tick
until client.player.on_ground?
bot.wait_tick
end
Expand All @@ -18,9 +28,8 @@ Spectator.describe Rosegold::Bot do
it "can move to location successfully" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
sleep 2 # load chunks
bot.chat "/tp 1 -60 1"
sleep 1 # teleport
bot.wait_tick

bot.move_to 2, 2
expect(bot.feet).to eq(Rosegold::Vec3d.new(2.5, -60, 2.5))
Expand Down Expand Up @@ -52,9 +61,8 @@ Spectator.describe Rosegold::Bot do
it "should jump and fall" do
client.join_game do |client|
Rosegold::Bot.new(client).try do |bot|
sleep 2 # load chunks
bot.chat "/tp 1 -60 1"
sleep 1 # teleport
bot.wait_tick

initial_feet = bot.feet

Expand All @@ -77,17 +85,16 @@ Spectator.describe Rosegold::Bot 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
bot.wait_tick

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
bot.wait_tick
end
end
end
Expand Down
Loading

0 comments on commit 4f248c6

Please sign in to comment.