minecraft 0.0.2 → 0.0.3
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.
- data/README.md +9 -5
- data/lib/minecraft.rb +1 -0
- data/lib/minecraft/commands.rb +143 -0
- data/lib/minecraft/data.rb +8 -1
- data/lib/minecraft/extensions.rb +102 -92
- data/lib/minecraft/server.rb +4 -8
- data/lib/minecraft/version.rb +1 -1
- metadata +3 -2
data/README.md
CHANGED
@@ -29,23 +29,27 @@ Current Features
|
|
29
29
|
- Give the user an item with a quantity of up to 2560 (by default Minecraft
|
30
30
|
will cap at 64).
|
31
31
|
- Use the item ID or item name. http://minecraftwiki.net/wiki/Data_values
|
32
|
+
- !giveall <item> <quantity>
|
32
33
|
- !tp <target_user>
|
34
|
+
- !tpall
|
33
35
|
- !nom
|
34
|
-
- !
|
36
|
+
- !nomall
|
37
|
+
- !kit <group>
|
35
38
|
- Diamond
|
36
39
|
- Gold armour
|
37
40
|
- Armour
|
38
41
|
- Ranged
|
39
42
|
- Nether
|
40
43
|
- Portal
|
44
|
+
- !kitall <group>
|
45
|
+
- !addtimer <item> <frequency>
|
46
|
+
- !deltimer <item>
|
47
|
+
- !printtimer
|
48
|
+
- !list
|
41
49
|
|
42
50
|
TODO
|
43
51
|
----
|
44
52
|
|
45
|
-
- Improved error handling.
|
46
|
-
- Log time users have spent on the server.
|
47
|
-
- !give timers (give user A an item every X seconds).
|
48
|
-
|
49
53
|
Contributors
|
50
54
|
------------
|
51
55
|
|
data/lib/minecraft.rb
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
module Minecraft
|
2
|
+
module Commands
|
3
|
+
include Data
|
4
|
+
|
5
|
+
def give(user, *args)
|
6
|
+
item, quantity = items_arg(1, args)
|
7
|
+
item = resolve_item(item)
|
8
|
+
|
9
|
+
quantify(user, item, quantity)
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate_kit(group = "")
|
13
|
+
return true if KITS.include? group.to_sym
|
14
|
+
@server.puts "say #{group} is not a valid kit."
|
15
|
+
kitlist
|
16
|
+
end
|
17
|
+
|
18
|
+
def kit(user, group)
|
19
|
+
KITS[group.to_sym].each do |item|
|
20
|
+
if item.is_a? Array
|
21
|
+
@server.puts quantify(user, item.first, item.last)
|
22
|
+
else
|
23
|
+
@server.puts "give #{user} #{item} 1"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def tp(user, target)
|
29
|
+
@server.puts "tp #{user} #{target}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def tpall(user, *args)
|
33
|
+
@users.each { |u| tp(u, user) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def nom(user)
|
37
|
+
@server.puts "give #{user} 322 1"
|
38
|
+
end
|
39
|
+
|
40
|
+
def list(user)
|
41
|
+
l = @users.inject("") do |s, u|
|
42
|
+
if u == user
|
43
|
+
pre = "["
|
44
|
+
suf = "]"
|
45
|
+
end
|
46
|
+
suf = "*" + (suf || "") if is_op? u
|
47
|
+
s + "#{", " unless s.empty?}#{pre}#{u}#{suf}"
|
48
|
+
end
|
49
|
+
@server.puts "say #{l}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def addtimer(user, *args)
|
53
|
+
item, duration = items_arg(30, args)
|
54
|
+
item = resolve_item(item)
|
55
|
+
@timers[user] ||= {}
|
56
|
+
@timers[user][item] = duration
|
57
|
+
@server.puts "say Timer added for #{user}. Giving #{item} every #{duration} seconds."
|
58
|
+
end
|
59
|
+
|
60
|
+
def deltimer(user, *args)
|
61
|
+
item = args.join(" ")
|
62
|
+
item = resolve_item(item)
|
63
|
+
@timers[user][item] = nil if @timers.has_key? user
|
64
|
+
end
|
65
|
+
|
66
|
+
def printtimer(user)
|
67
|
+
@server.puts "say Timer is at #{@counter}."
|
68
|
+
end
|
69
|
+
|
70
|
+
def help(*args)
|
71
|
+
@server.puts <<-eof
|
72
|
+
say !tp target_user
|
73
|
+
say !kit kit_name
|
74
|
+
say !give item quantity
|
75
|
+
say !nom
|
76
|
+
say !list
|
77
|
+
say !addtimer item frequency
|
78
|
+
say !deltimer item
|
79
|
+
eof
|
80
|
+
end
|
81
|
+
|
82
|
+
def kitlist(*args)
|
83
|
+
@server.puts "say Kits: #{KITS.keys.join(", ")}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def quantify(user, item, quantity)
|
87
|
+
if quantity <= 64
|
88
|
+
@server.puts "give #{user} #{item} #{quantity}"
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
quantity = 2560 if quantity > 2560
|
93
|
+
full_quantity = (quantity / 64.0).floor
|
94
|
+
sub_quantity = quantity % 64
|
95
|
+
@server.puts "give #{user} #{item} 64\n" * full_quantity
|
96
|
+
@server.puts "give #{user} #{item} #{sub_quantity}" if sub_quantity > 0
|
97
|
+
end
|
98
|
+
|
99
|
+
def items_arg(default, args)
|
100
|
+
if args.length == 1
|
101
|
+
second = default
|
102
|
+
first = args.first
|
103
|
+
else
|
104
|
+
if args.last.to_i.to_s == args.last # Last argument is an integer.
|
105
|
+
second = args.last.to_i
|
106
|
+
first = args[0..-2].join(" ")
|
107
|
+
else
|
108
|
+
second = default
|
109
|
+
first = args[0..-1].join(" ")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
return [first, second]
|
113
|
+
end
|
114
|
+
|
115
|
+
def resolve_item(item)
|
116
|
+
item.to_i.to_s == item ? item.to_i : DATA_VALUE_HASH[resolve_key(item.downcase)]
|
117
|
+
end
|
118
|
+
|
119
|
+
def resolve_key(key)
|
120
|
+
bucket = key[0]
|
121
|
+
return key if ITEM_BUCKETS[bucket].include? key
|
122
|
+
|
123
|
+
puts "Finding #{key} approximate in #{ITEM_BUCKETS[bucket]}"
|
124
|
+
shortest_diff = nil
|
125
|
+
shortest_key = nil
|
126
|
+
ITEM_BUCKETS[bucket].each do |test_key|
|
127
|
+
if test_key.length > key.length
|
128
|
+
diff = test_key.length - key.length if test_key.index(key)
|
129
|
+
else
|
130
|
+
diff = key.length - test_key.length if key.index(test_key)
|
131
|
+
end
|
132
|
+
next if diff.nil?
|
133
|
+
|
134
|
+
if shortest_diff.nil? or diff < shortest_diff
|
135
|
+
shortest_key = test_key
|
136
|
+
shortest_diff = diff
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
return shortest_key
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/minecraft/data.rb
CHANGED
@@ -70,7 +70,7 @@ module Minecraft
|
|
70
70
|
"lava" => "10",
|
71
71
|
"dead shrubs" => "32",
|
72
72
|
"double stone slab" => "43",
|
73
|
-
"furnace
|
73
|
+
"furnace" => "61",
|
74
74
|
"fence" => "85",
|
75
75
|
"stationary lava " => "11",
|
76
76
|
"piston" => "33",
|
@@ -246,5 +246,12 @@ module Minecraft
|
|
246
246
|
"saddle" => "329",
|
247
247
|
"cocoa beans" => "351"
|
248
248
|
}
|
249
|
+
|
250
|
+
ITEM_BUCKETS = {}
|
251
|
+
DATA_VALUE_HASH.each_key do |key|
|
252
|
+
bucket = key[0]
|
253
|
+
ITEM_BUCKETS[bucket] ||= []
|
254
|
+
ITEM_BUCKETS[bucket] << key
|
255
|
+
end
|
249
256
|
end
|
250
257
|
end
|
data/lib/minecraft/extensions.rb
CHANGED
@@ -1,31 +1,108 @@
|
|
1
|
+
require "json/pure"
|
2
|
+
|
1
3
|
module Minecraft
|
2
4
|
class Extensions
|
3
|
-
include
|
5
|
+
include Commands
|
4
6
|
|
5
|
-
def initialize
|
6
|
-
@ops = File.readlines("ops.txt").map { |s| s.
|
7
|
+
def initialize(server)
|
8
|
+
@ops = File.readlines("ops.txt").map { |s| s.chomp }
|
9
|
+
@userlog = get_user_log
|
7
10
|
@users = []
|
11
|
+
@timers = {}
|
12
|
+
@counter = 0
|
13
|
+
@logon_time = {}
|
14
|
+
@server = server
|
15
|
+
|
16
|
+
# Command set.
|
17
|
+
@commands = {}
|
18
|
+
add_command(:give, :ops => true, :all => true, :all_message => "is putting out.")
|
19
|
+
add_command(:tp, :ops => false, :all => true, :all_message => "is teleporting all users to their location.")
|
20
|
+
add_command(:kit, :ops => true, :all => true, :all_message => "is providing kits to all.")
|
21
|
+
add_command(:help, :ops => false, :all => false)
|
22
|
+
add_command(:nom, :ops => true, :all => true, :all_message => "is providing noms to all.")
|
23
|
+
add_command(:list, :ops => false, :all => false)
|
24
|
+
add_command(:addtimer, :ops => true, :all => false)
|
25
|
+
add_command(:deltimer, :ops => true, :all => false)
|
26
|
+
add_command(:printtimer, :ops => true, :all => false)
|
27
|
+
add_command(:kitlist, :ops => false, :all => false)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_user_log
|
31
|
+
if File.exists? "user.log"
|
32
|
+
JSON.parse(File.read("user.log"))
|
33
|
+
else
|
34
|
+
{}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_log
|
39
|
+
File.open("user.log", "w") { |f| f.print @userlog.to_json }
|
40
|
+
end
|
41
|
+
|
42
|
+
def call_command(user, command, *args)
|
43
|
+
is_all = command.to_s.end_with? "all"
|
44
|
+
root = command.to_s.chomp("all").to_sym
|
45
|
+
return invalid_command(command) unless @commands.include? root
|
46
|
+
|
47
|
+
# Any `all` suffixed command requires ops.
|
48
|
+
if @commands[root][:ops] or (is_all and @commands[root][:all])
|
49
|
+
return if !validate_ops(user, command)
|
50
|
+
end
|
51
|
+
|
52
|
+
if respond_to? "validate_" + root.to_s
|
53
|
+
return unless send("validate_" + root.to_s, *args)
|
54
|
+
end
|
55
|
+
|
56
|
+
if is_all
|
57
|
+
@server.puts "say #{user} #{@commands[root][:all_message]}"
|
58
|
+
if respond_to? command
|
59
|
+
send(command, user, *args)
|
60
|
+
else
|
61
|
+
@users.each { |u| send(root, u, *args) }
|
62
|
+
end
|
63
|
+
else
|
64
|
+
send(root, user, *args)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_command(command, opts)
|
69
|
+
@commands[command] = opts
|
8
70
|
end
|
9
71
|
|
10
72
|
def process(line)
|
11
73
|
puts line
|
12
74
|
return info_command(line) if line.index "INFO"
|
75
|
+
rescue Exception => e
|
76
|
+
puts "An error has occurred."
|
77
|
+
puts e
|
78
|
+
puts e.backtrace
|
79
|
+
end
|
80
|
+
|
81
|
+
def periodic
|
82
|
+
@counter += 1
|
83
|
+
@users.each do |user|
|
84
|
+
next unless @timers.has_key? user
|
85
|
+
@timers[user].each do |item, duration|
|
86
|
+
next if duration.nil?
|
87
|
+
@server.puts "give #{user} #{item} 64" if @counter % duration == 0
|
88
|
+
end
|
89
|
+
end
|
13
90
|
end
|
14
91
|
|
15
92
|
def info_command(line)
|
16
93
|
line.gsub! /^.*?\[INFO\]\s+/, ''
|
17
|
-
meta_check(line)
|
94
|
+
return if meta_check(line)
|
18
95
|
match_data = line.match /^\<(.*?)\>\s+!(.*?)$/
|
19
96
|
return if match_data.nil?
|
20
97
|
|
21
98
|
user = match_data[1]
|
22
99
|
args = match_data[2].split(" ")
|
23
|
-
|
100
|
+
call_command(user, args.slice!(0).to_sym, *args)
|
24
101
|
end
|
25
102
|
|
26
103
|
def meta_check(line)
|
27
|
-
return if check_ops(line)
|
28
|
-
return if check_join_part(line)
|
104
|
+
return true if check_ops(line)
|
105
|
+
return true if check_join_part(line)
|
29
106
|
end
|
30
107
|
|
31
108
|
def check_ops(line)
|
@@ -43,111 +120,44 @@ module Minecraft
|
|
43
120
|
user = line.split(" ").first
|
44
121
|
if line.index "lost connection"
|
45
122
|
@users.reject! { |u| u == user }
|
123
|
+
log_time(user)
|
46
124
|
return true
|
47
125
|
elsif line.index "logged in"
|
48
126
|
@users << user
|
127
|
+
@logon_time[user] = Time.now
|
49
128
|
return true
|
50
129
|
end
|
51
130
|
end
|
52
131
|
|
53
132
|
def method_missing(sym, *args)
|
54
|
-
if DATA_VALUE_HASH.has_key? sym.downcase
|
133
|
+
if DATA_VALUE_HASH.has_key? sym.downcase and is_op? args.first
|
55
134
|
give(args.first, sym, args.last)
|
56
135
|
else
|
57
136
|
puts "Invalid command given."
|
58
137
|
end
|
59
138
|
end
|
60
139
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def give(user, *args)
|
72
|
-
return privilege_error(user, "give") unless is_op? user
|
73
|
-
return mc_give(user, *args)
|
74
|
-
end
|
75
|
-
|
76
|
-
def mc_give(user, *args)
|
77
|
-
if args.length == 1
|
78
|
-
quantity = 1
|
79
|
-
item = args.first
|
80
|
-
else
|
81
|
-
quantity = args.last.to_i || 1
|
82
|
-
item = args[0..-2].join(" ")
|
83
|
-
end
|
84
|
-
item = (item.to_i.to_s == item) ? item.to_i : DATA_VALUE_HASH[item.downcase]
|
85
|
-
|
86
|
-
return quantify(user, item, quantity)
|
87
|
-
end
|
88
|
-
|
89
|
-
def kit(user, group)
|
90
|
-
return privilege_error(user, "kit") unless is_op? user
|
91
|
-
return "say #{group} is not a valid kit." unless KITS.has_key? group.to_sym
|
92
|
-
ret = ""
|
93
|
-
|
94
|
-
KITS[group.to_sym].each do |item|
|
95
|
-
if item.is_a? Array
|
96
|
-
ret += quantify(user, item.first, item.last)
|
97
|
-
else
|
98
|
-
ret += "give #{user} #{item} 1\n"
|
99
|
-
end
|
100
|
-
end
|
101
|
-
return ret.chop
|
102
|
-
end
|
103
|
-
|
104
|
-
def tp(user, target)
|
105
|
-
"tp #{user} #{target}"
|
106
|
-
end
|
107
|
-
|
108
|
-
def tpall(user)
|
109
|
-
return privilege_error(user, "tpall", "Wow, #{user} actually tried to pull that...") unless is_op? user
|
110
|
-
ret = "say #{user} is teleporting all users to their location.\n"
|
111
|
-
@users.each do |u|
|
112
|
-
ret += tp(u, user)
|
113
|
-
end
|
114
|
-
return ret
|
115
|
-
end
|
116
|
-
|
117
|
-
def nom(user)
|
118
|
-
return privilege_error(user, "nom", "No noms for you!") unless is_op? user
|
119
|
-
"give #{user} 322 1"
|
120
|
-
end
|
121
|
-
|
122
|
-
def help(*args)
|
123
|
-
<<-eof
|
124
|
-
say !tp target_user
|
125
|
-
say !tpall
|
126
|
-
say !kit kit_name
|
127
|
-
say !give item quantity
|
128
|
-
say !giveall item quantity
|
129
|
-
say !nom
|
130
|
-
say /help
|
131
|
-
eof
|
132
|
-
end
|
133
|
-
|
134
|
-
def quantify(user, item, quantity)
|
135
|
-
return "give #{user} #{item} #{quantity}" if quantity <= 64
|
136
|
-
|
137
|
-
quantity = 2560 if quantity > 2560
|
138
|
-
full_quantity = (quantity / 64.0).floor
|
139
|
-
sub_quantity = quantity % 64
|
140
|
-
ret = "give #{user} #{item} 64\n" * full_quantity
|
141
|
-
ret += "give #{user} #{item} #{sub_quantity}"
|
142
|
-
return ret
|
140
|
+
def log_time(user)
|
141
|
+
logoff = Time.now
|
142
|
+
logon = @logon_time[user]
|
143
|
+
time_spent = logoff - logon
|
144
|
+
@userlog[user] ||= 0
|
145
|
+
@userlog[user] += time_spent
|
146
|
+
@server.puts "say #{user} spent #{time_spent} seconds the server, totalling to #{@userlog[user]}."
|
147
|
+
write_log
|
143
148
|
end
|
144
149
|
|
145
150
|
def is_op?(user)
|
146
151
|
@ops.include? user
|
147
152
|
end
|
148
153
|
|
149
|
-
def
|
150
|
-
|
154
|
+
def validate_ops(user, command)
|
155
|
+
return true if is_op? user
|
156
|
+
@server.puts "say #{user} is not an op, cannot use !#{command}."
|
157
|
+
end
|
158
|
+
|
159
|
+
def invalid_command(command)
|
160
|
+
@server.puts "say #{command} is invalid."
|
151
161
|
end
|
152
162
|
end
|
153
163
|
end
|
data/lib/minecraft/server.rb
CHANGED
@@ -5,18 +5,14 @@ module Minecraft
|
|
5
5
|
attr_accessor :sin
|
6
6
|
|
7
7
|
def initialize(command)
|
8
|
-
@extensions = Extensions.new
|
9
8
|
@sin, @sout, @serr = Open3.popen3(command)
|
9
|
+
@extensions = Extensions.new(@sin)
|
10
10
|
threads = []
|
11
|
-
threads << Thread.new { loop { process(@sout.gets) } }
|
12
|
-
threads << Thread.new { loop { process(@serr.gets) } }
|
11
|
+
threads << Thread.new { loop { @extensions.process(@sout.gets) } }
|
12
|
+
threads << Thread.new { loop { @extensions.process(@serr.gets) } }
|
13
|
+
threads << Thread.new { loop { @extensions.periodic; sleep 1 } }
|
13
14
|
threads << Thread.new { loop { @sin.puts gets } }
|
14
15
|
threads.each(&:join)
|
15
16
|
end
|
16
|
-
|
17
|
-
def process(line)
|
18
|
-
result = @extensions.process(line)
|
19
|
-
@sin.puts(result) unless result.nil?
|
20
|
-
end
|
21
17
|
end
|
22
18
|
end
|
data/lib/minecraft/version.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: minecraft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Andrew Horsman
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-14 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- Rakefile
|
41
41
|
- bin/minecraft
|
42
42
|
- lib/minecraft.rb
|
43
|
+
- lib/minecraft/commands.rb
|
43
44
|
- lib/minecraft/data.rb
|
44
45
|
- lib/minecraft/extensions.rb
|
45
46
|
- lib/minecraft/server.rb
|