minecraft-pi-ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1,142 @@
1
+ #Minecraft-Pi Ruby
2
+
3
+ ##Please note
4
+ This project is still in the early stages of development. It is not ready for use
5
+ with students and has not yet been pushed to RubyGems.
6
+
7
+ ##Overview
8
+
9
+ This is a Ruby gem to allow access to the Minecraft Pi Edition API from Ruby.
10
+ The aim is that the syntax is clear for fledgling coders to read and
11
+ understand as they work towards creating their own scripts.
12
+
13
+ All the fun of Minecraft Pi Edition and all the goodness of Ruby! With Sonic Pi,
14
+ KidsRuby and Minecraft, there really is no reason not to show you students the
15
+ joy of Ruby programming!
16
+
17
+ ##Introduction
18
+ The Pi Edition of Minecraft needs to be running for the gem to make a connection. Then you can use Ruby
19
+ code such as:
20
+ ```
21
+ Minecraft.world do
22
+ say "Hello from Ruby!"
23
+
24
+ position1 = Position.new(0,10,0)
25
+ position2 = Position.new(10,20,10)
26
+ make_cuboid(position1, position2, Block::DIAMOND_BLOCK)
27
+ sleep 2
28
+ make_cuboid(position1, position2, Block::AIR)
29
+
30
+ 10.times do |counter|
31
+ set_block(counter, 20, 0, Block::STONE)
32
+ set_block(counter, 20, 9, Block::STONE)
33
+ set_block(0, 20, counter, Block::STONE)
34
+ set_block(9, 20, counter, Block::STONE)
35
+ end
36
+
37
+ say "Bye from Ruby!"
38
+ end
39
+ ```
40
+
41
+ You can also instantiate a Minecraft object instead of writing script inside Ruby blocks.
42
+ For example:
43
+ ```
44
+ mc = Minecraft.new
45
+ mc.say 'Hello to Steve!'
46
+ mc.make_cuboid(16,18,16,20,20,20,Block::TNT,1)
47
+ mc.say 'Now go and click on the TNT!'
48
+ ```
49
+ ##Installation
50
+
51
+ TODO
52
+
53
+ ##Usage
54
+
55
+ So far, only the following commands have been implemented
56
+
57
+ - `say "message"` to display a message on the screen
58
+ - `set_camera_mode` to either `:fixed`, `:normal` or `:follow`
59
+ - `set_block` takes 3 values for the x, y and z location, or a Position (`Position.new(x,y,z)`)
60
+ - `set_blocks` is the same as `make_cuboid`. It takes 2 Positions and an ID for the block (see below), or
61
+ two sets of x,y,z coordinates followed by the block ID. For example: `make_cuboid(0,0,0,20,20,20,Block::OBSIDIAN)`.
62
+ - `get_ground_height(x,z)` or just `ground_height(x,z)` return the height of the ground at the (x,z) location
63
+ - `set_player_position(x,y,z)` or `set_player_position(Position)` moves the player to that position
64
+
65
+ ###Block IDs
66
+
67
+ Blocks can be set using and ID in the form Block::NAME. For example Block::TNT.
68
+
69
+ The blocks are:
70
+
71
+ - AIR numerical value is 0
72
+ - STONE numerical value is 1
73
+ - GRASS numerical value is 2
74
+ - DIRT numerical value is 3
75
+ - COBBLESTONE numerical value is 4
76
+ - WOOD_PLANKS numerical value is 5
77
+ - SAPLING numerical value is 6
78
+ - BEDROCK numerical value is 7
79
+ - WATER_FLOWING numerical value is 8
80
+ - WATER numerical value is WATER_FLOWING
81
+ - WATER_STATIONARY numerical value is 9
82
+ - LAVA_FLOWING numerical value is 10
83
+ - LAVA numerical value is LAVA_FLOWING
84
+ - LAVA_STATIONARY numerical value is 11
85
+ - SAND numerical value is 12
86
+ - GRAVEL numerical value is 13
87
+ - GOLD_ORE numerical value is 14
88
+ - IRON_ORE numerical value is 15
89
+ - COAL_ORE numerical value is 16
90
+ - WOOD numerical value is 17
91
+ - LEAVES numerical value is 18
92
+ - GLASS numerical value is 20
93
+ - LAPIS_LAZULI_ORE numerical value is 21
94
+ - LAPIS_LAZULI_BLOCK numerical value is 22
95
+ - SANDSTONE numerical value is 24
96
+ - BED numerical value is 26
97
+ - COBWEB numerical value is 30
98
+ - GRASS_TALL numerical value is 31
99
+ - WOOL numerical value is 35
100
+ - FLOWER_YELLOW numerical value is 37
101
+ - FLOWER_CYAN numerical value is 38
102
+ - MUSHROOM_BROWN numerical value is 39
103
+ - MUSHROOM_RED numerical value is 40
104
+ - GOLD_BLOCK numerical value is 41
105
+ - IRON_BLOCK numerical value is 42
106
+ - STONE_SLAB_DOUBLE numerical value is 43
107
+ - STONE_SLAB numerical value is 44
108
+ - BRICK_BLOCK numerical value is 45
109
+ - TNT numerical value is 46
110
+ - BOOKSHELF numerical value is 47
111
+ - MOSS_STONE numerical value is 48
112
+ - OBSIDIAN numerical value is 49
113
+ - TORCH numerical value is 50
114
+ - FIRE numerical value is 51
115
+ - STAIRS_WOOD numerical value is 53
116
+ - CHEST numerical value is 54
117
+ - DIAMOND_ORE numerical value is 56
118
+ - DIAMOND_BLOCK numerical value is 57
119
+ - CRAFTING_TABLE numerical value is 58
120
+ - FARMLAND numerical value is 60
121
+ - FURNACE_INACTIVE numerical value is 61
122
+ - FURNACE_ACTIVE numerical value is 62
123
+ - DOOR_WOOD numerical value is 64
124
+ - LADDER numerical value is 65
125
+ - STAIRS_COBBLESTONE numerical value is 67
126
+ - DOOR_IRON numerical value is 71
127
+ - REDSTONE_ORE numerical value is 73
128
+ - SNOW numerical value is 78
129
+ - ICE numerical value is 79
130
+ - SNOW_BLOCK numerical value is 80
131
+ - CACTUS numerical value is 81
132
+ - CLAY numerical value is 82
133
+ - SUGAR_CANE numerical value is 83
134
+ - FENCE numerical value is 85
135
+ - GLOWSTONE_BLOCK numerical value is 89
136
+ - BEDROCK_INVISIBLE numerical value is 95
137
+ - STONE_BRICK numerical value is 98
138
+ - GLASS_PANE numerical value is 102
139
+ - MELON numerical value is 103
140
+ - FENCE_GATE numerical value is 107
141
+ - GLOWING_OBSIDIAN numerical value is 246
142
+ - NETHER_REACTOR_CORE numerical value is 247
@@ -0,0 +1,74 @@
1
+ module Block
2
+ AIR = 0
3
+ STONE = 1
4
+ GRASS = 2
5
+ DIRT = 3
6
+ COBBLESTONE = 4
7
+ WOOD_PLANKS = 5
8
+ SAPLING = 6
9
+ BEDROCK = 7
10
+ WATER_FLOWING = 8
11
+ WATER = WATER_FLOWING
12
+ WATER_STATIONARY = 9
13
+ LAVA_FLOWING = 10
14
+ LAVA = LAVA_FLOWING
15
+ LAVA_STATIONARY = 11
16
+ SAND = 12
17
+ GRAVEL = 13
18
+ GOLD_ORE = 14
19
+ IRON_ORE = 15
20
+ COAL_ORE = 16
21
+ WOOD = 17
22
+ LEAVES = 18
23
+ GLASS = 20
24
+ LAPIS_LAZULI_ORE = 21
25
+ LAPIS_LAZULI_BLOCK = 22
26
+ SANDSTONE = 24
27
+ BED = 26
28
+ COBWEB = 30
29
+ GRASS_TALL = 31
30
+ WOOL = 35
31
+ FLOWER_YELLOW = 37
32
+ FLOWER_CYAN = 38
33
+ MUSHROOM_BROWN = 39
34
+ MUSHROOM_RED = 40
35
+ GOLD_BLOCK = 41
36
+ IRON_BLOCK = 42
37
+ STONE_SLAB_DOUBLE = 43
38
+ STONE_SLAB = 44
39
+ BRICK_BLOCK = 45
40
+ TNT = 46
41
+ BOOKSHELF = 47
42
+ MOSS_STONE = 48
43
+ OBSIDIAN = 49
44
+ TORCH = 50
45
+ FIRE = 51
46
+ STAIRS_WOOD = 53
47
+ CHEST = 54
48
+ DIAMOND_ORE = 56
49
+ DIAMOND_BLOCK = 57
50
+ CRAFTING_TABLE = 58
51
+ FARMLAND = 60
52
+ FURNACE_INACTIVE = 61
53
+ FURNACE_ACTIVE = 62
54
+ DOOR_WOOD = 64
55
+ LADDER = 65
56
+ STAIRS_COBBLESTONE = 67
57
+ DOOR_IRON = 71
58
+ REDSTONE_ORE = 73
59
+ SNOW = 78
60
+ ICE = 79
61
+ SNOW_BLOCK = 80
62
+ CACTUS = 81
63
+ CLAY = 82
64
+ SUGAR_CANE = 83
65
+ FENCE = 85
66
+ GLOWSTONE_BLOCK = 89
67
+ BEDROCK_INVISIBLE = 95
68
+ STONE_BRICK = 98
69
+ GLASS_PANE = 102
70
+ MELON = 103
71
+ FENCE_GATE = 107
72
+ GLOWING_OBSIDIAN = 246
73
+ NETHER_REACTOR_CORE = 247
74
+ end
@@ -0,0 +1,31 @@
1
+ require 'socket'
2
+
3
+ class Connection
4
+ def initialize (server = 'localhost', port = 4711)
5
+ begin
6
+ @socket = TCPSocket.new server, port
7
+ rescue
8
+ puts "Error connecting to Minecraft. Is it running?\n\n"
9
+ @socket.close if @socket
10
+ abort("#{$!}")
11
+ end
12
+ end
13
+
14
+ def send_command(command)
15
+ if @socket
16
+ @socket.puts command
17
+ else
18
+ puts "Not connected to Minecraft Pi! Is it running?"
19
+ end
20
+ end
21
+
22
+ def send_with_response(command)
23
+ send_command command
24
+ return @socket.gets.chomp
25
+ end
26
+
27
+
28
+ def Connection.finalize(id)
29
+ @socket.close if @socket
30
+ end
31
+ end
@@ -0,0 +1,87 @@
1
+ require_relative 'connection'
2
+ require_relative 'position'
3
+ require_relative 'blocks'
4
+
5
+ class Minecraft
6
+ include Block
7
+
8
+ def initialize(connection = nil)
9
+ @connection = connection
10
+ @connection ||= Connection.new
11
+ end
12
+
13
+ class << self
14
+ def control(&script)
15
+ mc = self.new
16
+ mc.instance_eval(&script)
17
+ end
18
+
19
+ alias_method :world, :control
20
+ end
21
+
22
+ def say(message)
23
+ @connection.send_command "chat.post(#{message})"
24
+ end
25
+
26
+ def set_camera_mode(mode)
27
+ @connection.send_command 'camera.mode.setNormal' if mode == :normal
28
+ @connection.send_command 'camera.mode.setFixed' if mode == :fixed
29
+ @connection.send_command 'camera.mode.setFollow' if mode == :follow
30
+ end
31
+
32
+ def set_block(*args)
33
+ command = "world.setBlock("
34
+ case args.length
35
+ when 2
36
+ command = command + "#{args[0]},#{args[1]})"
37
+ when 3
38
+ command += "#{args[0]},#{args[1]},#{args[2]})"
39
+ when 4
40
+ command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]})"
41
+ when 5
42
+ command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]})"
43
+ else
44
+ return
45
+ end
46
+ @connection.send_command command
47
+ end
48
+
49
+ def set_blocks(*args)
50
+ command = "world.setBlocks("
51
+ case args.length
52
+ when 3
53
+ command += "#{args[0]},#{args[1]},#{args[2]})"
54
+ when 4
55
+ command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]})"
56
+ when 7
57
+ command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]},#{args[5]},#{args[6]})"
58
+ when 8
59
+ command += "#{args[0]},#{args[1]},#{args[2]},#{args[3]},#{args[4]},#{args[5]},#{args[6]},#{args[7]})"
60
+ else
61
+ return
62
+ end
63
+ @connection.send_command command
64
+ end
65
+ alias_method :make_cuboid, :set_blocks
66
+
67
+ def get_ground_height(x,z)
68
+ return @connection.send_with_response "world.getHeight(#{x},#{z})"
69
+ #return s
70
+ end
71
+ alias_method :ground_height, :get_ground_height
72
+
73
+ def set_player_position(*args)
74
+ command = "player.setPos("
75
+ case args.length
76
+ when 1
77
+ command += "#{args[0].x},#{args[0].y},#{args[0].z})"
78
+ when 3
79
+ command += "#{args[0]},#{args[1]},#{args[2]})"
80
+ else
81
+ return
82
+ end
83
+ @connection.send_command command
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,52 @@
1
+ class Position
2
+
3
+ attr_accessor :x, :y, :z
4
+
5
+ def initialize (x,y,z)
6
+ @x=x
7
+ @y=y
8
+ @z=z
9
+ end
10
+
11
+ def to_s
12
+ "#{@x},#{@y},#{@z}"
13
+ end
14
+
15
+
16
+ def eql?(position)
17
+ self.class.equal?(position.class) &&
18
+ @x == position.x &&
19
+ @y == position.y &&
20
+ @z == position.z
21
+ end
22
+ alias == eql?
23
+
24
+ def +(position)
25
+ @x+=position.x
26
+ @y+=position.y
27
+ @z+=position.z
28
+ self
29
+ end
30
+
31
+ def -(position)
32
+ @x-=position.x
33
+ @y-=position.y
34
+ @z-=position.z
35
+ self
36
+ end
37
+
38
+ def *(scale)
39
+ if scale.is_a?(Numeric)
40
+ @x*=scale
41
+ @y*=scale
42
+ @z*=scale
43
+ elsif scale.is_a?(Position)
44
+ @x*=scale.x
45
+ @y*=scale.y
46
+ @z*=scale.z
47
+ end
48
+
49
+ self
50
+ end
51
+
52
+ end
@@ -0,0 +1,12 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ Gem::Specification.new do |s|
3
+ s.name = 'minecraft-pi-ruby'
4
+ s.description = 'Control Minecraft Pi Edition using the Ruby programming language.'
5
+ s.version = '0.0.1'
6
+ s.date = '2014-10-26'
7
+ s.summary = 'Minecraft Pi Edition Ruby'
8
+ s.homepage = 'https://github.com/eaglestone/minecraft-pi-ruby'
9
+ s.authors = ["Tim Eaglestone"]
10
+ s.email = ["tim.eaglestone@gmail.com"]
11
+ s.files = `git ls-files`.split("\n")
12
+ end
data/test.rb ADDED
@@ -0,0 +1,29 @@
1
+ require_relative "lib/minecraft-pi-ruby"
2
+
3
+ Minecraft.world do
4
+ say "Hello from Ruby!"
5
+
6
+ position1 = Position.new(0,10,0)
7
+ position2 = Position.new(10,20,10)
8
+ make_cuboid(position1, position2, Block::DIAMOND_BLOCK)
9
+ sleep 2
10
+ make_cuboid(position1, position2, Block::AIR)
11
+
12
+ 10.times do |counter|
13
+ set_block(counter, 20, 0, Block::STONE)
14
+ set_block(counter, 20, 9, Block::STONE)
15
+ set_block(0, 20, counter, Block::STONE)
16
+ set_block(9, 20, counter, Block::STONE)
17
+ end
18
+
19
+ say "Bye from Ruby!"
20
+ end
21
+
22
+
23
+ mc = Minecraft.new
24
+ mc.say 'Hello to Steve!'
25
+ mc.set_player_position(16,16,16)
26
+ sleep 2
27
+ mc.set_player_position(Position.new(28,18,28))
28
+ mc.make_cuboid(16,18,16,20,20,20,Block::TNT,1)
29
+ mc.say 'Now go and click on the TNT!'
@@ -0,0 +1,63 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/minecraft-pi-ruby'
3
+ require_relative '../lib/position'
4
+
5
+ describe Minecraft do
6
+
7
+ before do
8
+ @conn = MiniTest::Mock.new
9
+ @mc = Minecraft.new(@conn)
10
+ end
11
+
12
+ it "can be created" do
13
+ Minecraft.new.must_be_instance_of Minecraft
14
+ end
15
+
16
+ it "can have control called on an instant of the class" do
17
+ Minecraft.must_respond_to 'control'
18
+ end
19
+
20
+ it "responds to world being called on an instance" do
21
+ Minecraft.must_respond_to 'world'
22
+ end
23
+
24
+ it "should call the cameraFollow API with the right protocol" do
25
+ @conn.expect :send_command, :return_value, ['camera.mode.setNormal']
26
+ @mc.set_camera_mode :normal
27
+
28
+ assert @conn.verify
29
+ end
30
+
31
+ it "should send the setBock(x,y,z,id) message" do
32
+ @conn.expect :send_command, :return_value, ['world.setBlock(1,2,3,4)']
33
+ @mc.set_block(1,2,3,4)
34
+
35
+ assert @conn.verify
36
+ end
37
+
38
+ it "should send the setBlock(x,y,z,id) message when called with a Position" do
39
+ @conn.expect :send_command, :return_value, ['world.setBlock(1,2,3,4)']
40
+ @mc.set_block(Position.new(1,2,3),4)
41
+ @conn.verify
42
+ end
43
+
44
+ it "should handle the setBlocks with two positions given" do
45
+ @conn.expect :send_command, :return_value, ['world.setBlocks(0,0,0,10,10,10,1)']
46
+ @mc.set_blocks(Position.new(0,0,0),Position.new(10,10,10),1)
47
+ assert @conn.verify
48
+ end
49
+
50
+ it "should handle setBlocks with individual coords" do
51
+ @conn.expect :send_command, :return_value, ['world.setBlocks(0,0,0,3,3,3,2)']
52
+ @mc.set_blocks(0,0,0,3,3,3,2)
53
+ assert @conn.verify
54
+ end
55
+
56
+ it "gets the ground level" do
57
+ @conn.expect :send_with_response, 10, ['world.getHeight(4,5)']
58
+ height = @mc.get_ground_height(4,5)
59
+ assert @conn.verify
60
+ height.must_be_kind_of(Numeric)
61
+ end
62
+
63
+ end
@@ -0,0 +1,34 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/position'
3
+
4
+ describe Position do
5
+ before do
6
+ @pos = Position.new(1,2,3)
7
+ end
8
+ it "initialises with 3 integers for x, y and z" do
9
+ @pos.x.must_equal 1
10
+ @pos.y.must_equal 2
11
+ @pos.z.must_equal 3
12
+ end
13
+
14
+ it "returns to_s in a format for sending to server" do
15
+ @pos.to_s.must_equal "1,2,3"
16
+ end
17
+
18
+ it "is equal to another Position if the coords are the same" do
19
+ Position.new(1,2,3).must_equal @pos
20
+ end
21
+
22
+ it "adds the dimensions with another position object" do
23
+ (@pos + @pos).must_equal Position.new(2,4,6)
24
+ end
25
+
26
+ it "subtracts the dimensions with another position object" do
27
+ (@pos - @pos).must_equal Position.new(0,0,0)
28
+ end
29
+
30
+ it "does scalar multiplication" do
31
+ (@pos*4).must_equal Position.new(4,8,12)
32
+ end
33
+
34
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minecraft-pi-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Eaglestone
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-10-26 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Control Minecraft Pi Edition using the Ruby programming language.
15
+ email:
16
+ - tim.eaglestone@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - README.md
23
+ - lib/blocks.rb
24
+ - lib/connection.rb
25
+ - lib/minecraft-pi-ruby.rb
26
+ - lib/position.rb
27
+ - minecraft-pi-ruby.gemspec
28
+ - test.rb
29
+ - test/minecraft_spec.rb
30
+ - test/position_spec.rb
31
+ homepage: https://github.com/eaglestone/minecraft-pi-ruby
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 1.8.23
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Minecraft Pi Edition Ruby
55
+ test_files: []