minecraft 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|