minecraft 0.1.0 → 0.2.0

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/CHANGES.md CHANGED
@@ -1,3 +1,25 @@
1
+ 0.2.0 (2011-08-21)
2
+ ------------------
3
+
4
+ * Added configuration file capability.
5
+ * Added `!points`, `!board`, `!kickvote`, `!vote`, `!cancelvote`, `!kickvotes`, `!roulette`, `change_time`, `!om`, `!dehop`, `!op`
6
+ * Added time changes (morning, night, dawn, etc...)
7
+ * Separated half-op and op privileges.
8
+ * `!property` now lists properties if none specified.
9
+ * Bugfix for `all` style commands (makes sure `:all => true`) is specified.
10
+ * `switch` is an alias for `lever`
11
+ * Refactored file saving/loading.
12
+ * Bugfix for default CLI options.
13
+ * Now saves instance files as well as executes `save-all` periodically.
14
+ * Bugfix for `uptime` stuff, offline users now can be computed.
15
+
16
+ 0.1.0 (2011-08-20)
17
+ ------------------
18
+
19
+ * Added yadocs.
20
+ * Updated README.
21
+ * Added test suites.
22
+
1
23
  0.0.5 (2011-08-17)
2
24
  ------------------
3
25
 
data/README.md CHANGED
@@ -44,7 +44,8 @@ Please refer to `Minecraft::Extensions#initialize`.
44
44
  !printtimer # Print timers of the user.
45
45
  !printtime # Print the current counter time.
46
46
  !list # List the connected users, notes ops.
47
- !property # Check a server property (!property spawn-monsters).
47
+ !property <key> # Check a server property by key.
48
+ !property # List server properties available.
48
49
  !s <label> <command> # Associates a command to a shortcut label for the user.
49
50
  !s <label> # Runs the command with the associated label.
50
51
  !shortcuts # Lists the users shortcuts.
@@ -52,6 +53,23 @@ Please refer to `Minecraft::Extensions#initialize`.
52
53
  !uptime <user> # Prints the uptime of the given user.
53
54
  !uptime # Prints the uptime of the current user.
54
55
  !help # Outputs the help contents.
56
+ !hop <user> # Give a user half-op privileges.
57
+ !dehop <user> # Remove a users half-op privileges.
58
+ !morning # Change time of day to morning.
59
+ !evening # Change time of day to evening.
60
+ !day # Change time of day to daytime.
61
+ !night # Change time of day to night.
62
+ !dawn # Change time of day to dawn.
63
+ !dusk # Change time of day to dusk.
64
+ !roulette # Kick a random person, person requesting has a higher chance.
65
+ !kickvote <user> # Initiate or vote for a kickvote against a user.
66
+ !kickvote # Vote to kick the last initiated user.
67
+ !vote # Vote to kick the last initiated user.
68
+ !cancelvote <user> # Cancel to kickvote on a user.
69
+ !points <user> <quantity> # Give a user points.
70
+ !board <user> # Check a users points.
71
+ !board # View the leaderboard of points.
72
+ !om <noms> # Give golden apples equivalent to the number of noms.
55
73
 
56
74
  Development Path
57
75
  ----------------
@@ -3,18 +3,32 @@
3
3
  require "slop"
4
4
  require "minecraft"
5
5
 
6
+ class Slop
7
+ alias :option_core :option
8
+ def option(*args, &block)
9
+ args << {} unless args.last.is_a? Hash
10
+ key = (args.first.is_a? Symbol and args[1].is_a? Symbol) ? args[1] : args.first
11
+ args.last[:default] = $default[key] if $default.has_key? key
12
+ return option_core(*args, &block)
13
+ end
14
+ end
15
+
16
+ $default = Minecraft::Tools.get_configuration_file
17
+
6
18
  opts = Slop.parse :help => true do
7
19
  banner "Usage: minecraft [options]"
8
20
 
9
- on :n, :no_run, "Don't run the Minecraft server instance."
10
- on :u, :update, "Download the latest version of the Minecraft server jarfile."
11
- on :s, :min_memory, "Specify the minimum amount of memory to allocate.", :optional => true
12
- on :x, :max_memory, "Specify the maximum amount of memory to allocate.", :optional => true
13
- on :no_auto_save, "Disable auto save."
14
- on :m, :tempmobs, "Temporarily toggles mobs."
15
- on :r, :rules, "Specify the server rules.", :optional => true
16
- on :f, :savefreq, "Specify the frequency in seconds to save the server.", :optional => true
17
- on :w, :welcome_message, "Specfiy a welcome message to connecting users.", :optional => true
21
+ option :n, :no_run, "Don't run the Minecraft server instance."
22
+ option :u, :update, "Download the latest version of the Minecraft server jarfile."
23
+ option :s, :min_memory, "Specify the minimum amount of memory to allocate.", :optional => true
24
+ option :x, :max_memory, "Specify the maximum amount of memory to allocate.", :optional => true
25
+ option :no_auto_save, "Disable auto save."
26
+ option :m, :tempmobs, "Temporarily toggles mobs."
27
+ option :r, :rules, "Specify the server rules.", :optional => true
28
+ option :f, :savefreq, "Specify the frequency in seconds to save the server.", :optional => true
29
+ option :w, :welcome_message, "Specfiy a welcome message to connecting users.", :optional => true
30
+ option :vote_threshold, "Specify the threshold of votes to kick somebody.", :optional => true
31
+ option :vote_expiration, "Specify the expiration time in seconds for kickvotes to expire.", :optional => true
18
32
  end
19
33
 
20
34
  runtime = Minecraft::Runtime.new(opts)
@@ -4,6 +4,232 @@ module Minecraft
4
4
  module Commands
5
5
  include Data
6
6
 
7
+ # Gives a user a specific amount of points, the quantity is capped
8
+ # depending on the privileges of the user.
9
+ #
10
+ # @params [String] user The requesting user.
11
+ # @params [String] target_user The target user to give points to.
12
+ # @params [Integer] points Quantity of points to give.
13
+ # @example
14
+ # points("basicxman", "mike_n_7")
15
+ # points("basicxman", "mike_n_7", "50")
16
+ def points(user, target_user, num_points = 1)
17
+ num_points = [num_points.to_i, cap_points(user)].min
18
+ @points[target_user] ||= 0
19
+ @points[target_user] += num_points
20
+ @server.puts "say #{user} has given #{target_user} #{num_points} points for a total of #{@points[target_user]}."
21
+ end
22
+
23
+ # Checks a users points or displays the leaderboard.
24
+ #
25
+ # @params [String] user The requesting user.
26
+ # @params [String] target_user The user to check points of.
27
+ # @example
28
+ # board("basicxman")
29
+ # board("basicxman", "mike_n_7")
30
+ def board(user, target_user = nil)
31
+ if target_user.nil?
32
+ leaderboard = {}
33
+ @points.each do |u, p|
34
+ leaderboard[p] ||= []
35
+ leaderboard[p] << u
36
+ end
37
+ num_to_display = 5
38
+ leaderboard.keys.sort.each do |points|
39
+ leaderboard[points].each do |u|
40
+ return unless num_to_display >= 1
41
+ @server.puts "say #{u}: #{points}"
42
+ num_to_display -= 1
43
+ end
44
+ end
45
+ else
46
+ if @points.has_key? target_user
47
+ @server.puts "say #{u}: #{@points[u]}"
48
+ end
49
+ end
50
+ end
51
+
52
+ # Caps the quantity of points able to be given based on requesting user.
53
+ #
54
+ # @param [String] user The requesting user.
55
+ # @return [Integer] Maximum quantity of points.
56
+ # @example
57
+ # cap_points("basicxman")
58
+ def cap_points(user)
59
+ return 1000 if is_op? user
60
+ return 500 if is_hop? user
61
+ return 1
62
+ end
63
+
64
+ # Initiates or votes for a specific user to be kicked, since half-ops and
65
+ # regular connected players cannot kick users they can initiate a vote
66
+ # instead.
67
+ #
68
+ # @params [String] user The requesting user.
69
+ # @params [String] target_user The target user to be kicked if the vote
70
+ # succeeds.
71
+ # @example
72
+ # kickvote("basicxman", "blizzard4U")
73
+ # kickvote("basicxman")
74
+ def kickvote(user, target_user = nil)
75
+ return @server.puts "say No user #{target_user} exists." unless @users.include? target_user
76
+ return vote(user) if target_user.nil?
77
+ unless submit_vote(user, target_user)
78
+ @kickvotes[target_user] = {
79
+ :tally => kick_influence(user),
80
+ :votes => [user],
81
+ :start => Time.now
82
+ }
83
+ @last_kick_vote = target_user
84
+ @server.puts "say A kickvote has been initiated for #{target_user}."
85
+ @server.puts "say To vote enter !kickvote #{target_user}."
86
+ end
87
+ end
88
+
89
+ # Votes for the last initiated kickvote.
90
+ #
91
+ # @params [String] user The requesting user.
92
+ # @example
93
+ # vote("basicxman")
94
+ def vote(user)
95
+ unless submit_vote(user, @last_kick_vote)
96
+ @server.puts "say No kickvote was initiated, dummy."
97
+ end
98
+ end
99
+
100
+ # Cancels a kickvote initiation for a specific user.
101
+ #
102
+ # @params [String] user The requesting user.
103
+ # @params [String] target_user The user which currently has a kickvote.
104
+ # @example
105
+ # cancelvote("basicxman", "blizzard4U")
106
+ def cancelvote(user, target_user)
107
+ if @kickvotes.has_key? target_user
108
+ @kickvotes.delete(target_user)
109
+ @server.puts "say #{user} has cancelled the kickvote on #{target_user}."
110
+ else
111
+ @server.puts "say There is no kickvote against #{target_user} dummy."
112
+ end
113
+ end
114
+
115
+ # Displays all current kickvote initiations.
116
+ #
117
+ # @params [String] user The requesting user.
118
+ # @example
119
+ # kickvotes("basicxman")
120
+ def kickvotes(user)
121
+ @kickvotes.each do |target_user, data|
122
+ @server.puts "say #{target_user}: #{data[:tally]} #{data[:votes].map { |u| u[0] + u[-1] }.join(", ")}"
123
+ end
124
+ end
125
+
126
+ # Submits a kickvote.
127
+ #
128
+ # @params [String] user The requesting user who is voting.
129
+ # @params [String] target_user The user being voted against.
130
+ # @return [Boolean] Returns true if the kickvote has been initiated yet.
131
+ # @example
132
+ # submit_vote("basicxman", "blizzard4U")
133
+ def submit_vote(user, target_user)
134
+ return unless @users.include? target_user
135
+ if @kickvotes.has_key? target_user
136
+ if @kickvotes[target_user][:votes].include? user
137
+ @server.puts "say You have already voted."
138
+ else
139
+ @kickvotes[target_user][:votes] << user
140
+ @kickvotes[target_user][:tally] += kick_influence(user)
141
+ check_kickvote(target_user)
142
+ end
143
+ return true
144
+ else
145
+ return false
146
+ end
147
+ end
148
+
149
+ # Checks a kickvote entry to see if the tally number has crossed the
150
+ # threshold, if so, kicks the user.
151
+ #
152
+ # @param [String] user The specified user.
153
+ # @example
154
+ # check_kickvote("blizzard4U")
155
+ def check_kickvote(user)
156
+ if @kickvotes[user][:tally] >= @vote_threshold
157
+ @server.puts "say Enough votes have been given to kick #{user}."
158
+ @server.puts "kick #{user}"
159
+ @kickvotes.delete(user)
160
+ end
161
+ end
162
+
163
+ # Computes the influence a user has for kickvotes.
164
+ #
165
+ # @param [String] user The specified user.
166
+ # @return [Integer] The influence level.
167
+ # @example
168
+ # kick_influence("basicxman")
169
+ def kick_influence(user)
170
+ return 3 if is_op? user
171
+ return 2 if is_hop? user
172
+ return 1
173
+ end
174
+
175
+ # Checks to see if any kickvotes are expired.
176
+ def expire_kickvotes
177
+ @kickvotes.each do |target_user, data|
178
+ puts "Checking #{Time.now} against #{data[:start] + @vote_expiration}}"
179
+ if Time.now > data[:start] + @vote_expiration
180
+ @server.puts "say The kickvote for #{target_user} has expired."
181
+ @kickvotes.delete(target_user)
182
+ end
183
+ end
184
+ end
185
+
186
+ # Kicks a random person, the requesting user has a higher cance of being
187
+ # picked.
188
+ #
189
+ # @param [String] user The requesting user.
190
+ # @example
191
+ # roulette("basicxman")
192
+ def roulette(user)
193
+ users = @users + [user] * 3
194
+ picked_user = users.sample
195
+ @server.puts "say #{user} has requested a roulette kick, s/he has a higher chance of being kicked."
196
+ @server.puts "kick #{picked_user}"
197
+ end
198
+
199
+ # Changes the time of day.
200
+ #
201
+ # @param [String] time The time of day to change it to.
202
+ # @example
203
+ # change_time("morning")
204
+ def change_time(time)
205
+ return false unless TIME.include? time
206
+ @server.puts "time set #{TIME[time]}"
207
+ @server.puts "say #{TIME_QUOTES[time]}" unless TIME_QUOTES[time] == ""
208
+ return true
209
+ end
210
+
211
+ # Gives half-op privileges to the target user.
212
+ #
213
+ # @param [String] user The requesting user.
214
+ # @param [String] target_user The target user to be hop'ed.
215
+ # @example
216
+ # hop("basicxman", "blizzard4U")
217
+ def hop(user, target_user)
218
+ @hops << target_user.downcase unless @hops.include? target_user.downcase
219
+ @server.puts "#{target_user} is now a hop, thanks #{user}!"
220
+ end
221
+
222
+ # De-half-ops the target user.
223
+ #
224
+ # @param [String] user The requesting user.
225
+ # @param [String] target_user The target user to be de-hop'ed.
226
+ # @example
227
+ # dehop("basicxman", "blizzard4U")
228
+ def dehop(user, target_user)
229
+ @hops.reject! { |u| u == target_user.downcase }
230
+ @server.puts "#{target_user} has been de-hoped, thanks #{user}!"
231
+ end
232
+
7
233
  # Give command takes an item name or numeric id and a quantifier. If a
8
234
  # quantifier is not specified then the quantity defaults to 1. Items will
9
235
  # try to resolved if they are not an exact match.
@@ -74,14 +300,31 @@ module Minecraft
74
300
  @server.puts "give #{user} 322 1"
75
301
  end
76
302
 
303
+ # Gives multiple golden apples to the specified user.
304
+ #
305
+ # @param [String] user Target user.
306
+ # @param args noms!
307
+ # @example
308
+ # om("basicxman", "nom", "nom", "nom")
309
+ def om(user, *args)
310
+ args.length.times { nom(user) }
311
+ end
312
+
77
313
  # Outputs the current value of a server property.
78
314
  #
79
315
  # @param [String] user The requesting user.
80
316
  # @param [String] key The server property requested.
81
317
  # @example
82
318
  # property("basicxman", "spawn-monsters")
83
- def property(user, key)
84
- @server.puts "say #{key} is currently #{@server_properties[key]}" if @server_properties.include? key
319
+ # property("basicxman")
320
+ def property(user, key = nil)
321
+ if key.nil?
322
+ (@server_properties.length / 3.0).ceil.times do |n|
323
+ @server.puts "say #{@server_properties.keys[n * 3, 3].join(", ")}"
324
+ end
325
+ else
326
+ @server.puts "say #{key} is currently #{@server_properties[key]}" if @server_properties.include? key
327
+ end
85
328
  end
86
329
 
87
330
  # Checks the current uptime of the current or target user. Prints their
@@ -95,6 +338,15 @@ module Minecraft
95
338
  # uptime("basicxman", "mike_n_7")
96
339
  def uptime(user, target_user = nil)
97
340
  target_user ||= user
341
+ unless @users.include? target_user
342
+ if @userlog.has_key? target_user
343
+ @server.puts "say #{target_user} has #{format_uptime(@userlog[target_user])} minutes of logged time."
344
+ else
345
+ @server.puts "say #{target_user} Does not exist."
346
+ end
347
+ return
348
+ end
349
+
98
350
  time_spent = calculate_uptime(target_user)
99
351
  if @userlog.has_key? target_user
100
352
  total = " Out of a total of #{format_uptime(@userlog[target_user] + time_spent)} minutes."
@@ -118,13 +370,16 @@ module Minecraft
118
370
  # list("basicxman")
119
371
  def list(user)
120
372
  l = @users.inject("") do |s, u|
373
+ pre, suf = "", ""
121
374
  if u == user
122
375
  pre = "["
123
376
  suf = "]"
124
377
  end
125
- suf = "*" + (suf || "") if is_op? u
378
+ pre = pre + "@" if is_op? u
379
+ pre = pre + "%" if is_hop? u
126
380
  s + "#{", " unless s.empty?}#{pre}#{u}#{suf}"
127
381
  end
382
+
128
383
  @server.puts "say #{l}"
129
384
  end
130
385
 
@@ -12,6 +12,26 @@ module Minecraft
12
12
  :redstone => [[331, 256], [356, 64], [69, 64], [77, 64], [70, 64]]
13
13
  }
14
14
 
15
+ # Values for time, 0 to 24000. 0 is dawn, 12000 is dusk.
16
+ TIME = {
17
+ :morning => 1000,
18
+ :evening => 13000,
19
+ :day => 5000,
20
+ :night => 16000,
21
+ :dawn => 0,
22
+ :dusk => 12000
23
+ }
24
+
25
+ # Quotes for each time of day.
26
+ TIME_QUOTES = {
27
+ :morning => "Anyone like a little toasted zombie?",
28
+ :evening => "Let them come.",
29
+ :day => "",
30
+ :night => "",
31
+ :dawn => "What are you doing? Those wraiths are still out there.",
32
+ :dusk => ""
33
+ }
34
+
15
35
  # All item keys.
16
36
  DATA_VALUE_HASH = {
17
37
  "glass" => "20",
@@ -117,6 +137,7 @@ module Minecraft
117
137
  "pink wool" => "35",
118
138
  "brick block" => "45",
119
139
  "lever" => "69",
140
+ "switch" => "69",
120
141
  "birch wood" => "17",
121
142
  "gray wool" => "35",
122
143
  "tnt" => "46",
@@ -11,53 +11,78 @@ module Minecraft
11
11
  # @param [Slop] opts Command line options from Slop.
12
12
  def initialize(server, opts)
13
13
  @ops = File.readlines("ops.txt").map { |s| s.chomp }
14
- @userlog = get_json("user.log")
14
+ get_json :hops, []
15
+ get_json :uptime
16
+ get_json :timers
17
+ get_json :shortcuts
18
+ get_json :userlog
19
+ get_json :points
15
20
  @users = []
16
- @timers = get_json("user_timers.json")
17
- @shortcuts = get_json("user_shortcuts.json")
18
21
  @counter = 0
19
22
  @logon_time = {}
20
23
  @server = server
24
+ @kickvotes = {}
25
+ @last_kick_vote = nil
21
26
  load_server_properties
22
27
 
23
- opts = {
24
- :rules => "No rules specified."
25
- }.merge(opts)
26
- opts.each { |k, v| instance_variable_set("@#{k}", v) }
28
+ opts.to_hash.each { |k, v| instance_variable_set("@#{k}", v) }
29
+ @vote_expiration ||= 300
30
+ @vote_threshold ||= 5
31
+ @rules ||= "No rules specified."
27
32
 
28
33
  # Command set.
29
34
  @commands = {}
30
- add_command(:give, :ops => true, :all => true, :all_message => "is putting out.")
31
- add_command(:tp, :ops => false, :all => true, :all_message => "is teleporting all users to their location.")
32
- add_command(:kit, :ops => true, :all => true, :all_message => "is providing kits to all.")
33
- add_command(:help, :ops => false, :all => false)
34
- add_command(:rules, :ops => false, :all => false)
35
- add_command(:nom, :ops => true, :all => true, :all_message => "is providing noms to all.")
36
- add_command(:list, :ops => false, :all => false)
37
- add_command(:s, :ops => false, :all => false)
38
- add_command(:uptime, :ops => false, :all => false)
39
- add_command(:addtimer, :ops => true, :all => false)
40
- add_command(:deltimer, :ops => true, :all => false)
41
- add_command(:printtimer, :ops => true, :all => false)
42
- add_command(:printtime, :ops => true, :all => false)
43
- add_command(:shortcuts, :ops => false, :all => false)
44
- add_command(:kitlist, :ops => false, :all => false)
45
- add_command(:property, :ops => true, :all => false)
35
+ add_command(:give, :ops => :hop, :all => true, :all_message => "is putting out.")
36
+ add_command(:tp, :ops => :hop, :all => true, :all_message => "is teleporting all users to their location.")
37
+ add_command(:kit, :ops => :hop, :all => true, :all_message => "is providing kits to all.")
38
+ add_command(:kitlist, :ops => :hop, :all => false)
39
+ add_command(:help, :ops => :none, :all => false)
40
+ add_command(:rules, :ops => :none, :all => false)
41
+ add_command(:nom, :ops => :hop, :all => true, :all_message => "is providing noms to all.")
42
+ add_command(:om, :ops => :hop, :all => true, :all_message => "is noming everybody, gross.")
43
+ add_command(:list, :ops => :none, :all => false)
44
+ add_command(:s, :ops => :hop, :all => false)
45
+ add_command(:shortcuts, :ops => :hop, :all => false)
46
+ add_command(:hop, :ops => :op, :all => false)
47
+ add_command(:dehop, :ops => :op, :all => false)
48
+ add_command(:uptime, :ops => :none, :all => false)
49
+ add_command(:addtimer, :ops => :hop, :all => false)
50
+ add_command(:deltimer, :ops => :hop, :all => false)
51
+ add_command(:printtimer, :ops => :hop, :all => false)
52
+ add_command(:printtime, :ops => :op, :all => false)
53
+ add_command(:property, :ops => :op, :all => false)
54
+ add_command(:morning, :ops => :op, :all => false)
55
+ add_command(:evening, :ops => :op, :all => false)
56
+ add_command(:day, :ops => :op, :all => false)
57
+ add_command(:night, :ops => :op, :all => false)
58
+ add_command(:dawn, :ops => :op, :all => false)
59
+ add_command(:dusk, :ops => :op, :all => false)
60
+ add_command(:roulette, :ops => :op, :all => false)
61
+ add_command(:kickvote, :ops => :none, :all => false)
62
+ add_command(:vote, :ops => :none, :all => false)
63
+ add_command(:cancelvote, :ops => :op, :all => false)
64
+ add_command(:kickvotes, :ops => :op, :all => false)
65
+ add_command(:points, :ops => :none, :all => false)
66
+ add_command(:board, :ops => :none, :all => false)
46
67
  end
47
68
 
48
- # Gets a hash from a JSON file (or a blank one).
49
- def get_json(file)
50
- if File.exists? file
69
+ # Sets an instance variable with it's corresponding data file or a blank hash.
70
+ def get_json(var, blank = {})
71
+ file = "#{var}.json"
72
+ t = if File.exists? file
51
73
  JSON.parse(File.read(file))
52
74
  else
53
- {}
75
+ blank
54
76
  end
77
+ instance_variable_set("@#{var}", t)
55
78
  end
56
79
 
57
80
  # Save the user timers and shortcuts hash to a data file.
58
81
  def save
59
82
  save_file :timers
60
83
  save_file :shortcuts
84
+ save_file :hops
85
+ save_file :points
61
86
  end
62
87
 
63
88
  # Save an instance hash to it's associated data file.
@@ -66,12 +91,7 @@ module Minecraft
66
91
  # @example
67
92
  # save_file :timers
68
93
  def save_file(var)
69
- File.open("user_#{var}.json", "w") { |f| f.print instance_variable_get("@#{var}").to_json }
70
- end
71
-
72
- # Writes the user uptime log to disk.
73
- def write_log
74
- File.open("user.log", "w") { |f| f.print @userlog.to_json }
94
+ File.open("#{var}.json", "w") { |f| f.print instance_variable_get("@#{var}").to_json }
75
95
  end
76
96
 
77
97
  # Complicated method to decide the logic of calling a command. Checks
@@ -96,14 +116,17 @@ module Minecraft
96
116
  return send(root, user, *args) unless @commands.include? root
97
117
 
98
118
  # Any `all` suffixed command requires ops.
99
- if @commands[root][:ops] or (is_all and @commands[root][:all])
100
- return if !validate_ops(user, command)
119
+ if @commands[root][:ops] == :ops or (is_all and @commands[root][:all])
120
+ return unless validate_ops(user, command)
121
+ elsif @commands[root][:ops] == :hop
122
+ return unless validate_ops(user, command, false) or validate_hops(user, command)
101
123
  end
102
124
 
103
125
  if respond_to? "validate_" + root.to_s
104
126
  return unless send("validate_" + root.to_s, *args)
105
127
  end
106
128
 
129
+ is_all = @commands[root][:all] if is_all
107
130
  if is_all
108
131
  @server.puts "say #{user} #{@commands[root][:all_message]}"
109
132
  if respond_to? command
@@ -144,12 +167,15 @@ module Minecraft
144
167
  def check_save
145
168
  if @savefreq.nil?
146
169
  freq = 30
147
- elsif @savefreq == 0
170
+ elsif @savefreq == "0"
148
171
  return
149
172
  else
150
173
  freq = @savefreq.to_i
151
174
  end
152
- @server.puts "save-all" if @counter % freq == 0
175
+ if @counter % freq == 0
176
+ @server.puts "save-all"
177
+ save
178
+ end
153
179
  end
154
180
 
155
181
  # Increments the counter and checks if any timers are needed to be
@@ -157,6 +183,7 @@ module Minecraft
157
183
  def periodic
158
184
  @counter += 1
159
185
  check_save
186
+ expire_kickvotes if @counter % 10 == 0
160
187
  @users.each do |user|
161
188
  next unless @timers.has_key? user
162
189
  @timers[user].each do |item, duration|
@@ -240,6 +267,7 @@ module Minecraft
240
267
  # If a command method is called and is not specified, take in the arguments
241
268
  # here and attempt to !give the player the item. Otherwise print an error.
242
269
  def method_missing(sym, *args)
270
+ return if change_time(sym)
243
271
  item, quantity = items_arg(1, [sym.to_s.downcase, args.last])
244
272
  item = resolve_item(item)
245
273
  if item and is_op? args.first
@@ -256,7 +284,7 @@ module Minecraft
256
284
  @userlog[user] ||= 0
257
285
  @userlog[user] += time_spent
258
286
  @server.puts "say #{user} spent #{format_uptime(time_spent)} minutes in the server, totalling to #{format_uptime(@userlog[user])}."
259
- write_log
287
+ save_file :userlog
260
288
  end
261
289
 
262
290
  # Format an uptime for printing. Should not be used for logging.
@@ -272,7 +300,7 @@ module Minecraft
272
300
  # @param [String] user The specified user.
273
301
  # @return [Integer] The uptime in seconds.
274
302
  def calculate_uptime(user)
275
- Time.now - @logon_time[user]
303
+ Time.now - (@logon_time[user] || 0)
276
304
  end
277
305
 
278
306
  # Check if a user has op privileges.
@@ -283,14 +311,32 @@ module Minecraft
283
311
  @ops.include? user.downcase
284
312
  end
285
313
 
286
- # Check if a user is ops and print a privilege error if not.
314
+ # Check if a user has half op privileges.
315
+ #
316
+ # @param [String] user The specified user.
317
+ # @return [Boolean]
318
+ def is_hop?(user)
319
+ @hops.include? user.downcase
320
+ end
321
+
322
+ # Check if a user has op privileges and print a privilege error if not.
323
+ #
324
+ # @param [String] user The specified user.
325
+ # @param [String] command The command they tried to use.
326
+ # @return [Boolean] Returns true if the user is an op.
327
+ def validate_ops(user, command, message = true)
328
+ return true if is_op? user.downcase
329
+ @server.puts "say #{user} is not an op, cannot use !#{command}." if message
330
+ end
331
+
332
+ # Check if a user has half op privileges and print a privilege error if not.
287
333
  #
288
334
  # @param [String] user The specified user.
289
335
  # @param [String] command The command they tried to use.
290
336
  # @return [Boolean] Returns true if the user is an op.
291
- def validate_ops(user, command)
292
- return true if is_op? user
293
- @server.puts "say #{user} is not an op, cannot use !#{command}."
337
+ def validate_hops(user, command, message = true)
338
+ return true if is_hop? user.downcase
339
+ @server.puts "say #{user} is not a half-op, cannot use !#{command}." if message
294
340
  end
295
341
 
296
342
  # An error message for invalid commands.
@@ -15,19 +15,19 @@ module Minecraft
15
15
  pre_checks
16
16
 
17
17
  Minecraft::Tools.check_jarfile
18
- unless @opts.no_run?
18
+ unless @opts[:no_run]
19
19
  command = Minecraft::Tools.command(@opts)
20
20
  puts "[+] #{command}"
21
21
  server = Minecraft::Server.new(command, @opts)
22
- server.sin.puts("save-on") unless @opts.no_auto_save?
22
+ server.sin.puts("save-on") unless @opts[:no_auto_save]
23
23
  end
24
24
  end
25
25
 
26
26
  # Checks if Minecraft needs to be updated, checks if mobs are to be
27
27
  # toggled.
28
28
  def pre_checks
29
- Minecraft::Tools.download_minecraft if @opts.update?
30
- puts "[+] Temporarily toggling mobs. Setting to #{Minecraft::Tools.toggle_mobs}." if @opts.tempmobs?
29
+ Minecraft::Tools.download_minecraft if @opts[:update]
30
+ puts "[+] Temporarily toggling mobs. Setting to #{Minecraft::Tools.toggle_mobs}." if @opts[:tempmobs]
31
31
  end
32
32
  end
33
33
  end
@@ -35,7 +35,7 @@ module Minecraft
35
35
  # An exit hook, checks if mobs need to be untoggled and saves the server.
36
36
  # Server is stopped gracefully.
37
37
  def minecraft_exit
38
- puts "[+] Restoring previous mob state to #{Minecraft::Tools.toggle_mobs}." if @opts.tempmobs?
38
+ puts "[+] Restoring previous mob state to #{Minecraft::Tools.toggle_mobs}." if @opts[:tempmobs]
39
39
  puts "\n[+] Saving..."
40
40
  @extensions.save
41
41
  @threads.each(&:kill)
@@ -39,5 +39,17 @@ module Minecraft
39
39
  File.open("server.properties", "w") { |f| f.print content }
40
40
  return new_state
41
41
  end
42
+
43
+ def self.get_configuration_file
44
+ return {} unless File.exists? "minecraft.properties"
45
+ File.readlines("minecraft.properties").map { |l| l.split(" ") }.inject({}) do |hash, (key, *value)|
46
+ hash.merge({ key.to_sym => config_value(value) })
47
+ end
48
+ end
49
+
50
+ def self.config_value(value)
51
+ return true if value.nil? or value.length == 0
52
+ return value.join(" ")
53
+ end
42
54
  end
43
55
  end
@@ -1,5 +1,5 @@
1
1
  # Global Minecraft module.
2
2
  module Minecraft
3
3
  # Yay, keep these versions coming!
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: minecraft
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.2.0
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-19 00:00:00 -04:00
13
+ date: 2011-08-21 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency