craft_client 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 592c72705373be273846ad8d1cb49469e054a70e
4
+ data.tar.gz: 231ad9f9885fef0b0404072954714310b40d4d69
5
+ SHA512:
6
+ metadata.gz: 87de667d615450eb2a21387b765ae21dafb9b34cd4e7ae3b9cd824888acf177848fb486e40a7d1fdcaef4a885162b99cc183378d4ccd0ca518939a32c1373511
7
+ data.tar.gz: d62dc48e8c33f26d14d4356333f32b20621796c91c746f82095eea4f919ec61c7225601f6563efda7d241f76ed0e4bd2f76992f7f63791a7dac4c504969cd614
@@ -0,0 +1,11 @@
1
+ module CraftClient
2
+ NAME = 'CraftClient'
3
+ VERSION = '0.0.1'
4
+
5
+ CHUNK_SIZE = 32
6
+ end
7
+
8
+ require 'net/http'
9
+ require 'socket'
10
+
11
+ require_relative 'craft_client/server'
@@ -0,0 +1,157 @@
1
+ module CraftClient
2
+ class Server
3
+ attr_accessor :block_cache
4
+ attr_reader :username, :players
5
+
6
+ def initialize(username, identity_token, server_name, server_port)
7
+ @username = username
8
+ @identity_token = identity_token
9
+
10
+ @server_name = server_name
11
+ @server_port = server_port
12
+ @block_cache = {}
13
+ @players = {}
14
+
15
+ @write_mutex = Mutex.new
16
+
17
+ @buffer = ''
18
+
19
+ @tcp = nil
20
+ end
21
+
22
+ def connect
23
+ # Authenticate with craft.michaelfogleman.com
24
+ uri = URI.parse('https://craft.michaelfogleman.com/api/1/identity')
25
+ http = Net::HTTP.new(uri.host, uri.port)
26
+ http.use_ssl = true
27
+
28
+ response = http.post(uri.request_uri, "username=#{@username}&identity_token=#{@identity_token}")
29
+ server_token = response.body.chomp
30
+ fail 'Could not authenticate!' if server_token.length != 32
31
+
32
+ # Connect and authenticate with the server
33
+ @tcp = TCPSocket.new(@server_name, @server_port)
34
+ @tcp.puts("A,#{@username},#{server_token}")
35
+ end
36
+
37
+ def get_event
38
+ # Blocks and returns an event hash
39
+ data = @tcp.gets.chomp.split(',')
40
+
41
+ case data[0]
42
+ when 'T' # Chat message
43
+ message_contents = data[1 .. -1].join(',')
44
+ if !message_contents.split('>')[1].nil? # If message was said by player
45
+ return { type: :chat_message, sender: message_contents.split('>')[0], message: message_contents.split('>')[1 .. -1].join('>').lstrip }
46
+ else
47
+ return { type: :chat_special, message: message_contents }
48
+ end
49
+ when 'B' # Block change
50
+ pos = [data[3].to_i, data[4].to_i, data[5].to_i] # Create the position data
51
+ return nil if data[1].to_i != pos[0] / CHUNK_SIZE || data[2].to_i != pos[2] / CHUNK_SIZE
52
+ @block_cache[pos] = data[6].to_i
53
+ return { type: :block_change, pos: pos, id: data[6].to_i }
54
+ when 'S' # Sign change
55
+ return { type: :sign_update, pos: [data[3].to_i, data[4].to_i, data[5].to_i], facing: data[6].to_i, text: (data[7..-1] || []).join(',') }
56
+ when 'N' # Player join
57
+ prepare_player(data[1].to_i)
58
+ @players[data[1].to_i][:name] = data[2..-1].join(',')
59
+ return { type: :player_join, id: data[1].to_i, name: data[2..-1].join(',') }
60
+ when 'P' # Player position
61
+ prepare_player(data[1].to_i)
62
+ @players[data[1].to_i][:pos] = data[2..-1].map(&:to_f)
63
+ return { type: :player_position, id: data[1].to_i, pos: @players[data[1].to_i][:pos] }
64
+ when 'D' # Player leave
65
+ event = { type: :player_leave, id: data[1].to_i, name: @players[data[1].to_i][:name] }
66
+ @players.delete(data[1].to_i)
67
+ return event
68
+ else
69
+ return nil
70
+ end
71
+ end
72
+
73
+ def get_block(x, y, z) # get_block_at
74
+ # Return block if it exists in cache
75
+ return @block_cache[[x, y, z]] unless @block_cache[[x, y, z]].nil?
76
+
77
+ # Otherwise, request the chunk the block is in.
78
+ @write_mutex.synchronize do
79
+ chunk_x = (x / CHUNK_SIZE).floor
80
+ chunk_z = (z / CHUNK_SIZE).floor
81
+ @tcp.puts("C,#{chunk_x},#{chunk_z}")
82
+ @tcp.flush
83
+
84
+ # Keep mutex locked to stop other threads requesting from server
85
+ loop do
86
+ data = @tcp.gets.chomp.split(',')
87
+ if data[0] == 'B'
88
+ @block_cache[[data[3].to_i, data[4].to_i, data[5].to_i]] = data[6].to_i
89
+ elsif data[0] == 'C'
90
+ break
91
+ end
92
+ end
93
+ end
94
+
95
+ @block_cache[[x, y, z]]
96
+ end
97
+
98
+ def set_block(x, y, z, id) # set_block
99
+ @block_cache[[x, y, z]] = id
100
+ @write_mutex.synchronize do
101
+ @buffer += "B,#{x},#{y},#{z},#{id}\n"
102
+ end
103
+ end
104
+
105
+ def flush_buffer
106
+ @write_mutex.synchronize do
107
+ @tcp.write(@buffer)
108
+ @tcp.flush
109
+ @buffer = ''
110
+ end
111
+ end
112
+
113
+ def send_chat_message(message)
114
+ @write_mutex.synchronize do
115
+ message.lines.each do |line|
116
+ @buffer += "T,#{line.chomp}\n"
117
+ end
118
+ end
119
+ end
120
+
121
+ def send_private_message(player, message)
122
+ @write_mutex.synchronize do
123
+ message.lines.each do |line|
124
+ @buffer += "T,@#{player} #{line.chomp}\n"
125
+ end
126
+ end
127
+ end
128
+
129
+ def set_sign(x, y, z, facing, text)
130
+ @write_mutex.synchronize do
131
+ @buffer += "S,#{x},#{y},#{z},#{facing},#{text}\n"
132
+ end
133
+ end
134
+
135
+ def set_position(x, y, z, rotate_x, rotate_y)
136
+ @write_mutex.synchronize do
137
+ @buffer += "P,#{x.to_f},#{y.to_f},#{z.to_f},#{rotate_x.to_f},#{rotate_y.to_f}\n"
138
+ end
139
+ end
140
+
141
+ def set_light(x, y, z, light)
142
+ @write_mutex.synchronize do
143
+ @buffer += "L,#{x},#{y},#{z},#{light}\n"
144
+ end
145
+ end
146
+
147
+ def disconnect
148
+ @tcp.close unless @tcp.nil?
149
+ end
150
+
151
+ private
152
+
153
+ def prepare_player(id)
154
+ @players[id] = { name: nil, pos: nil } if @players[id].nil?
155
+ end
156
+ end
157
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: craft_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - nick
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Ruby client library for Craft
14
+ email: nick@nxk.me
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/craft_client.rb
20
+ - lib/craft_client/server.rb
21
+ homepage: https://github.com/nicko-/craft_client
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.4.5
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Craft client
45
+ test_files: []