Merge branch 'refs/heads/master' into release

Conflicts:
	EssentialsGroupManager/src/org/anjocaido/groupmanager/GroupManager.java
This commit is contained in:
snowleo 2011-10-22 11:55:01 +02:00
commit 11e8240c5c
98 changed files with 10249 additions and 969 deletions

7
.gitignore vendored
View File

@ -32,4 +32,9 @@
/YamlAnnotations/
/EssentialsUpdate/nbproject/private/
/EssentialsRelease/
/EssentialsUpdate/
/EssentialsUpdate/dist/
/EssentialsUpdate/build/
/WebPush/apikey.php
/WebPush/apikey.php
/WebPush/apikey.php

View File

@ -1,6 +1,7 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.run.all.processors=true
annotation.processing.processors.list=lombok.core.AnnotationProcessor
annotation.processing.run.all.processors=false
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=Essentials
application.vendor=
@ -68,6 +69,7 @@ file.reference.iCo4.jar=../lib/iCo4.jar
file.reference.iCo5.jar=../lib/iCo5.jar
file.reference.iCo6.jar=../lib/iCo6.jar
file.reference.junit-4.5.jar=..\\lib\\junit_4\\junit-4.5.jar
file.reference.lombok-0.10.1.jar=../lib/lombok-0.10.1.jar
file.reference.MultiCurrency.jar=../lib/MultiCurrency.jar
file.reference.Permissions3.jar=../lib/Permissions3.jar
file.reference.PermissionsBukkit-1.2.jar=../lib/PermissionsBukkit-1.2.jar
@ -86,7 +88,8 @@ javac.classpath=\
${file.reference.BOSEconomy7.jar}:\
${file.reference.PermissionsEx.jar}:\
${file.reference.bPermissions.jar}:\
${file.reference.PermissionsBukkit-1.2.jar}
${file.reference.PermissionsBukkit-1.2.jar}:\
${file.reference.lombok-0.10.1.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false

View File

@ -164,7 +164,6 @@ public class Essentials extends JavaPlugin implements IEssentials
pm.registerEvent(Type.PLAYER_EGG_THROW, playerListener, Priority.High, this);
pm.registerEvent(Type.PLAYER_BUCKET_EMPTY, playerListener, Priority.High, this);
pm.registerEvent(Type.PLAYER_ANIMATION, playerListener, Priority.High, this);
pm.registerEvent(Type.PLAYER_BED_ENTER, playerListener, Priority.Lowest, this);
final EssentialsBlockListener blockListener = new EssentialsBlockListener(this);
pm.registerEvent(Type.BLOCK_PLACE, blockListener, Priority.Lowest, this);

View File

@ -388,16 +388,4 @@ public class EssentialsPlayerListener extends PlayerListener
user.updateActivity(true);
}
}
@Override
public void onPlayerBedEnter(PlayerBedEnterEvent event)
{
if (event.isCancelled()) {
return;
}
if (event.getPlayer().isSleepingIgnored()) {
event.setCancelled(true);
event.getPlayer().sendMessage("You can't go to bed, your sleep is ignored.");
}
}
}

View File

@ -3,9 +3,9 @@ package com.earth2me.essentials;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import lombok.Delegate;
import org.bukkit.Achievement;
import org.bukkit.Effect;
import org.bukkit.GameMode;
@ -36,40 +36,32 @@ import org.bukkit.util.Vector;
public class OfflinePlayer implements Player
{
private final String name;
final transient IEssentials ess;
private final transient IEssentials ess;
private Location location = new Location(null, 0, 0, 0, 0, 0);
private World world;
private UUID uniqueId = UUID.randomUUID();
private org.bukkit.OfflinePlayer base;
@Delegate(types=org.bukkit.OfflinePlayer.class)
private final org.bukkit.OfflinePlayer base;
public OfflinePlayer(String name, IEssentials ess)
public OfflinePlayer(final String name, final IEssentials ess)
{
this.name = name;
this.ess = ess;
this.world = ess.getServer().getWorlds().get(0);
this.base = ess.getServer().getOfflinePlayer(name);
}
public boolean isOnline()
{
return base.isOnline();
}
public boolean isOp()
{
return base.isOp();
}
public void sendMessage(String string)
@Override
public void sendMessage(final String string)
{
}
@Override
public String getDisplayName()
{
return name;
return base.getName();
}
@Override
public void setDisplayName(String string)
{
}
@ -87,11 +79,6 @@ public class OfflinePlayer implements Player
{
}
public String getName()
{
return name;
}
public PlayerInventory getInventory()
{
return null;
@ -577,42 +564,13 @@ public class OfflinePlayer implements Player
{
throw new UnsupportedOperationException("Not supported yet.");
}
public void setOp(boolean bln)
{
base.setOp(bln);
}
@Override
public void sendMap(MapView mv)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isBanned()
{
return base.isBanned();
}
@Override
public void setBanned(boolean bln)
{
base.setBanned(bln);
}
@Override
public boolean isWhitelisted()
{
return base.isWhitelisted();
}
@Override
public void setWhitelisted(boolean bln)
{
base.setWhitelisted(bln);
}
@Override
public GameMode getGameMode()
{
@ -738,10 +696,4 @@ public class OfflinePlayer implements Player
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Map<String, Object> serialize()
{
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -1,28 +1,53 @@
package com.earth2me.essentials;
import lombok.Delegate;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.IInventory;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.ServerOperator;
public class PlayerExtension extends PlayerWrapper
public class PlayerExtension implements Player
{
protected final IEssentials ess;
public PlayerExtension(Player base, IEssentials ess)
protected final transient IEssentials ess;
@Delegate(types =
{
super(base);
Player.class, Entity.class, CommandSender.class, ServerOperator.class,
HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
Permissible.class
})
protected Player base;
public PlayerExtension(final Player base, final IEssentials ess)
{
this.base = base;
this.ess = ess;
}
public void showInventory(IInventory inventory)
public final Player getBase()
{
return base;
}
public final Player setBase(final Player base)
{
return this.base = base;
}
public void showInventory(final IInventory inventory)
{
getHandle().a(inventory);
}
public void showInventory(CraftInventoryPlayer inventory)
public void showInventory(final CraftInventoryPlayer inventory)
{
showInventory((IInventory)inventory.getInventory());
}
@ -37,7 +62,7 @@ public class PlayerExtension extends PlayerWrapper
return ess.getPermissionsHandler().getGroup(base);
}
public boolean inGroup(String group)
public boolean inGroup(final String group)
{
return ess.getPermissionsHandler().inGroup(base, group);
}

View File

@ -1,777 +0,0 @@
package com.earth2me.essentials;
import java.net.InetSocketAddress;
import java.util.*;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.*;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.*;
import org.bukkit.map.MapView;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
public class PlayerWrapper implements Player
{
protected Player base;
public PlayerWrapper(Player base)
{
this.base = base;
}
public final Player getBase()
{
return base;
}
public final Player setBase(Player base)
{
return this.base = base;
}
@Override
public void setDisplayName(String string)
{
base.setDisplayName(string);
}
@Override
public void setCompassTarget(Location lctn)
{
base.setCompassTarget(lctn);
}
@Override
public InetSocketAddress getAddress()
{
return base.getAddress();
}
@Override
public void kickPlayer(String string)
{
base.kickPlayer(string);
}
@Override
public String getName()
{
return base.getName();
}
@Override
public PlayerInventory getInventory()
{
return base.getInventory();
}
@Override
public ItemStack getItemInHand()
{
return base.getItemInHand();
}
@Override
public void setItemInHand(ItemStack is)
{
base.setItemInHand(is);
}
@Override
public int getHealth()
{
return base.getHealth();
}
@Override
public void setHealth(int i)
{
base.setHealth(i);
}
@Override
public Egg throwEgg()
{
return base.throwEgg();
}
@Override
public Snowball throwSnowball()
{
return base.throwSnowball();
}
@Override
public Arrow shootArrow()
{
return base.shootArrow();
}
@Override
public boolean isInsideVehicle()
{
return base.isInsideVehicle();
}
@Override
public boolean leaveVehicle()
{
return base.leaveVehicle();
}
@Override
public Vehicle getVehicle()
{
return base.getVehicle();
}
@Override
public Location getLocation()
{
return base.getLocation();
}
@Override
public World getWorld()
{
return base.getWorld();
}
@Override
public Server getServer()
{
return base.getServer();
}
@Override
public boolean isOnline()
{
return base.isOnline();
}
@Override
public boolean isOp()
{
return base.isOp();
}
@Override
public boolean teleport(Location lctn)
{
return base.teleport(lctn);
}
@Override
public boolean teleport(Entity entity)
{
return base.teleport(entity);
}
@Override
public void sendMessage(String string)
{
base.sendMessage(string);
}
@Override
public void setVelocity(Vector vector)
{
base.setVelocity(vector);
}
@Override
public Vector getVelocity()
{
return base.getVelocity();
}
@Override
public double getEyeHeight()
{
return base.getEyeHeight();
}
@Override
public double getEyeHeight(boolean bln)
{
return base.getEyeHeight(bln);
}
@Override
public List<Block> getLineOfSight(HashSet<Byte> hs, int i)
{
return base.getLineOfSight(hs, i);
}
@Override
public Block getTargetBlock(HashSet<Byte> hs, int i)
{
return base.getTargetBlock(hs, i);
}
@Override
public List<Block> getLastTwoTargetBlocks(HashSet<Byte> hs, int i)
{
return base.getLastTwoTargetBlocks(hs, i);
}
@Override
public int getFireTicks()
{
return base.getFireTicks();
}
@Override
public int getMaxFireTicks()
{
return base.getMaxFireTicks();
}
@Override
public void setFireTicks(int i)
{
base.setFireTicks(i);
}
@Override
public void remove()
{
base.remove();
}
/**
* This is not deprecated because the underlying method isn't really deprecated; rather, it's just "imperfect". By
* We will continue to use this method even after the underlying CraftBukkit method is changed, so do not deprecate
* it. Chances are Bukkit will also choose to un-deprecate this method at some point.
*/
@Override
public void updateInventory()
{
base.updateInventory();
}
@Override
public void chat(String string)
{
base.chat(string);
}
@Override
public boolean isSneaking()
{
return base.isSneaking();
}
@Override
public void setSneaking(boolean bln)
{
base.setSneaking(bln);
}
@Override
public int getEntityId()
{
return base.getEntityId();
}
@Override
public boolean performCommand(String string)
{
return base.performCommand(string);
}
@Override
public int getRemainingAir()
{
return base.getRemainingAir();
}
@Override
public void setRemainingAir(int i)
{
base.setRemainingAir(i);
}
@Override
public int getMaximumAir()
{
return base.getMaximumAir();
}
@Override
public void setMaximumAir(int i)
{
base.setMaximumAir(i);
}
@Override
public String getDisplayName()
{
if (base.getDisplayName() != null)
return base.getDisplayName();
else
return base.getName();
}
@Override
public void damage(int i)
{
base.damage(i);
}
@Override
public void damage(int i, Entity entity)
{
base.damage(i, entity);
}
@Override
public Location getEyeLocation()
{
return base.getEyeLocation();
}
@Override
public void sendRawMessage(String string) {
base.sendRawMessage(string);
}
@Override
public Location getCompassTarget()
{
return base.getCompassTarget();
}
@Override
public int getMaximumNoDamageTicks()
{
return base.getMaximumNoDamageTicks();
}
@Override
public void setMaximumNoDamageTicks(int i)
{
base.setMaximumNoDamageTicks(i);
}
@Override
public int getLastDamage()
{
return base.getLastDamage();
}
@Override
public void setLastDamage(int i)
{
base.setLastDamage(i);
}
@Override
public int getNoDamageTicks()
{
return base.getNoDamageTicks();
}
@Override
public void setNoDamageTicks(int i)
{
base.setNoDamageTicks(i);
}
@Override
public Entity getPassenger()
{
return base.getPassenger();
}
@Override
public boolean setPassenger(Entity entity)
{
return base.setPassenger(entity);
}
@Override
public boolean isEmpty()
{
return base.isEmpty();
}
@Override
public boolean eject()
{
return base.eject();
}
public void saveData()
{
base.saveData();
}
public void loadData()
{
base.loadData();
}
public boolean isSleeping()
{
return base.isSleeping();
}
public int getSleepTicks()
{
return base.getSleepTicks();
}
public List<Entity> getNearbyEntities(double d, double d1, double d2)
{
return base.getNearbyEntities(d, d1, d2);
}
public boolean isDead()
{
return base.isDead();
}
public float getFallDistance()
{
return base.getFallDistance();
}
public void setFallDistance(float f)
{
base.setFallDistance(f);
}
public void setSleepingIgnored(boolean bln)
{
base.setSleepingIgnored(bln);
}
public boolean isSleepingIgnored()
{
return base.isSleepingIgnored();
}
public void awardAchievement(Achievement a)
{
base.awardAchievement(a);
}
public void incrementStatistic(Statistic ststc)
{
base.incrementStatistic(ststc);
}
public void incrementStatistic(Statistic ststc, int i)
{
base.incrementStatistic(ststc, i);
}
public void incrementStatistic(Statistic ststc, Material mtrl)
{
base.incrementStatistic(ststc, mtrl);
}
public void incrementStatistic(Statistic ststc, Material mtrl, int i)
{
base.incrementStatistic(ststc, mtrl, i);
}
public void playNote(Location lctn, byte b, byte b1)
{
base.playNote(lctn, b, b1);
}
public void sendBlockChange(Location lctn, Material mtrl, byte b)
{
base.sendBlockChange(lctn, mtrl, b);
}
public void sendBlockChange(Location lctn, int i, byte b)
{
base.sendBlockChange(lctn, i, b);
}
public void setLastDamageCause(EntityDamageEvent ede)
{
base.setLastDamageCause(ede);
}
public EntityDamageEvent getLastDamageCause()
{
return base.getLastDamageCause();
}
public void playEffect(Location lctn, Effect effect, int i)
{
base.playEffect(lctn, effect, i);
}
public boolean sendChunkChange(Location lctn, int i, int i1, int i2, byte[] bytes)
{
return base.sendChunkChange(lctn, i, i1, i2, bytes);
}
public UUID getUniqueId()
{
return base.getUniqueId();
}
public void playNote(Location lctn, Instrument i, Note note)
{
base.playNote(lctn, i, note);
}
public void setPlayerTime(long l, boolean bln)
{
base.setPlayerTime(l, bln);
}
public long getPlayerTime()
{
return base.getPlayerTime();
}
public long getPlayerTimeOffset()
{
return base.getPlayerTimeOffset();
}
public boolean isPlayerTimeRelative()
{
return base.isPlayerTimeRelative();
}
public void resetPlayerTime()
{
base.resetPlayerTime();
}
public boolean isPermissionSet(String string)
{
return base.isPermissionSet(string);
}
public boolean isPermissionSet(Permission prmsn)
{
return base.isPermissionSet(prmsn);
}
public boolean hasPermission(String string)
{
return base.hasPermission(string);
}
public boolean hasPermission(Permission prmsn)
{
return base.hasPermission(prmsn);
}
public PermissionAttachment addAttachment(Plugin plugin, String string, boolean bln)
{
return base.addAttachment(plugin, string, bln);
}
public PermissionAttachment addAttachment(Plugin plugin)
{
return base.addAttachment(plugin);
}
public PermissionAttachment addAttachment(Plugin plugin, String string, boolean bln, int i)
{
return base.addAttachment(plugin, string, bln, i);
}
public PermissionAttachment addAttachment(Plugin plugin, int i)
{
return base.addAttachment(plugin, i);
}
public void removeAttachment(PermissionAttachment pa)
{
throw new UnsupportedOperationException("Not supported yet.");
}
public void recalculatePermissions()
{
base.recalculatePermissions();
}
public Set<PermissionAttachmentInfo> getEffectivePermissions()
{
return base.getEffectivePermissions();
}
public void setOp(boolean bln)
{
base.setOp(bln);
}
@Override
public void sendMap(MapView mv)
{
base.sendMap(mv);
}
@Override
public boolean isBanned()
{
return base.isBanned();
}
@Override
public void setBanned(boolean bln)
{
base.setBanned(bln);
}
@Override
public boolean isWhitelisted()
{
return base.isWhitelisted();
}
@Override
public void setWhitelisted(boolean bln)
{
base.setWhitelisted(bln);
}
@Override
public GameMode getGameMode()
{
return base.getGameMode();
}
@Override
public void setGameMode(GameMode gm)
{
base.setGameMode(gm);
}
@Override
public int getExperience()
{
return base.getExperience();
}
@Override
public void setExperience(int i)
{
base.setExperience(i);
}
@Override
public int getLevel()
{
return base.getLevel();
}
@Override
public void setLevel(int i)
{
base.setLevel(i);
}
@Override
public int getTotalExperience()
{
return base.getTotalExperience();
}
@Override
public void setTotalExperience(int i)
{
base.setTotalExperience(i);
}
@Override
public float getExhaustion()
{
return base.getExhaustion();
}
@Override
public void setExhaustion(float f)
{
base.setExhaustion(f);
}
@Override
public float getSaturation()
{
return base.getSaturation();
}
@Override
public void setSaturation(float f)
{
base.setSaturation(f);
}
@Override
public int getFoodLevel()
{
return base.getFoodLevel();
}
@Override
public void setFoodLevel(int i)
{
base.setFoodLevel(i);
}
@Override
public Location getBedSpawnLocation()
{
return base.getBedSpawnLocation();
}
@Override
public boolean isSprinting()
{
return base.isSprinting();
}
@Override
public void setSprinting(boolean bln)
{
base.setSprinting(bln);
}
@Override
public void setPlayerListName(String name)
{
base.setPlayerListName(name);
}
@Override
public String getPlayerListName()
{
return base.getPlayerListName();
}
@Override
public int getTicksLived()
{
return base.getTicksLived();
}
@Override
public void setTicksLived(int i)
{
base.setTicksLived(i);
}
@Override
public Map<String, Object> serialize()
{
return base.serialize();
}
}

View File

@ -46,7 +46,7 @@ public class Settings implements ISettings
@Override
public int getHomeLimit(final User user)
{
final List<String> homeList = getMultipleHomes();
final List<String> homeList = getMultipleHomes();
if (homeList == null)
{
//TODO: Replace this code to remove backwards compat, after settings are automatically updated
@ -56,8 +56,7 @@ public class Settings implements ISettings
int limit = getHomeLimit("default");
for (String set : homeList)
{
logger.log(Level.INFO, "Found home set: " + set);
if (user.hasPermission("essentials.sethome.multiple." + set) && limit < getHomeLimit(set))
if (user.isAuthorized("essentials.sethome.multiple." + set) && (limit < getHomeLimit(set)))
{
limit = getHomeLimit(set);
}
@ -67,7 +66,7 @@ public class Settings implements ISettings
@Override
public int getHomeLimit(final String set)
{
{
return config.getInt("sethome-multiple." + set, config.getInt("sethome-multiple.default", 3));
}

View File

@ -282,16 +282,23 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
return nickname.toString();
}
public void setDisplayNick(String name)
{
setDisplayName(name);
//TODO: Maybe we need to limit nick length, or try use a string trim.
if (name.length() <= 16) {
if (name.length() <= 16)
{
setPlayerListName(name);
}
}
@Override
public String getDisplayName()
{
return super.getDisplayName() == null ? super.getName() : super.getDisplayName();
}
public Teleport getTeleport()
{
return teleport;
@ -355,7 +362,8 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
public void setAfk(final boolean set)
{
this.setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set);
if (set && !isAfk()) {
if (set && !isAfk())
{
afkPosition = getLocation();
}
super.setAfk(set);
@ -461,7 +469,8 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorized("essentials.afk"))
{
setAfk(true);
if (!isHidden()) {
if (!isHidden())
{
ess.broadcastMessage(this, Util.format("userIsAway", getDisplayName()));
}
}
@ -475,7 +484,8 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
@Override
public boolean toggleGodModeEnabled()
{
if (!isGodModeEnabled()) {
if (!isGodModeEnabled())
{
setFoodLevel(20);
}
return super.toggleGodModeEnabled();

View File

@ -46,7 +46,7 @@ public class Commandban extends EssentialsCommand
if (args.length > 1)
{
banReason = getFinalArg(args, 1);
player.setBanReason(commandLabel);
player.setBanReason(banReason);
}
else
{

View File

@ -15,17 +15,44 @@ public class Commandcompass extends EssentialsCommand
@Override
public void run(Server server, User user, String commandLabel, String[] args) throws Exception
{
int r = (int)user.getLocation().getYaw();
int r = (int)(user.getLocation().getYaw() + 180 + 360) % 360;
String dir;
if (r < 23) dir = "N";
else if (r < 68) dir = "NE";
else if (r < 113) dir = "E";
else if (r < 158) dir = "SE";
else if (r < 203) dir = "S";
else if (r < 248) dir = "SW";
else if (r < 293) dir = "W";
else if (r < 338) dir = "NW";
else dir = "N";
if (r < 23)
{
dir = "N";
}
else if (r < 68)
{
dir = "NE";
}
else if (r < 113)
{
dir = "E";
}
else if (r < 158)
{
dir = "SE";
}
else if (r < 203)
{
dir = "S";
}
else if (r < 248)
{
dir = "SW";
}
else if (r < 293)
{
dir = "W";
}
else if (r < 338)
{
dir = "NW";
}
else
{
dir = "N";
}
user.sendMessage(Util.format("compassBearing", dir, r));
}
}

View File

@ -16,10 +16,10 @@ public class Commandgetpos extends EssentialsCommand
public void run(Server server, User user, String commandLabel, String[] args) throws Exception
{
Location coords = user.getLocation();
user.sendMessage("§7X: " + coords.getBlockX() + " (-North <-> +South)");
user.sendMessage("§7X: " + coords.getBlockX() + " (+East <-> -West)");
user.sendMessage("§7Y: " + coords.getBlockY() + " (+Up <-> -Down)");
user.sendMessage("§7Z: " + coords.getBlockZ() + " (+East <-> -West)");
user.sendMessage("§7Yaw: " + coords.getYaw() + " (Rotation)");
user.sendMessage("§7Z: " + coords.getBlockZ() + " (+South <-> -North)");
user.sendMessage("§7Yaw: " + (coords.getYaw() + 180 + 360) % 360 + " (Rotation)");
user.sendMessage("§7Pitch: " + coords.getPitch() + " (Head angle)");
}
}

View File

@ -5,6 +5,7 @@ import org.bukkit.Server;
import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -69,4 +70,59 @@ public class Commandmail extends EssentialsCommand
}
throw new NotEnoughArgumentsException();
}
@Override
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length >= 1 && "read".equalsIgnoreCase(args[0]))
{
throw new Exception(Util.format("onlyPlayers", commandLabel + " read"));
}
else if (args.length >= 1 && "clear".equalsIgnoreCase(args[0]))
{
throw new Exception(Util.format("onlyPlayers", commandLabel + " clear"));
}
else if (args.length >= 3 && "send".equalsIgnoreCase(args[0]))
{
Player player = server.getPlayer(args[1]);
User u;
if (player != null)
{
u = ess.getUser(player);
}
else
{
u = ess.getOfflineUser(args[1]);
}
if (u == null)
{
throw new Exception(Util.format("playerNeverOnServer", args[1]));
}
u.addMail("Server: " + getFinalArg(args, 2));
sender.sendMessage(Util.i18n("mailSent"));
return;
}
else if (args.length >= 2)
{
//allow sending from console without "send" argument, since it's the only thing the console can do
Player player = server.getPlayer(args[0]);
User u;
if (player != null)
{
u = ess.getUser(player);
}
else
{
u = ess.getOfflineUser(args[0]);
}
if (u == null)
{
throw new Exception(Util.format("playerNeverOnServer", args[0]));
}
u.addMail("Server: " + getFinalArg(args, 1));
sender.sendMessage(Util.i18n("mailSent"));
return;
}
throw new NotEnoughArgumentsException();
}
}

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials.commands;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
@ -15,7 +16,7 @@ public class Commandrealname extends EssentialsCommand
}
@Override
public void run(Server server, User user, String commandLabel, String[] args) throws Exception
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length < 1)
{
@ -36,7 +37,7 @@ public class Commandrealname extends EssentialsCommand
{
continue;
}
user.sendMessage(u.getDisplayName() + " " + Util.i18n("is") + " " + u.getName());
sender.sendMessage(u.getDisplayName() + " " + Util.i18n("is") + " " + u.getName());
}
}
}

View File

@ -4,6 +4,7 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
public class Commandweather extends EssentialsCommand
@ -29,16 +30,50 @@ public class Commandweather extends EssentialsCommand
world.setStorm(isStorm ? true : false);
world.setWeatherDuration(Integer.parseInt(args[1]) * 20);
user.sendMessage(isStorm
? Util.format("weatherStormFor", args[1])
: Util.format("weatherSunFor", args[1]));
? Util.format("weatherStormFor", world.getName(), args[1])
: Util.format("weatherSunFor", world.getName(), args[1]));
return;
}
else
{
world.setStorm(isStorm ? true : false);
user.sendMessage(isStorm
? Util.i18n("weatherStorm")
: Util.i18n("weatherSun"));
? Util.format("weatherStorm", world.getName())
: Util.format("weatherSun", world.getName()));
return;
}
}
@Override
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length < 2) //running from console means inserting a world arg before other args
{
throw new Exception("When running from console, usage is: /" + commandLabel + " <world> <storm/sun> [duration]");
}
boolean isStorm = args[1].equalsIgnoreCase("storm");
World world = server.getWorld(args[0]);
if (world == null)
{
throw new Exception("World named " + args[0] + " not found!");
}
if (args.length > 2)
{
world.setStorm(isStorm ? true : false);
world.setWeatherDuration(Integer.parseInt(args[2]) * 20);
sender.sendMessage(isStorm
? Util.format("weatherStormFor", world.getName(), args[2])
: Util.format("weatherSunFor", world.getName(), args[2]));
return;
}
else
{
world.setStorm(isStorm ? true : false);
sender.sendMessage(isStorm
? Util.format("weatherStorm", world.getName())
: Util.format("weatherSun", world.getName()));
return;
}
}

View File

@ -3,6 +3,8 @@ package com.earth2me.essentials.commands;
import org.bukkit.Server;
import com.earth2me.essentials.User;
import com.earth2me.essentials.Util;
import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack;
@ -33,7 +35,7 @@ public class Commandworth extends EssentialsCommand
}
catch (NumberFormatException ex)
{
amount = 64;
amount = is.getType().getMaxStackSize();
}
is.setAmount(amount);
@ -56,4 +58,49 @@ public class Commandworth extends EssentialsCommand
amount,
Util.formatCurrency(worth, ess)));
}
@Override
protected void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length < 1)
{
throw new NotEnoughArgumentsException();
}
ItemStack is = ess.getItemDb().get(args[0]);
int amount = is.getAmount();
try
{
if (args.length > 1)
{
amount = Integer.parseInt(args[1]);
}
}
catch (NumberFormatException ex)
{
amount = is.getType().getMaxStackSize();
}
is.setAmount(amount);
double worth = ess.getWorth().getPrice(is);
if (Double.isNaN(worth))
{
throw new Exception(Util.i18n("itemCannotBeSold"));
}
sender.sendMessage(is.getDurability() != 0
? Util.format("worthMeta",
is.getType().toString().toLowerCase().replace("_", ""),
is.getDurability(),
Util.formatCurrency(worth * amount, ess),
amount,
Util.formatCurrency(worth, ess))
: Util.format("worth",
is.getType().toString().toLowerCase().replace("_", ""),
Util.formatCurrency(worth * amount, ess),
amount,
Util.formatCurrency(worth, ess)));
}
}

View File

@ -0,0 +1,17 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Backup extends StorageObject
{
@Comment("Interval in minutes")
private long interval = 60;
@Comment("Add a command that backups your data, e.g. 'rdiff-backup World1 backups/World1'")
private String command;
}

View File

@ -0,0 +1,32 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Chat extends StorageObject
{
@Comment("The character(s) to prefix all nicknames, so that you know they are not true usernames.")
private String nicknamePrefix = "~";
@Comment("Disable this if you have any other plugin, that modifies the displayname of a user.")
private boolean changeDisplayname = true;
private String displaynameFormat = "{PREFIX}{NICKNAMEPREFIX}{NAME}{SUFFIX}";
@Comment({
"If EssentialsChat is installed, this will define how far a player's voice travels, in blocks. Set to 0 to make all chat global.",
"Note that users with the \"essentials.chat.spy\" permission will hear everything, regardless of this setting.",
"Users with essentials.chat.shout can override this by prefixing text with an exclamation mark (!)",
"Or with essentials.chat.question can override this by prefixing text with a question mark (?)",
"You can add command costs for shout/question by adding chat-shout and chat-question to the command costs section."
})
private int localRadius = 0;
@Comment("Set the default chat format here, it will be overwritten by group specific chat formats.")
private String defaultFormat = "&7[{GROUP}]&f {DISPLAYNAME}&7:&f {MESSAGE}";
}

View File

@ -0,0 +1,47 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.settings.commands.Afk;
import com.earth2me.essentials.settings.commands.God;
import com.earth2me.essentials.settings.commands.Help;
import com.earth2me.essentials.settings.commands.Home;
import com.earth2me.essentials.settings.commands.Kit;
import com.earth2me.essentials.settings.commands.Lightning;
import com.earth2me.essentials.settings.commands.Spawnmob;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.ListType;
import com.earth2me.essentials.storage.StorageObject;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Commands extends StorageObject
{
private Afk afk = new Afk();
private God god = new God();
private Help help = new Help();
private Home home = new Home();
private Kit kit = new Kit();
private Lightning lightning = new Lightning();
private Spawnmob spawnmob = new Spawnmob();
@ListType
@Comment(
{
"When a command conflicts with another plugin, by default, Essentials will try to force the OTHER plugin to take",
"priority. If a command is in this list, Essentials will try to give ITSELF priority. This does not always work:",
"usually whichever plugin was updated most recently wins out. However, the full name of the command will always work.",
"For example, if WorldGuard and Essentials are both enabled, and WorldGuard takes control over /god, /essentials:god",
"will still map to Essentials, whereas it might normally get forced upon WorldGuard. Commands prefixed with an \"e\",",
"such as /egod, will always grant Essentials priority.",
"We should try to take priority over /god. If this doesn't work, use /essentials:god or /egod.",
"If god is set using WorldGuard, use /ungod to remove then use whichever you see fit."
})
private List<String> overwritten = new ArrayList<String>();
@ListType
@Comment("Disabled commands will be completelly unavailable on the server.")
private List<String> disabled = new ArrayList<String>();
}

View File

@ -0,0 +1,42 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.MapType;
import com.earth2me.essentials.storage.StorageObject;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Economy extends StorageObject
{
@Comment("Defines the balance with which new players begin. Defaults to 0.")
private double startingBalance = 0.0;
@MapType(Double.class)
@Comment("Defines the cost to use the given commands PER USE")
private Map<String, Double> commandCosts = new HashMap<String, Double>();
@Comment("Set this to a currency symbol you want to use.")
private String currencySymbol = "$";
public String getCurrencySymbol()
{
return currencySymbol == null || currencySymbol.isEmpty() ? "$" : currencySymbol.substring(0, 1);
}
private final transient static double MAXMONEY = 10000000000000.0;
@Comment(
{
"Set the maximum amount of money a player can have",
"The amount is always limited to 10 trillions because of the limitations of a java double"
})
private double maxMoney = MAXMONEY;
public double getMaxMoney()
{
return Math.abs(maxMoney) > MAXMONEY ? MAXMONEY : Math.abs(maxMoney);
}
@Comment("Enable this to log all interactions with trade/buy/sell signs and sell command")
private boolean logEnabled = false;
}

View File

@ -0,0 +1,33 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class General extends StorageObject
{
@Comment("Backup runs a command while saving is disabled")
private Backup backup = new Backup();
@Comment("You can disable the death messages of minecraft.")
private boolean deathMessages = true;
@Comment("Turn this on, if you want to see more error messages, if something goes wrong.")
private boolean debug = false;
@Comment(
{
"Set the locale here, if you want to change the language of Essentials.",
"If this is not set, Essentials will use the language of your computer.",
"Available locales: da, de, en, fr, nl"
})
private String locale;
@Comment(
{
"Should we announce to the server when someone logs in for the first time?",
"If so, use this format, replacing {DISPLAYNAME} with the player name.",
"If not, set to ''"
})
private String newPlayerAnnouncement = "&dWelcome {DISPLAYNAME} to the server!";
}

View File

@ -0,0 +1,27 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class GroupOptions extends StorageObject
{
@Comment("Message format of chat messages")
private String messageFormat;
@Comment("Prefix for name")
private String prefix;
@Comment("Suffix for name")
private String suffix;
@Comment("Amount of homes a player can have")
private Integer homes;
@Comment("Cooldown between teleports")
private Integer teleportCooldown;
@Comment("Delay before teleport")
private Integer teleportDelay;
@Comment("Cooldown between heals")
private Integer healCooldown;
}

View File

@ -0,0 +1,27 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.MapType;
import com.earth2me.essentials.storage.StorageObject;
import java.util.LinkedHashMap;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Groups extends StorageObject
{
public Groups() {
GroupOptions defaultOptions = new GroupOptions();
groups.put("default", defaultOptions);
}
@Comment(
{
"The order of the groups matters, the groups are checked from top to bottom.",
"All group names have to be lower case.",
"The groups can be connected to users using the permission essentials.groups.groupname"
})
@MapType(GroupOptions.class)
private LinkedHashMap<String, GroupOptions> groups = new LinkedHashMap<String, GroupOptions>();
}

View File

@ -0,0 +1,28 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.bukkit.Server;
@Data
@EqualsAndHashCode(callSuper = false)
public class Location extends StorageObject
{
private String worldName = "Test";
private double x;
private double y;
private double z;
private Float yaw;
private Float pitch;
public org.bukkit.Location getBukkit(Server server)
{
if (yaw == null || pitch == null)
{
return new org.bukkit.Location(server.getWorld(worldName), x, y, z);
}
return new org.bukkit.Location(server.getWorld(worldName), x, y, z, yaw, pitch);
}
}

View File

@ -0,0 +1,58 @@
package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Settings extends StorageObject
{
@Comment(
{
"##########################################################",
"+------------------------------------------------------+ #",
"| General Settings | #",
"+------------------------------------------------------+ #",
"##########################################################"
})
private General general = new General();
@Comment(
{
"##########################################################",
"+------------------------------------------------------+ #",
"| Chat Settings | #",
"+------------------------------------------------------+ #",
"##########################################################"
})
private Chat chat = new Chat();
@Comment(
{
"##########################################################",
"+------------------------------------------------------+ #",
"| Economy Settings | #",
"+------------------------------------------------------+ #",
"##########################################################"
})
private Economy economy = new Economy();
@Comment(
{
"##########################################################",
"+------------------------------------------------------+ #",
"| Commands Settings | #",
"+------------------------------------------------------+ #",
"##########################################################"
})
private Commands commands = new Commands();
@Comment(
{
"##########################################################",
"+------------------------------------------------------+ #",
"| Group Settings | #",
"+------------------------------------------------------+ #",
"##########################################################"
})
private Groups groups = new Groups();
}

View File

@ -0,0 +1,36 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Afk extends StorageObject
{
@Comment(
{
"After this timeout in seconds, the user will be set as afk.",
"Set to -1 for no timeout."
})
private int autoAFK = 300;
@Comment(
{
"Auto-AFK Kick",
"After this timeout in seconds, the user will be kicked from the server.",
"Set to -1 for no timeout."
})
private int autoAFKKick = -1;
@Comment(
{
"Set this to true, if you want to freeze the player, if he is afk.",
"Other players or monsters can't push him out of afk mode then.",
"This will also enable temporary god mode for the afk player.",
"The player has to use the command /afk to leave the afk mode.",
"You have to add a message to your welcome message or help page,",
"since the player will not get a message, if he tries to move."
})
private boolean freezeAFKPlayers = false;
}

View File

@ -0,0 +1,14 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper=false)
public class God extends StorageObject
{
@Comment("Turn off god mode when people exit")
private boolean removeOnDisconnect = false;
}

View File

@ -0,0 +1,23 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Help extends StorageObject
{
@Comment("Show other plugins commands in help")
private boolean showNonEssCommandsInHelp = true;
@Comment(
{
"Hide plugins which don't give a permission in their plugin.yml for each command.",
"You can override a true value here for a single plugin by adding a permission to a user/group.",
"The individual permission is: essentials.help.<plugin>, anyone with essentials.* or '*' will see all help this setting reguardless.",
"You can use negative permissions to remove access to just a single plugins help if the following is enabled."
})
private boolean hidePermissionlessCommands = true;
}

View File

@ -0,0 +1,24 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Home extends StorageObject
{
@Comment("When players die, should they respawn at their homes, instead of the spawnpoint?")
private boolean respawnAtHome = false;
@Comment(
{
"When a player interacts with a bed, should their home be set to that location?",
"If you enable this and remove default player access to the /sethome command, ",
"you can make beds the only way for players to set their home location."
})
private boolean bedSetsHome = false;
@Comment("If no home is set, should the player be send to spawn, when /home is used.")
private boolean spawnIfNoHome = false;
}

View File

@ -0,0 +1,28 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.MapType;
import com.earth2me.essentials.storage.StorageObject;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Kit extends StorageObject
{
public Kit()
{
final KitObject kit = new KitObject();
kit.setDelay(10.0);
kit.setItems(Arrays.asList("277 1,278 1,279 1".split(",")));
kits.put("tools", kit);
}
@MapType(KitObject.class)
private Map<String,KitObject> kits = new HashMap<String, KitObject>();
}

View File

@ -0,0 +1,18 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.ListType;
import com.earth2me.essentials.storage.StorageObject;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class KitObject extends StorageObject
{
@ListType
private List<String> items = new ArrayList<String>();
private Double delay;
}

View File

@ -0,0 +1,14 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Lightning extends StorageObject
{
@Comment("Shall we notify users when using /lightning")
private boolean warnPlayer = true;
}

View File

@ -0,0 +1,14 @@
package com.earth2me.essentials.settings.commands;
import com.earth2me.essentials.storage.Comment;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class Spawnmob extends StorageObject
{
@Comment("The maximum amount of monsters, a player can spawn with a call of /spawnmob.")
private int limit = 10;
}

View File

@ -0,0 +1,16 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Comment
{
String[] value() default "";
}

View File

@ -0,0 +1,14 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ListType
{
Class value() default String.class;
}

View File

@ -0,0 +1,14 @@
package com.earth2me.essentials.storage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MapType
{
Class value() default String.class;
}

View File

@ -0,0 +1,250 @@
package com.earth2me.essentials.storage;
import java.io.PrintWriter;
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.composer.Composer;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.introspector.PropertyUtils;
public class StorageObject
{
protected Class<? extends StorageObject> clazz;
protected StorageObject()
{
}
private static Map<Class, Constructor> constructors = new HashMap<Class, Constructor>();
public static <T extends StorageObject> T load(Class<? extends T> clazz, Reader reader)
{
Constructor constructor;
if (constructors.containsKey(clazz))
{
constructor = constructors.get(clazz);
}
else
{
constructor = prepareConstructor(clazz);
constructors.put(clazz, constructor);
}
final Yaml yaml = new Yaml(constructor);
T ret = (T)yaml.load(reader);
if (ret == null)
{
try
{
ret = (T)clazz.newInstance();
}
catch (InstantiationException ex)
{
Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
}
}
ret.clazz = clazz;
return ret;
}
private static Constructor prepareConstructor(final Class<?> clazz)
{
final Constructor constructor = new Constructor(clazz);
final Set<Class> classes = new HashSet<Class>();
prepareConstructor(constructor, classes, clazz);
return constructor;
}
private static void prepareConstructor(final Constructor constructor, final Set<Class> classes, final Class clazz)
{
classes.add(clazz);
final TypeDescription description = new TypeDescription(clazz);
for (Field field : clazz.getDeclaredFields())
{
final ListType listType = field.getAnnotation(ListType.class);
if (listType != null)
{
description.putListPropertyType(field.getName(), listType.value());
if (StorageObject.class.isAssignableFrom(listType.value())
&& !classes.contains(listType.value()))
{
prepareConstructor(constructor, classes, listType.value());
}
}
final MapType mapType = field.getAnnotation(MapType.class);
if (mapType != null)
{
description.putMapPropertyType(field.getName(), String.class, mapType.value());
if (StorageObject.class.isAssignableFrom(mapType.value())
&& !classes.contains(mapType.value()))
{
prepareConstructor(constructor, classes, mapType.value());
}
}
if (StorageObject.class.isAssignableFrom(field.getType())
&& !classes.contains(field.getType()))
{
prepareConstructor(constructor, classes, field.getType());
}
}
constructor.addTypeDescription(description);
}
private transient Yaml yaml;
public void save(final PrintWriter writer)
{
final DumperOptions ops = new DumperOptions();
yaml = new Yaml(ops);
try
{
writeToFile(this, writer, 0, clazz);
}
catch (IllegalArgumentException ex)
{
Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void writeToFile(final Object object, final PrintWriter writer, final int depth, final Class clazz) throws IllegalArgumentException, IllegalAccessException
{
for (Field field : clazz.getDeclaredFields())
{
final int modifier = field.getModifiers();
if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier))
{
field.setAccessible(true);
final boolean commentPresent = field.isAnnotationPresent(Comment.class);
final String name = field.getName();
if (commentPresent)
{
final Comment comments = field.getAnnotation(Comment.class);
for (String comment : comments.value())
{
final String trimmed = comment.trim();
if (trimmed.isEmpty())
{
continue;
}
writeIndention(writer, depth);
writer.print("# ");
writer.print(trimmed);
writer.println();
}
}
final Object data = field.get(object);
if (data == null && !commentPresent)
{
continue;
}
writeIndention(writer, depth);
if (data == null && commentPresent)
{
writer.print('#');
}
writer.print(name);
writer.print(": ");
if (data == null && commentPresent)
{
writer.println();
writer.println();
continue;
}
if (data instanceof StorageObject)
{
writer.println();
writeToFile(data, writer, depth + 1, data.getClass());
}
else if (data instanceof Map)
{
writer.println();
for (Entry<String, Object> entry : ((Map<String, Object>)data).entrySet())
{
final Object value = entry.getValue();
if (value != null)
{
writeIndention(writer, depth + 1);
writer.print(entry.getKey());
writer.print(": ");
if (value instanceof StorageObject)
{
writer.println();
writeToFile(value, writer, depth + 2, value.getClass());
}
else if (value instanceof String || value instanceof Boolean || value instanceof Number)
{
yaml.dumpAll(Collections.singletonList(value).iterator(), writer);
writer.println();
}
else
{
throw new UnsupportedOperationException();
}
}
}
}
else if (data instanceof Collection)
{
writer.println();
for (Object entry : (Collection<Object>)data)
{
if (entry != null)
{
writeIndention(writer, depth + 1);
writer.print("- ");
if (entry instanceof String || entry instanceof Boolean || entry instanceof Number)
{
yaml.dumpAll(Collections.singletonList(entry).iterator(), writer);
}
else
{
throw new UnsupportedOperationException();
}
}
}
writer.println();
}
else if (data instanceof String || data instanceof Boolean || data instanceof Number)
{
yaml.dumpAll(Collections.singletonList(data).iterator(), writer);
writer.println();
}
else
{
throw new UnsupportedOperationException();
}
}
}
}
private void writeIndention(final PrintWriter writer, final int depth)
{
for (int i = 0; i < depth; i++)
{
writer.print(" ");
}
}
}

View File

@ -351,10 +351,10 @@ warpSet = \u00a77Warp {0} set.
warpUsePermission = \u00a7cYou do not have Permission to use that warp.
warpingTo = \u00a77Warping to {0}.
warpsCount = \u00a77There are {0} warps. Showing page {1} of {2}.
weatherStorm = \u00a77You set the weather to storm in your world
weatherStormFor = \u00a77You set the weather to storm in your world for {0} seconds
weatherSun = \u00a77You set the weather to sun in your world
weatherSunFor = \u00a77You set the weather to sun in your world for {0} seconds
weatherStorm = \u00a77You set the weather to storm in {0}
weatherStormFor = \u00a77You set the weather to storm in {0} for {1} seconds
weatherSun = \u00a77You set the weather to sun in {0}
weatherSunFor = \u00a77You set the weather to sun in {0} for {1} seconds
whoisGeoLocation = \u00a79 - Location: {0}
whoisHealth = \u00a79 - Health: {0}/20
whoisIPAddress = \u00a79 - IP Address: {0}

View File

@ -350,10 +350,10 @@ warpSet = \u00a77Warp {0} sat.
warpUsePermission = \u00a7cDu har ikke tilladelse til at benytte den warp.
warpingTo = \u00a77Warper til {0}.
warpsCount = \u00a77There are {0} warps. Showing page {1} of {2}.
weatherStorm = \u00a77Du har sat vejret til storm i din verden
weatherStormFor = \u00a77Du har sat vejret til storm i din verden i {0} sekunder
weatherSun = \u00a77Du har sat vejret til sol
weatherSunFor = \u00a77Du har sat vejret til sol i din verden i {0} sekunder
weatherStorm = \u00a77Du har sat vejret til storm i {0}
weatherStormFor = \u00a77Du har sat vejret til storm i {0} i {1} sekunder
weatherSun = \u00a77Du har sat vejret til sol i {0}
weatherSunFor = \u00a77Du har sat vejret til sol i {0} i {1} sekunder
whoisGeoLocation = \u00a79 - Placering: {0}
whoisHealth = \u00a79 - Helbred: {0}/20
whoisIPAddress = \u00a79 - IP Addresse: {0}

View File

@ -53,9 +53,9 @@ deleteHome = \u00a77Zuhause {0} wurde gel\u00f6scht.
deleteJail = \u00a77Gef\u00e4ngnis {0} wurde gel\u00f6scht.
deleteWarp = \u00a77Warp-Punkt {0} wurde gel\u00f6scht.
deniedAccessCommand = {0} hat keinen Zugriff auf diesen Befehl.
dependancyDownloaded = [Essentials] Dependancy {0} downloaded successfully.
dependancyException = [Essentials] An error occured when trying to download a dependacy
dependancyNotFound = [Essentials] A required dependancy was not found, downloading now.
dependancyDownloaded = [Essentials] Abh\u00e4ngigkeit {0} erfolgreich runtergeladen.
dependancyException = [Essentials] W\u00e4hrend dem Download von einer Abh\u00e4ngigkeit ist ein Fehler aufgetreten.
dependancyNotFound = [Essentials] Eine erforderliche Abh\u00e4ngigkeit wurde nicht gefunde, Download startet jetzt..
depth = \u00a77Du bist auf Meeresh\u00f6he.
depthAboveSea = \u00a77Du bist {0} Bl\u00f6cke \u00fcber Meeresh\u00f6he.
depthBelowSea = \u00a77Du bist {0} Bl\u00f6cke unter Meeresh\u00f6he.
@ -99,7 +99,7 @@ helpPages = Seite \u00a7c{0}\u00a7f von \u00a7c{1}\u00a7f:
holeInFloor = Loch im Boden
homeSet = \u00a77Zuhause gesetzt.
homeSetToBed = \u00a77Dein Zuhause ist nun an diesem Bett.
homes = Homes: {0}
homes = Heime: {0}
hour = Stunde
hours = Stunden
ignorePlayer = Du ignorierst ab jetzt Spieler {0}.
@ -132,11 +132,11 @@ itemSoldConsole = {0} verkauft {1} f\u00fcr \u00a77{2}\u00a77 ({3} Einheiten je
itemSpawn = \u00a77Gebe {0}x {1}
itemsCsvNotLoaded = Konnte items.csv nicht laden.
jailAlreadyIncarcerated = \u00a7cPerson is already in jail: {0}
jailMessage = \u00a7cYou do the crime, you do the time.
jailMessage = \u00a7cDu hast ein Verbrechen begangen, also hast du Zeit.
jailNotExist = Dieses Gef\u00e4ngnis existiert nicht.
jailReleased = \u00a77Player \u00a7e{0}\u00a77 unjailed.
jailReleasedPlayerNotify = \u00a77You have been released!
jailSentenceExtended = Jail time extend to: {0)
jailReleased = \u00a77Spieler \u00a7e{0}\u00a77 wurde freigelassen.
jailReleasedPlayerNotify = \u00a77Du wurdest freigelassen!
jailSentenceExtended = Gef\u00e4ngnisszeit erweitert auf: {0)
jailSet = \u00a77Gef\u00e4ngnis {0} wurde erstellt.
jumpError = Das w\u00fcrde deinen Computer \u00fcberlasten.
kickDefault = Vom Server geworfen
@ -193,7 +193,7 @@ nickSet = \u00a77Dein Nickname ist nun \u00a7c{0}
noAccessCommand = \u00a7cDu hast keinen Zugriff auf diesen Befehl.
noAccessPermission = \u00a7cDu hast keine Rechte, den Block {0} zu \u00f6ffnen.
noDestroyPermission = \u00a7cDu hast keine Rechte, den Block {0} zu zerst\u00f6ren.
noHelpFound = \u00a7cNo matching commands.
noHelpFound = \u00a7cKeine \u00fcbereinstimmenden Kommandos.
noHomeSet = Du hast kein Zuhause gesetzt.
noHomeSetPlayer = Spieler hat kein Zuhause gesetzt.
noKitPermission = \u00a7cDu brauchst die Berechtigung \u00a7c{0}\u00a7c um diese Ausr\u00fcstung anzufordern.
@ -204,7 +204,7 @@ noMotd = \u00a7cEs existiert keine Willkommensnachricht.
noNewMail = \u00a77Du hast keine Nachrichten.
noPendingRequest = Du hast keine Teleportierungsanfragen.
noPlacePermission = \u00a7cDu hast keine Rechte, einen Block in der N\u00e4he des Schildes zu platzieren.
noPowerTools=You have no power tools assigned.
noPowerTools = Du hast keine Powertools zugewiesen.
noRules = \u00a7cEs wurden keine Regeln definiert.
noWarpsDefined = Keine Warp-Punkte erstellt.
none = keine
@ -225,7 +225,7 @@ pTimeOthersPermission = \u00a7cDu hast keine Berechtigung die Zeit von anderen S
pTimePlayers = Diese Spieler haben ihre eigene Zeit:
pTimeReset = Zeit wurde zur\u00fcgesetzt f\u00fcr: \u00a7e{0}
pTimeSet = Zeit wurde f\u00fcr \u00a7e{1}\u00a7f zu \u00a73{0}\u00a7f gesetzt.
pTimeSetFixed = Player time is fixed to \u00a73{0}\u00a7f for: \u00a7e{1}
pTimeSetFixed = Spielerzeit ist festgesetzt zu \u00a73{0}\u00a7f f\u00fcr: \u00a7e{1}
parseError = Fehler beim Parsen von {0} in Zeile {1}
pendingTeleportCancelled = \u00a7cLaufende Teleportierung abgebrochen.
permissionsError = Permissions/GroupManager fehlt; Chat-Prefixe/-Suffixe sind ausgeschaltet.
@ -244,13 +244,14 @@ possibleWorlds = \u00a77M\u00f6gliche Welten sind nummeriet von 0 bis {0}.
powerToolAir = Befehl kann nicht mit Luft verbunden werden.
powerToolAlreadySet = Befehl \u00a7c{0}\u00a7f ist bereits zu {1} hinzugef\u00fcgt.
powerToolAttach = Befehl \u00a7c{0}\u00a7f erfolgreich zu {1} hinzugef\u00fcgt.
powerToolClearAll= Alle Powertoolkommandos wurden entfernt.
powerToolList = {1} hat die folgenden Befehle: \u00a7c{0}\u00a7f.
powerToolListEmpty = {0} hat keinen Befehl.
powerToolNoSuchCommandAssigned = Befehl \u00a7c{0}\u00a7f wurde nicht zu {1} hinzugef\u00fcgt.
powerToolRemove = Befehl \u00a7c{0}\u00a7f erfolgreich von {1} entfernt.
powerToolRemoveAll = Alle Befehle von {0} entfernt.
powerToolsEnabled=All of your power tools have been enabled.
powerToolsDisabled=All of your power tools have been disabled.
powerToolsEnabled = Alle deine Powertools wurden aktiviert.
powerToolsDisabled = Alle deine Powertools wurden deaktiviert.
protectionOwner = \u00a76[EssentialsProtect] Besitzer dieses Blocks: {0}
questionFormat = \u00a77[Frage]\u00a7f {0}
reloadAllPlugins = \u00a77Alle plugins neu geladen.
@ -275,7 +276,7 @@ shoutFormat = \u00a77[Schrei]\u00a7f {0}
signFormatFail = \u00a74[{0}]
signFormatSuccess = \u00a71[{0}]
signFormatTemplate = [{0}]
signProtectInvalidLocation = \u00a74You are not allowed to create sign here.
signProtectInvalidLocation = \u00a74Du bist nicht befugt ein Schild hierhin zu setzen.
similarWarpExist = Ein Warp-Punkt mit einem \u00e4hnlichen Namen existiert bereits.
slimeMalformedSize = Ung\u00fcltige Gr\u00f6sse.
soloMob = Das Monster m\u00f6chte allein sein.
@ -327,7 +328,7 @@ unknownItemInList = Unbekannter Gegenstand {0} in Liste {1}.
unknownItemName = Unbekannter Gegenstand: {0}
unlimitedItemPermission = \u00a7cDu hast keine Rechte f\u00fcr {0}.
unlimitedItems = Unendliche Objekte:
unmutedPlayer = Player {0} ist nicht mehr stumm.
unmutedPlayer = Spieler {0} ist nicht mehr stumm.
upgradingFilesError = Fehler beim Aktualisieren der Dateien
userCreatedPortal = {0} benutzt ein Portal und hat ein Ausgangsportal erstellt.
userDoesNotExist = Spieler {0} existiert nicht.
@ -349,10 +350,10 @@ warpSet = \u00a77Warp-Punkt {0} wurde erstellt.
warpUsePermission = \u00a7cDu hast keinen Zugriff f\u00fcr diesen Warp-Punkt.
warpingTo = \u00a77Teleportiere zu Warp-Punkt {0}.
warpsCount = \u00a77Es gibt {0} Warp-Punkte. Zeige Seite {1} von {2}.
weatherStorm = \u00a77In deiner Welt st\u00fcrmt es nun.
weatherStormFor = \u00a77In deiner Welt st\u00fcrmt es nun f\u00fcr {0} Sekunden.
weatherSun = \u00a77In deiner Welt scheint nun die Sonne.
weatherSunFor = \u00a77In deiner Welt scheint nun f\u00fcr {0} Sekunden die Sonne.
weatherStorm = \u00a77In {0} st\u00fcrmt es nun.
weatherStormFor = \u00a77In {0} st\u00fcrmt es nun f\u00fcr {1} Sekunden.
weatherSun = \u00a77In {0} scheint nun die Sonne.
weatherSunFor = \u00a77In {0} scheint nun f\u00fcr {1} Sekunden die Sonne.
whoisGeoLocation = \u00a79 - Herkunft: {0}
whoisHealth = \u00a79 - Gesundheit: {0}/20
whoisIPAddress = \u00a79 - IP-Adresse: {0}
@ -368,6 +369,4 @@ year = Jahr
years = Jahre
youAreHealed = \u00a77Du wurdest geheilt.
youHaveNewMail = \u00a7cDu hast {0} Nachrichten!\u00a7f Schreibe \u00a77/mail read\u00a7f um deine Nachrichten anzuzeigen.
powerToolClearAll= All powertool commands have been cleared.

View File

@ -350,10 +350,10 @@ warpSet = \u00a77Warp {0} set.
warpUsePermission = \u00a7cYou do not have Permission to use that warp.
warpingTo = \u00a77Warping to {0}.
warpsCount = \u00a77There are {0} warps. Showing page {1} of {2}.
weatherStorm = \u00a77You set the weather to storm in your world
weatherStormFor = \u00a77You set the weather to storm in your world for {0} seconds
weatherSun = \u00a77You set the weather to sun in your world
weatherSunFor = \u00a77You set the weather to sun in your world for {0} seconds
weatherStorm = \u00a77You set the weather to storm in {0}
weatherStormFor = \u00a77You set the weather to storm in {0} for {1} seconds
weatherSun = \u00a77You set the weather to sun in {0}
weatherSunFor = \u00a77You set the weather to sun in {0} for {1} seconds
whoisGeoLocation = \u00a79 - Location: {0}
whoisHealth = \u00a79 - Health: {0}/20
whoisIPAddress = \u00a79 - IP Address: {0}

View File

@ -350,10 +350,10 @@ warpSet = \u00a77Le warp {0} a \u00e9t\u00e9 cr\u00e9\u00e9.
warpUsePermission = \u00a7cVous n''avez pas la permission d''utiliser ce warp.
warpingTo = \u00a77T\u00e9l\u00e9portation au warp {0}.
warpsCount = \u00a77There are {0} warps. Showing page {1} of {2}.
weatherStorm = \u00a77Vous avez d\u00e9fini l''orage dans votre monde
weatherStormFor = \u00a77Vous avez d\u00e9fini l''orage dans votre monde pour {0} secondes.
weatherSun = \u00a77Vous avez mis le beau temps dans votre monde
weatherSunFor = \u00a77Vous avez mis le beau temps dans votre monde pour {0} secondes.
weatherStorm = \u00a77Vous avez d\u00e9fini l''orage dans {0}
weatherStormFor = \u00a77Vous avez d\u00e9fini l''orage dans {0} pour {1} secondes.
weatherSun = \u00a77Vous avez mis le beau temps dans {0}
weatherSunFor = \u00a77Vous avez mis le beau temps dans {0} pour {1} secondes.
whoisGeoLocation = \u00a79 - Emplacement: {0}
whoisHealth = \u00a79 - Vie: {0} / 20
whoisIPAddress = \u00a79 - Adresse IP: {0}

View File

@ -350,10 +350,10 @@ warpSet = \u00a77Warp {0} ingesteld.
warpUsePermission = \u00a7cOnbevoegd om die warp te gebruiken.
warpingTo = \u00a77Aan het warpen naar {0}.
warpsCount = \u00a77There are {0} warps. Showing page {1} of {2}.
weatherStorm = \u00a77Je hebt het weer naar storm gezet in de wereld
weatherStormFor = \u00a77Je hebt het weer in de wereld naar storm gezet voor {0} seconde
weatherSun = \u00a77Je hebt het weer naar zon gezet in de wereld
weatherSunFor = \u00a77Je hebt het weer in de wereld naar zon gezet voor {0} seconde
weatherStorm = \u00a77Je hebt het weer naar storm gezet in de {0}
weatherStormFor = \u00a77Je hebt het weer in de {0} naar storm gezet voor {1} seconde
weatherSun = \u00a77Je hebt het weer naar zon gezet in de {0}
weatherSunFor = \u00a77Je hebt het weer in de {0} naar zon gezet voor {1} seconde
whoisGeoLocation = \u00a79 - Locatie: {0}
whoisHealth = \u00a79 - Levens: {0}/20
whoisIPAddress = \u00a79 - IP Adres: {0}

View File

@ -467,9 +467,70 @@ public class FakeServer implements Server
}
@Override
public org.bukkit.OfflinePlayer getOfflinePlayer(String string)
public org.bukkit.OfflinePlayer getOfflinePlayer(final String string)
{
return null;
return new org.bukkit.OfflinePlayer() {
@Override
public boolean isOnline()
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String getName()
{
return string;
}
@Override
public boolean isBanned()
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setBanned(boolean bln)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isWhitelisted()
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setWhitelisted(boolean bln)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Player getPlayer()
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isOp()
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setOp(boolean bln)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Map<String, Object> serialize()
{
throw new UnsupportedOperationException("Not supported yet.");
}
};
}
@Override

View File

@ -0,0 +1,37 @@
package com.earth2me.essentials;
import junit.framework.TestCase;
import com.earth2me.essentials.settings.Settings;
import com.earth2me.essentials.storage.StorageObject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import org.junit.Test;
public class StorageTest extends TestCase
{
@Test
public void testSettings()
{
assertTrue(StorageObject.class.isAssignableFrom(Settings.class));
final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
final Reader reader = new InputStreamReader(bais);
final Settings settings = StorageObject.load(Settings.class, reader);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintWriter writer = new PrintWriter(baos);
settings.save(writer);
writer.close();
byte[] written = baos.toByteArray();
System.out.println(new String(written));
final ByteArrayInputStream bais2 = new ByteArrayInputStream(written);
final Reader reader2 = new InputStreamReader(bais2);
final Settings settings2 = StorageObject.load(Settings.class, reader2);
System.out.println(settings.toString());
System.out.println(settings2.toString());
//assertEquals("Default and rewritten config should be equal", settings, settings2);
//that assertion fails, because empty list and maps return as null
}
}

View File

@ -39,4 +39,13 @@ v 1.3:
- Fix for Bukkit passing a null To location on a player Portaling
- Fixed manudelsub not correctly selecting the group to remove.
- Added two new permission nodes - groupmanager.notify.self & groupmanager.notify.other
These allow players/admins to be notified when players are moved between groups.
These allow players/admins to be notified when players are moved between groups.
v 1.4:
- Updated for Bukkits new YamlConfiguration.
- Cleared remaining Cast errors cause by object cloning.
- Removed extra notification messages for the player issuing the group move command.
- Added a config setting - bukkit_perms_override: false
Enable to allow default Bukkit based permissions to remain enabled, unless directly negated within GroupManager.
- Fixed reading world mirrors from the config.
- Simplified config.yml while retaining backwards compatibility.
- Added data.save.hours setting to config. This allow control over how long backups are retained.

View File

@ -2,17 +2,24 @@ settings:
config:
# With this enabled anyone set as op has full permissions when managing GroupManager
opOverrides: true
# If enabled any bukkit permissiosn which default to true will be left enabled.
# If the player is op any permissions set to Op will follow suit.
bukkit_perms_override: false
data:
save:
# How often GroupManager will save it's data back to groups and users.yml
minutes: 10
# Number of hours to retain backups (plugins/GroupManager/backup)
hours: 24
logging:
# level of detail GroupManager will use when logging.
# Acceptable entries are - ALL,CONFIG,FINE,FINER,FINEST,INFO,OFF,SEVERE,WARNING
level: INFO
permission:
world:
mirror:
mirrors:
# Worlds listed here have their permissions mirrored in their children.
world:
- world_nether

View File

@ -10,7 +10,7 @@ import java.util.Map;
import java.util.logging.Level;
import org.anjocaido.groupmanager.utils.Tasks;
import org.bukkit.util.config.Configuration;
import org.bukkit.configuration.file.YamlConfiguration;
/**
*
@ -20,7 +20,7 @@ public class GMConfiguration {
private GroupManager plugin;
private File configFile;
private Configuration GMconfig;
private YamlConfiguration GMconfig;
public GMConfiguration(GroupManager plugin) {
this.plugin = plugin;
@ -41,10 +41,10 @@ public class GMConfiguration {
}
}
GMconfig = new Configuration(configFile);
GMconfig = new YamlConfiguration();
try {
GMconfig.load();
GMconfig.load(configFile);
} catch (Exception ex) {
throw new IllegalArgumentException("The following file couldn't pass on Parser.\n" + configFile.getPath(), ex);
}
@ -52,17 +52,28 @@ public class GMConfiguration {
}
public boolean isOpOverride() {
return GMconfig.getBoolean("settings.config.bukkit_perms_override", true);
}
public boolean isBukkitPermsOverride() {
return GMconfig.getBoolean("settings.config.opOverrides", true);
}
@SuppressWarnings("unchecked")
public Map<String, Object> getMirrorsMap() {
return (Map<String, Object>) GMconfig.getProperty("settings.permission.world.mirror");
public Map<String, Object> getMirrorsMap() {
// Try to fetch the old mirror path first
if (GMconfig.isConfigurationSection("settings.permission.world.mirror"))
return (Map<String, Object>) GMconfig.getConfigurationSection("settings.permission.world.mirror").getValues(false);
else
return (Map<String, Object>) GMconfig.getConfigurationSection("settings.mirrors").getValues(false);
}
public Integer getSaveInterval() {
return GMconfig.getInt("settings.data.save.minutes", 10);
}
public Integer getBackupDuration() {
return GMconfig.getInt("settings.data.save.hours", 24);
}
public void adjustLoggerLevel() {

View File

@ -57,7 +57,7 @@ public class GroupManager extends JavaPlugin {
private boolean validateOnlinePlayer = true;
private boolean isReady = false;
private static boolean isLoaded = false;
private GMConfiguration config;
protected GMConfiguration config;
private GMLoggerHandler ch;
public static BukkitPermissions BukkitPermissions;
private static WorldListener WorldEvents;
@ -163,6 +163,7 @@ public class GroupManager extends JavaPlugin {
int minutes = getGMConfig().getSaveInterval();
scheduler.scheduleAtFixedRate(commiter, minutes, minutes, TimeUnit.MINUTES);
GroupManager.logger.info("Scheduled Data Saving is set for every " + minutes + " minutes!");
GroupManager.logger.info("Backups will be retained for " + getGMConfig().getBackupDuration() + " hours!");
}
}
@ -369,7 +370,8 @@ public class GroupManager extends JavaPlugin {
//PARECE OK
auxUser.setGroup(auxGroup);
sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' group to '" + auxGroup.getName() + "'.");
if (!sender.hasPermission("groupmanager.notify.other"))
sender.sendMessage(ChatColor.YELLOW + "You changed player '" + auxUser.getName() + "' group to '" + auxGroup.getName() + "'.");
targetPlayer = this.getServer().getPlayer(auxUser.getName());
if (targetPlayer != null) BukkitPermissions.updatePermissions(targetPlayer);
@ -1590,7 +1592,8 @@ public class GroupManager extends JavaPlugin {
}
//PARECE OK
auxUser.setGroup(auxGroup);
sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + ".");
if (!sender.hasPermission("groupmanager.notify.other"))
sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + ".");
targetPlayer = this.getServer().getPlayer(auxUser.getName());
if (targetPlayer != null) BukkitPermissions.updatePermissions(targetPlayer);
@ -1648,7 +1651,8 @@ public class GroupManager extends JavaPlugin {
}
//PARECE OK
auxUser.setGroup(auxGroup);
sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + ".");
if (!sender.hasPermission("groupmanager.notify.other"))
sender.sendMessage(ChatColor.YELLOW + "You changed " + auxUser.getName() + " group to " + auxGroup.getName() + ".");
targetPlayer = this.getServer().getPlayer(auxUser.getName());
if (targetPlayer != null) BukkitPermissions.updatePermissions(targetPlayer);
@ -1770,10 +1774,10 @@ public class GroupManager extends JavaPlugin {
for(Player test: Bukkit.getServer().getOnlinePlayers()) {
if (!test.equals(player)){
if (test.hasPermission("groupmanager.notify.other"))
test.sendMessage(ChatColor.YELLOW + name +" was " + msg);
test.sendMessage(ChatColor.YELLOW + name +" was" + msg);
} else
if ((player != null) && ((player.hasPermission("groupmanager.notify.self")) || (player.hasPermission("groupmanager.notify.other"))))
player.sendMessage(ChatColor.YELLOW + "You were " + msg);
player.sendMessage(ChatColor.YELLOW + "You were" + msg);
}
}

View File

@ -102,7 +102,7 @@ public abstract class DataUnit {
* @return a copy of the permission list
*/
public ArrayList<String> getPermissionList() {
return (ArrayList<String>) permissions.clone();
return new ArrayList<String>(permissions);
}
public void sortPermissions() {

View File

@ -41,7 +41,7 @@ public class Group extends DataUnit implements Cloneable {
@Override
public Group clone() {
Group clone = new Group(getDataSource(), this.getName());
clone.inherits = ((ArrayList<String>) this.getInherits().clone());
clone.inherits = new ArrayList<String>(this.getInherits());
for (String perm : this.getPermissionList()) {
clone.addPermission(perm);
}
@ -60,7 +60,7 @@ public class Group extends DataUnit implements Cloneable {
return null;
}
Group clone = getDataSource().createGroup(this.getName());
clone.inherits = ((ArrayList<String>) this.getInherits().clone());
clone.inherits = new ArrayList<String>(this.getInherits());
for (String perm : this.getPermissionList()) {
clone.addPermission(perm);
}
@ -76,7 +76,7 @@ public class Group extends DataUnit implements Cloneable {
* @return the inherits
*/
public ArrayList<String> getInherits() {
return (ArrayList<String>) inherits.clone();
return new ArrayList<String>(inherits);
}
/**

View File

@ -183,7 +183,7 @@ public class User extends DataUnit implements Cloneable {
}
public ArrayList<String> subGroupListStringCopy() {
return (ArrayList<String>) subGroups.clone();
return new ArrayList<String>(subGroups);
}
/**

View File

@ -99,11 +99,11 @@ public class WorldsHolder {
* don't load any worlds which are already loaded
* or mirrored worlds that don't need data.
*/
if (worldsData.containsKey(folder.getName().toLowerCase())
|| mirrors.containsKey(folder.getName().toLowerCase())) {
continue;
if (!worldsData.containsKey(folder.getName().toLowerCase())
|| !mirrors.containsKey(folder.getName().toLowerCase())) {
loadWorld(folder.getName());
}
loadWorld(folder.getName());
}
}
}
@ -168,7 +168,7 @@ public class WorldsHolder {
if (alreadyDone.contains(w)) {
continue;
}
Tasks.removeOldFiles(plugin.getBackupFolder());
Tasks.removeOldFiles(plugin, plugin.getBackupFolder());
if (w == null) {
GroupManager.logger.severe("WHAT HAPPENED?");
continue;

View File

@ -43,6 +43,7 @@ import org.bukkit.event.server.ServerListener;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
@ -124,15 +125,31 @@ public class BukkitPermissions {
User user = worldData.getUser(player.getName());
// clear permissions
for (String permission : attachment.getPermissions().keySet()) {
attachment.unsetPermission(permission);
}
// clear permissions
for (String permission : attachment.getPermissions().keySet())
attachment.unsetPermission(permission);
// find matching permissions
/*
* find matching permissions
*
* and base bukkit perms if we are set to allow bukkit permissions to override.
*/
Boolean value;
for (Permission permission : registeredPermissions) {
value = worldData.getPermissionsHandler().checkUserPermission(user, permission.getName());
value = worldData.getPermissionsHandler().checkUserPermission(user, permission.getName());
// Only check bukkit override IF we don't have the permission directly.
if (value = false) {
PermissionDefault permDefault = permission.getDefault();
if ((plugin.getGMConfig().isBukkitPermsOverride())
&& ((permDefault == PermissionDefault.TRUE)
|| ((permDefault == PermissionDefault.NOT_OP) && !player.isOp())
|| ((permDefault == PermissionDefault.OP) && player.isOp())))
value = true;
}
if (value == true)
attachment.setPermission(permission, value);
}

View File

@ -13,6 +13,8 @@ import java.io.OutputStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.data.Group;
/**
@ -43,9 +45,9 @@ public abstract class Tasks {
copy(in, dst);
}
public static void removeOldFiles(File folder) {
public static void removeOldFiles(GroupManager gm, File folder) {
if (folder.isDirectory()) {
long oldTime = System.currentTimeMillis() - 86400000L;
long oldTime = System.currentTimeMillis() - (((long)gm.getGMConfig().getBackupDuration()*60*60)*1000);
for (File olds : folder.listFiles()) {
if (olds.isFile()) {
if (olds.lastModified() < oldTime) {

View File

@ -1,5 +1,5 @@
name: GroupManager
version: "1.3 (Phoenix)"
version: "1.4 (Phoenix)"
main: org.anjocaido.groupmanager.GroupManager
website: http://www.anjocaido.info/
description: Provides on-the-fly system for permissions system created by Nijikokun. But all in memory, and with flat-file saving schedule.

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="EssentialsUpdate" default="default" basedir=".">
<description>Builds, tests, and runs the project EssentialsUpdate.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="EssentialsUpdate-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
build.xml.data.CRC32=fd4b98a9
build.xml.script.CRC32=334f342d
build.xml.stylesheet.CRC32=28e38971@1.44.1.45
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=fd4b98a9
nbproject/build-impl.xml.script.CRC32=1cab9494
nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45

View File

@ -0,0 +1,75 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=EssentialsUpdate
application.vendor=essentialsteam
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/EssentialsUpdate.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.bukkit-0.0.1-SNAPSHOT.jar=../lib/bukkit-0.0.1-SNAPSHOT.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.bukkit-0.0.1-SNAPSHOT.jar}:\
${libs.junit_4.classpath}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>EssentialsUpdate</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
<definitions>../lib/nblibraries.properties</definitions>
</libraries>
</configuration>
</project>

View File

@ -0,0 +1,479 @@
package com.earth2me.essentials.update;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.jibble.pircbot.User;
public class EssentialsHelp extends PlayerListener
{
private transient Player chatUser;
private final transient Server server;
private final transient Plugin plugin;
private final static Charset UTF8 = Charset.forName("utf-8");
private transient IrcBot ircBot;
public EssentialsHelp(final Plugin plugin)
{
super();
this.plugin = plugin;
this.server = plugin.getServer();
}
public void registerEvents()
{
final PluginManager pluginManager = server.getPluginManager();
pluginManager.registerEvent(Type.PLAYER_QUIT, this, Priority.Low, plugin);
pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Low, plugin);
}
public void onCommand(CommandSender sender)
{
if (sender instanceof Player && sender.hasPermission("essentials.helpchat"))
{
if (chatUser == null)
{
chatUser = (Player)sender;
ircBot = null;
sender.sendMessage("You will be connected to the Essentials Help Chat.");
sender.sendMessage("All your chat messages will be forwarded to the channel. You can't chat with other players on your server while in help chat, but you can use commands.");
sender.sendMessage("Please be patient, if noone is available, check back later.");
sender.sendMessage("Type !help to get a list of all commands.");
sender.sendMessage("Type !quit to leave the channel.");
sender.sendMessage("Do you want to join the channel now? (yes/no)");
}
if (!chatUser.equals(sender))
{
sender.sendMessage("The player " + chatUser.getDisplayName() + " is already using the essentialshelp.");
}
}
else
{
sender.sendMessage("Please run the command as op from in game.");
}
}
public void onDisable()
{
if ( ircBot != null)
{
ircBot.quit();
ircBot = null;
}
}
private boolean sendChatMessage(final Player player, final String message)
{
final String messageCleaned = message.trim();
if (messageCleaned.isEmpty())
{
return false;
}
if (ircBot == null)
{
if (messageCleaned.equalsIgnoreCase("yes"))
{
player.sendMessage("Connecting...");
connectToIRC(player);
return true;
}
if (messageCleaned.equalsIgnoreCase("no") || message.equalsIgnoreCase("!quit"))
{
chatUser = null;
return true;
}
return false;
}
else
{
if (ircBot.isKicked()) {
chatUser = null;
ircBot.quit();
ircBot = null;
return false;
}
final String lowMessage = messageCleaned.toLowerCase();
if (lowMessage.startsWith("!quit"))
{
chatUser = null;
if (ircBot != null) {
ircBot.quit();
ircBot = null;
}
player.sendMessage("Connection closed.");
return true;
}
if (!ircBot.isConnected() || ircBot.getChannels().length == 0)
{
return false;
}
if (lowMessage.startsWith("!list"))
{
final User[] members = ircBot.getUsers();
final StringBuilder sb = new StringBuilder();
for (User user : members)
{
if (sb.length() > 0)
{
sb.append("§f, ");
}
if (user.isOp() || user.hasVoice())
{
sb.append("§6");
}
else
{
sb.append("§7");
}
sb.append(user.getPrefix()).append(user.getNick());
}
player.sendMessage(sb.toString());
return true;
}
if (lowMessage.startsWith("!help"))
{
player.sendMessage("Commands: (Note: Files send to the chat will be public viewable.)");
player.sendMessage("!errors - Send the last server errors to the chat.");
player.sendMessage("!startup - Send the last startup messages to the chat.");
player.sendMessage("!config - Sends your Essentials config to the chat.");
player.sendMessage("!list - List all players in chat.");
player.sendMessage("!quit - Leave chat.");
return true;
}
if (lowMessage.startsWith("!errors"))
{
sendErrors();
return true;
}
if (lowMessage.startsWith("!startup"))
{
sendStartup();
return true;
}
if (lowMessage.startsWith("!config"))
{
sendConfig();
return true;
}
ircBot.sendMessage(messageCleaned);
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + messageCleaned);
return true;
}
}
private String buildIrcName()
{
final StringBuilder nameBuilder = new StringBuilder();
nameBuilder.append(chatUser.getName());
final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(server.getVersion());
if (versionMatch.matches())
{
nameBuilder.append(" CB");
nameBuilder.append(versionMatch.group(4));
}
final Plugin essentials = server.getPluginManager().getPlugin("Essentials");
if (essentials != null)
{
nameBuilder.append(" ESS");
nameBuilder.append(essentials.getDescription().getVersion());
}
final Plugin groupManager = server.getPluginManager().getPlugin("GroupManager");
if (groupManager != null)
{
nameBuilder.append(" GM");
if (!groupManager.isEnabled())
{
nameBuilder.append('!');
}
}
final Plugin pex = server.getPluginManager().getPlugin("PermissionsEx");
if (pex != null)
{
nameBuilder.append(" PEX");
if (!pex.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(pex.getDescription().getVersion());
}
final Plugin pb = server.getPluginManager().getPlugin("PermissionsBukkit");
if (pb != null)
{
nameBuilder.append(" PB");
if (!pb.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(pb.getDescription().getVersion());
}
final Plugin bp = server.getPluginManager().getPlugin("bPermissions");
if (bp != null)
{
nameBuilder.append(" BP");
if (!bp.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(bp.getDescription().getVersion());
}
final Plugin perm = server.getPluginManager().getPlugin("Permissions");
if (perm != null)
{
nameBuilder.append(" P");
if (!perm.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(perm.getDescription().getVersion());
}
return nameBuilder.toString();
}
private void connectToIRC(final Player player)
{
ircBot = new IrcBot(player, "Ess_" + player.getName(), buildIrcName());
}
private void sendErrors()
{
BufferedReader page = null;
try
{
File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile();
if (bukkitFolder == null || !bukkitFolder.exists())
{
chatUser.sendMessage("Bukkit folder not found.");
return;
}
File logFile = new File(bukkitFolder, "server.log");
if (!logFile.exists())
{
chatUser.sendMessage("Server log not found.");
return;
}
FileInputStream fis = new FileInputStream(logFile);
if (logFile.length() > 1000000)
{
fis.skip(logFile.length() - 1000000);
}
page = new BufferedReader(new InputStreamReader(fis));
final StringBuilder input = new StringBuilder();
String line;
Pattern pattern = Pattern.compile("^[0-9 :-]+\\[INFO\\].*");
while ((line = page.readLine()) != null)
{
if (!pattern.matcher(line).matches())
{
input.append(line).append("\n");
}
}
if (input.length() > 10000)
{
input.delete(0, input.length() - 10000);
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Errors: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void sendStartup()
{
BufferedReader page = null;
try
{
File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile();
if (bukkitFolder == null || !bukkitFolder.exists())
{
chatUser.sendMessage("Bukkit folder not found.");
return;
}
File logFile = new File(bukkitFolder, "server.log");
if (!logFile.exists())
{
chatUser.sendMessage("Server log not found.");
return;
}
FileInputStream fis = new FileInputStream(logFile);
if (logFile.length() > 1000000)
{
fis.skip(logFile.length() - 1000000);
}
page = new BufferedReader(new InputStreamReader(fis));
final StringBuilder input = new StringBuilder();
String line;
Pattern patternStart = Pattern.compile("^[0-9 :-]+\\[INFO\\] Starting minecraft server version.*");
Pattern patternEnd = Pattern.compile("^[0-9 :-]+\\[INFO\\] Done \\([0-9.,]+s\\)! For help, type \"help\".*");
boolean log = false;
while ((line = page.readLine()) != null)
{
if (patternStart.matcher(line).matches())
{
if (input.length() > 0)
{
input.delete(0, input.length());
}
log = true;
}
if (log)
{
input.append(line).append("\n");
}
if (patternEnd.matcher(line).matches())
{
log = false;
}
}
if (input.length() > 10000)
{
input.delete(0, input.length() - 10000);
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Startup: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void sendConfig()
{
BufferedReader page = null;
try
{
File configFolder = new File(plugin.getDataFolder().getParentFile(), "Essentials");
if (!configFolder.exists())
{
chatUser.sendMessage("Essentials plugin folder not found.");
return;
}
File configFile = new File(configFolder, "config.yml");
if (!configFile.exists())
{
chatUser.sendMessage("Essentials config file not found.");
return;
}
page = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), UTF8));
final StringBuilder input = new StringBuilder();
String line;
while ((line = page.readLine()) != null)
{
input.append(line).append("\n");
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Essentials config.yml: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Override
public void onPlayerChat(PlayerChatEvent event)
{
if (event.getPlayer() == chatUser)
{
boolean success = sendChatMessage(event.getPlayer(), event.getMessage());
event.setCancelled(success);
return;
}
}
@Override
public void onPlayerQuit(PlayerQuitEvent event)
{
chatUser = null;
if (ircBot != null) {
ircBot.quit();
ircBot = null;
}
return;
}
}

View File

@ -0,0 +1,66 @@
package com.earth2me.essentials.update;
import com.earth2me.essentials.update.UpdateCheck.CheckResult;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
public class EssentialsUpdate extends JavaPlugin
{
private transient EssentialsHelp essentialsHelp;
private transient UpdateProcess updateProcess;
@Override
public void onEnable()
{
if (!getDataFolder().exists() && !getDataFolder().mkdirs() ) {
Bukkit.getLogger().severe("Could not create data folder:"+getDataFolder().getPath());
}
essentialsHelp = new EssentialsHelp(this);
essentialsHelp.registerEvents();
final UpdateCheck updateCheck = new UpdateCheck(this);
updateProcess = new UpdateProcess(this, updateCheck);
updateProcess.registerEvents();
Bukkit.getLogger().info("EssentialsUpdate " + getDescription().getVersion() + " loaded.");
if (updateCheck.isEssentialsInstalled())
{
updateCheck.checkForUpdates();
final Version myVersion = new Version(getDescription().getVersion());
if (updateCheck.getResult() == CheckResult.NEW_ESS && myVersion.equals(updateCheck.getNewVersion()))
{
Bukkit.getLogger().info("Versions of EssentialsUpdate and Essentials do not match. Starting automatic update.");
updateProcess.doAutomaticUpdate();
}
updateCheck.scheduleUpdateTask();
}
else
{
Bukkit.getLogger().info("Essentials is ready for installation. Join the game and follow the instructions.");
}
}
@Override
public void onDisable()
{
essentialsHelp.onDisable();
}
@Override
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args)
{
if (command.getName().equalsIgnoreCase("essentialsupdate"))
{
updateProcess.onCommand(sender);
}
if (command.getName().equalsIgnoreCase("essentialshelp"))
{
essentialsHelp.onCommand(sender);
}
return true;
}
}

View File

@ -0,0 +1,112 @@
package com.earth2me.essentials.update;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;
public class GetFile
{
private transient URLConnection connection;
private transient MessageDigest digest;
public GetFile(final String urlString) throws MalformedURLException, IOException
{
final URL url = new URL(urlString);
this.connection = url.openConnection();
this.connection.setConnectTimeout(1000);
this.connection.setReadTimeout(5000);
this.connection.setUseCaches(false);
this.connection.connect();
final int respCode = ((HttpURLConnection)this.connection).getResponseCode();
if (respCode >= 300 && respCode < 400 && this.connection.getHeaderField("Location") != null)
{
connection.getInputStream().close();
final URL redirect = new URL(this.connection.getHeaderField("Location"));
this.connection = redirect.openConnection();
this.connection.setConnectTimeout(1000);
this.connection.setReadTimeout(5000);
this.connection.setUseCaches(false);
this.connection.connect();
}
}
public void saveTo(final File file) throws IOException
{
try
{
saveTo(file, null);
}
catch (NoSuchAlgorithmException ex)
{
// Ignore because the code is never called
}
}
public void saveTo(final File file, final String key) throws IOException, NoSuchAlgorithmException
{
if (key != null)
{
digest = MessageDigest.getInstance("SHA256");
}
final byte[] buffer = new byte[1024 * 8];
boolean brokenFile = false;
final BufferedInputStream input = new BufferedInputStream(connection.getInputStream());
try
{
final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));
try
{
int length;
do
{
length = input.read(buffer);
if (length >= 0)
{
if (key != null)
{
digest.update(buffer, 0, length);
}
output.write(buffer, 0, length);
}
}
while (length >= 0);
if (key != null)
{
final byte[] checksum = digest.digest();
final String checksumString = new BigInteger(checksum).toString(36);
if (!checksumString.equals(key))
{
brokenFile = true;
}
}
}
finally
{
output.close();
}
if (brokenFile && !file.delete())
{
Logger.getLogger("Minecraft").severe("Could not delete file " + file.getPath());
}
}
finally
{
input.close();
}
if (brokenFile)
{
throw new IOException("Checksum check failed.");
}
}
}

View File

@ -0,0 +1,188 @@
package com.earth2me.essentials.update;
import java.io.IOException;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jibble.pircbot.Colors;
import org.jibble.pircbot.IrcException;
import org.jibble.pircbot.PircBot;
import org.jibble.pircbot.User;
public class IrcBot extends PircBot
{
private static final String CHANNEL = "#essentials";
private static final int PORT = 6667;
private static final String SERVER = "irc.esper.net";
private transient boolean reconnect = true;
private final transient Player player;
private transient boolean kicked = false;
public IrcBot(final Player player, final String nickName, final String versionString)
{
super();
this.player = player;
setName(nickName);
setLogin("esshelp");
setVersion(versionString);
connect();
joinChannel(CHANNEL);
}
private void connect()
{
try
{
connect(SERVER, PORT);
return;
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
catch (IrcException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
public void quit()
{
reconnect = false;
disconnect();
}
@Override
protected void onConnect()
{
reconnect = true;
}
@Override
protected void onDisconnect()
{
if (reconnect)
{
int tries = 10;
while (!isConnected())
{
try
{
tries--;
reconnect();
}
catch (Exception e)
{
Bukkit.getLogger().log(Level.WARNING, e.getMessage(), e);
try
{
Thread.sleep(10000);
}
catch (InterruptedException ex)
{
Bukkit.getLogger().log(Level.WARNING, e.getMessage(), e);
}
}
if (tries <= 0)
{
player.sendMessage("Connection lost to server.");
kicked = true;
break;
}
}
}
}
@Override
protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason)
{
if (recipientNick.equals(getNick()))
{
player.sendMessage("You have been kicked from the channel: " + reason);
quit();
kicked = true;
}
}
public boolean isKicked()
{
return kicked;
}
@Override
protected void onMessage(String channel, String sender, String login, String hostname, String message)
{
player.sendMessage(formatChatMessage(sender, message, false));
}
@Override
protected void onAction(String sender, String login, String hostname, String target, String action)
{
player.sendMessage(formatChatMessage(sender, action, true));
}
@Override
protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice)
{
player.sendMessage(formatChatMessage(sourceNick, notice, false));
}
@Override
protected void onTopic(String channel, String topic, String setBy, long date, boolean changed)
{
player.sendMessage(formatChatMessage(channel, topic, false));
}
public String formatChatMessage(final String nick, final String message, final boolean action)
{
final StringBuilder builder = new StringBuilder();
builder.append("§6");
if (action)
{
builder.append('*');
}
builder.append(nick);
if (!action)
{
builder.append(':');
}
builder.append(" §7");
builder.append(replaceColors(message));
return builder.toString();
}
private String replaceColors(final String message)
{
String m = Colors.removeFormatting(message);
m = m.replaceAll("\u000310(,(0?[0-9]|1[0-5]))?", "§b");
m = m.replaceAll("\u000311(,(0?[0-9]|1[0-5]))?", "§f");
m = m.replaceAll("\u000312(,(0?[0-9]|1[0-5]))?", "§9");
m = m.replaceAll("\u000313(,(0?[0-9]|1[0-5]))?", "§d");
m = m.replaceAll("\u000314(,(0?[0-9]|1[0-5]))?", "§8");
m = m.replaceAll("\u000315(,(0?[0-9]|1[0-5]))?", "§7");
m = m.replaceAll("\u00030?1(,(0?[0-9]|1[0-5]))?", "§0");
m = m.replaceAll("\u00030?2(,(0?[0-9]|1[0-5]))?", "§1");
m = m.replaceAll("\u00030?3(,(0?[0-9]|1[0-5]))?", "§2");
m = m.replaceAll("\u00030?4(,(0?[0-9]|1[0-5]))?", "§c");
m = m.replaceAll("\u00030?5(,(0?[0-9]|1[0-5]))?", "§4");
m = m.replaceAll("\u00030?6(,(0?[0-9]|1[0-5]))?", "§5");
m = m.replaceAll("\u00030?7(,(0?[0-9]|1[0-5]))?", "§6");
m = m.replaceAll("\u00030?8(,(0?[0-9]|1[0-5]))?", "§e");
m = m.replaceAll("\u00030?9(,(0?[0-9]|1[0-5]))?", "§a");
m = m.replaceAll("\u00030?0(,(0?[0-9]|1[0-5]))?", "§f");
m = m.replace("\u000f", "§7");
m = Colors.removeColors(m);
return m;
}
public void sendMessage(final String message)
{
sendMessage(CHANNEL, message);
}
public User[] getUsers()
{
return getUsers(CHANNEL);
}
}

View File

@ -0,0 +1,35 @@
package com.earth2me.essentials.update;
import java.net.MalformedURLException;
import java.net.URL;
import org.bukkit.configuration.Configuration;
public class ModuleInfo
{
private final transient String url;
private final transient String version;
private final transient String hash;
public ModuleInfo(final Configuration updateConfig, final String path)
{
url = updateConfig.getString(path + ".url", null);
version = updateConfig.getString(path + ".version", null);
hash = updateConfig.getString(path + ".hash", null);
}
public URL getUrl() throws MalformedURLException
{
return new URL(url);
}
public String getVersion()
{
return version;
}
public String getHash()
{
return hash;
}
}

View File

@ -0,0 +1,40 @@
package com.earth2me.essentials.update;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PastieUpload
{
private final transient PostToUrl connection;
public PastieUpload() throws MalformedURLException
{
connection = new PostToUrl(new URL("http://pastie.org/pastes"));
}
public String send(final String data) throws IOException
{
final Map<String, Object> map = new HashMap<String, Object>();
map.put("paste[parser_id]", "19");
map.put("paste[authorization]", "burger");
map.put("paste[body]", data);
map.put("paste[restricted]", "1");
final String html = connection.send(map);
final Matcher matcher = Pattern.compile("(?s).*\\?key=([a-z0-9]+).*").matcher(html);
if (matcher.matches())
{
final String key = matcher.group(1);
return "http://pastie.org/private/" + key;
}
else
{
throw new IOException("Failed to upload to pastie.org");
}
}
}

View File

@ -0,0 +1,66 @@
package com.earth2me.essentials.update;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Random;
public class PostToUrl
{
private final transient URL url;
private final transient String boundary;
private final transient Random random = new Random();
private final static String CRLF = "\r\n";
private final static Charset UTF8 = Charset.forName("utf-8");
public PostToUrl(final URL url)
{
this.url = url;
final byte[] bytes = new byte[32];
random.nextBytes(bytes);
this.boundary = "----------" + new BigInteger(bytes).toString(Character.MAX_RADIX) + "_$";
}
public String send(final Map<String, Object> data) throws IOException
{
final URLConnection connection = url.openConnection();
connection.setRequestProperty("content-type", "multipart/form-data; boundary=" + boundary);
final StringBuilder dataBuilder = new StringBuilder();
for (Map.Entry<String, Object> entry : data.entrySet())
{
if (entry.getValue() instanceof String)
{
dataBuilder.append("--").append(boundary).append(CRLF);
dataBuilder.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append('"').append(CRLF);
dataBuilder.append(CRLF);
dataBuilder.append(entry.getValue()).append(CRLF);
}
// TODO: Add support for file upload
}
dataBuilder.append("--").append(boundary).append("--").append(CRLF);
dataBuilder.append(CRLF);
connection.setDoOutput(true);
final byte[] message = dataBuilder.toString().getBytes(UTF8);
connection.setRequestProperty("content-length", Integer.toString(message.length));
connection.connect();
final OutputStream stream = connection.getOutputStream();
stream.write(message);
stream.close();
final BufferedReader page = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF8));
final StringBuilder input = new StringBuilder();
String line;
while ((line = page.readLine()) != null)
{
input.append(line).append("\n");
}
page.close();
return input.toString();
}
}

View File

@ -0,0 +1,203 @@
package com.earth2me.essentials.update;
import java.io.File;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
public class UpdateCheck
{
private transient CheckResult result = CheckResult.UNKNOWN;
private transient Version currentVersion;
private transient Version newVersion = null;
private transient int bukkitResult = 0;
private transient UpdateFile updateFile;
private final static int CHECK_INTERVAL = 20 * 60 * 60 * 6;
private final transient Plugin plugin;
private transient boolean essentialsInstalled;
public UpdateCheck(Plugin plugin)
{
this.plugin = plugin;
updateFile = new UpdateFile(plugin);
checkForEssentials();
}
private void checkForEssentials()
{
PluginManager pm = plugin.getServer().getPluginManager();
Plugin essentials = pm.getPlugin("Essentials");
if (essentials == null)
{
essentialsInstalled = false;
if (new File(plugin.getDataFolder().getParentFile(), "Essentials.jar").exists())
{
Bukkit.getLogger().severe("Essentials.jar found, but not recognized by Bukkit. Broken download?");
}
}
else
{
essentialsInstalled = true;
currentVersion = new Version(essentials.getDescription().getVersion());
}
}
public void scheduleUpdateTask()
{
plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
{
@Override
public void run()
{
updateFile = new UpdateFile(plugin);
checkForUpdates();
}
}, CHECK_INTERVAL, CHECK_INTERVAL);
}
public boolean isEssentialsInstalled()
{
return essentialsInstalled;
}
public CheckResult getResult()
{
return result;
}
int getNewBukkitVersion()
{
return bukkitResult;
}
VersionInfo getNewVersionInfo()
{
return updateFile.getVersions().get(newVersion);
}
public enum CheckResult
{
NEW_ESS, NEW_ESS_BUKKIT, NEW_BUKKIT, OK, UNKNOWN
}
public void checkForUpdates()
{
if (currentVersion == null)
{
return;
}
final Map<Version, VersionInfo> versions = updateFile.getVersions();
final int bukkitVersion = getBukkitVersion();
Version higher = null;
Version found = null;
Version lower = null;
int bukkitHigher = 0;
int bukkitLower = 0;
for (Entry<Version, VersionInfo> entry : versions.entrySet())
{
final int minBukkit = entry.getValue().getMinBukkit();
final int maxBukkit = entry.getValue().getMaxBukkit();
if (minBukkit == 0 || maxBukkit == 0)
{
continue;
}
if (bukkitVersion <= maxBukkit)
{
if (bukkitVersion < minBukkit)
{
if (higher == null || higher.compareTo(entry.getKey()) < 0)
{
higher = entry.getKey();
bukkitHigher = minBukkit;
}
}
else
{
if (found == null || found.compareTo(entry.getKey()) < 0)
{
found = entry.getKey();
}
}
}
else
{
if (lower == null || lower.compareTo(entry.getKey()) < 0)
{
lower = entry.getKey();
bukkitLower = minBukkit;
}
}
}
if (found != null)
{
if (found.compareTo(currentVersion) > 0)
{
result = CheckResult.NEW_ESS;
newVersion = found;
}
else
{
result = CheckResult.OK;
}
}
else if (higher != null)
{
if (higher.compareTo(currentVersion) > 0)
{
newVersion = higher;
result = CheckResult.NEW_ESS_BUKKIT;
bukkitResult = bukkitHigher;
}
else if (higher.compareTo(currentVersion) < 0)
{
result = CheckResult.UNKNOWN;
}
else
{
result = CheckResult.NEW_BUKKIT;
bukkitResult = bukkitHigher;
}
}
else if (lower != null)
{
if (lower.compareTo(currentVersion) > 0)
{
result = CheckResult.NEW_ESS_BUKKIT;
newVersion = lower;
bukkitResult = bukkitLower;
}
else if (lower.compareTo(currentVersion) < 0)
{
result = CheckResult.UNKNOWN;
}
else
{
result = CheckResult.NEW_BUKKIT;
bukkitResult = bukkitLower;
}
}
}
private int getBukkitVersion()
{
final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(plugin.getServer().getVersion());
if (versionMatch.matches())
{
return Integer.parseInt(versionMatch.group(4));
}
throw new NumberFormatException("Bukkit Version changed!");
}
public Version getNewVersion()
{
return newVersion;
}
}

View File

@ -0,0 +1,204 @@
package com.earth2me.essentials.update;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.plugin.Plugin;
import org.bukkit.configuration.file.YamlConfiguration;
public class UpdateFile
{
private final static Logger LOGGER = Logger.getLogger("Minecraft");
private final static String UPDATE_URL = "http://goo.gl/67jev";
private final static BigInteger PUBLIC_KEY = new BigInteger("5ha6a2d4qdy17ttkg8evh74sl5a87djojwenu12k1lvy8ui6003e6l06rntczpoh99mhc3txj8mqlxw111oyy9yl7s7qpyluyzix3j1odxrxx4u52gxvyu6qiteapczkzvi7rxgeqsozz7b19rdx73a7quo9ybwpz1cr82r7x5k0pg2a73pjjsv2j1awr13azo7klrcxp9y5xxwf5qv1s3tw4zqftli18u0ek5qkbzfbgk1v5n2f11pkwwk6p0mibrn26wnjbv11vyiqgu95o7busmt6vf5q7grpcenl637w83mbin56s3asj1131b2mscj9xep3cbj7la9tgsxl5bj87vzy8sk2d34kzwqdqgh9nry43nqqus12l1stmiv184r8r3jcy8w43e8h1u1mzklldb5eytkuhayqik8l3ns04hwt8sgacvw534be8sx26qrn5s1", 36);
private final transient File file;
private transient YamlConfiguration updateConfig;
private final transient Plugin plugin;
private final transient TreeMap<Version, VersionInfo> versions = new TreeMap<Version, VersionInfo>();
public UpdateFile(final Plugin plugin)
{
this.plugin = plugin;
final long lastUpdate = Long.parseLong(plugin.getConfig().getString("lastupdate", "0"));
file = new File(plugin.getDataFolder(), "update.yml");
if (lastUpdate < System.currentTimeMillis() - 1000 * 60 * 60 * 6 || !file.exists())
{
if (file.exists() && !file.delete())
{
LOGGER.log(Level.SEVERE, "Could not delete file update.yml!");
return;
}
if (!downloadFile() || !checkFile())
{
LOGGER.log(Level.SEVERE, "Could not download and verify file update.yml!");
return;
}
}
try
{
readVersions();
}
catch (Exception ex)
{
LOGGER.log(Level.SEVERE, "Could not load update.yml!");
return;
}
}
private boolean downloadFile()
{
GetFile getFile;
try
{
getFile = new GetFile(UPDATE_URL);
getFile.saveTo(file);
plugin.getConfig().set("lastupdate", System.currentTimeMillis());
plugin.getConfig().save(new File(plugin.getDataFolder(),"config.yml"));
return true;
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, "Error while downloading update.yml", ex);
return false;
}
}
private boolean checkFile()
{
BufferedInputStream bis = null;
try
{
bis = new BufferedInputStream(new FileInputStream(file));
if (bis.read() != '#')
{
throw new IOException("File has to start with #");
}
final StringBuilder length = new StringBuilder();
final StringBuilder signature = new StringBuilder();
boolean isSignature = false;
do
{
final int cur = bis.read();
if (cur == -1)
{
break;
}
if (cur == ':')
{
isSignature = true;
}
else if (cur == '\n')
{
break;
}
else if ((cur >= '0' && cur <= '9')
|| (cur >= 'a' && cur <= 'z'))
{
if (isSignature)
{
signature.append((char)cur);
}
else
{
length.append((char)cur);
}
}
else
{
throw new IOException("Illegal character in signature!");
}
}
while (true);
if (length.length() == 0 || signature.length() == 0)
{
throw new IOException("Broken signature!");
}
final int sigLength = new BigInteger(length.toString(), 36).intValue();
if (sigLength < 0 || sigLength > 2048)
{
throw new IOException("Invalid signature length!");
}
final byte[] sigBytes = new BigInteger(signature.toString(), 36).toByteArray();
if (sigLength < sigBytes.length)
{
throw new IOException("Length is less then available bytes.");
}
byte[] realBytes;
if (sigLength == sigBytes.length)
{
realBytes = sigBytes;
}
else
{
realBytes = new byte[sigLength];
System.arraycopy(sigBytes, 0, realBytes, sigLength - sigBytes.length, sigBytes.length);
}
final X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(PUBLIC_KEY.toByteArray());
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
final PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
final Signature rsa = Signature.getInstance("SHA256withRSA");
rsa.initVerify(pubKey);
final byte[] buffer = new byte[2048];
int readLength;
do
{
readLength = bis.read(buffer);
if (readLength >= 0)
{
rsa.update(buffer, 0, readLength);
}
}
while (readLength >= 0);
return rsa.verify(realBytes);
}
catch (Exception ex)
{
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
}
finally
{
try
{
if (bis != null)
{
bis.close();
}
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
}
}
return false;
}
private void readVersions() throws Exception
{
updateConfig = new YamlConfiguration();
updateConfig.load(file);
versions.clear();
for (String versionString : updateConfig.getKeys(false))
{
final Version version = new Version(versionString);
final VersionInfo info = new VersionInfo(updateConfig, versionString);
versions.put(version, info);
}
}
public Map<Version, VersionInfo> getVersions()
{
return Collections.unmodifiableMap(versions.descendingMap());
}
}

View File

@ -0,0 +1,128 @@
package com.earth2me.essentials.update;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
public class UpdateProcess extends PlayerListener
{
private transient Player currentPlayer;
private final transient Plugin plugin;
private final transient UpdateCheck updateCheck;
public UpdateProcess(final Plugin plugin, final UpdateCheck updateCheck)
{
this.plugin = plugin;
this.updateCheck = updateCheck;
}
public void registerEvents()
{
final PluginManager pluginManager = plugin.getServer().getPluginManager();
pluginManager.registerEvent(Type.PLAYER_QUIT, this, Priority.Low, plugin);
pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Lowest, plugin);
}
@Override
public void onPlayerChat(final PlayerChatEvent event)
{
if (event.getPlayer() == currentPlayer)
{
reactOnMessage(event.getMessage());
event.setCancelled(true);
return;
}
}
@Override
public void onPlayerJoin(final PlayerJoinEvent event)
{
final Player player = event.getPlayer();
if (player.hasPermission("essentials.update") && !updateCheck.isEssentialsInstalled())
{
player.sendMessage("Hello " + player.getDisplayName());
player.sendMessage("Please type /essentialsupdate into the chat to start the installation of Essentials.");
}
if (player.hasPermission("essentials.update"))
{
final UpdateCheck.CheckResult result = updateCheck.getResult();
switch (result)
{
case NEW_ESS:
player.sendMessage("The new version " + updateCheck.getNewVersion().toString() + " for Essentials is available. Please type /essentialsupdate to update.");
break;
case NEW_BUKKIT:
player.sendMessage("Your bukkit version is not the recommended build for Essentials, please update to version " + updateCheck.getNewBukkitVersion() + ".");
break;
case NEW_ESS_BUKKIT:
player.sendMessage("There is a new version " + updateCheck.getNewVersion().toString() + " of Essentials for Bukkit " + updateCheck.getNewBukkitVersion());
break;
default:
}
}
}
void doAutomaticUpdate()
{
final UpdatesDownloader downloader = new UpdatesDownloader();
final VersionInfo info = updateCheck.getNewVersionInfo();
final List<String> changelog = info.getChangelog();
Bukkit.getLogger().info("Essentials changelog " + updateCheck.getNewVersion().toString());
for (String line : changelog)
{
Bukkit.getLogger().info(" - "+line);
}
downloader.start(plugin.getServer().getUpdateFolderFile(), info);
}
void doManualUpdate()
{
}
void onCommand(CommandSender sender)
{
if (sender instanceof Player && sender.hasPermission("essentials.install"))
{
if (currentPlayer == null)
{
currentPlayer = (Player)sender;
if (updateCheck.isEssentialsInstalled())
{
doManualUpdate();
}
else
{
sender.sendMessage("Thank you for choosing Essentials.");
sender.sendMessage("The following installation wizard will guide you through the installation of Essentials.");
sender.sendMessage("Your answers will be saved for a later update.");
sender.sendMessage("Please answer the messages with yes or no, if not otherwise stated.");
sender.sendMessage("Write bye/exit/quit if you want to exit the wizard at anytime.");
}
}
if (!currentPlayer.equals(sender))
{
sender.sendMessage("The player " + currentPlayer.getDisplayName() + " is already using the wizard.");
}
}
else
{
sender.sendMessage("Please run the command as op from in game.");
}
}
private void reactOnMessage(String message)
{
throw new UnsupportedOperationException("Not yet implemented");
}
}

View File

@ -0,0 +1,19 @@
package com.earth2me.essentials.update;
import java.io.File;
public class UpdatesDownloader
{
UpdatesDownloader()
{
}
void start(File updateFolderFile, VersionInfo newVersion)
{
}
}

View File

@ -0,0 +1,173 @@
package com.earth2me.essentials.update;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Version implements Comparable<Version>
{
public enum Type
{
STABLE, PREVIEW, DEVELOPER
}
public int getMajor()
{
return major;
}
public int getMinor()
{
return minor;
}
public int getBuild()
{
return build;
}
public Type getType()
{
return type;
}
private final transient int major;
private final transient int minor;
private final transient int build;
private final transient Type type;
public Version(final String versionString)
{
final Matcher matcher = Pattern.compile("(Pre|Dev)?([0-9]+)[_\\.]([0-9]+)[_\\.]([0-9]+).*").matcher(versionString);
if (!matcher.matches() || matcher.groupCount() < 4)
{
type = Type.DEVELOPER;
major = 99;
minor = build = 0;
return;
}
if (versionString.startsWith("Pre"))
{
type = Type.PREVIEW;
}
else if (versionString.startsWith("Dev"))
{
type = Type.DEVELOPER;
}
else
{
type = Type.STABLE;
}
major = Integer.parseInt(matcher.group(2));
minor = Integer.parseInt(matcher.group(3));
build = Integer.parseInt(matcher.group(4));
}
@Override
public int compareTo(final Version other)
{
int ret = 0;
if (other.getType() == Type.DEVELOPER && getType() != Type.DEVELOPER)
{
ret = -1;
}
else if (getType() == Type.DEVELOPER && other.getType() != Type.DEVELOPER)
{
ret = 1;
}
else if (other.getMajor() > getMajor())
{
ret = -1;
}
else if (getMajor() > other.getMajor())
{
ret = 1;
}
else if (other.getMinor() > getMinor())
{
ret = -1;
}
else if (getMinor() > other.getMinor())
{
ret = 1;
}
else if (other.getBuild() > getBuild())
{
ret = -1;
}
else if (getBuild() > other.getBuild())
{
ret = 1;
}
else if (other.getType() == Type.STABLE && getType() == Type.PREVIEW)
{
ret = -1;
}
else if (getType() == Type.STABLE && other.getType() == Type.PREVIEW)
{
ret = 1;
}
return ret;
}
@Override
public boolean equals(final Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Version other = (Version)obj;
if (this.major != other.major)
{
return false;
}
if (this.minor != other.minor)
{
return false;
}
if (this.build != other.build)
{
return false;
}
if (this.type != other.type)
{
return false;
}
return true;
}
@Override
public int hashCode()
{
int hash = 5;
hash = 71 * hash + this.major;
hash = 71 * hash + this.minor;
hash = 71 * hash + this.build;
hash = 71 * hash + (this.type != null ? this.type.hashCode() : 0);
return hash;
}
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder();
if (type == Type.DEVELOPER)
{
builder.append("Dev");
}
if (type == Type.PREVIEW)
{
builder.append("Pre");
}
builder.append(major);
builder.append('.');
builder.append(minor);
builder.append('.');
builder.append(build);
return builder.toString();
}
}

View File

@ -0,0 +1,48 @@
package com.earth2me.essentials.update;
import java.util.ArrayList;
import org.bukkit.configuration.Configuration;
import java.util.Collections;
import java.util.List;
public class VersionInfo
{
private final transient List<String> changelog;
private final transient int minBukkit;
private final transient int maxBukkit;
private final transient List<ModuleInfo> modules;
public VersionInfo(final Configuration updateConfig, final String path)
{
changelog = updateConfig.getList(path + ".changelog", Collections.<String>emptyList());
minBukkit = updateConfig.getInt(path + ".min-bukkit", 0);
maxBukkit = updateConfig.getInt(path + ".max-bukkit", 0);
modules = new ArrayList<ModuleInfo>();
final String modulesPath = path + ".modules";
for (String module : updateConfig.getKeys(false))
{
modules.add(new ModuleInfo(updateConfig, modulesPath + module));
}
}
public List<String> getChangelog()
{
return Collections.unmodifiableList(changelog);
}
public int getMinBukkit()
{
return minBukkit;
}
public int getMaxBukkit()
{
return maxBukkit;
}
public List<ModuleInfo> getModules()
{
return Collections.unmodifiableList(modules);
}
}

View File

@ -0,0 +1,7 @@
package com.earth2me.essentials.update.states;
public class Modules
{
}

View File

@ -0,0 +1,293 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
/**
* The Colors class provides several static fields and methods that you may
* find useful when writing an IRC Bot.
* <p>
* This class contains constants that are useful for formatting lines
* sent to IRC servers. These constants allow you to apply various
* formatting to the lines, such as colours, boldness, underlining
* and reverse text.
* <p>
* The class contains static methods to remove colours and formatting
* from lines of IRC text.
* <p>
* Here are some examples of how to use the contants from within a
* class that extends PircBot and imports org.jibble.pircbot.*;
*
* <pre> sendMessage("#cs", Colors.BOLD + "A bold hello!");
* <b>A bold hello!</b>
* sendMessage("#cs", Colors.RED + "Red" + Colors.NORMAL + " text");
* <font color="red">Red</font> text
* sendMessage("#cs", Colors.BOLD + Colors.RED + "Bold and red");
* <b><font color="red">Bold and red</font></b></pre>
*
* Please note that some IRC channels may be configured to reject any
* messages that use colours. Also note that older IRC clients may be
* unable to correctly display lines that contain colours and other
* control characters.
* <p>
* Note that this class name has been spelt in the American style in
* order to remain consistent with the rest of the Java API.
*
*
* @since 0.9.12
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class Colors {
/**
* Removes all previously applied color and formatting attributes.
*/
public static final String NORMAL = "\u000f";
/**
* Bold text.
*/
public static final String BOLD = "\u0002";
/**
* Underlined text.
*/
public static final String UNDERLINE = "\u001f";
/**
* Reversed text (may be rendered as italic text in some clients).
*/
public static final String REVERSE = "\u0016";
/**
* White coloured text.
*/
public static final String WHITE = "\u000300";
/**
* Black coloured text.
*/
public static final String BLACK = "\u000301";
/**
* Dark blue coloured text.
*/
public static final String DARK_BLUE = "\u000302";
/**
* Dark green coloured text.
*/
public static final String DARK_GREEN = "\u000303";
/**
* Red coloured text.
*/
public static final String RED = "\u000304";
/**
* Brown coloured text.
*/
public static final String BROWN = "\u000305";
/**
* Purple coloured text.
*/
public static final String PURPLE = "\u000306";
/**
* Olive coloured text.
*/
public static final String OLIVE = "\u000307";
/**
* Yellow coloured text.
*/
public static final String YELLOW = "\u000308";
/**
* Green coloured text.
*/
public static final String GREEN = "\u000309";
/**
* Teal coloured text.
*/
public static final String TEAL = "\u000310";
/**
* Cyan coloured text.
*/
public static final String CYAN = "\u000311";
/**
* Blue coloured text.
*/
public static final String BLUE = "\u000312";
/**
* Magenta coloured text.
*/
public static final String MAGENTA = "\u000313";
/**
* Dark gray coloured text.
*/
public static final String DARK_GRAY = "\u000314";
/**
* Light gray coloured text.
*/
public static final String LIGHT_GRAY = "\u000315";
/**
* This class should not be constructed.
*/
private Colors() {
}
/**
* Removes all colours from a line of IRC text.
*
* @since PircBot 1.2.0
*
* @param line the input text.
*
* @return the same text, but with all colours removed.
*/
public static String removeColors(String line) {
int length = line.length();
StringBuffer buffer = new StringBuffer();
int i = 0;
while (i < length) {
char ch = line.charAt(i);
if (ch == '\u0003') {
i++;
// Skip "x" or "xy" (foreground color).
if (i < length) {
ch = line.charAt(i);
if (Character.isDigit(ch)) {
i++;
if (i < length) {
ch = line.charAt(i);
if (Character.isDigit(ch)) {
i++;
}
}
// Now skip ",x" or ",xy" (background color).
if (i < length) {
ch = line.charAt(i);
if (ch == ',') {
i++;
if (i < length) {
ch = line.charAt(i);
if (Character.isDigit(ch)) {
i++;
if (i < length) {
ch = line.charAt(i);
if (Character.isDigit(ch)) {
i++;
}
}
}
else {
// Keep the comma.
i--;
}
}
else {
// Keep the comma.
i--;
}
}
}
}
}
}
else if (ch == '\u000f') {
i++;
}
else {
buffer.append(ch);
i++;
}
}
return buffer.toString();
}
/**
* Remove formatting from a line of IRC text.
*
* @since PircBot 1.2.0
*
* @param line the input text.
*
* @return the same text, but without any bold, underlining, reverse, etc.
*/
public static String removeFormatting(String line) {
int length = line.length();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < length; i++) {
char ch = line.charAt(i);
if (ch == '\u000f' || ch == '\u0002' || ch == '\u001f' || ch == '\u0016') {
// Don't add this character.
}
else {
buffer.append(ch);
}
}
return buffer.toString();
}
/**
* Removes all formatting and colours from a line of IRC text.
*
* @since PircBot 1.2.0
*
* @param line the input text.
*
* @return the same text, but without formatting and colour characters.
*
*/
public static String removeFormattingAndColors(String line) {
return removeFormatting(removeColors(line));
}
}

View File

@ -0,0 +1,169 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* A Thread which reads lines from the IRC server. It then
* passes these lines to the PircBot without changing them.
* This running Thread also detects disconnection from the server
* and is thus used by the OutputThread to send lines to the server.
*
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class InputThread extends Thread {
/**
* The InputThread reads lines from the IRC server and allows the
* PircBot to handle them.
*
* @param bot An instance of the underlying PircBot.
* @param breader The BufferedReader that reads lines from the server.
* @param bwriter The BufferedWriter that sends lines to the server.
*/
InputThread(PircBot bot, Socket socket, BufferedReader breader, BufferedWriter bwriter) {
_bot = bot;
_socket = socket;
_breader = breader;
_bwriter = bwriter;
this.setName(this.getClass() + "-Thread");
}
/**
* Sends a raw line to the IRC server as soon as possible, bypassing the
* outgoing message queue.
*
* @param line The raw line to send to the IRC server.
*/
void sendRawLine(String line) {
OutputThread.sendRawLine(_bot, _bwriter, line);
}
/**
* Returns true if this InputThread is connected to an IRC server.
* The result of this method should only act as a rough guide,
* as the result may not be valid by the time you act upon it.
*
* @return True if still connected.
*/
boolean isConnected() {
return _isConnected;
}
/**
* Called to start this Thread reading lines from the IRC server.
* When a line is read, this method calls the handleLine method
* in the PircBot, which may subsequently call an 'onXxx' method
* in the PircBot subclass. If any subclass of Throwable (i.e.
* any Exception or Error) is thrown by your method, then this
* method will print the stack trace to the standard output. It
* is probable that the PircBot may still be functioning normally
* after such a problem, but the existance of any uncaught exceptions
* in your code is something you should really fix.
*/
public void run() {
try {
boolean running = true;
while (running) {
try {
String line = null;
while ((line = _breader.readLine()) != null) {
try {
_bot.handleLine(line);
}
catch (Throwable t) {
// Stick the whole stack trace into a String so we can output it nicely.
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.flush();
StringTokenizer tokenizer = new StringTokenizer(sw.toString(), "\r\n");
synchronized (_bot) {
_bot.log("### Your implementation of PircBot is faulty and you have");
_bot.log("### allowed an uncaught Exception or Error to propagate in your");
_bot.log("### code. It may be possible for PircBot to continue operating");
_bot.log("### normally. Here is the stack trace that was produced: -");
_bot.log("### ");
while (tokenizer.hasMoreTokens()) {
_bot.log("### " + tokenizer.nextToken());
}
}
}
}
if (line == null) {
// The server must have disconnected us.
running = false;
}
}
catch (InterruptedIOException iioe) {
// This will happen if we haven't received anything from the server for a while.
// So we shall send it a ping to check that we are still connected.
this.sendRawLine("PING " + (System.currentTimeMillis() / 1000));
// Now we go back to listening for stuff from the server...
}
}
}
catch (Exception e) {
// Do nothing.
}
// If we reach this point, then we must have disconnected.
try {
_socket.close();
}
catch (Exception e) {
// Just assume the socket was already closed.
}
if (!_disposed) {
_bot.log("*** Disconnected.");
_isConnected = false;
_bot.onDisconnect();
}
}
/**
* Closes the socket without onDisconnect being called subsequently.
*/
public void dispose () {
try {
_disposed = true;
_socket.close();
}
catch (Exception e) {
// Do nothing.
}
}
private PircBot _bot = null;
private Socket _socket = null;
private BufferedReader _breader = null;
private BufferedWriter _bwriter = null;
private boolean _isConnected = true;
private boolean _disposed = false;
public static final int MAX_LINE_LENGTH = 512;
}

View File

@ -0,0 +1,35 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
/**
* An IrcException class.
*
* @since 0.9
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class IrcException extends Exception {
/**
* Constructs a new IrcException.
*
* @param e The error message to report.
*/
public IrcException(String e) {
super(e);
}
}

View File

@ -0,0 +1,38 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
/**
* A NickAlreadyInUseException class. This exception is
* thrown when the PircBot attempts to join an IRC server
* with a user name that is already in use.
*
* @since 0.9
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class NickAlreadyInUseException extends IrcException {
/**
* Constructs a new IrcException.
*
* @param e The error message to report.
*/
public NickAlreadyInUseException(String e) {
super(e);
}
}

View File

@ -0,0 +1,105 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
import java.io.*;
import java.net.*;
/**
* A Thread which is responsible for sending messages to the IRC server.
* Messages are obtained from the outgoing message queue and sent
* immediately if possible. If there is a flood of messages, then to
* avoid getting kicked from a channel, we put a small delay between
* each one.
*
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class OutputThread extends Thread {
/**
* Constructs an OutputThread for the underlying PircBot. All messages
* sent to the IRC server are sent by this OutputThread to avoid hammering
* the server. Messages are sent immediately if possible. If there are
* multiple messages queued, then there is a delay imposed.
*
* @param bot The underlying PircBot instance.
* @param outQueue The Queue from which we will obtain our messages.
*/
OutputThread(PircBot bot, Queue outQueue) {
_bot = bot;
_outQueue = outQueue;
this.setName(this.getClass() + "-Thread");
}
/**
* A static method to write a line to a BufferedOutputStream and then pass
* the line to the log method of the supplied PircBot instance.
*
* @param bot The underlying PircBot instance.
* @param out The BufferedOutputStream to write to.
* @param line The line to be written. "\r\n" is appended to the end.
* @param encoding The charset to use when encoing this string into a
* byte array.
*/
static void sendRawLine(PircBot bot, BufferedWriter bwriter, String line) {
if (line.length() > bot.getMaxLineLength() - 2) {
line = line.substring(0, bot.getMaxLineLength() - 2);
}
synchronized(bwriter) {
try {
bwriter.write(line + "\r\n");
bwriter.flush();
bot.log(">>>" + line);
}
catch (Exception e) {
// Silent response - just lose the line.
}
}
}
/**
* This method starts the Thread consuming from the outgoing message
* Queue and sending lines to the server.
*/
public void run() {
try {
boolean running = true;
while (running) {
// Small delay to prevent spamming of the channel
Thread.sleep(_bot.getMessageDelay());
String line = (String) _outQueue.next();
if (line != null) {
_bot.sendRawLine(line);
}
else {
running = false;
}
}
}
catch (InterruptedException e) {
// Just let the method return naturally...
}
}
private PircBot _bot = null;
private Queue _outQueue = null;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
import java.util.Vector;
/**
* Queue is a definition of a data structure that may
* act as a queue - that is, data can be added to one end of the
* queue and data can be requested from the head end of the queue.
* This class is thread safe for multiple producers and a single
* consumer. The next() method will block until there is data in
* the queue.
*
* This has now been modified so that it is compatible with
* the earlier JDK1.1 in order to be suitable for running on
* mobile appliances. This means replacing the LinkedList with
* a Vector, which is hardly ideal, but this Queue is typically
* only polled every second before dispatching messages.
*
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class Queue {
/**
* Constructs a Queue object of unlimited size.
*/
public Queue() {
}
/**
* Adds an Object to the end of the Queue.
*
* @param o The Object to be added to the Queue.
*/
public void add(Object o) {
synchronized(_queue) {
_queue.addElement(o);
_queue.notify();
}
}
/**
* Adds an Object to the front of the Queue.
*
* @param o The Object to be added to the Queue.
*/
public void addFront(Object o) {
synchronized(_queue) {
_queue.insertElementAt(o, 0);
_queue.notify();
}
}
/**
* Returns the Object at the front of the Queue. This
* Object is then removed from the Queue. If the Queue
* is empty, then this method shall block until there
* is an Object in the Queue to return.
*
* @return The next item from the front of the queue.
*/
public Object next() {
Object o = null;
// Block if the Queue is empty.
synchronized(_queue) {
if (_queue.size() == 0) {
try {
_queue.wait();
}
catch (InterruptedException e) {
return null;
}
}
// Return the Object.
try {
o = _queue.firstElement();
_queue.removeElementAt(0);
}
catch (ArrayIndexOutOfBoundsException e) {
throw new InternalError("Race hazard in Queue object.");
}
}
return o;
}
/**
* Returns true if the Queue is not empty. If another
* Thread empties the Queue before <b>next()</b> is
* called, then the call to <b>next()</b> shall block
* until the Queue has been populated again.
*
* @return True only if the Queue not empty.
*/
public boolean hasNext() {
return (this.size() != 0);
}
/**
* Clears the contents of the Queue.
*/
public void clear() {
synchronized(_queue) {
_queue.removeAllElements();
}
}
/**
* Returns the size of the Queue.
*
* @return The current size of the queue.
*/
public int size() {
return _queue.size();
}
private Vector _queue = new Vector();
}

View File

@ -0,0 +1,176 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
/**
* This interface contains the values of all numeric replies specified
* in section 6 of RFC 1459. Refer to RFC 1459 for further information.
* <p>
* If you override the onServerResponse method in the PircBot class,
* you may find these constants useful when comparing the numeric
* value of a given code.
*
* @since 1.0.0
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public interface ReplyConstants {
// Error Replies.
public static final int ERR_NOSUCHNICK = 401;
public static final int ERR_NOSUCHSERVER = 402;
public static final int ERR_NOSUCHCHANNEL = 403;
public static final int ERR_CANNOTSENDTOCHAN = 404;
public static final int ERR_TOOMANYCHANNELS = 405;
public static final int ERR_WASNOSUCHNICK = 406;
public static final int ERR_TOOMANYTARGETS = 407;
public static final int ERR_NOORIGIN = 409;
public static final int ERR_NORECIPIENT = 411;
public static final int ERR_NOTEXTTOSEND = 412;
public static final int ERR_NOTOPLEVEL = 413;
public static final int ERR_WILDTOPLEVEL = 414;
public static final int ERR_UNKNOWNCOMMAND = 421;
public static final int ERR_NOMOTD = 422;
public static final int ERR_NOADMININFO = 423;
public static final int ERR_FILEERROR = 424;
public static final int ERR_NONICKNAMEGIVEN = 431;
public static final int ERR_ERRONEUSNICKNAME = 432;
public static final int ERR_NICKNAMEINUSE = 433;
public static final int ERR_NICKCOLLISION = 436;
public static final int ERR_USERNOTINCHANNEL = 441;
public static final int ERR_NOTONCHANNEL = 442;
public static final int ERR_USERONCHANNEL = 443;
public static final int ERR_NOLOGIN = 444;
public static final int ERR_SUMMONDISABLED = 445;
public static final int ERR_USERSDISABLED = 446;
public static final int ERR_NOTREGISTERED = 451;
public static final int ERR_NEEDMOREPARAMS = 461;
public static final int ERR_ALREADYREGISTRED = 462;
public static final int ERR_NOPERMFORHOST = 463;
public static final int ERR_PASSWDMISMATCH = 464;
public static final int ERR_YOUREBANNEDCREEP = 465;
public static final int ERR_KEYSET = 467;
public static final int ERR_CHANNELISFULL = 471;
public static final int ERR_UNKNOWNMODE = 472;
public static final int ERR_INVITEONLYCHAN = 473;
public static final int ERR_BANNEDFROMCHAN = 474;
public static final int ERR_BADCHANNELKEY = 475;
public static final int ERR_NOPRIVILEGES = 481;
public static final int ERR_CHANOPRIVSNEEDED = 482;
public static final int ERR_CANTKILLSERVER = 483;
public static final int ERR_NOOPERHOST = 491;
public static final int ERR_UMODEUNKNOWNFLAG = 501;
public static final int ERR_USERSDONTMATCH = 502;
// Command Responses.
public static final int RPL_TRACELINK = 200;
public static final int RPL_TRACECONNECTING = 201;
public static final int RPL_TRACEHANDSHAKE = 202;
public static final int RPL_TRACEUNKNOWN = 203;
public static final int RPL_TRACEOPERATOR = 204;
public static final int RPL_TRACEUSER = 205;
public static final int RPL_TRACESERVER = 206;
public static final int RPL_TRACENEWTYPE = 208;
public static final int RPL_STATSLINKINFO = 211;
public static final int RPL_STATSCOMMANDS = 212;
public static final int RPL_STATSCLINE = 213;
public static final int RPL_STATSNLINE = 214;
public static final int RPL_STATSILINE = 215;
public static final int RPL_STATSKLINE = 216;
public static final int RPL_STATSYLINE = 218;
public static final int RPL_ENDOFSTATS = 219;
public static final int RPL_UMODEIS = 221;
public static final int RPL_STATSLLINE = 241;
public static final int RPL_STATSUPTIME = 242;
public static final int RPL_STATSOLINE = 243;
public static final int RPL_STATSHLINE = 244;
public static final int RPL_LUSERCLIENT = 251;
public static final int RPL_LUSEROP = 252;
public static final int RPL_LUSERUNKNOWN = 253;
public static final int RPL_LUSERCHANNELS = 254;
public static final int RPL_LUSERME = 255;
public static final int RPL_ADMINME = 256;
public static final int RPL_ADMINLOC1 = 257;
public static final int RPL_ADMINLOC2 = 258;
public static final int RPL_ADMINEMAIL = 259;
public static final int RPL_TRACELOG = 261;
public static final int RPL_NONE = 300;
public static final int RPL_AWAY = 301;
public static final int RPL_USERHOST = 302;
public static final int RPL_ISON = 303;
public static final int RPL_UNAWAY = 305;
public static final int RPL_NOWAWAY = 306;
public static final int RPL_WHOISUSER = 311;
public static final int RPL_WHOISSERVER = 312;
public static final int RPL_WHOISOPERATOR = 313;
public static final int RPL_WHOWASUSER = 314;
public static final int RPL_ENDOFWHO = 315;
public static final int RPL_WHOISIDLE = 317;
public static final int RPL_ENDOFWHOIS = 318;
public static final int RPL_WHOISCHANNELS = 319;
public static final int RPL_LISTSTART = 321;
public static final int RPL_LIST = 322;
public static final int RPL_LISTEND = 323;
public static final int RPL_CHANNELMODEIS = 324;
public static final int RPL_NOTOPIC = 331;
public static final int RPL_TOPIC = 332;
public static final int RPL_TOPICINFO = 333;
public static final int RPL_INVITING = 341;
public static final int RPL_SUMMONING = 342;
public static final int RPL_VERSION = 351;
public static final int RPL_WHOREPLY = 352;
public static final int RPL_NAMREPLY = 353;
public static final int RPL_LINKS = 364;
public static final int RPL_ENDOFLINKS = 365;
public static final int RPL_ENDOFNAMES = 366;
public static final int RPL_BANLIST = 367;
public static final int RPL_ENDOFBANLIST = 368;
public static final int RPL_ENDOFWHOWAS = 369;
public static final int RPL_INFO = 371;
public static final int RPL_MOTD = 372;
public static final int RPL_ENDOFINFO = 374;
public static final int RPL_MOTDSTART = 375;
public static final int RPL_ENDOFMOTD = 376;
public static final int RPL_YOUREOPER = 381;
public static final int RPL_REHASHING = 382;
public static final int RPL_TIME = 391;
public static final int RPL_USERSSTART = 392;
public static final int RPL_USERS = 393;
public static final int RPL_ENDOFUSERS = 394;
public static final int RPL_NOUSERS = 395;
// Reserved Numerics.
public static final int RPL_TRACECLASS = 209;
public static final int RPL_STATSQLINE = 217;
public static final int RPL_SERVICEINFO = 231;
public static final int RPL_ENDOFSERVICES = 232;
public static final int RPL_SERVICE = 233;
public static final int RPL_SERVLIST = 234;
public static final int RPL_SERVLISTEND = 235;
public static final int RPL_WHOISCHANOP = 316;
public static final int RPL_KILLDONE = 361;
public static final int RPL_CLOSING = 362;
public static final int RPL_CLOSEEND = 363;
public static final int RPL_INFOSTART = 373;
public static final int RPL_MYPORTIS = 384;
public static final int ERR_YOUWILLBEBANNED = 466;
public static final int ERR_BADCHANMASK = 476;
public static final int ERR_NOSERVICEHOST = 492;
}

View File

@ -0,0 +1,161 @@
/*
Copyright Paul James Mutton, 2001-2009, http://www.jibble.org/
This file is part of PircBot.
This software is dual-licensed, allowing you to choose between the GNU
General Public License (GPL) and the www.jibble.org Commercial License.
Since the GPL may be too restrictive for use in a proprietary application,
a commercial license is also provided. Full license information can be
found at http://www.jibble.org/licenses/
*/
package org.jibble.pircbot;
/**
* This class is used to represent a user on an IRC server.
* Instances of this class are returned by the getUsers method
* in the PircBot class.
* <p>
* Note that this class no longer implements the Comparable interface
* for Java 1.1 compatibility reasons.
*
* @since 1.0.0
* @author Paul James Mutton,
* <a href="http://www.jibble.org/">http://www.jibble.org/</a>
* @version 1.5.0 (Build time: Mon Dec 14 20:07:17 2009)
*/
public class User {
/**
* Constructs a User object with a known prefix and nick.
*
* @param prefix The status of the user, for example, "@".
* @param nick The nick of the user.
*/
User(String prefix, String nick) {
_prefix = prefix;
_nick = nick;
_lowerNick = nick.toLowerCase();
}
/**
* Returns the prefix of the user. If the User object has been obtained
* from a list of users in a channel, then this will reflect the user's
* status in that channel.
*
* @return The prefix of the user. If there is no prefix, then an empty
* String is returned.
*/
public String getPrefix() {
return _prefix;
}
/**
* Returns whether or not the user represented by this object is an
* operator. If the User object has been obtained from a list of users
* in a channel, then this will reflect the user's operator status in
* that channel.
*
* @return true if the user is an operator in the channel.
*/
public boolean isOp() {
return _prefix.indexOf('@') >= 0;
}
/**
* Returns whether or not the user represented by this object has
* voice. If the User object has been obtained from a list of users
* in a channel, then this will reflect the user's voice status in
* that channel.
*
* @return true if the user has voice in the channel.
*/
public boolean hasVoice() {
return _prefix.indexOf('+') >= 0;
}
/**
* Returns the nick of the user.
*
* @return The user's nick.
*/
public String getNick() {
return _nick;
}
/**
* Returns the nick of the user complete with their prefix if they
* have one, e.g. "@Dave".
*
* @return The user's prefix and nick.
*/
public String toString() {
return this.getPrefix() + this.getNick();
}
/**
* Returns true if the nick represented by this User object is the same
* as the argument. A case insensitive comparison is made.
*
* @return true if the nicks are identical (case insensitive).
*/
public boolean equals(String nick) {
return nick.toLowerCase().equals(_lowerNick);
}
/**
* Returns true if the nick represented by this User object is the same
* as the nick of the User object given as an argument.
* A case insensitive comparison is made.
*
* @return true if o is a User object with a matching lowercase nick.
*/
public boolean equals(Object o) {
if (o instanceof User) {
User other = (User) o;
return other._lowerNick.equals(_lowerNick);
}
return false;
}
/**
* Returns the hash code of this User object.
*
* @return the hash code of the User object.
*/
public int hashCode() {
return _lowerNick.hashCode();
}
/**
* Returns the result of calling the compareTo method on lowercased
* nicks. This is useful for sorting lists of User objects.
*
* @return the result of calling compareTo on lowercased nicks.
*/
public int compareTo(Object o) {
if (o instanceof User) {
User other = (User) o;
return other._lowerNick.compareTo(_lowerNick);
}
return -1;
}
private String _prefix;
private String _nick;
private String _lowerNick;
}

View File

@ -0,0 +1,21 @@
# This determines the command prefix when there are conflicts (/name:home, /name:help, etc.)
name: EssentialsUpdate
main: com.earth2me.essentials.update.EssentialsUpdate
# Note to developers: This next line cannot change, or the automatic versioning system will break.
version: TeamCity
description: This plugin allows to install or update all Essentials plugins
authors: [snowleo]
commands:
essentialsupdate:
description: Install or update the Essentials plugins.
usage: /<command>
essentialshelp:
description: Get help from the Essentials support chat.
usage: /<command>
permissions:
essentials.update:
description: Allows you to update Essentials
default: op
essentials.helpchat:
description: Allows you to join Essentials help chat
default: op

View File

@ -0,0 +1,27 @@
package com.earth2me.essentials.update;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import junit.framework.TestCase;
import org.junit.Test;
public class UploadTest extends TestCase
{
@Test
public void testPastieUpload()
{
try
{
final PastieUpload pastie = new PastieUpload();
assertNotNull(pastie);
//final String url = pastie.send("test");
//System.out.println(url);
}
catch (IOException ex)
{
Logger.getLogger(UploadTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

View File

@ -0,0 +1,87 @@
package com.earth2me.essentials.update;
import com.earth2me.essentials.update.Version.Type;
import java.util.TreeSet;
import junit.framework.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
public class VersionTest extends TestCase
{
@Test
public void testStable()
{
final Version instance = new Version("1.2.3");
assertEquals("Testing Major", 1, instance.getMajor());
assertEquals("Testing Minor", 2, instance.getMinor());
assertEquals("Testing Build", 3, instance.getBuild());
assertEquals("Testing Type", Type.STABLE, instance.getType());
}
@Test
public void testDev()
{
final Version instance = new Version("Dev2.3.4");
assertEquals("Testing Major", 2, instance.getMajor());
assertEquals("Testing Minor", 3, instance.getMinor());
assertEquals("Testing Build", 4, instance.getBuild());
assertEquals("Testing Type", Type.DEVELOPER, instance.getType());
}
@Test
public void testTeamCity()
{
final Version instance = new Version("Teamcity");
assertEquals("Testing Type", Type.DEVELOPER, instance.getType());
}
@Test
public void testPre()
{
final Version instance = new Version("Pre5.7.400.2");
assertEquals("Testing Major", 5, instance.getMajor());
assertEquals("Testing Minor", 7, instance.getMinor());
assertEquals("Testing Build", 400, instance.getBuild());
assertEquals("Testing Type", Type.PREVIEW, instance.getType());
}
@Test
public void testCompareTo()
{
Version a = new Version("1.1.1");
Version b = new Version("Dev1.1.2");
Version c = new Version("1.1.2");
Version d = new Version("1.2.0");
Version e = new Version("2.0.0");
Version f = new Version("Pre1.1.1.1");
Version g = new Version("Dev1.2.2");
assertTrue("Testing dev", a.compareTo(b) < 0);
assertTrue("Testing dev", b.compareTo(a) > 0);
assertTrue("Testing build", a.compareTo(c) < 0);
assertTrue("Testing build", c.compareTo(a) > 0);
assertTrue("Testing minor", a.compareTo(d) < 0);
assertTrue("Testing minor", d.compareTo(a) > 0);
assertTrue("Testing major", a.compareTo(e) < 0);
assertTrue("Testing major", e.compareTo(a) > 0);
assertTrue("Testing pre", f.compareTo(a) < 0);
assertTrue("Testing pre", a.compareTo(f) > 0);
assertTrue("Testing dev vs dev", b.compareTo(g) < 0);
assertTrue("Testing dev vs dev", g.compareTo(b) > 0);
final TreeSet<Version> set = new TreeSet<Version>();
set.add(a);
set.add(b);
set.add(c);
set.add(d);
set.add(e);
set.add(f);
set.add(g);
assertEquals("Testing sorting", f, set.pollFirst());
assertEquals("Testing sorting", a, set.pollFirst());
assertEquals("Testing sorting", c, set.pollFirst());
assertEquals("Testing sorting", d, set.pollFirst());
assertEquals("Testing sorting", e, set.pollFirst());
assertEquals("Testing sorting", b, set.pollFirst());
assertEquals("Testing sorting", g, set.pollFirst());
}
}

5
WebPush/apikey.php Normal file
View File

@ -0,0 +1,5 @@
<?php
$params['api-key'] = "c73c331c7e44c156c852f7d08de3f22bb7a6e948";
?>

52
WebPush/index.php Normal file
View File

@ -0,0 +1,52 @@
<?php
//We want to be able to continue if the client aborts.
ignore_user_abort();
set_time_limit(0);
error_reporting(E_ALL);
ini_set('display_errors', 'Off');
ini_set('error_log', 'errors.log');
//Abort the browser so it doesn't hang while we do the uploading.
ob_end_clean();
header("Connection: close");
ob_start();
header("Content-Length: 0");
ob_end_flush();
flush();
//Lets get to work!
include('upload.php');
$build = $_GET['buildid'];
$branch = $_GET['branch'];
$version = $_GET['version'];
if ($build == "" || $branch == "" || $version == "")
{
die();
}
//Don't upload dev builds atm.
if ($branch == "bt2")
{
die();
}
sleep(60);
$changes = getChanges($build, $branch);
uploadit($build, $branch, 'Essentials.jar', $version, $changes);
sleep(1);
uploadit($build, $branch, 'EssentialsChat.jar', $version, $changes);
sleep(1);
uploadit($build, $branch, 'EssentialsSpawn.jar', $version, $changes);
sleep(1);
uploadit($build, $branch, 'EssentialsProtect.jar', $version, $changes);
sleep(1);
uploadit($build, $branch, 'EssentialsXMPP.jar', $version, $changes);
sleep(1);
uploadit($build, $branch, 'EssentialsGeoIP.jar', $version, $changes);
?>

View File

@ -0,0 +1,8 @@
copy.src.files=false
copy.src.target=
index.file=index.php
remote.connection=localhost-d13e79
remote.directory=/upload
remote.upload=ON_SAVE
run.as=REMOTE
url=http://ess.khhq.net/upload/

View File

@ -0,0 +1,7 @@
include.path=${php.global.include.path}
php.version=PHP_5
source.encoding=UTF-8
src.dir=.
tags.asp=false
tags.short=true
web.root=.

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.php.project</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/php-project/1">
<name>Push</name>
</data>
</configuration>
</project>

1727
WebPush/simple_html_dom.php Normal file

File diff suppressed because it is too large Load Diff

100
WebPush/upload.php Normal file
View File

@ -0,0 +1,100 @@
<?php
include_once('simple_html_dom.php');
function uploadit($build, $branch, $file, $version, $changes)
{
file_put_contents('status.log', "\nUploading file $file to devbukkit! ", FILE_APPEND);
$slug = "essentials";
$plugin = "Essentials";
$url = "http://ci.earth2me.net/guestAuth/repository/download/$branch/$build:id/$file";
$filename = explode('.', $file);
$request_url = "http://dev.bukkit.org/server-mods/$slug/upload-file.json";
include ('apikey.php');
$params['name'] = $filename[0] . '-' . $version;
$params['game_versions'] = 176;
$params['change_log'] = $changes;
$params['change_markup_type'] = "html";
$params['fileurl'] = $url;
if (stripos($version, 'Dev') !== false)
{
$params['file_type'] = "a";
}
elseif (stripos($version, 'Pre') !== false)
{
$params['file_type'] = "b";
}
else
{
$params['file_type'] = "r";
}
$content = file_get_contents($url);
file_put_contents($file, $content);
$params['file'] = '@' . $file;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
if ($result === false)
{
$result = curl_error($ch);
}
elseif ($result == "")
{
$result = "Success uploading $file - $version";
}
curl_close($ch);
file_put_contents('status.log', $result, FILE_APPEND);
return true;
}
function getChanges($job, $project)
{
$commitblacklist = array(
'Merge branch',
'Merge pull',
'Revert',
'Cleanup',
);
$url = "http://ci.earth2me.net/viewLog.html?buildId=$job&tab=buildChangesDiv&buildTypeId=$project&guest=1";
$html = new simple_html_dom();
$html->load_file($url);
$output = "Change Log:<ul>";
foreach ($html->find('.changelist') as $list)
{
foreach ($list->find('.comment') as $comment)
{
$text = $comment->innertext;
foreach ($commitblacklist as $matchtext)
{
if (stripos($text, $matchtext) !== FALSE)
{
$text = "";
}
}
if ($text != "")
{
$output .= "<li>$text</li>\n";
}
}
}
$output .= "</ul>";
file_put_contents('status.log', "Collected changes! ", FILE_APPEND);
return $output;
}
?>

Binary file not shown.

Binary file not shown.

BIN
lib/lombok-0.10.1.jar Normal file

Binary file not shown.