Compare commits

...
59 Commits
Author SHA1 Message Date
sk89q 79518e6503 Updated CHANGELOG. 2010-11-24 12:44:37 -08:00
sk89q 2999f9d168 Removed warning emitted when a hook does not exist. 2010-11-24 12:43:18 -08:00
sk89q b4d8b2095d Changed some configuration defaults: summary-on-start=true, disable-lava-fire=true, simulate-sponge=true, item-durability=false. 2010-11-24 12:41:32 -08:00
sk89q f7099f2093 Improved README. 2010-11-24 12:31:56 -08:00
sk89q 8c51795b1a Removed mention of the block lag fix. 2010-11-24 12:26:58 -08:00
sk89q ba523ce3f3 Updated for 1.5. 2010-11-24 12:18:45 -08:00
sk89q e4af400acb Added a startup message indicating when all features all supported. 2010-11-24 12:17:26 -08:00
sk89q ffa38f9fd1 Removed the block lag fix and cleaned up code. 2010-11-24 12:02:04 -08:00
sk89q 84ccabdf34 Improved missing feature detection. 2010-11-24 11:58:54 -08:00
sk89q c0b4d95082 Added documentation for required hooks. Improved missing hook messages. 2010-11-23 22:42:30 -08:00
sk89q f305b3a119 Hooks are now conditionally loaded. summary-on-start is now disabled by default and mentioned in the README. 2010-11-23 22:31:28 -08:00
sk89q 48ace4947b Updated for 1.4.1. 2010-11-21 11:40:26 -08:00
sk89q 57acbebaf1 Fixed issue with the block lag fix dropping item stacks of 0 quantity. 2010-11-21 11:34:46 -08:00
sk89q e15311178b Updated the README.txt. 2010-11-21 01:36:13 -08:00
sk89q 7385be7eff Fixed typo in worldguard.properties. 2010-11-21 01:30:50 -08:00
sk89q 9a29474132 Updated for 1.4. 2010-11-21 01:29:52 -08:00
sk89q 881f050f0d Inventory checks now won't be used if there are no on-acquire events. 2010-11-21 01:25:59 -08:00
sk89q 339bf1a06d Improved documentation. 2010-11-21 01:21:20 -08:00
sk89q bc70678387 Updated for new version of durability fix. 2010-11-21 01:13:33 -08:00
sk89q c3eef60672 Added no-physics-gravel, no-physics-sand, and allow-portal-anywhere. 2010-11-21 01:12:00 -08:00
sk89q eb78b390ca Added item-durability and blacklist on-acquire event. Thanks to Dinnerbone for heading my requests :) 2010-11-21 00:45:16 -08:00
sk89q a0fc3472e4 Updated blacklist and added Sturmeh's item durability 'fix' as sample rules. 2010-11-20 20:10:29 -08:00
sk89q 915946317d Updated the changelog to note the table schema change. 2010-11-20 12:01:38 -08:00
sk89q d4c4a497c4 Updated for 1.3. 2010-11-20 11:59:35 -08:00
sk89q 0286900829 The notify, log, and tell actions will now trigger every time for the on-break, on-create, on-drop events. 2010-11-20 11:53:57 -08:00
sk89q cf7874f776 Added comments and messages. Made the blacklist notification messages more compact and a different color. 2010-11-20 11:47:32 -08:00
sk89q 93c0295744 Added on-break event to the blacklist. 2010-11-20 11:13:18 -08:00
sk89q 9bc3a25191 Fixed signs being blank if they were denied via the blacklist. 2010-11-20 10:59:34 -08:00
sk89q e95d7a8b6e Improved plugin compatibility with the block lag fix. 2010-11-20 10:56:47 -08:00
sk89q 1edc48b16f Added SQL for the blacklist database table. 2010-11-19 22:06:49 -08:00
sk89q 07c8abff54 Improved blacklist documentation. 2010-11-19 22:02:46 -08:00
sk89q afff62120e Updated documentation and version for 1.2. 2010-11-19 21:59:56 -08:00
sk89q ff8c48e69e Added fire spread spreading enabling and disabling commands. 2010-11-19 21:49:31 -08:00
sk89q b9e84f7b4a Improved item drop list for the block lag fix. 2010-11-19 21:34:14 -08:00
sk89q 924e6f3777 Fixed typo in source. 2010-11-19 21:17:30 -08:00
sk89q 6d0d2ee538 Sponge now removes water and obeys new 'sponge-radius' configuration variable. 2010-11-19 21:14:01 -08:00
sk89q 8983d7bc84 Fixed classic water for the onFlow update. 2010-11-19 21:02:54 -08:00
sk89q fc81a7034e Block lag fix now fakes block status 3 for other plugins. 2010-11-19 20:58:34 -08:00
sk89q b7e5828c3f WorldGuard should now close loggers on disable and reload. 2010-11-19 20:34:38 -08:00
sk89q e543ac733f Fixed errors caused by reloading the plugin. 2010-11-19 20:32:41 -08:00
sk89q d09fcab7b3 Updated onFlow hook for the new changes. 2010-11-19 20:31:12 -08:00
sk89q 70c6b26db5 Added summary-on-start configuration setting to control whether the summary should be printed. 2010-11-19 20:09:26 -08:00
sk89q 1859fc5db2 Overhauled the blacklist system.
- The blacklist's method of preventing notification repeats is now better, instead waiting 3 seconds before notifying again (before it didn't notify again at all unless the user started using another blocked action).
- To give users the ability to receive notifications, the command to give permission to has been changed to /worldguardnotify, although the old one (that was never mentioned anywhere) still works.
- Water and lava buckets are now psuedo-blocked using an unreliable method that risks the stability of your server (no other plugin does it better though). Use it as your own risk.
- Added on item drop and on item use (i.e. chest) events.
- Chests, signs, and furnaces can now be blocked better with the blacklist system.
- The event names in the blacklist configuration have changed but the old event names should still work. The new names should make "more sense."
- A new "ban" action has been added to the blacklist.
- Action messages have been improved, now longer saying "destroyed" for everything.
- Logging to file has been completely changed, allowing you to use the date and time and the player's username in the log filename. It no longer rotates log files based on size, however.
- Logging to database is now supported.
2010-11-19 20:03:19 -08:00
sk89q 47a4046d47 Merge branch 'master' of https://github.com/Sturmeh/worldguard into Worldguard. 2010-11-19 02:12:11 -08:00
sk89q 7b3a8402a1 Added 'right click on' events to the blacklist. 2010-11-19 02:01:10 -08:00
sk89q 84eb9343ce Improved water/bucket fix by having it set back the original block. Unfortunately this doesn't do anything about setting water buckets into lava (creating obsidian). 2010-11-19 00:14:08 -08:00
sk89q 0a8dd85224 Added a bucket block fix, but not a great one. 2010-11-18 23:58:22 -08:00
sk89q f8a63b372d Updated for 1.1.2. 2010-11-18 10:47:05 -08:00
sk89q 8a731617e1 Block lag fix: glass and snow should no longer drop any items. The block object is reset now after the canDestroyBlock() call to lessen the impact of the double hook call. 2010-11-18 10:44:04 -08:00
sk89q 028ec89d26 Added startup messages that indicate protection status. 2010-11-18 01:33:56 -08:00
sk89q 9fd633cbe9 Changed blacklist filename to worldguard-blacklist.txt. 2010-11-17 23:07:43 -08:00
sk89q c1da391653 Updated for 1.1.1. 2010-11-17 23:06:57 -08:00
sk89q 92edff6ffe Added protection and plugin support. 2010-11-17 22:51:41 -08:00
Sturmeh d4a3e04622 Merge branch 'master' of http://github.com/sk89q/worldguard 2010-11-18 16:40:49 +11:00
Sturmeh 2562502d26 Added itemDropBlacklist 2010-11-18 16:40:43 +11:00
sk89q e12fcdb1b8 Moved the block lag fix to a low priority listener. 2010-11-17 20:33:29 -08:00
sk89q a7aed1a278 Fixed the block lag fix not allowing the destruction of leaves. 2010-11-17 19:34:06 -08:00
sk89q e5dcb557dc Fixed the block fix dropping wood for redstone wire. 2010-11-17 12:22:40 -08:00
sk89q 447f192027 Changed project name to WorldGuard. 2010-11-17 12:05:07 -08:00
22 changed files with 3289 additions and 835 deletions

No files matched your search

+100
View File
@@ -0,0 +1,100 @@
1.5
- Removed the block lag fix.
- WorldGuard now conditionally loads features so you can use any up-to-date
build of hMod and the unsupported features won't break the entire
plugin. When WG loads, check the server console for a report of
features that are not supported by your version of hMod.
- Changed some configuration defaults:
disable-lava-fire=true
simulate-sponge=true
item-durability=false
1.4.1
- Fixed issue with the block lag fix dropping item stacks of 0 quantity.
1.4
- New on-acquire hook. This does both a total inventory check on inventory
change and item pick up denial. The item pick up denial is largely
thanks to Dinnerbone for fulfilling my request to add a particular hook.
- Item durability can now be toggled with item-durability. Thanks to
Dinnerbone for figuring this out while filfilling my request. The
default setting is to fix item durability.
- New no-physics-gravel and no-physics-sand options allow you to
prevent gravel and sand from falling.
- New allow-portal-anywhere option allows you to create portal blocks
anywhere.
1.3
- UPGRADE WARNING: If you are using database logging, you must add a
NULL 'comment' VARCHAR field to the table. The line of SQL that you
can run for MySQL can be found in blacklist_table.sql.
- Improved plugin compatibility with the block lag fix. For maximum
compatibility, you must now list WorldGuard as the first plugin in
server.properties and you cannot reload or enable the plugin
while the server is up. This is for bad plugins that unnecessarily
use the "critical" priority for its hooks like the LWC. Most plugins
don't do that though, so this won't apply for most people.
- Fixed signs being blank if they were denied via the blacklist.
- Added on-break event to the blacklist.
- Added comments and messages. Comments are only for your own use and they
are printed with the log and notify actions of the blacklist. The
message replaces the message that is shown the user and it is optional.
- The blacklist notification messages are now more compact and are
light grey instead of light purple.
- The notify, log, and tell actions will now trigger every time for the
on-break, on-create, on-drop events rather than wait 3 seconds between
events for the same item or block for a player.
1.2
- /stopfire and /allowfire disable and enable fire spreading globally.
- Block lag fix slightly improved in accuracy for item drops.
- Sponge updated to remove water when the sponge block is set. Sponge radius
can now be controlled using the 'sponge-radius' parameter and the
default is now set to simulate Classic.
- Updated for a newer build of "b126," meaning that lava spread control
now works well!
- A new summary of the status of some core protections is now printed
on start. Disable this with 'summary-on-start'.
- Blacklist system has been overhauled. Check README.txt for changed
configuration settings!
- The blacklist's method of preventing notification repeats is now better,
instead waiting 3 seconds before notifying again (before it didn't
notify again at all unless the user started using another blocked
action).
- To give users the ability to receive notifications, the command to give
permission to has been changed to /worldguardnotify, although the
old one (that was never mentioned anywhere) still works.
- Water and lava buckets are now psuedo-blocked using an unreliable
method that risks the stability of your server (no other plugin
does it better though). Use it as your own risk.
- Added on item drop and on item use (i.e. chest) events.
- Chests, signs, and furnaces can now be blocked better with the
blacklist system.
- The event names in the blacklist configuration have changed but the old
event names should still work. The new names should make "more sense."
- A new "ban" action has been added to the blacklist.
- Action messages have been improved, now longer saying "destroyed"
for everything.
- Logging to file has been completely changed, allowing you to use
the date and time and the player's username in the log filename. It
no longer rotates log files based on size, however.
- Logging to database is now supported.
- Tools can now be destroyed on drop to alleviate the durability cheat.
You can do this with either with the blacklist or with the
'item-drop-blacklist' configuration option. The configuration option
prints more friendly messages than the 'tell' action of blacklists.
1.1.2
- Block lag fix: Snow and glass should no longer drop items.
- Block lag fix: Block object now reset after hook call.
1.1.1
- Fixed redstone wire dropping wood blocks with the block lag fix.
- The block lag fix now consults other plugins so that ALL protection
mechanisms and plugins should work.
1.1
- Added block lag fix.
1.0
- Initial release.
+3 -3
View File
@@ -5,11 +5,11 @@ This plugin requires Hey0's server modification.
1. Create a "plugins" folder inside your "bin" folder.
2. Copy WorldProtect.jar into "plugins".
2. Copy WorldGuard.jar into "plugins".
3. Add "WorldProtect" to the "plugins" line of your server.properties file.
3. Add "WorldGuard" to the "plugins" line of your server.properties file.
If it's not already there, add the line. The line should look like this:
plugins=WorldProtect
plugins=WorldGuard
If you have multiple plugins, separate plugin names with commas.
+147 -44
View File
@@ -1,11 +1,11 @@
WorldProtect
WorldGuard
Copyright (c) 2010 sk89q <http://www.sk89q.com>
Licensed under the GNU Lesser General Public License v3
Introduction
------------
WorldProtect has a number of features, any of which you can choose to
WorldGuard has a number of features, any of which you can choose to
use or not:
- Enforce only one session for a player on a server (can't login twice).
@@ -18,21 +18,36 @@ use or not:
- Restrict lava spreading to only some block types.
- Simulate classic-esque water by letting water infinitely expand in
area (only if there is a block underneath).
- Simulate the sponge.
- Block the use, destruction and/or placement of some items or block types.
- Notify admins when a certain block type or item is used, destroyed,
or place.
- Log the use, destruction, and/or placement of some blocks/items.
- Kick for the use, destruction, and/or placement of some blocks.
- Simulate the function of the sponge from Minecraft Classic.
- Notify admins, block, log, kick or ban for the use of certain block types
or items.
- Temporarily stop fire globally with some commands.
- Destroy tools on drop to alleviate the durability cheat.
- OR just fix the durability bug. *Requires special version of hMod
- Prevent gravel and sand from falling. *Requires special version of hMod
- Allow portal blocks to be placed anywhere.
*Requires special version of hMod
hMod is required as WorldProtect is a plugin for hMod.
hMod is required as WorldGuard is a plugin for hMod.
Configuration
-------------
A "worldprotect.properties" will be created the first the time that you load
WorldProtect on your server. You can either restart your server or use
/reloadplugin WorldProtect to reload the configuraton file after editing it.
A "worldguard.properties" will be created the first the time that you load
WorldGuard on your server. You can either restart your server or use
/reloadplugin WorldGuard to reload the configuraton file after editing it.
NOTE: Some features may require a custom version of hMod. When the server
is loaded with the plugin, WorldGuard will tell you the features
unsupported by your version of hMod.
- summary-on-start (def. true)
Print a summary of WorldGuard's protection settings at-a-glance when
the plugin is loaded.
- item-durability (def. false)
**Requires special version of hMod
Enables item durability.
- classic-water (def. false)
Toggle use of classic water. Be foreward that your world may be
@@ -42,50 +57,47 @@ WorldProtect on your server. You can either restart your server or use
ground, but if there are air blocks underneath, the water will not
spread (preventing waterfalls from becoming tsunamis).
- simulate-sponge (def. false)
Toggle simulation of the sponge. The sponge only prevents water
from spreading. It will not take away existing water. Simulation of
the sponge requires iterating over a 9x9x9 cuboid around the water
block and the resource impact of this has not been quantified.
- simulate-sponge (def. true)
Toggle simulation of the sponge from Classic. It blocks water from
flowing near the sponge.
- sponge-radius (def. 3)
The radius of the sponge's effect. The default is that of Classic,
creating a 5x5x5 cuboid free of water. Increasing the number will
increase server load exponentially, although 3-5 has fairly low impact.
- no-physics-gravel (def. false)
**Requires special version of hMod
Prevents gravel from falling due to gravity.
- no-physics-sand (def. false)
**Requires special version of hMod
Prevents sand from falling due to gravity.
- allow-portal-anywhere (def. false)
**Requires special version of hMod
Allows you to place portal blocks anywhere.
- enforce-single-session (def. true)
Enforce single sessions. If the player is already found to be on
the server when s/he logs in, the other player will be kicked with
an informative message. The inventory will have been saved before
the new session starts.
- blacklist-log-console (def. true)
For log actions, print to console as well.
- blacklist-log-file (no default)
File to log to. Log files are automatically rotated based on size, and
you can use these patterns in the path:
%t the system temporary directory
%h the value of the "user.home" system property
%g the generation number to distinguish rotated logs
%u a unique number to resolve conflicts
%% translates to a single percent sign "%"
There is no way to put the date in the filename or rotate by date.
- blacklist-log-file-limit (def. 5242880)
Size in bytes before the log file is rotated.
- blacklist-log-file-count (def. 10)
Number of log files to keep in rotation at maximum.
- block-tnt (def. false)
Block TNT explosions. TNT will still explode client-side but the blocks
will be "restored" in a few seconds afterwards.
- block-lighter (def. false)
Block flint and steel fires. Those with access to the commands
/uselighter or /lighter can bypass this. /uselighter is not a real
command; it is only used for permissions.
- block-creepers (def. false)
Block creeper explosions. They will not explode client-side.
Block creeper explosions from destroying terrain (and possibly from
causing damage).
- disable-lava-fire (def. false)
- disable-lava-fire (def. true)
Prevent lava from starting fires.
- allowed-lava-spread-blocks (no default)
@@ -100,11 +112,102 @@ WorldProtect on your server. You can either restart your server or use
to disable this feature. Enabling disable-all-fire-spread will
override this function.
- block-lag-fix (def. false)
Attempts to fix block lag.
- item-drop-blacklist (no default)
List of block names/IDs to destroy on drop. This can alleviate the
durability cheat that allows you to drop your tools to fix their
durability. You can also enforce this with the blacklist but
this is an easier way to do it (this way also prints a more
friendly message than if you used the 'tell' action of the blacklist).
- log-console (def. true)
For blacklist log actions, print to console.
- log-file (def. false)
For blacklist log actions, log to file.
- log-file-path (def. "worldguard/logs/%Y-%m-%d.log")
Log blacklist events to file. You can use these patterns in the path:
%Y the year (YYYY)
%m the month (MM)
%d the day (DD)
%W the week of the year (00-52)
%H 24-hour time (HH)
%h 12-hour time (HH)
%i the minute (mm)
%s the second (ss)
%u the user's name
%% translates to a single percent sign "%"
The files are not automatically rotated if they get large so you should
perhaps put a week in the filename at least.
Escape backslashes with another backslash, like so:
C:\path\to\log.txt -> C:\\path\\to\\log.txt
- log-file-open-files (def. 10)
The number of log files to keep open at once. Unless you use dynamic
patterns in the path, the value of this variable won't matter. However,
if, for example, you use a player's username in the filename and you
have many users who cause logged events to occur, files would have
to be opened for each user and this parameter would matter.
- log-database (def. false)
Log blacklist events to database.
- log-database-dsn (def. "jdbc:mysql://localhost:3306/minecraft")
Connection string. A string to use for MySQL would be:
jdbc:mysql://localhost:3306/minecraft
The "minecraft" part at the end is the database name.
Escape colons with a backslash, like so:
jdbc:mysql://localhost:3306/minecraft
->
jdbc\:mysql\://localhost\:3306/minecraft
- log-database-user (def. "root")
Database username.
- log-database-pass (def. "")
Database password.
- log-database-table (def. "blacklist_events")
Database table to use.
Commands
--------
- /stopfire and /allowfire
Disables and enables fire spread globally. Both commands require the
permission to use only "/stopfire. Re-enabling fire spread with this
command will not override other fire spread control features of
WorldGuard. Note that disabling fire does not disable fire damage
but fire at least won't spread.
Server Commands
---------------
- fire-stop and fire-allow
Disables and enables fire spread globally. Re-enabling fire spread
with this command will not override other fire spread control features
of WorldGuard. Note that disabling fire does not disable fire damage
but fire at least won't spread.
Blacklists
----------
Edit the included worldprotect-blacklist.txt file and follow the
instructions inside.
Blacklists let you control the use of blocks and items. You can have
certain rules apply to only some groups.
Edit the included worldguard-blacklist.txt file and follow the
instructions inside. The file comes with the download for WorldGuard.
Thanks
------
While I would like to thank everyone for their support, I would like to
say thanks to the following individuals for their direct
contributions to WorldGuard:
- Sturmeh, for contributing the original durability workaround
- Meaglin, for changing the on flow hook at my request
- Dinnerbone, for implementing the on item pick up hook at my request,
and also for figuring out the durability bug in the process
+21
View File
@@ -0,0 +1,21 @@
-- Blacklist table for MySQL.
-- You must still configure WorldGuard to use your database.
-- If you do not plan on using a database for logging blacklist events,
-- you do not need to do anything with this file.
CREATE TABLE `blacklist_events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`event` varchar(25) NOT NULL,
`player` varchar(16) NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`z` int(11) NOT NULL,
`item` int(11) NOT NULL,
`time` int(11) NOT NULL,
`comment` varchar(255) NULL,
PRIMARY KEY (`id`)
);
-- Required update if you have an older version of the table:
ALTER TABLE `blacklist_events` ADD `comment` VARCHAR( 255 ) NULL
+1 -1
View File
@@ -1,2 +1,2 @@
Manifest-Version: 1.0
WorldProtect-Version: 1.1
WorldGuard-Version: 1.5
+397
View File
@@ -0,0 +1,397 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.*;
/**
*
* @author sk89q
*/
public class Blacklist {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* List of entries by block ID.
*/
private Map<Integer,List<BlacklistEntry>> blacklist
= new HashMap<Integer,List<BlacklistEntry>>();
/**
* Logger.
*/
private BlacklistLogger blacklistLogger = new BlacklistLogger();
/**
* Blacklist contains on-acquire events.
*/
private boolean hasOnAcquire;
/**
* Returns whether the list is empty.
*
* @return
*/
public boolean isEmpty() {
return blacklist.isEmpty();
}
/**
* Get the entries for an item or list.
*/
public List<BlacklistEntry> getEntries(int id) {
return blacklist.get(id);
}
/**
* Get the logger.
*
* @return
*/
public BlacklistLogger getLogger() {
return blacklistLogger;
}
/**
* Called on block destruction. Returns true to let the action pass
* through.
*
* @param block
* @param player
* @return
*/
public boolean onDestroy(final Block block, final Player player) {
List<BlacklistEntry> entries = getEntries(block.getType());
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onDestroy(block, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on block break. Returns true to let the action pass
* through.
*
* @param block
* @param player
* @return
*/
public boolean onBreak(final Block block, final Player player) {
List<BlacklistEntry> entries = getEntries(block.getType());
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onBreak(block, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on left click. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onDestroyWith(int item, Player player) {
List<BlacklistEntry> entries = getEntries(item);
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onDestroyWith(item, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on right click. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onCreate(int item, Player player) {
List<BlacklistEntry> entries = getEntries(item);
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onCreate(item, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on right click upon. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onUse(Block block, Player player) {
List<BlacklistEntry> entries = getEntries(block.getType());
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onUse(block, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on right click upon. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onSilentUse(Block block, Player player) {
List<BlacklistEntry> entries = getEntries(block.getType());
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onSilentUse(block, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on drop. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onDrop(int item, Player player) {
List<BlacklistEntry> entries = getEntries(item);
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onDrop(item, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on acquire. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onAcquire(int item, Player player) {
List<BlacklistEntry> entries = getEntries(item);
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onAcquire(item, player)) {
ret = false;
}
}
return ret;
}
/**
* Called on acquire. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onSilentAcquire(int item, Player player) {
List<BlacklistEntry> entries = getEntries(item);
if (entries == null) {
return true;
}
boolean ret = true;
for (BlacklistEntry entry : entries) {
if (!entry.onSilentAcquire(item, player)) {
ret = false;
}
}
return ret;
}
/**
* Load the blacklist.
*
* @param file
* @return
* @throws IOException
*/
public void load(File file) throws IOException {
FileReader input = null;
Map<Integer,List<BlacklistEntry>> blacklist =
new HashMap<Integer,List<BlacklistEntry>>();
try {
input = new FileReader(file);
BufferedReader buff = new BufferedReader(input);
hasOnAcquire = false;
String line;
List<BlacklistEntry> currentEntries = null;
while ((line = buff.readLine()) != null) {
line = line.trim();
// Blank line
if (line.length() == 0) {
continue;
} else if (line.charAt(0) == ';' || line.charAt(0) == '#') {
continue;
}
if (line.matches("^\\[.*\\]$")) {
String[] items = line.substring(1, line.length() - 1).split(",");
currentEntries = new ArrayList<BlacklistEntry>();
for (String item : items) {
int id = 0;
try {
id = Integer.parseInt(item.trim());
} catch (NumberFormatException e) {
id = etc.getDataSource().getItem(item.trim());
if (id == 0) {
logger.log(Level.WARNING, "WorldGuard: Unknown block name: "
+ item);
break;
}
}
BlacklistEntry entry = new BlacklistEntry(this);
if (blacklist.containsKey(id)) {
blacklist.get(id).add(entry);
} else {
List<BlacklistEntry> entries = new ArrayList<BlacklistEntry>();
entries.add(entry);
blacklist.put(id, entries);
}
currentEntries.add(entry);
}
} else if (currentEntries != null) {
String[] parts = line.split("=");
if (parts.length == 1) {
logger.log(Level.WARNING, "Found option with no value "
+ file.getName() + " for '" + line + "'");
continue;
}
boolean unknownOption = false;
for (BlacklistEntry entry : currentEntries) {
if (parts[0].equalsIgnoreCase("ignore-groups")) {
entry.setIgnoreGroups(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-destroy")) {
entry.setDestroyActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-break")) {
entry.setBreakActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-left")
|| parts[0].equalsIgnoreCase("on-destroy-with")) {
entry.setDestroyWithActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-right")
|| parts[0].equalsIgnoreCase("on-create")) {
entry.setCreateActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-right-on")
|| parts[0].equalsIgnoreCase("on-use")) {
entry.setUseActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-drop")) {
entry.setDropActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("on-acquire")) {
hasOnAcquire = true;
entry.setAcquireActions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("message")) {
entry.setMessage(parts[1].trim());
} else if (parts[0].equalsIgnoreCase("comment")) {
entry.setComment(parts[1].trim());
} else {
unknownOption = true;
}
}
if (unknownOption) {
logger.log(Level.WARNING, "Unknown option '" + parts[0]
+ "' in " + file.getName() + " for '" + line + "'");
}
} else {
logger.log(Level.WARNING, "Found option with no heading "
+ file.getName() + " for '" + line + "'");
}
}
this.blacklist = blacklist;
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e2) {
}
}
}
/**
* Blacklist contains on-acquire events.
*
* @return
*/
public boolean hasOnAcquire() {
return hasOnAcquire;
}
}
+484 -57
View File
@@ -1,6 +1,6 @@
// $Id$
/*
* WorldProtect
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -32,12 +32,12 @@ public class BlacklistEntry {
/**
* Used to prevent spamming.
*/
private static Map<String,Integer> lastAffected =
new HashMap<String,Integer>();
private static Map<String,BlacklistTrackedEvent> lastAffected =
new HashMap<String,BlacklistTrackedEvent>();
/**
* Logger.
* Parent blacklist entry.
*/
private static final Logger logger = Logger.getLogger("WorldProtect.Blacklist");
private Blacklist blacklist;
/**
* List of groups to not affect.
*/
@@ -46,14 +46,58 @@ public class BlacklistEntry {
* List of actions to perform on destruction.
*/
private String[] destroyActions;
/**
* List of actions to perform on break.
*/
private String[] breakActions;
/**
* List of actions to perform on left click.
*/
private String[] leftClickActions;
private String[] destroyWithActions;
/**
* List of actions to perform on right click.
*/
private String[] rightClickActions;
private String[] createActions;
/**
* List of actions to perform on right click upon.
*/
private String[] useActions;
/**
* List of actions to perform on drop.
*/
private String[] dropActions;
/**
* List of actions to perform on drop.
*/
private String[] acquireActions;
/**
* Message for users.
*/
private String message;
/**
* Comment for administrators.
*/
private String comment;
/**
* Used to ignore messages.
*/
private static ActionHandler silentHandler = new ActionHandler() {
public void log(String itemName) {}
public void kick(String itemName) {}
public void ban(String itemName) {}
public void notifyAdmins(String itemName) {}
public void tell(String itemName) {}
};
/**
* Construct the object.
*
* @param blacklist
*/
public BlacklistEntry(Blacklist blacklist) {
this.blacklist = blacklist;
}
/**
* @return the ignoreGroups
@@ -74,45 +118,129 @@ public class BlacklistEntry {
}
/**
* @return the destroyActions
* @return
*/
public String[] getDestroyActions() {
return destroyActions;
}
/**
* @param destroyActions the destroyActions to set
* @param actions
*/
public void setDestroyActions(String[] destroyActions) {
this.destroyActions = destroyActions;
public void setDestroyActions(String[] actions) {
this.destroyActions = actions;
}
/**
* @return the leftClickActions
* @return
*/
public String[] getLeftClickActions() {
return leftClickActions;
public String[] getBreakActions() {
return breakActions;
}
/**
* @param leftClickActions the leftClickActions to set
* @param actions
*/
public void setLeftClickActions(String[] leftClickActions) {
this.leftClickActions = leftClickActions;
public void setBreakActions(String[] actions) {
this.breakActions = actions;
}
/**
* @return
*/
public String[] getDestroyWithActions() {
return destroyWithActions;
}
/**
* @param action
*/
public void setDestroyWithActions(String[] actions) {
this.destroyWithActions = actions;
}
/**
* @return the rightClickActions
*/
public String[] getRightClickActions() {
return rightClickActions;
public String[] getCreateActions() {
return createActions;
}
/**
* @param rightClickActions the rightClickActions to set
* @param actions
*/
public void setRightClickActions(String[] rightClickActions) {
this.rightClickActions = rightClickActions;
public void setCreateActions(String[] actions) {
this.createActions = actions;
}
/**
* @return
*/
public String[] getUseActions() {
return useActions;
}
/**
* @param actions
*/
public void setUseActions(String[] actions) {
this.useActions = actions;
}
/**
* @return
*/
public String[] getDropActions() {
return dropActions;
}
/**
* @param actions
*/
public void setDropActions(String[] actions) {
this.dropActions = actions;
}
/**
* @return
*/
public String[] getAcquireActions() {
return acquireActions;
}
/**
* @param actions
*/
public void setAcquireActions(String[] actions) {
this.acquireActions = actions;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
/**
* @param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
/**
* @return the comment
*/
public String getComment() {
return comment;
}
/**
* @param comment the comment to set
*/
public void setComment(String comment) {
this.comment = comment;
}
/**
@@ -141,19 +269,25 @@ public class BlacklistEntry {
*/
public void notifyAdmins(String str) {
for (Player player : etc.getServer().getPlayerList()) {
if (player.canUseCommand("/wprotectalerts")) {
player.sendMessage(Colors.LightPurple + "WorldProtect: " + str);
if (player.canUseCommand("/wprotectalerts")
|| player.canUseCommand("/worldguardnotify")) {
player.sendMessage(Colors.LightGray + "WG: " + str);
}
}
}
/**
* Log a message.
* Ban a player.
*
* @param message
* @param player
* @param msg
*/
public void log(String message) {
logger.log(Level.INFO, message);
public void banPlayer(Player player, String msg) {
etc.getServer().ban(player.getName());
etc.getLoader().callHook(PluginLoader.Hook.BAN, new Object[]{
player.getUser(), player.getUser(), msg
});
player.kick(msg);
}
/**
@@ -164,13 +298,70 @@ public class BlacklistEntry {
* @param player
* @return
*/
public boolean onDestroy(Block block, Player player) {
public boolean onDestroy(final Block block, final Player player) {
if (destroyActions == null) {
return true;
}
boolean ret = process(block.getType(), player, destroyActions);
lastAffected.put(player.getName(), block.getType());
return ret;
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logDestroyAttempt(player, block, comment);
}
public void kick(String itemName) {
player.kick("You are not allowed to destroy " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You are not allowed to destroy " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (destroy) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You are not allowed to destroy " + itemName + ".");
}
};
return process(block.getType(), player, destroyActions, handler, false, false);
}
/**
* Called on block break. Returns true to let the action pass
* through.
*
* @param block
* @param player
* @return
*/
public boolean onBreak(final Block block, final Player player) {
if (breakActions == null) {
return true;
}
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logBreakAttempt(player, block, comment);
}
public void kick(String itemName) {
player.kick("You are not allowed to break " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You are not allowed to break " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (break) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You are not allowed to break " + itemName + ".");
}
};
return process(block.getType(), player, breakActions, handler, true, false);
}
/**
@@ -180,29 +371,207 @@ public class BlacklistEntry {
* @param player
* @return
*/
public boolean onLeftClick(int item, Player player) {
if (leftClickActions == null) {
public boolean onDestroyWith(final int item, final Player player) {
if (destroyWithActions == null) {
return true;
}
boolean ret = process(item, player, leftClickActions);
lastAffected.put(player.getName(), item);
return ret;
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logDestroyWithAttempt(player, item, comment);
}
public void kick(String itemName) {
player.kick("You can't destroy with " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You can't destroy with " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (destroy w/) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You can't destroy with " + itemName + ".");
}
};
return process(item, player, destroyWithActions, handler, false, false);
}
/**
* Called on right right. Returns true to let the action pass through.
* Called on right click. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onRightClick(int item, Player player) {
if (rightClickActions == null) {
public boolean onCreate(final int item, final Player player) {
if (createActions == null) {
return true;
}
boolean ret = process(item, player, rightClickActions);
lastAffected.put(player.getName(), item);
return ret;
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logCreateAttempt(player, item, comment);
}
public void kick(String itemName) {
player.kick("You can't place " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You can't place " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (place) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You can't place " + itemName + ".");
}
};
return process(item, player, createActions, handler, true, false);
}
/**
* Called on right click upon. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onUse(final Block block, final Player player) {
if (useActions == null) {
return true;
}
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logUseAttempt(player, block, comment);
}
public void kick(String itemName) {
player.kick("You can't use " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You can't use " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (use) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You're not allowed to use " + itemName + ".");
}
};
return process(block.getType(), player, useActions, handler, false, false);
}
/**
* Called on right click upon. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onSilentUse(final Block block, final Player player) {
if (useActions == null) {
return true;
}
return process(block.getType(), player, useActions, silentHandler, false, true);
}
/**
* Called on item drop. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onDrop(final int item, final Player player) {
if (dropActions == null) {
return true;
}
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logDropAttempt(player, item, comment);
}
public void kick(String itemName) {
player.kick("You can't drop " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You can't drop " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (drop) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You're not allowed to drop " + itemName + ".");
}
};
return process(item, player, dropActions, handler, true, false);
}
/**
* Called on item acquire. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onAcquire(final int item, final Player player) {
if (acquireActions == null) {
return true;
}
final BlacklistEntry entry = this;
ActionHandler handler = new ActionHandler() {
public void log(String itemName) {
blacklist.getLogger().logAcquireAttempt(player, item, comment);
}
public void kick(String itemName) {
player.kick("You can't acquire " + itemName);
}
public void ban(String itemName) {
entry.banPlayer(player, "Banned: You can't acquire " + itemName);
}
public void notifyAdmins(String itemName) {
entry.notifyAdmins(player.getName() + " (acquire) " + itemName
+ (comment != null ? " (" + comment + ")" : "") + ".");
}
public void tell(String itemName) {
player.sendMessage(Colors.Yellow + "You're not allowed to acquire " + itemName + ".");
}
};
return process(item, player, acquireActions, handler, true, false);
}
/**
* Called on item acquire. Returns true to let the action pass through.
*
* @param item
* @param player
* @return
*/
public boolean onSilentAcquire(final int item, final Player player) {
if (acquireActions == null) {
return true;
}
return process(item, player, acquireActions, silentHandler, false, true);
}
/**
@@ -211,35 +580,82 @@ public class BlacklistEntry {
* @param id
* @param player
* @param actions
* @param handler
* @param allowRepeat
* @param silent
* @return
*/
private boolean process(int id, Player player, String[] actions) {
private boolean process(int id, Player player, String[] actions,
ActionHandler handler, boolean allowRepeat, boolean silent) {
if (shouldIgnore(player)) {
return true;
}
String name = player.getName();
boolean repeating = lastAffected.containsKey(name)
&& lastAffected.get(name) == id;
long now = System.currentTimeMillis();
boolean repeating = false;
// Check to see whether this event is being repeated
BlacklistTrackedEvent tracked = lastAffected.get(name);
if (tracked != null) {
if (tracked.getId() == id && tracked.getTime() > now - 3000) {
repeating = true;
} else {
tracked.setTime(now);
tracked.setId(id);
}
} else {
lastAffected.put(name, new BlacklistTrackedEvent(id, now));
}
boolean ret = true;
for (String action : actions) {
// Deny
if (action.equalsIgnoreCase("deny")) {
if (silent) {
return false;
}
ret = false;
// Kick
} else if (action.equalsIgnoreCase("kick")) {
player.kick("Performed disallowed action with "
+ etc.getDataSource().getItem(id) + ".");
} else if (!repeating) {
if (this.message != null) {
player.kick(String.format(this.message,
etc.getDataSource().getItem(id)));
} else {
handler.kick(etc.getDataSource().getItem(id));
}
// Ban
} else if (action.equalsIgnoreCase("ban")) {
handler.ban(etc.getDataSource().getItem(id));
if (this.message != null) {
banPlayer(player, "Banned: " + String.format(this.message,
etc.getDataSource().getItem(id)));
} else {
handler.ban(etc.getDataSource().getItem(id));
}
} else if (!repeating || allowRepeat) {
// Notify
if (action.equalsIgnoreCase("notify")) {
notifyAdmins(player.getName() + " on destroy: "
+ etc.getDataSource().getItem(id));
handler.notifyAdmins(etc.getDataSource().getItem(id));
// Log
} else if (action.equalsIgnoreCase("log")) {
log(player.getName() + " on destroy: "
+ etc.getDataSource().getItem(id));
} else if (!repeating && action.equalsIgnoreCase("tell")) {
player.sendMessage("Can't do that with "
+ etc.getDataSource().getItem(id) + ".");
handler.log(etc.getDataSource().getItem(id));
// Tell
} else if (action.equalsIgnoreCase("tell")) {
if (this.message != null) {
player.sendMessage(Colors.Yellow +
String.format(message, etc.getDataSource().getItem(id))
+ ".");
} else {
handler.tell(etc.getDataSource().getItem(id));
}
}
}
}
@@ -262,6 +678,17 @@ public class BlacklistEntry {
* @param player
*/
public static void forgetAllPlayers() {
lastAffected = new HashMap<String,Integer>();
lastAffected.clear();
}
/**
* Gets called for actions.
*/
private static interface ActionHandler {
public void log(String itemName);
public void kick(String itemName);
public void ban(String itemName);
public void notifyAdmins(String itemName);
public void tell(String itemName);
}
}
+153
View File
@@ -0,0 +1,153 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.Set;
import java.util.HashSet;
/**
*
* @author sk89q
*/
public class BlacklistLogger implements BlacklistLoggerHandler {
/**
* List of logger handlers.
*/
private Set<BlacklistLoggerHandler> handlers
= new HashSet<BlacklistLoggerHandler>();
/**
* Add a handler.
*
* @param handler
*/
public void addHandler(BlacklistLoggerHandler handler) {
handlers.add(handler);
}
/**
* Add a handler.
*
* @param handler
*/
public void removeHandler(BlacklistLoggerHandler handler) {
handlers.remove(handler);
}
/**
* Add a handler.
*
* @param handler
*/
public void clearHandlers() {
handlers.clear();
}
/**
* Log a block destroy attempt.
*
* @param player
* @param block
*/
public void logDestroyAttempt(Player player, Block block, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logDestroyAttempt(player, block, comment);
}
}
/**
* Log a block break attempt.
*
* @param player
* @param block
*/
public void logBreakAttempt(Player player, Block block, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logBreakAttempt(player, block, comment);
}
}
/**
* Log a right click on attempt.
*
* @param player
* @param block
*/
public void logUseAttempt(Player player, Block block, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logUseAttempt(player, block, comment);
}
}
/**
* Right a left click attempt.
*
* @param player
* @param item
*/
public void logDestroyWithAttempt(Player player, int item, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logDestroyWithAttempt(player, item, comment);
}
}
/**
* Log a right click attempt.
*
* @param player
* @param item
*/
public void logCreateAttempt(Player player, int item, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logCreateAttempt(player, item, comment);
}
}
/**
* Log a drop attempt.
*
* @param player
* @param item
*/
public void logDropAttempt(Player player, int item, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logDropAttempt(player, item, comment);
}
}
/**
* Log an acquire attempt.
*
* @param player
* @param item
*/
public void logAcquireAttempt(Player player, int item, String comment) {
for (BlacklistLoggerHandler handler : handlers) {
handler.logAcquireAttempt(player, item, comment);
}
}
/**
* Close the connection.
*/
public void close() {
for (BlacklistLoggerHandler handler : handlers) {
handler.close();
}
}
}
+79
View File
@@ -0,0 +1,79 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Interface for loggers for the blacklist.
*
* @author sk89q
*/
public interface BlacklistLoggerHandler {
/**
* Log a block destroy attempt.
*
* @param player
* @param block
*/
public void logDestroyAttempt(Player player, Block block, String comment);
/**
* Log a block break attempt.
*
* @param player
* @param block
*/
public void logBreakAttempt(Player player, Block block, String comment);
/**
* Log a right click on attempt.
*
* @param player
* @param block
*/
public void logUseAttempt(Player player, Block block, String comment);
/**
* Right a left click attempt.
*
* @param player
* @param item
*/
public void logDestroyWithAttempt(Player player, int item, String comment);
/**
* Log a right click attempt.
*
* @param player
* @param item
*/
public void logCreateAttempt(Player player, int item, String comment);
/**
* Log a drop attempt.
*
* @param player
* @param item
*/
public void logDropAttempt(Player player, int item, String comment);
/**
* Log an acquire attempt.
*
* @param player
* @param item
*/
public void logAcquireAttempt(Player player, int item, String comment);
/**
* Close the logger.
*/
public void close();
}
@@ -1,6 +1,6 @@
// $Id$
/*
* WorldProtect
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -17,31 +17,50 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldprotect;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Level;
/**
* Used for formatting.
*
* @author sk89q
*/
public class SimpleLogFormat extends Formatter {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public String format(LogRecord record) {
StringBuilder text = new StringBuilder();
Level level = record.getLevel();
public class BlacklistTrackedEvent {
private int id;
private long time;
text.append("[");
text.append(dateFormat.format(new Date(record.getMillis())));
text.append("] ");
text.append(record.getMessage());
text.append("\r\n");
return text.toString();
/**
* Construct the object.
*
* @param id
* @param time
*/
public BlacklistTrackedEvent(int id, long time) {
this.id = id;
this.time = time;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return the time
*/
public long getTime() {
return time;
}
/**
* @param time the time to set
*/
public void setTime(long time) {
this.time = time;
}
}
+131
View File
@@ -0,0 +1,131 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
/**
*
* @author sk89q
*/
public class ConsoleLoggerHandler implements BlacklistLoggerHandler {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* Log a block destroy attempt.
*
* @param player
* @param block
*/
public void logDestroyAttempt(Player player, Block block, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to destroy " + getFriendlyItemName(block.getType())
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log a block break attempt.
*
* @param player
* @param block
*/
public void logBreakAttempt(Player player, Block block, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to break " + getFriendlyItemName(block.getType())
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log a right click on attempt.
*
* @param player
* @param block
*/
public void logUseAttempt(Player player, Block block, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to use " + getFriendlyItemName(block.getType())
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log an attempt to destroy with an item.
*
* @param player
* @param item
*/
public void logDestroyWithAttempt(Player player, int item, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to destroy with " + getFriendlyItemName(item)
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log a block creation attempt.
*
* @param player
* @param item
*/
public void logCreateAttempt(Player player, int item, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to create " + getFriendlyItemName(item)
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log a drop attempt.
*
* @param player
* @param item
*/
public void logDropAttempt(Player player, int item, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to drop " + getFriendlyItemName(item)
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Log an acquire attempt.
*
* @param player
* @param item
*/
public void logAcquireAttempt(Player player, int item, String comment) {
logger.log(Level.INFO, "WorldGuard: " + player.getName()
+ " tried to acquire " + getFriendlyItemName(item)
+ (comment != null ? " (" + comment + ")" : ""));
}
/**
* Get an item's friendly name with its ID.
*
* @param id
*/
private static String getFriendlyItemName(int id) {
return etc.getDataSource().getItem(id) + " (#" + id + ")";
}
/**
* Close the connection.
*/
public void close() {
}
}
+215
View File
@@ -0,0 +1,215 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
/**
*
* @author sk89q
*/
public class DatabaseLoggerHandler implements BlacklistLoggerHandler {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* DSN.
*/
private String dsn;
/**
* Username.
*/
private String user;
/**
* Password.
*/
private String pass;
/**
* Table.
*/
private String table;
/**
* Database connection.
*/
private Connection conn;
/**
* Construct the object.
*
* @param dsn
* @param user
* @param pass
*/
public DatabaseLoggerHandler(String dsn, String user, String pass, String table) {
this.dsn = dsn;
this.user = user;
this.pass = pass;
this.table = table;
}
/**
* Gets the database connection.
*
* @return
* @throws SQLException
*/
private Connection getConnection() throws SQLException {
if (conn == null || conn.isClosed()) {
conn = DriverManager.getConnection(dsn, user, pass);
}
return conn;
}
/**
* Log an event to the database.
*
* @param event
* @param name
* @param x
* @param y
* @param z
* @param item
* @param comment
*/
private void logEvent(String event, String name, int x, int y, int z, int item,
String comment) {
try {
Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO " + table
+ "(event, player, x, y, z, item, time, comment) VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setString(1, event);
stmt.setString(2, name);
stmt.setInt(3, x);
stmt.setInt(4, y);
stmt.setInt(5, z);
stmt.setInt(6, item);
stmt.setInt(7, (int)(System.currentTimeMillis() / 1000));
stmt.setString(8, comment);
stmt.executeUpdate();
} catch (SQLException e) {
logger.log(Level.SEVERE, "Failed to log blacklist event to database: "
+ e.getMessage());
}
}
/**
* Log a block destroy attempt.
*
* @param player
* @param block
*/
public void logDestroyAttempt(Player player, Block block, String comment) {
logEvent("DESTROY", player.getName(),
block.getX(), block.getY(), block.getZ(), block.getType(),
comment);
}
/**
* Log a block break attempt.
*
* @param player
* @param block
*/
public void logBreakAttempt(Player player, Block block, String comment) {
logEvent("BREAK", player.getName(),
block.getX(), block.getY(), block.getZ(), block.getType(),
comment);
}
/**
* Log a right click on attempt.
*
* @param player
* @param block
*/
public void logUseAttempt(Player player, Block block, String comment) {
logEvent("USE", player.getName(),
block.getX(), block.getY(), block.getZ(), block.getType(),
comment);
}
/**
* Right a left click attempt.
*
* @param player
* @param item
*/
public void logDestroyWithAttempt(Player player, int item, String comment) {
logEvent("DESTROY_WITH", player.getName(),
(int)Math.floor(player.getX()), (int)Math.floor(player.getY()),
(int)Math.floor(player.getZ()), item, comment);
}
/**
* Log a right click attempt.
*
* @param player
* @param item
*/
public void logCreateAttempt(Player player, int item, String comment) {
logEvent("CREATE", player.getName(),
(int)Math.floor(player.getX()), (int)Math.floor(player.getY()),
(int)Math.floor(player.getZ()), item, comment);
}
/**
* Log a drop attempt.
*
* @param player
* @param item
*/
public void logDropAttempt(Player player, int item, String comment) {
logEvent("DROP", player.getName(),
(int)Math.floor(player.getX()), (int)Math.floor(player.getY()),
(int)Math.floor(player.getZ()), item, comment);
}
/**
* Log an aquire attempt.
*
* @param player
* @param item
*/
public void logAcquireAttempt(Player player, int item, String comment) {
logEvent("AQUIRE", player.getName(),
(int)Math.floor(player.getX()), (int)Math.floor(player.getY()),
(int)Math.floor(player.getZ()), item, comment);
}
/**
* Close the connection.
*/
public void close() {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
}
}
}
+304
View File
@@ -0,0 +1,304 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.*;
import java.util.regex.*;
import java.util.Map;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TreeMap;
import java.util.Iterator;
import java.text.SimpleDateFormat;
/**
*
* @author sk89q
*/
public class FileLoggerHandler implements BlacklistLoggerHandler {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* Regex for patterns in the path.
*/
private static Pattern pattern = Pattern.compile("%.");
/**
* Date format.
*/
private static SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyyy-MM-dd HH:mm:ss");
/**
* Number of files to keep open at a time.
*/
private int cacheSize = 10;
/**
* Path pattern.
*/
private String pathPattern;
/**
* Cache of writers.
*/
private TreeMap<String,FileLoggerWriter> writers =
new TreeMap<String,FileLoggerWriter>();
/**
* Construct the object.
*
* @param pathPattern
*/
public FileLoggerHandler(String pathPattern) {
this.pathPattern = pathPattern;
}
/**
* Construct the object.
*
* @param pathPattern
* @param cacheSize
*/
public FileLoggerHandler(String pathPattern, int cacheSize) {
if (cacheSize < 1) {
throw new IllegalArgumentException("Cache size cannot be less than 1");
}
this.pathPattern = pathPattern;
this.cacheSize = cacheSize;
}
/**
* Build the path.
*
* @return
*/
private String buildPath(String playerName) {
GregorianCalendar calendar = new GregorianCalendar();
Pattern p = Pattern.compile("%.");
Matcher m = p.matcher(pathPattern);
StringBuffer buffer = new StringBuffer();
// Pattern replacements
while (m.find()) {
String group = m.group();
String rep = "?";
if (group.matches("%%")) {
rep = "%";
} else if (group.matches("%u")) {
rep = playerName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
if (rep.length() > 32) { // Actual max length is 16
rep = rep.substring(0, 32);
}
// Date and time
} else if (group.matches("%Y")) {
rep = String.valueOf(calendar.get(Calendar.YEAR));
} else if (group.matches("%m")) {
rep = String.format("%02d", calendar.get(Calendar.MONTH));
} else if (group.matches("%d")) {
rep = String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH));
} else if (group.matches("%W")) {
rep = String.format("%02d", calendar.get(Calendar.WEEK_OF_YEAR));
} else if (group.matches("%H")) {
rep = String.format("%02d", calendar.get(Calendar.HOUR_OF_DAY));
} else if (group.matches("%h")) {
rep = String.format("%02d", calendar.get(Calendar.HOUR));
} else if (group.matches("%i")) {
rep = String.format("%02d", calendar.get(Calendar.MINUTE));
} else if (group.matches("%s")) {
rep = String.format("%02d", calendar.get(Calendar.SECOND));
}
m.appendReplacement(buffer, rep);
}
m.appendTail(buffer);
return buffer.toString();
}
/**
* Log a message.
*
* @param player
* @param message
*/
private void log(Player player, String message, String comment) {
String path = buildPath(player.getName());
try {
String date = dateFormat.format(new Date());
String line = "[" + date + "] " + player.getName() + ": " + message
+ (comment != null ? " (" + comment + ")" : "") + "\r\n";
FileLoggerWriter writer = writers.get(path);
// Writer already exists!
if (writer != null) {
try {
BufferedWriter out = writer.getWriter();
out.write(line);
out.flush();
writer.updateLastUse();
return;
} catch (IOException e) {
// Failed initial rewrite... let's re-open
}
}
// Make parent directory
File file = new File(path);
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
}
FileWriter stream = new FileWriter(path, true);
BufferedWriter out = new BufferedWriter(stream);
out.write(line);
out.flush();
writer = new FileLoggerWriter(path, out);
writers.put(path, writer);
// Check to make sure our cache doesn't get too big!
if (writers.size() > cacheSize) {
Iterator<Map.Entry<String,FileLoggerWriter>> it =
writers.entrySet().iterator();
// Remove some entries
for (; it.hasNext(); ) {
Map.Entry<String,FileLoggerWriter> entry = it.next();
try {
entry.getValue().getWriter().close();
} catch (IOException e) {
}
it.remove();
// Trimmed enough
if (writers.size() <= cacheSize) {
break;
}
}
}
} catch (IOException e) {
logger.log(Level.WARNING, "Failed to log blacklist event to '"
+ path + "': " + e.getMessage());
}
}
/**
* Log a block destroy attempt.
*
* @param player
* @param block
*/
public void logDestroyAttempt(Player player, Block block, String comment) {
log(player, "Tried to destroy " + getFriendlyItemName(block.getType()),
comment);
}
/**
* Log a block break attempt.
*
* @param player
* @param block
*/
public void logBreakAttempt(Player player, Block block, String comment) {
log(player, "Tried to break " + getFriendlyItemName(block.getType()),
comment);
}
/**
* Log a right click on attempt.
*
* @param player
* @param block
*/
public void logUseAttempt(Player player, Block block, String comment) {
log(player, "Tried to use " + getFriendlyItemName(block.getType()),
comment);
}
/**
* Log an attempt to destroy with an item.
*
* @param player
* @param item
*/
public void logDestroyWithAttempt(Player player, int item, String comment) {
log(player, "Tried to destroy with " + getFriendlyItemName(item), comment);
}
/**
* Log a block creation attempt.
*
* @param player
* @param item
*/
public void logCreateAttempt(Player player, int item, String comment) {
log(player, "Tried to create " + getFriendlyItemName(item), comment);
}
/**
* Log a drop attempt.
*
* @param player
* @param item
*/
public void logDropAttempt(Player player, int item, String comment) {
log(player, "Tried to drop " + getFriendlyItemName(item), comment);
}
/**
* Log an acquire attempt.
*
* @param player
* @param item
*/
public void logAcquireAttempt(Player player, int item, String comment) {
log(player, "Tried to acquire " + getFriendlyItemName(item), comment);
}
/**
* Get an item's friendly name with its ID.
*
* @param id
*/
private static String getFriendlyItemName(int id) {
return etc.getDataSource().getItem(id) + " (#" + id + ")";
}
/**
* Close handles.
*/
public void close() {
for (Map.Entry<String,FileLoggerWriter> entry : writers.entrySet()) {
try {
entry.getValue().getWriter().close();
} catch (IOException e) {
}
}
writers.clear();
}
}
+98
View File
@@ -0,0 +1,98 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.*;
/**
*
* @author sk89q
*/
public class FileLoggerWriter implements Comparable<FileLoggerWriter> {
/**
* Path.
*/
public String path;
/**
* Writer.
*/
private BufferedWriter writer;
/**
* Last use.
*/
private long lastUse;
/**
* Construct the object.
*
* @param writer
*/
public FileLoggerWriter(String path, BufferedWriter writer) {
this.path = path;
this.writer = writer;
lastUse = System.currentTimeMillis();
}
/**
* File path.
*
* @return
*/
public String getPath() {
return path;
}
/**
* @return the writer
*/
public BufferedWriter getWriter() {
return writer;
}
/**
* @return the lastUse
*/
public long getLastUse() {
return lastUse;
}
/**
* Update last use time.
*
* @return
*/
public void updateLastUse() {
lastUse = System.currentTimeMillis();
}
/**
* Comparison function.
*
* @param other
* @return
*/
public int compareTo(FileLoggerWriter other) {
if (lastUse > other.lastUse) {
return 1;
} else if (lastUse < other.lastUse) {
return -1;
} else {
return 0;
}
}
}
+207
View File
@@ -0,0 +1,207 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.List;
import java.util.ArrayList;
import java.net.URL;
import java.io.*;
import java.lang.reflect.*;
/**
* Entry point for the plugin for hey0's mod.
*
* @author sk89q
*/
public class WorldGuard extends Plugin {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* Listener for the plugin system.
*/
private WorldGuardListener listener;
/**
* Initialize the plugin.
*/
public WorldGuard() {
listener = new WorldGuardListener(this);
}
/**
* Initializes the plugin.
*/
@Override
public void initialize() {
PluginLoader loader = etc.getLoader();
List<String> missingFeatures = new ArrayList<String>();
registerHook("COMMAND", PluginListener.Priority.MEDIUM);
registerHook("SERVERCOMMAND", PluginListener.Priority.MEDIUM);
if (!registerHook("EXPLODE", PluginListener.Priority.HIGH)) {
missingFeatures.add("disabling TNT or creeper explosions");
}
if (!registerHook("IGNITE", PluginListener.Priority.HIGH)) {
missingFeatures.add("disabling fire or lava fire");
}
if (!registerHook("FLOW", PluginListener.Priority.HIGH)) {
missingFeatures.add("controlling lava flow");
missingFeatures.add("sponge simulation");
}
registerHook("LOGINCHECK", PluginListener.Priority.HIGH);
registerHook("LOGIN", PluginListener.Priority.MEDIUM);
registerHook("BLOCK_CREATED", PluginListener.Priority.HIGH);
registerHook("BLOCK_DESTROYED", PluginListener.Priority.CRITICAL);
registerHook("BLOCK_BROKEN", PluginListener.Priority.HIGH);
registerHook("DISCONNECT", PluginListener.Priority.HIGH);
registerHook("ITEM_DROP", PluginListener.Priority.HIGH);
if (!registerHook("ITEM_PICK_UP", PluginListener.Priority.HIGH)) {
missingFeatures.add("denying item pickups");
missingFeatures.add("the item durability fix");
} else {
try {
Method method =
Item.class.getDeclaredMethod("setDamage", new Class[]{ Integer.class });
if (method == null) {
missingFeatures.add("the item durability fix");
}
} catch (NoSuchMethodException e) {
missingFeatures.add("the item durability fix");
}
}
registerHook("COMPLEX_BLOCK_CHANGE", PluginListener.Priority.HIGH);
registerHook("COMPLEX_BLOCK_SEND", PluginListener.Priority.HIGH);
registerHook("INVENTORY_CHANGE", PluginListener.Priority.HIGH);
if (!registerHook("BLOCK_PHYSICS", PluginListener.Priority.MEDIUM)) {
missingFeatures.add("controlling the physics of gravel, sand, or portal blocks");
}
if (missingFeatures.size() > 0) {
logger.log(Level.WARNING, "WorldGuard: Your version of hMod does not support "
+ concatMissingFeatures(missingFeatures) + ".");
} else {
logger.log(Level.INFO, "WorldGuard: Your version of hMod appears to"
+ " support all features.");
}
}
/**
* Conditionally registers a hook.
*
* @param name
* @param priority
* @return where the hook was registered correctly
*/
public boolean registerHook(String name, PluginListener.Priority priority) {
try {
PluginLoader.Hook hook = PluginLoader.Hook.valueOf(name);
etc.getLoader().addListener(hook, listener, this, priority);
return true;
} catch (IllegalArgumentException e) {
//logger.log(Level.WARNING, "WorldGuard: Missing hook " + name + "!");
return false;
}
}
/**
* Enables the plugin.
*/
@Override
public void enable() {
logger.log(Level.INFO, "WorldGuard version " + getVersion() + " loaded");
listener.loadConfiguration();
etc.getInstance().addCommand("/stopfire", "Globally stop fire spread");
etc.getInstance().addCommand("/allowfire", "Globally re-enable fire spread");
}
/**
* Disables the plugin.
*/
@Override
public void disable() {
try {
listener.disable();
BlacklistEntry.forgetAllPlayers();
} catch (Throwable t) {
}
etc.getInstance().removeCommand("/stopfire");
etc.getInstance().removeCommand("/allowfire");
}
/**
* Get the WorldGuard version.
*
* @return
*/
private String getVersion() {
try {
String classContainer = WorldGuard.class.getProtectionDomain()
.getCodeSource().getLocation().toString();
URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(manifestUrl.openStream());
Attributes attrib = manifest.getMainAttributes();
String ver = (String)attrib.getValue("WorldGuard-Version");
return ver != null ? ver : "(unavailable)";
} catch (IOException e) {
return "(unknown)";
}
}
/**
* Joins a string from an array of strings.
*
* @param str
* @param delimiter
* @return
*/
private static String concatMissingFeatures(List<String> str) {
if (str.isEmpty()) {
return "";
}
int size = str.size();
StringBuilder buffer = new StringBuilder();
buffer.append("(1) ");
buffer.append(str.get(0));
for (int i = 1; i < size; i++) {
if (i == size - 1) {
buffer.append(" or ");
buffer.append("(");
buffer.append(i + 1);
buffer.append(") ");
buffer.append(str.get(i));
} else {
buffer.append(", ");
buffer.append("(");
buffer.append(i + 1);
buffer.append(") ");
buffer.append(str.get(i));
}
}
return buffer.toString();
}
}
+767
View File
@@ -0,0 +1,767 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.Set;
import java.util.HashSet;
import java.util.Random;
import java.io.*;
/**
* Event listener for Hey0's server mod.
*
* @author sk89q
*/
public class WorldGuardListener extends PluginListener {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
/**
* Timer for threading.
*/
private static final Timer timer = new Timer();
/**
* Random number generator.
*/
private static Random rand = new Random();
/**
* Plugin host.
*/
private WorldGuard plugin;
/**
* Properties file for WorldGuard.
*/
private PropertiesFile properties = new PropertiesFile("worldguard.properties");
/**
* Stop fire spread mode.
*/
private boolean stopFireSpread = false;
private boolean enforceOneSession;
private boolean blockCreepers;
private boolean blockTNT;
private boolean blockLighter;
private boolean preventLavaFire;
private boolean disableAllFire;
private boolean simulateSponge;
private int spongeRadius;
private boolean itemDurability;
private Set<Integer> fireNoSpreadBlocks;
private Set<Integer> allowedLavaSpreadOver;
private Set<Integer> itemDropBlacklist;
private boolean classicWater;
private boolean noPhysicsGravel;
private boolean noPhysicsSand;
private boolean allowPortalAnywhere;
private Blacklist blacklist;
/**
* Construct the listener.
*
* @param plugin
*/
public WorldGuardListener(WorldGuard plugin) {
this.plugin = plugin;
}
/**
* Convert a comma-delimited list to a set of integers.
*
* @param str
* @return
*/
private static Set<Integer> toBlockIDSet(String str) {
if (str.trim().length() == 0) {
return null;
}
String[] items = str.split(",");
Set<Integer> result = new HashSet<Integer>();
for (String item : items) {
try {
result.add(Integer.parseInt(item.trim()));
} catch (NumberFormatException e) {
int id = etc.getDataSource().getItem(item.trim());
if (id != 0) {
result.add(id);
} else {
logger.log(Level.WARNING, "WorldGuard: Unknown block name: "
+ item);
}
}
}
return result;
}
/**
* Load the configuration
*/
public void loadConfiguration() {
properties.load();
// Load basic options
enforceOneSession = properties.getBoolean("enforce-single-session", true);
blockCreepers = properties.getBoolean("block-creepers", false);
blockTNT = properties.getBoolean("block-tnt", false);
blockLighter = properties.getBoolean("block-lighter", false);
preventLavaFire = properties.getBoolean("disable-lava-fire", true);
disableAllFire = properties.getBoolean("disable-all-fire-spread", false);
itemDropBlacklist = toBlockIDSet(properties.getString("item-drop-blacklist", ""));
fireNoSpreadBlocks = toBlockIDSet(properties.getString("disallowed-fire-spread-blocks", ""));
allowedLavaSpreadOver = toBlockIDSet(properties.getString("allowed-lava-spread-blocks", ""));
classicWater = properties.getBoolean("classic-water", false);
simulateSponge = properties.getBoolean("simulate-sponge", true);
spongeRadius = Math.max(1, properties.getInt("sponge-radius", 3)) - 1;
itemDurability = properties.getBoolean("item-durability", false);
noPhysicsGravel = properties.getBoolean("no-physics-gravel", false);
noPhysicsSand = properties.getBoolean("no-physics-sand", false);
allowPortalAnywhere = properties.getBoolean("allow-portal-anywhere", false);
// Console log configuration
boolean logConsole = properties.getBoolean("log-console", true);
// Database log configuration
boolean logDatabase = properties.getBoolean("log-database", false);
String dsn = properties.getString("log-database-dsn", "jdbc:mysql://localhost:3306/minecraft");
String user = properties.getString("log-database-user", "root");
String pass = properties.getString("log-database-pass", "");
String table = properties.getString("log-database-table", "blacklist_events");
// File log configuration
boolean logFile = properties.getBoolean("log-file", false);
String logFilePattern = properties.getString("log-file-path", "worldguard/logs/%Y-%m-%d.log");
int logFileCacheSize = Math.max(1, properties.getInt("log-file-open-files", 10));
// Load the blacklist
try {
// If there was an existing blacklist, close loggers
if (blacklist != null) {
blacklist.getLogger().close();
}
// First load the blacklist data from worldguard-blacklist.txt
Blacklist blist = new Blacklist();
blist.load(new File("worldguard-blacklist.txt"));
// If the blacklist is empty, then set the field to null
// and save some resources
if (blist.isEmpty()) {
this.blacklist = null;
} else {
this.blacklist = blist;
logger.log(Level.INFO, "WorldGuard: Blacklist loaded.");
BlacklistLogger blacklistLogger = blist.getLogger();
if (logDatabase) {
blacklistLogger.addHandler(new DatabaseLoggerHandler(dsn, user, pass, table));
}
if (logConsole) {
blacklistLogger.addHandler(new ConsoleLoggerHandler());
}
if (logFile) {
FileLoggerHandler handler =
new FileLoggerHandler(logFilePattern, logFileCacheSize);
blacklistLogger.addHandler(handler);
}
}
} catch (FileNotFoundException e) {
logger.log(Level.WARNING, "WorldGuard blacklist does not exist.");
} catch (IOException e) {
logger.log(Level.WARNING, "Could not load WorldGuard blacklist: "
+ e.getMessage());
}
// Print an overview of settings
if (properties.getBoolean("summary-on-start", true)) {
logger.log(Level.INFO, enforceOneSession ? "WorldGuard: Single session is enforced."
: "WorldGuard: Single session is NOT ENFORCED.");
logger.log(Level.INFO, blockTNT ? "WorldGuard: TNT ignition is blocked."
: "WorldGuard: TNT ignition is PERMITTED.");
logger.log(Level.INFO, blockLighter ? "WorldGuard: Lighters are blocked."
: "WorldGuard: Lighters are PERMITTED.");
logger.log(Level.INFO, preventLavaFire ? "WorldGuard: Lava fire is blocked."
: "WorldGuard: Lava fire is PERMITTED.");
if (disableAllFire) {
logger.log(Level.INFO, "WorldGuard: All fire spread is disabled.");
} else {
if (fireNoSpreadBlocks != null) {
logger.log(Level.INFO, "WorldGuard: Fire spread is limited to "
+ fireNoSpreadBlocks.size() + " block types.");
} else {
logger.log(Level.INFO, "WorldGuard: Fire spread is UNRESTRICTED.");
}
}
}
}
/**
* Called during the early login process to check whether or not to kick the
* player
*
* @param user
* @return kick reason. null if you don't want to kick the player.
*/
@Override
public String onLoginChecks(String user) {
if (enforceOneSession) {
for (Player player : etc.getServer().getPlayerList()) {
if (player.getName().equalsIgnoreCase(user)) {
player.kick("Logged in from another location.");
}
}
}
return null;
}
/**
* Called during the later login process
*
* @param player
*/
@Override
public void onLogin(Player player) {
if (stopFireSpread) {
player.sendMessage(Colors.Yellow + "Fire spread is currently globally disabled.");
}
}
/**
* Called before the command is parsed. Return true if you don't want the
* command to be parsed.
*
* @param player
* @param split
* @return false if you want the command to be parsed.
*/
@Override
public boolean onCommand(Player player, String[] split) {
if (split[0].equalsIgnoreCase("/stopfire") &&
player.canUseCommand("/stopfire")) {
if (!stopFireSpread) {
etc.getServer().messageAll(Colors.Yellow
+ "Fire spread has been globally disabled by " + player.getName() + ".");
} else {
player.sendMessage(Colors.Yellow + "Fire spread was already globally disabled.");
}
stopFireSpread = true;
return true;
} else if (split[0].equalsIgnoreCase("/allowfire")
&& player.canUseCommand("/stopfire")) {
if (stopFireSpread) {
etc.getServer().messageAll(Colors.Yellow
+ "Fire spread has been globally re-enabled by " + player.getName() + ".");
} else {
player.sendMessage(Colors.Yellow + "Fire spread was already globally enabled.");
}
stopFireSpread = false;
return true;
}
return false;
}
/**
* Called before the console command is parsed. Return true if you don't
* want the server command to be parsed by the server.
*
* @param split
* @return false if you want the command to be parsed.
*/
@Override
public boolean onConsoleCommand(String[] split) {
if (split[0].equalsIgnoreCase("fire-stop")) {
if (!stopFireSpread) {
etc.getServer().messageAll(Colors.Yellow
+ "Fire spread has been globally disabled by server console.");
logger.log(Level.INFO, "Fire spread is now globally disabled.");
} else {
logger.log(Level.INFO, "Fire spread was already globally disabled.");
}
stopFireSpread = true;
return true;
} else if (split[0].equalsIgnoreCase("fire-allow")) {
if (stopFireSpread) {
etc.getServer().messageAll(Colors.Yellow
+ "Fire spread has been globally re-enabled by server console.");
logger.log(Level.INFO, "Fire spread is now globally enabled.");
} else {
logger.log(Level.INFO, "Fire spread was already globally enabled.");
}
stopFireSpread = false;
return true;
}
return false;
}
/**
* Called when a player drops an item.
*
* @param player
* player who dropped the item
* @param item
* item that was dropped
* @return true if you don't want the dropped item to be spawned in the
* world
*/
@Override
public boolean onItemDrop(Player player, Item item) {
if (itemDropBlacklist != null) {
int n = item.getItemId();
if (itemDropBlacklist.contains(n)) {
player.sendMessage(Colors.Rose + "Item was destroyed!");
return true;
}
}
if (blacklist != null) {
if (!blacklist.onDrop(item.getItemId(), player)) {
return true;
}
}
if (!itemDurability) {
try {
item.setDamage(0);
} catch (java.lang.NoSuchMethodError e) {
}
}
return false;
}
/**
* Called when a player picks up an item.
*
* @param player
* player who picked up the item
* @param item
* item that was picked up
* @return true if you want to leave the item where it was
*/
@Override
public boolean onItemPickUp(Player player, Item item) {
if (blacklist != null && blacklist.hasOnAcquire()) {
if (!blacklist.onSilentAcquire(item.getItemId(), player)) {
return true;
}
}
return false;
}
/**
* Called when a player's inventory is modified.
*
* @param player
* player who's inventory was modified
* @return true if you want any changes to be reverted
*/
@Override
public boolean onInventoryChange(Player player) {
if (blacklist != null && blacklist.hasOnAcquire()) {
hl[] items = player.getInventory().getArray();
boolean needUpdate = false;
for (int i = 0; i < items.length; i++) {
if (items[i] != null) {
if (!blacklist.onAcquire(items[i].c, player)) {
items[i] = null;
needUpdate = true;
}
}
}
if (needUpdate) {
player.getInventory().updateInventory();
}
}
return false;
}
/**
* Called when someone presses right click. If they right clicked with a
* block you can return true to cancel that. You can intercept this to add
* your own right click actions to different item types (see itemInHand)
*
* @param player
* @param blockPlaced
* @param blockClicked
* @param itemInHand
* @return false if you want the action to go through
*/
@Override
public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked,
int itemInHand) {
if (blacklist != null) {
if (!blacklist.onCreate(itemInHand, player)) {
// Water/lava bucket fix
if (itemInHand == 326 || itemInHand == 327) {
final int x = blockPlaced.getX();
final int y = blockPlaced.getY();
final int z = blockPlaced.getZ();
final int existingID = etc.getServer().getBlockIdAt(x, y, z);
// This is REALLY BAD, but there's no other choice
// at the moment that is as reliable
timer.schedule(new TimerTask() {
public void run() {
try {
etc.getServer().setBlockAt(existingID, x, y, z);
} catch (Throwable t) {}
}
}, 200); // Just in case
}
return true;
}
if (!blacklist.onUse(blockClicked, player)) {
return true;
}
}
if (simulateSponge && blockPlaced.getType() == 19) {
int ox = blockPlaced.getX();
int oy = blockPlaced.getY();
int oz = blockPlaced.getZ();
Server server = etc.getServer();
for (int cx = -spongeRadius; cx <= spongeRadius; cx++) {
for (int cy = -spongeRadius; cy <= spongeRadius; cy++) {
for (int cz = -spongeRadius; cz <= spongeRadius; cz++) {
int id = server.getBlockIdAt(ox + cx, oy + cy, oz + cz);
if (id == 8 || id == 9) {
server.setBlockAt(0, ox + cx, oy + cy, oz + cz);
}
}
}
}
}
return false;
}
/**
* Called when a person left clicks a block.
*
* @param player
* @param block
* @return
*/
@Override
public boolean onBlockDestroy(Player player, Block block) {
int type = block.getType();
if (blacklist != null) {
if (!blacklist.onDestroyWith(player.getItemInHand(), player)) {
return true;
}
if (!blacklist.onDestroy(block, player)) {
return true;
}
}
return false;
}
/**
* Called when a person actually breaks the block.
*
* @param player
* @param block
* @return
*/
@Override
public boolean onBlockBreak(Player player, Block block) {
if (blacklist != null) {
if (!blacklist.onBreak(block, player)) {
return true;
}
}
return false;
}
/**
* Called when either a sign, chest or furnace is changed.
*
* @param player
* player who changed it
* @param complexBlock
* complex block that changed
* @return true if you want any changes to be reverted
*/
@Override
public boolean onComplexBlockChange(Player player, ComplexBlock complexBlock) {
if (blacklist != null) {
if (complexBlock instanceof Chest) {
Block block = new Block(54, complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
if (!blacklist.onSilentUse(block, player)) {
return true;
}
} else if (complexBlock instanceof Furnace) {
int id = etc.getServer().getBlockIdAt(complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
Block block = new Block(id, complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
if (!blacklist.onSilentUse(block, player)) {
return true;
}
} else if (complexBlock instanceof Sign) {
int id = etc.getServer().getBlockIdAt(complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
Block block = new Block(id, complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
if (!blacklist.onSilentUse(block, player)) {
return true;
}
}
}
return false;
}
/**
* Called when either a sign, chest or furnace is sent to a player
*
* @param player
* player who the block is being sent to
* @param complexBlock
* complex block that's being sent
* @return true if you want the chest, furnace or sign to be empty
*/
@Override
public boolean onSendComplexBlock(Player player, ComplexBlock complexBlock) {
if (blacklist != null) {
if (complexBlock instanceof Chest) {
Block block = new Block(54, complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
if (!blacklist.onSilentUse(block, player)) {
return true;
}
} else if (complexBlock instanceof Furnace) {
int id = etc.getServer().getBlockIdAt(complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
Block block = new Block(id, complexBlock.getX(),
complexBlock.getY(), complexBlock.getZ());
if (!blacklist.onSilentUse(block, player)) {
return true;
}
}
}
return false;
}
/*
* Called when either a lava block or a lighter tryes to light something on fire.
* block status depends on the light source:
* 1 = lava.
* 2 = lighter (flint + steel).
* 3 = spread (dynamic spreading of fire).
* @param block
* block that the fire wants to spawn in.
*
* @return true if you dont want the fire to ignite.
*/
@Override
public boolean onIgnite(Block block, Player player) {
if (preventLavaFire && block.getStatus() == 1) {
return true;
}
if (blockLighter && block.getStatus() == 2) {
return !player.canUseCommand("/uselighter")
&& !player.canUseCommand("/lighter");
}
if (stopFireSpread && block.getStatus() == 3) {
return true;
}
if (disableAllFire && block.getStatus() == 3) {
return true;
}
if (fireNoSpreadBlocks != null && block.getStatus() == 3) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
if (fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y - 1, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x + 1, y, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x - 1, y, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z - 1))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z + 1))) {
return true;
}
}
return false;
}
/*
* Called when a dynamite block or a creeper is triggerd.
* block status depends on explosive compound:
* 1 = dynamite.
* 2 = creeper.
* @param block
* dynamite block/creeper location block.
*
* @return true if you dont the block to explode.
*/
@Override
public boolean onExplode(Block block) {
if (blockCreepers && block.getStatus() == 2) {
return true;
}
if (blockTNT && block.getStatus() == 1) {
return true;
}
return false;
}
/*
* Called when fluid wants to flow to a certain block.
* (10 & 11 for lava and 8 & 9 for water)
*
* @param blockFrom
* the block where the fluid came from.
* (blocktype = fluid type)
* @param blockTo
* the block where fluid wants to flow to.
*
*
* @return true if you dont want the substance to flow.
*/
@Override
public boolean onFlow(Block blockFrom, Block blockTo) {
int x = blockFrom.getX();
int y = blockFrom.getY();
int z = blockFrom.getZ();
boolean isWater = blockFrom.getType() == 8 || blockFrom.getType() == 9;
boolean isLava = blockFrom.getType() == 10 || blockFrom.getType() == 11;
if (simulateSponge && isWater) {
int ox = blockTo.getX();
int oy = blockTo.getY();
int oz = blockTo.getZ();
Server server = etc.getServer();
for (int cx = -spongeRadius; cx <= spongeRadius; cx++) {
for (int cy = -spongeRadius; cy <= spongeRadius; cy++) {
for (int cz = -spongeRadius; cz <= spongeRadius; cz++) {
if (server.getBlockIdAt(ox + cx, oy + cy, oz + cz) == 19) {
return true;
}
}
}
}
}
if (classicWater && isWater) {
int blockBelow = etc.getServer().getBlockIdAt(blockFrom.getX(), blockFrom.getY() - 1, blockFrom.getZ());
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
etc.getServer().setBlockAt(9, blockFrom.getX(), blockFrom.getY(), blockFrom.getZ());
return false;
}
}
if (allowedLavaSpreadOver != null && isLava) {
int targetId = etc.getServer().getBlockIdAt(
blockTo.getX(), blockTo.getY() - 1, blockTo.getZ());
if (!allowedLavaSpreadOver.contains(targetId)) {
return true;
}
}
return false;
}
/**
* Called when the game is checking the physics for a certain block.
* This method is called frequently whenever a nearby block is changed,
* or if the block has just been placed.
* Currently the only supported blocks are sand, gravel and portals.
*
* @param block Block which requires special physics
* @param boolean true if this block has just been placed
* @return true if you do want to stop the default physics for this block
*/
public boolean onBlockPhysics(Block block, boolean placed) {
int id = block.getType();
if (id == 13 && noPhysicsGravel) {
return true;
}
if (id == 12 && noPhysicsSand) {
return true;
}
if (id == 90 && allowPortalAnywhere) {
return true;
}
return false;
}
/**
* Called on player disconnect
*
* @param player
*/
@Override
public void onDisconnect(Player player) {
BlacklistEntry.forgetPlayer(player);
}
/**
* Call to disable the plugin.
*/
public void disable() {
if (blacklist != null) {
blacklist.getLogger().close();
}
}
}
-102
View File
@@ -1,102 +0,0 @@
// $Id$
/*
* WorldProtect
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.net.URL;
import java.io.*;
/**
* Entry point for the plugin for hey0's mod.
*
* @author sk89q
*/
public class WorldProtect extends Plugin {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldProtect");
/**
* Listener for the plugin system.
*/
private static final WorldProtectListener listener =
new WorldProtectListener();
/**
* Initializes the plugin.
*/
@Override
public void initialize() {
PluginLoader loader = etc.getLoader();
loader.addListener(PluginLoader.Hook.EXPLODE, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.IGNITE, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.FLOW, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.LOGINCHECK, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.BLOCK_CREATED, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.BLOCK_DESTROYED, listener, this,
PluginListener.Priority.HIGH);
loader.addListener(PluginLoader.Hook.DISCONNECT, listener, this,
PluginListener.Priority.HIGH);
}
/**
* Enables the plugin.
*/
@Override
public void enable() {
listener.loadConfiguration();
logger.log(Level.INFO, "WorldProtect version " + getVersion() + " loaded");
}
/**
* Disables the plugin.
*/
@Override
public void disable() {
BlacklistEntry.forgetAllPlayers();
}
/**
* Get the WorldProtect version.
*
* @return
*/
private String getVersion() {
try {
String classContainer = WorldProtect.class.getProtectionDomain()
.getCodeSource().getLocation().toString();
URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(manifestUrl.openStream());
Attributes attrib = manifest.getMainAttributes();
String ver = (String)attrib.getValue("WorldProtect-Version");
return ver != null ? ver : "(unavailable)";
} catch (IOException e) {
return "(unknown)";
}
}
}
-510
View File
@@ -1,510 +0,0 @@
// $Id$
/*
* WorldProtect
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.logging.Handler;
import java.util.logging.ConsoleHandler;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.io.*;
import com.sk89q.worldprotect.*;
import java.util.logging.FileHandler;
/**
* Event listener for Hey0's server mod.
*
* @author sk89q
*/
public class WorldProtectListener extends PluginListener {
/**
* Logger.
*/
private static final Logger logger = Logger.getLogger("Minecraft.WorldProtect");
/**
* Properties file for CraftBook.
*/
private PropertiesFile properties = new PropertiesFile("worldprotect.properties");
/**
* Random number generator.
*/
private static Random rand = new Random();
private boolean enforceOneSession;
private boolean blockCreepers;
private boolean blockTNT;
private boolean blockLighter;
private boolean preventLavaFire;
private boolean disableAllFire;
private boolean simulateSponge;
private boolean blockLagFix;
private Set<Integer> fireNoSpreadBlocks;
private Set<Integer> allowedLavaSpreadOver;
private boolean classicWater;
private Map<Integer,BlacklistEntry> blacklist;
/**
* Convert a comma-delimited list to a set of integers.
*
* @param str
* @return
*/
private static Set<Integer> toBlockIDSet(String str) {
if (str.trim().length() == 0) {
return null;
}
String[] items = str.split(",");
Set<Integer> result = new HashSet<Integer>();
for (String item : items) {
try {
result.add(Integer.parseInt(item.trim()));
} catch (NumberFormatException e) {
int id = etc.getDataSource().getItem(item.trim());
if (id != 0) {
result.add(id);
} else {
logger.log(Level.WARNING, "WorldProtect: Unknown block name: "
+ item);
}
}
}
return result;
}
/**
* Load the configuration
*/
public void loadConfiguration() {
properties.load();
enforceOneSession = properties.getBoolean("enforce-single-session", true);
blockCreepers = properties.getBoolean("block-creepers", false);
blockTNT = properties.getBoolean("block-tnt", false);
blockLighter = properties.getBoolean("block-lighter", false);
preventLavaFire = properties.getBoolean("disable-lava-fire", false);
disableAllFire = properties.getBoolean("disable-all-fire-spread", false);
fireNoSpreadBlocks = toBlockIDSet(properties.getString("disallowed-fire-spread-blocks", ""));
allowedLavaSpreadOver = toBlockIDSet(properties.getString("allowed-lava-spread-blocks", ""));
classicWater = properties.getBoolean("classic-water", false);
simulateSponge = properties.getBoolean("simulate-sponge", false);
blockLagFix = properties.getBoolean("block-lag-fix", false);
try {
blacklist = loadBlacklist(new File("worldprotect-blacklist.txt"));
} catch (FileNotFoundException e) {
logger.log(Level.WARNING, "WorldProtect blacklist does not exist.");
} catch (IOException e) {
logger.log(Level.WARNING, "Could not load WorldProtect blacklist: "
+ e.getMessage());
}
Logger blacklistLogger = Logger.getLogger("WorldProtect.Blacklist");
blacklistLogger.setUseParentHandlers(false);
for (Handler handler : blacklistLogger.getHandlers()) {
blacklistLogger.removeHandler(handler);
}
// Blacklist log to console
if (properties.getBoolean("blacklist-log-console", true)) {
Handler handler = new ConsoleHandler();
handler.setFormatter(new ConsoleLogFormat());
blacklistLogger.addHandler(handler);
}
// Blacklist log file
String logFile = properties.getString("blacklist-log-file", "").trim();
int limit = properties.getInt("blacklist-log-file-limit", 1024 * 1024 * 5);
int count = properties.getInt("blacklist-log-file-count", 10);
if (logFile.length() > 0) {
try {
Handler handler = new FileHandler(logFile, limit, count, true);
handler.setFormatter(new SimpleLogFormat());
blacklistLogger.addHandler(handler);
} catch (IOException e) {
logger.log(Level.WARNING, "Could not open blacklist log file: "
+ e.getMessage());
}
}
}
/**
* Called during the early login process to check whether or not to kick the
* player
*
* @param user
* @return kick reason. null if you don't want to kick the player.
*/
public String onLoginChecks(String user) {
if (enforceOneSession) {
for (Player player : etc.getServer().getPlayerList()) {
if (player.getName().equalsIgnoreCase(user)) {
player.kick("Logged in from another location.");
}
}
}
return null;
}
/**
* Called when someone presses right click. If they right clicked with a
* block you can return true to cancel that. You can intercept this to add
* your own right click actions to different item types (see itemInHand)
*
* @param player
* @param blockPlaced
* @param blockClicked
* @param itemInHand
* @return false if you want the action to go through
*/
public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked,
int itemInHand) {
if (blacklist != null) {
BlacklistEntry entry = blacklist.get(itemInHand);
if (entry != null) {
if (!entry.onRightClick(itemInHand, player)) {
return true;
}
}
}
return false;
}
/**
* Called when a person left clicks a block.
*
* @param player
* @param block
* @return
*/
public boolean onBlockDestroy(Player player, Block block) {
int type = block.getType();
if (blacklist != null) {
BlacklistEntry entry = blacklist.get(player.getItemInHand());
if (entry != null) {
if (entry.onLeftClick(player.getItemInHand(), player)) {
return true;
}
}
entry = blacklist.get(block.getType());
if (entry != null) {
if (!entry.onDestroy(block, player)) {
return true;
}
}
}
if (blockLagFix
&& type != 64 // Wooden door
&& type != 71 // Iron door
&& type != 77 // Stone button
&& type != 69 // Lever
&& type != 7 // Bedrock
&& type != 51 // Fire
&& type != 46 // TNT
&& type != 59 // Crops
&& type != 62 // Burning furnace
&& type != 50 // Torch
&& type != 75 // Redstone torch
&& type != 76 // Redstone torch
) {
if (block.getStatus() == 3) {
int dropped = type;
int count = 1;
if (type == 1) { dropped = 4; } // Stone
else if (type == 2) { dropped = 3; } // Grass
else if (type == 16) { dropped = 263; } // Coal ore
else if (type == 18) { // Leaves
if (rand.nextDouble() > 0.95) {
dropped = 6;
} else {
dropped = 0;
}
}
else if (type == 47) { dropped = 0; } // Bookshelves
else if (type == 52) { dropped = 0; } // Mob spawner
else if (type == 53) { dropped = 5; } // Wooden stairs
else if (type == 55) { dropped = 5; } // Redstone wire
else if (type == 56) { dropped = 264; } // Diamond ore
else if (type == 60) { dropped = 3; } // Soil
else if (type == 63) { dropped = 323; } // Sign post
else if (type == 67) { dropped = 4; } // Cobblestone stairs
else if (type == 68) { dropped = 323; } // Wall sign
else if (type == 73) { dropped = 331; count = 4; } // Redstone ore
else if (type == 74) { dropped = 331; count = 4; } // Glowing redstone ore
else if (type == 75) { dropped = 76; count = 4; } // Redstone torch
else if (type == 79) { dropped = 0; count = 4; } // Ice
else if (type == 82) { dropped = 337; count = 4; } // Clay
else if (type == 83) { dropped = 338; count = 4; } // Reed
else if (type == 89) { dropped = 348; } // Lightstone
if (dropped > 0) {
etc.getServer().setBlockAt(0, block.getX(), block.getY(), block.getZ());
for (int i = 0; i < count; i++) {
etc.getServer().dropItem(block.getX(), block.getY(), block.getZ(),
dropped, i);
}
// Drop flint with gravel
if (type == 13) {
if (rand.nextDouble() > 0.95) {
etc.getServer().dropItem(block.getX(), block.getY(), block.getZ(),
318, 1);
}
}
}
}
return true;
}
return false;
}
/*
* Called when either a lava block or a lighter tryes to light something on fire.
* block status depends on the light source:
* 1 = lava.
* 2 = lighter (flint + steel).
* 3 = spread (dynamic spreading of fire).
* @param block
* block that the fire wants to spawn in.
*
* @return true if you dont want the fire to ignite.
*/
public boolean onIgnite(Block block, Player player) {
if (preventLavaFire && block.getStatus() == 1) {
return true;
}
if (blockLighter && block.getStatus() == 2) {
return !player.canUseCommand("/uselighter")
&& !player.canUseCommand("/lighter");
}
if (disableAllFire && block.getStatus() == 3) {
return true;
}
if (fireNoSpreadBlocks != null && block.getStatus() == 3) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
if (fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y - 1, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x + 1, y, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x - 1, y, z))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z - 1))
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z + 1))) {
return true;
}
}
return false;
}
/*
* Called when a dynamite block or a creeper is triggerd.
* block status depends on explosive compound:
* 1 = dynamite.
* 2 = creeper.
* @param block
* dynamite block/creeper location block.
*
* @return true if you dont the block to explode.
*/
public boolean onExplode(Block block) {
if (blockCreepers && block.getStatus() == 2) {
return true;
}
if (blockTNT && block.getStatus() == 1) {
return true;
}
return false;
}
/*
* Called when lava wants to flow to a certain block.
* block status represents the type that wants to flow.
* (10 & 11 for lava and 8 & 9 for water)
*
* @param block
* the block beneath where the substance wants to flow to.
*
* for example:
* lava want to flow to block x,y,z then the param block is the block x,y-1,z.
*
* @return true if you dont want the substance to flow.
*/
public boolean onFlow(Block block) {
if (simulateSponge && (block.getStatus() == 8 || block.getStatus() == 9)) {
int ox = block.getX();
int oy = block.getY() + 1;
int oz = block.getZ();
Server server = etc.getServer();
for (int x = -4; x <= 4; x++) {
for (int y = -4; y <= 4; y++) {
for (int z = -4; z <= 4; z++) {
if (server.getBlockIdAt(ox + x, oy + y, oz + z) == 19) {
return true;
}
}
}
}
}
if (classicWater && (block.getStatus() == 8 || block.getStatus() == 9)) {
int blockBelow = etc.getServer().getBlockIdAt(block.getX(), block.getY(), block.getZ());
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
etc.getServer().setBlockAt(9, block.getX(), block.getY() + 1, block.getZ());
return false;
}
}
if (allowedLavaSpreadOver != null && (block.getStatus() == 10 || block.getStatus() == 11)) {
if (!allowedLavaSpreadOver.contains(block.getType())) {
return true;
}
}
return false;
}
/**
* Called on player disconnect
*
* @param player
*/
public void onDisconnect(Player player) {
BlacklistEntry.forgetPlayer(player);
}
/**
* Load the blacklist.
*
* @param file
* @return
* @throws IOException
*/
public Map<Integer,BlacklistEntry> loadBlacklist(File file)
throws IOException {
FileReader input = null;
Map<Integer,BlacklistEntry> blacklist = new HashMap<Integer,BlacklistEntry>();
try {
input = new FileReader(file);
BufferedReader buff = new BufferedReader(input);
String line;
List<BlacklistEntry> entries = null;
while ((line = buff.readLine()) != null) {
line = line.trim();
// Blank line
if (line.length() == 0) {
continue;
} else if (line.charAt(0) == ';' || line.charAt(0) == '#') {
continue;
}
if (line.matches("^\\[.*\\]$")) {
String[] items = line.substring(1, line.length() - 1).split(",");
entries = new ArrayList<BlacklistEntry>();
for (String item : items) {
int id = 0;
try {
id = Integer.parseInt(item.trim());
} catch (NumberFormatException e) {
id = etc.getDataSource().getItem(item.trim());
if (id == 0) {
logger.log(Level.WARNING, "WorldProtect: Unknown block name: "
+ item);
break;
}
}
BlacklistEntry entry = new BlacklistEntry();
blacklist.put(id, entry);
entries.add(entry);
}
} else if (entries != null) {
String[] parts = line.split("=");
if (parts.length == 1) {
logger.log(Level.WARNING, "Found option with no value "
+ file.getName() + " for '" + line + "'");
continue;
}
boolean unknownOption = false;
for (BlacklistEntry entry : entries) {
if (parts[0].equalsIgnoreCase("ignore-groups")) {
entry.setIgnoreGroups(parts[1].split(","));
} else if(parts[0].equalsIgnoreCase("on-destroy")) {
entry.setDestroyActions(parts[1].split(","));
} else if(parts[0].equalsIgnoreCase("on-left")) {
entry.setLeftClickActions(parts[1].split(","));
} else if(parts[0].equalsIgnoreCase("on-right")) {
entry.setRightClickActions(parts[1].split(","));
} else {
unknownOption = true;
}
}
if (unknownOption) {
logger.log(Level.WARNING, "Unknown option '" + parts[0]
+ "' in " + file.getName() + " for '" + line + "'");
}
} else {
logger.log(Level.WARNING, "Found option with no heading "
+ file.getName() + " for '" + line + "'");
}
}
return blacklist.isEmpty() ? null : blacklist;
} finally {
try {
if (input != null) {
input.close();
}
} catch (IOException e2) {
}
}
}
}
@@ -1,64 +0,0 @@
// $Id$
/*
* WorldProtect
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldprotect;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import java.util.logging.Level;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Used for formatting.
*
* @author sk89q
*/
public class ConsoleLogFormat extends Formatter {
public String format(LogRecord record) {
StringBuilder text = new StringBuilder();
Level level = record.getLevel();
if (level == Level.FINEST) {
text.append("[FINEST] ");
} else if (level == Level.FINER) {
text.append("[FINER] ");
} else if (level == Level.FINE) {
text.append("[FINE] ");
} else if (level == Level.INFO) {
text.append("[INFO] ");
} else if (level == Level.WARNING) {
text.append("[WARNING] ");
} else if (level == Level.SEVERE) {
text.append("[SEVERE] ");
}
text.append(record.getMessage());
text.append("\r\n");
Throwable t = record.getThrown();
if (t != null) {
StringWriter writer = new StringWriter();
t.printStackTrace(new PrintWriter(writer));
text.append(writer.toString());
}
return text.toString();
}
}
+91
View File
@@ -0,0 +1,91 @@
#
# This is the blacklist for WorldGuard. Comments start with # and they
# are ignored so you can put your own notes.
#
# Format:
# [item1,item2]
# option1=options
# event1=whatToDo1,whatToDo2,whatToDo3
# event2=whatToDo1,whatToDo2
#
# Example to block ore and catch some events:
# [coalore,goldore,ironore]
# on-destroy-with=deny,log,kick
# on-create=deny,tell
#
# Options:
# - ignore-groups (comma-delimited list of groups to not affect)
# - comment (message for yourself that is printed with 'log' and 'notify')
# - message (optional message to show the user instead; %s is the item name)
#
# Events:
# - on-destroy (when a block of this type is being destroyed)
# - on-break (when a block of this type is about to be broken)
# - on-destroy-with (the item/block held by the user while destroying)
# - on-create (the item/block in the user's inventory is being created)
# - on-use (the block is right clicked)
# - on-drop (the item is being dropped from the player's inventory)
# - on-acquire (the item enters a player's inventory via some method)
#
# Actions (for events):
# - deny (deny completely)
# - notify (notify admins)
# - log (log to console/file/database)
# - tell (tell a player that that's not allowed)
# - kick (kick player)
# - ban (ban player)
#
# With the on-acquire event, it will completely block item pick ups
# (the item will still be on the ground) if you use 'deny' but the other
# actions (notify, log, etc.) won't do anything. However, if the player
# receives the item via a different method (i.e. from a chest), all actions
# will work although the item is removed after a short delay rather than
# blocked from the beginning (as it is part client-side).
#
# Users with the /worldguardnotify permission will be receive notifications.
#
# -------------
#
# You can have the same block or item used in two different sections and
# they will both apply:
#
# [goldblock]
# ignore-groups=vip
# on-destroy=deny
# [goldblock]
# ignore-groups=admins
# on-destroy=tell
#
# However, some events override others. For example, if you disable both
# usage of the diamond pickaxe (with the on-destroy-with event) and
# destruction of gold blocks (with the on-destroy event) and a player tries
# to destroy a gold block with a diamond pickaxe, because the
# on-destroy-with event comes first, the rules for the gold block
# will not be applied (but the player will be denied nevertheless).
#
# -------------
#
# Some examples follow. Remember to remove # in front if you want them
# to work for you!
#[lavabucket]
#ignore-groups=admins,mods
#on-destroy-with=deny,log,kick
#on-create=deny,tell
#[coalore,goldore,ironore]
#ignore-groups=admins,mods,vip
#on-destroy=notify,deny,log
#[cobblestone]
#on-create=deny,tell,log
#[lever]
#on-break=deny
# This is an example of the 'durability cheat' workaround that destroys your
# tool when you drop it
#[256,257,258,259,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294,346]
#on-drop=deny,tell
#comment=Durability Hacks
#message=Your tool was destroyed
+50
View File
@@ -0,0 +1,50 @@
# This is a starter copy of WorldGuard's configuration so you can configure
# WorldGuard right from the beginning. Copy it into your server folder
# (into where server.properties resides) and edit the file as your desire.
# These comments will be lost whenever WorldGuard updates this file.
# More detailed descriptions of the options can be found in README.txt!
summary-on-start=true
# Toggle the item durabiltiy fix
item-durability=true
# Simulate sponge
simulate-sponge=false
sponge-radius=3
# Simulate classic water
classic-water=false
# Adjust physics
allow-portal-anywhere=false
no-physics-gravel=false
no-physics-sand=false
# Protection
enforce-single-session=true
item-drop-blacklist=
# Simple prevention
block-creepers=false
block-lighter=false
block-tnt=false
# Control fire
disable-all-fire-spread=false
disallowed-fire-spread-blocks=
# Disable lava fire and spread
disable-lava-fire=false
allowed-lava-spread-blocks=
# Log/blacklist
log-console=true
log-database-dsn=jdbc\:mysql\://localhost\:3306/minecraft
log-database-pass=
log-database-table=blacklist_events
log-database-user=root
log-database=false
log-file-open-files=10
log-file-path=worldguard/logs/%Y-%m-%d.log
log-file=false
-32
View File
@@ -1,32 +0,0 @@
#
# This is the blacklist for WorldProtect. Comments start with # and they
# are ignored so you can put your own notes.
#
# Format:
# [item1,item2,itemN]
# option1=options
# event1=action1,action2,actionN
# eventN=action1,action2,actionN
#
# Events/Options:
# - ignore-groups (comma-delimited list of groups to not affect)
# - on-destroy (when a block of this type is destroyed)
# - on-left (when this item is held and the player is left clicking)
# - on-right (when this item is held and the player is right clicking)
#
# Actions:
# - deny (deny completely)
# - notify (notify admins)
# - log (log to console/file)
# - kick (kick player)
# - tell (tell a player that that's not allowed)
#
# Some examples follow.
#
#[lavabucket]
#on-left=deny,log,kick
#on-right=deny,tell
#[coalore,goldore,ironore]
#on-destroy=notify,deny,log
#[cobblestone]
#on-right=deny,tell,log