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 +7 -0
- data/lib/craft_client.rb +11 -0
- data/lib/craft_client/server.rb +157 -0
- metadata +45 -0
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
|
data/lib/craft_client.rb
ADDED
|
@@ -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: []
|