minecraft 0.1.0 → 0.2.0

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