Auto-AFK, AFK-Kick and freeze afk players

This commit is contained in:
snowleo 2011-08-27 13:59:39 +02:00
parent 00050d08d4
commit 8998168ec2
6 changed files with 176 additions and 85 deletions

View File

@ -73,11 +73,7 @@ public class EssentialsPlayerListener extends PlayerListener
it.remove(); it.remove();
} }
} }
if (user.isAfk()) user.updateActivity();
{
user.setAfk(false);
ess.broadcastMessage(user.getName(), Util.format("userIsNotAway", user.getDisplayName()));
}
if (ess.getSettings().changeDisplayName()) if (ess.getSettings().changeDisplayName())
{ {
user.setDisplayName(user.getNick()); user.setDisplayName(user.getNick());
@ -93,11 +89,12 @@ public class EssentialsPlayerListener extends PlayerListener
} }
final User user = ess.getUser(event.getPlayer()); final User user = ess.getUser(event.getPlayer());
if (user.isAfk()) if (user.isAfk() && ess.getSettings().getFreezeAfkPlayers()) {
{ event.setCancelled(true);
user.setAfk(false); return;
ess.broadcastMessage(user.getName(), Util.format("userIsNotAway", user.getDisplayName()));
} }
user.updateActivity();
if (!ess.getSettings().getNetherPortalsEnabled()) if (!ess.getSettings().getNetherPortalsEnabled())
{ {
@ -216,6 +213,7 @@ public class EssentialsPlayerListener extends PlayerListener
user.getInventory().setContents(user.getSavedInventory()); user.getInventory().setContents(user.getSavedInventory());
user.setSavedInventory(null); user.setSavedInventory(null);
} }
user.updateActivity();
user.dispose(); user.dispose();
if (!ess.getSettings().getReclaimSetting()) if (!ess.getSettings().getReclaimSetting())
{ {
@ -304,7 +302,8 @@ public class EssentialsPlayerListener extends PlayerListener
return; return;
} }
User user = ess.getUser(event.getPlayer()); User user = ess.getUser(event.getPlayer());
if (user == null) { if (user == null)
{
user = new User(event.getPlayer(), ess); user = new User(event.getPlayer(), ess);
} }
user.setNPC(false); user.setNPC(false);
@ -436,7 +435,7 @@ public class EssentialsPlayerListener extends PlayerListener
{ {
return; return;
} }
// We need to loop through each command and execute // We need to loop through each command and execute
for (String command : commandList) for (String command : commandList)
{ {
@ -479,10 +478,6 @@ public class EssentialsPlayerListener extends PlayerListener
} }
} }
} }
if (user.isAfk()) user.updateActivity();
{
user.setAfk(false);
ess.broadcastMessage(user.getName(), Util.format("userIsNotAway", user.getDisplayName()));
}
} }
} }

View File

@ -24,16 +24,17 @@ public class EssentialsTimer implements Runnable
{ {
final User user = ess.getUser(player); final User user = ess.getUser(player);
onlineUsers.add(user); onlineUsers.add(user);
user.setLastActivity(currentTime); user.setLastOnlineActivity(currentTime);
user.checkActivity();
} }
final Iterator<User> iterator = onlineUsers.iterator(); final Iterator<User> iterator = onlineUsers.iterator();
while (iterator.hasNext()) while (iterator.hasNext())
{ {
final User user = iterator.next(); final User user = iterator.next();
if (user.getLastActivity() < currentTime && user.getLastActivity() > user.getLastLogout()) if (user.getLastOnlineActivity() < currentTime && user.getLastOnlineActivity() > user.getLastLogout())
{ {
user.setLastLogout(user.getLastActivity()); user.setLastLogout(user.getLastOnlineActivity());
iterator.remove(); iterator.remove();
continue; continue;
} }

View File

@ -109,8 +109,6 @@ public interface ISettings extends IConf
boolean permissionBasedItemSpawn(); boolean permissionBasedItemSpawn();
void reloadConfig();
boolean showNonEssCommandsInHelp(); boolean showNonEssCommandsInHelp();
boolean spawnIfNoHome(); boolean spawnIfNoHome();
@ -136,4 +134,10 @@ public interface ISettings extends IConf
boolean addPrefixSuffix(); boolean addPrefixSuffix();
boolean isUpdateEnabled(); boolean isUpdateEnabled();
long getAutoAfk();
long getAutoAfkKick();
boolean getFreezeAfkPlayers();
} }

View File

@ -485,4 +485,22 @@ public class Settings implements ISettings
{ {
return config.getBoolean("update-check", true); return config.getBoolean("update-check", true);
} }
@Override
public long getAutoAfk()
{
return config.getLong("auto-afk", 300);
}
@Override
public long getAutoAfkKick()
{
return config.getLong("auto-afk-kick", -1);
}
@Override
public boolean getFreezeAfkPlayers()
{
return config.getBoolean("freeze-afk-players", false);
}
} }

View File

@ -1,11 +1,9 @@
package com.earth2me.essentials; package com.earth2me.essentials;
import com.earth2me.essentials.commands.IEssentialsCommand; import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.register.payment.Method; import com.earth2me.essentials.register.payment.Method;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.logging.Logger;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -14,38 +12,43 @@ import org.bukkit.entity.Player;
public class User extends UserData implements Comparable<User>, IReplyTo, IUser public class User extends UserData implements Comparable<User>, IReplyTo, IUser
{ {
private static final Logger logger = Logger.getLogger("Minecraft");
private boolean justPortaled = false; private boolean justPortaled = false;
private CommandSender replyTo = null; private CommandSender replyTo = null;
private User teleportRequester; private transient User teleportRequester;
private boolean teleportRequestHere; private transient boolean teleportRequestHere;
private final Teleport teleport; private transient final Teleport teleport;
private long lastActivity; private transient long lastOnlineActivity;
private transient long lastActivity;
private boolean hidden = false; private boolean hidden = false;
private transient boolean godStateBeforeAfk;
User(Player base, IEssentials ess) User(final Player base, final IEssentials ess)
{ {
super(base, ess); super(base, ess);
teleport = new Teleport(this, ess); teleport = new Teleport(this, ess);
godStateBeforeAfk = isGodModeEnabled();
} }
User update(Player base) User update(final Player base)
{ {
setBase(base); setBase(base);
return this; return this;
} }
public boolean isAuthorized(IEssentialsCommand cmd) @Override
public boolean isAuthorized(final IEssentialsCommand cmd)
{ {
return isAuthorized(cmd, "essentials."); return isAuthorized(cmd, "essentials.");
} }
public boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix) @Override
public boolean isAuthorized(final IEssentialsCommand cmd, final String permissionPrefix)
{ {
return isAuthorized(permissionPrefix + (cmd.getName().equals("r") ? "msg" : cmd.getName())); return isAuthorized(permissionPrefix + (cmd.getName().equals("r") ? "msg" : cmd.getName()));
} }
public boolean isAuthorized(String node) @Override
public boolean isAuthorized(final String node)
{ {
if (isOp()) if (isOp())
{ {
@ -62,11 +65,11 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
public void healCooldown() throws Exception public void healCooldown() throws Exception
{ {
Calendar now = new GregorianCalendar(); final Calendar now = new GregorianCalendar();
if (getLastHealTimestamp() > 0) if (getLastHealTimestamp() > 0)
{ {
double cooldown = ess.getSettings().getHealCooldown(); final double cooldown = ess.getSettings().getHealCooldown();
Calendar cooldownTime = new GregorianCalendar(); final Calendar cooldownTime = new GregorianCalendar();
cooldownTime.setTimeInMillis(getLastHealTimestamp()); cooldownTime.setTimeInMillis(getLastHealTimestamp());
cooldownTime.add(Calendar.SECOND, (int)cooldown); cooldownTime.add(Calendar.SECOND, (int)cooldown);
cooldownTime.add(Calendar.MILLISECOND, (int)((cooldown * 1000.0) % 1000.0)); cooldownTime.add(Calendar.MILLISECOND, (int)((cooldown * 1000.0) % 1000.0));
@ -78,12 +81,13 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
setLastHealTimestamp(now.getTimeInMillis()); setLastHealTimestamp(now.getTimeInMillis());
} }
public void giveMoney(double value) @Override
public void giveMoney(final double value)
{ {
giveMoney(value, null); giveMoney(value, null);
} }
public void giveMoney(double value, CommandSender initiator) public void giveMoney(final double value, final CommandSender initiator)
{ {
if (value == 0) if (value == 0)
{ {
@ -93,35 +97,36 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
sendMessage(Util.format("addedToAccount", Util.formatCurrency(value, ess))); sendMessage(Util.format("addedToAccount", Util.formatCurrency(value, ess)));
if (initiator != null) if (initiator != null)
{ {
initiator.sendMessage((Util.format("addedToOthersAccount", Util.formatCurrency(value, ess), this.getDisplayName()))); initiator.sendMessage(Util.format("addedToOthersAccount", Util.formatCurrency(value, ess), this.getDisplayName()));
} }
} }
public void payUser(User reciever, double value) throws Exception public void payUser(final User reciever, final double value) throws Exception
{ {
if (value == 0) if (value == 0)
{ {
return; return;
} }
if (!canAfford(value)) if (canAfford(value))
{
throw new Exception(Util.i18n("notEnoughMoney"));
}
else
{ {
setMoney(getMoney() - value); setMoney(getMoney() - value);
reciever.setMoney(reciever.getMoney() + value); reciever.setMoney(reciever.getMoney() + value);
sendMessage(Util.format("moneySentTo", Util.formatCurrency(value, ess), reciever.getDisplayName())); sendMessage(Util.format("moneySentTo", Util.formatCurrency(value, ess), reciever.getDisplayName()));
reciever.sendMessage(Util.format("moneyRecievedFrom", Util.formatCurrency(value, ess), getDisplayName())); reciever.sendMessage(Util.format("moneyRecievedFrom", Util.formatCurrency(value, ess), getDisplayName()));
} }
else
{
throw new Exception(Util.i18n("notEnoughMoney"));
}
} }
public void takeMoney(double value) @Override
public void takeMoney(final double value)
{ {
takeMoney(value, null); takeMoney(value, null);
} }
public void takeMoney(double value, CommandSender initiator) public void takeMoney(final double value, final CommandSender initiator)
{ {
if (value == 0) if (value == 0)
{ {
@ -131,13 +136,13 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
sendMessage(Util.format("takenFromAccount", Util.formatCurrency(value, ess))); sendMessage(Util.format("takenFromAccount", Util.formatCurrency(value, ess)));
if (initiator != null) if (initiator != null)
{ {
initiator.sendMessage((Util.format("takenFromOthersAccount", Util.formatCurrency(value, ess), this.getDisplayName()))); initiator.sendMessage(Util.format("takenFromOthersAccount", Util.formatCurrency(value, ess), this.getDisplayName()));
} }
} }
public boolean canAfford(double cost) public boolean canAfford(final double cost)
{ {
double mon = getMoney(); final double mon = getMoney();
return mon >= cost || isAuthorized("essentials.eco.loan"); return mon >= cost || isAuthorized("essentials.eco.loan");
} }
@ -151,34 +156,37 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
return justPortaled; return justPortaled;
} }
public void setJustPortaled(boolean value) public void setJustPortaled(final boolean value)
{ {
justPortaled = value; justPortaled = value;
} }
public void setReplyTo(CommandSender user) @Override
public void setReplyTo(final CommandSender user)
{ {
replyTo = user; replyTo = user;
} }
@Override
public CommandSender getReplyTo() public CommandSender getReplyTo()
{ {
return replyTo; return replyTo;
} }
public int compareTo(User t) @Override
public int compareTo(final User other)
{ {
return ChatColor.stripColor(this.getDisplayName()).compareToIgnoreCase(ChatColor.stripColor(t.getDisplayName())); return ChatColor.stripColor(this.getDisplayName()).compareToIgnoreCase(ChatColor.stripColor(other.getDisplayName()));
} }
@Override @Override
public boolean equals(Object o) public boolean equals(final Object object)
{ {
if (!(o instanceof User)) if (!(object instanceof User))
{ {
return false; return false;
} }
return ChatColor.stripColor(this.getDisplayName()).equalsIgnoreCase(ChatColor.stripColor(((User)o).getDisplayName())); return ChatColor.stripColor(this.getDisplayName()).equalsIgnoreCase(ChatColor.stripColor(((User)object).getDisplayName()));
} }
@ -188,7 +196,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
return ChatColor.stripColor(this.getDisplayName()).hashCode(); return ChatColor.stripColor(this.getDisplayName()).hashCode();
} }
public Boolean canSpawnItem(int itemId) public Boolean canSpawnItem(final int itemId)
{ {
return !ess.getSettings().itemSpawnBlacklist().contains(itemId); return !ess.getSettings().itemSpawnBlacklist().contains(itemId);
} }
@ -203,17 +211,18 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
setHome("home", getLocation()); setHome("home", getLocation());
} }
public void setHome(String name) public void setHome(final String name)
{ {
setHome(name, getLocation()); setHome(name, getLocation());
} }
@Override
public void setLastLocation() public void setLastLocation()
{ {
setLastLocation(getLocation()); setLastLocation(getLocation());
} }
public void requestTeleport(User player, boolean here) public void requestTeleport(final User player, final boolean here)
{ {
teleportRequester = player; teleportRequester = player;
teleportRequestHere = here; teleportRequestHere = here;
@ -274,14 +283,14 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
return teleport; return teleport;
} }
public long getLastActivity() public long getLastOnlineActivity()
{ {
return lastActivity; return lastOnlineActivity;
} }
public void setLastActivity(long timestamp) public void setLastOnlineActivity(final long timestamp)
{ {
lastActivity = timestamp; lastOnlineActivity = timestamp;
} }
@Override @Override
@ -291,12 +300,12 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
{ {
try try
{ {
Method method = ess.getPaymentMethod().getMethod(); final Method method = ess.getPaymentMethod().getMethod();
if (!method.hasAccount(this.getName())) if (!method.hasAccount(this.getName()))
{ {
throw new Exception(); throw new Exception();
} }
Method.MethodAccount account = ess.getPaymentMethod().getMethod().getAccount(this.getName()); final Method.MethodAccount account = ess.getPaymentMethod().getMethod().getAccount(this.getName());
return account.balance(); return account.balance();
} }
catch (Throwable ex) catch (Throwable ex)
@ -307,18 +316,18 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
} }
@Override @Override
public void setMoney(double value) public void setMoney(final double value)
{ {
if (ess.getPaymentMethod().hasMethod()) if (ess.getPaymentMethod().hasMethod())
{ {
try try
{ {
Method method = ess.getPaymentMethod().getMethod(); final Method method = ess.getPaymentMethod().getMethod();
if (!method.hasAccount(this.getName())) if (!method.hasAccount(this.getName()))
{ {
throw new Exception(); throw new Exception();
} }
Method.MethodAccount account = ess.getPaymentMethod().getMethod().getAccount(this.getName()); final Method.MethodAccount account = ess.getPaymentMethod().getMethod().getAccount(this.getName());
account.set(value); account.set(value);
} }
catch (Throwable ex) catch (Throwable ex)
@ -329,16 +338,23 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
} }
@Override @Override
public void setAfk(boolean set) public void setAfk(final boolean set)
{ {
this.setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set); this.setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set);
if (set && !isAfk() && ess.getSettings().getFreezeAfkPlayers()) {
godStateBeforeAfk = isGodModeEnabled();
setGodModeEnabled(true);
}
if (!set && isAfk() && ess.getSettings().getFreezeAfkPlayers()) {
setGodModeEnabled(godStateBeforeAfk);
}
super.setAfk(set); super.setAfk(set);
} }
@Override @Override
public boolean toggleAfk() public boolean toggleAfk()
{ {
boolean now = super.toggleAfk(); final boolean now = super.toggleAfk();
this.setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : now); this.setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : now);
return now; return now;
} }
@ -348,7 +364,7 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
return hidden; return hidden;
} }
public void setHidden(boolean hidden) public void setHidden(final boolean hidden)
{ {
this.hidden = hidden; this.hidden = hidden;
} }
@ -389,4 +405,42 @@ public class User extends UserData implements Comparable<User>, IReplyTo, IUser
ess.getBans().unbanByName(getName()); ess.getBans().unbanByName(getName());
} }
} }
public void updateActivity()
{
if (isAfk())
{
setAfk(false);
ess.broadcastMessage(getName(), Util.format("userIsNotAway", getDisplayName()));
return;
}
lastActivity = System.currentTimeMillis();
}
public void checkActivity()
{
final long autoafkkick = ess.getSettings().getAutoAfkKick();
if (autoafkkick > 0 && lastActivity + autoafkkick * 1000 < System.currentTimeMillis()
&& !isAuthorized("essentials.kick.exempt") && !isAuthorized("essentials.afk.kickexempt"))
{
final String kickReason = Util.i18n("autoAfkKickReason");
kickPlayer(kickReason);
for (Player player : ess.getServer().getOnlinePlayers())
{
final User user = ess.getUser(player);
if (user.isAuthorized("essentials.kick.notify"))
{
player.sendMessage(Util.format("playerKicked", Console.NAME, getName(), kickReason));
}
}
}
final long autoafk = ess.getSettings().getAutoAfk();
if (autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis())
{
setAfk(true);
ess.broadcastMessage(getName(), Util.format("userIsAway", getDisplayName()));
}
}
} }

View File

@ -91,7 +91,7 @@ nether:
# Mob limit on spawnmob # Mob limit on spawnmob
spawnmob-limit: 10 spawnmob-limit: 10
#Shall we notify users when using /lightning # Shall we notify users when using /lightning
warn-on-smite: true warn-on-smite: true
# The message of the day, displayed on connect and by typing /motd. # The message of the day, displayed on connect and by typing /motd.
@ -207,7 +207,7 @@ backup:
# Interval in minutes # Interval in minutes
interval: 60 interval: 60
# Add a command that backups your data, e.g. # Add a command that backups your data, e.g.
# command: 'rdiff-backup World1 backups/World1' #command: 'rdiff-backup World1 backups/World1'
# Set this true to enable permission per warp. # Set this true to enable permission per warp.
per-warp-permission: false per-warp-permission: false
@ -223,7 +223,7 @@ debug: false
# Don't forget to remove the # infront of the line # Don't forget to remove the # infront of the line
#locale: de_DE #locale: de_DE
#turn off god mode when people exit # Turn off god mode when people exit
remove-god-on-disconnect: false remove-god-on-disconnect: false
# Use the permission system of bukkit # Use the permission system of bukkit
@ -231,8 +231,27 @@ remove-god-on-disconnect: false
use-bukkit-permissions: false use-bukkit-permissions: false
# Check for updates # Check for updates
# We do not recommend to disable this unless you are using CraftbukkitUpToDate or Bukget.
# If you don't like the notices in game, remove the permission
# essentials.admin.notices.update from your user.
update-check: true update-check: true
# Auto-AFK
# After this timeout in seconds, the user will be set as afk.
# Set to -1 for no timeout.
auto-afk: 300
# Auto-AFK Kick
# After this timeout in seconds, the user will be kicked from the server.
# Set to -1 for no timeout.
auto-afk-kick: -1
# 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.
freeze-afk-player: false
############################################################ ############################################################
# +------------------------------------------------------+ # # +------------------------------------------------------+ #
# | EssentialsHome | # # | EssentialsHome | #
@ -246,7 +265,7 @@ respawn-at-home: false
# If you enable this and remove default user access to the /sethome command, you can make beds the only way for players to set their home location. # If you enable this and remove default user access to the /sethome command, you can make beds the only way for players to set their home location.
bed-sethome: false bed-sethome: false
#if no home is set send you to spawn when /home is used # If no home is set send you to spawn when /home is used
spawn-if-no-home: false spawn-if-no-home: false
# If users have essentials.sethome.multiple how many homes can they have # If users have essentials.sethome.multiple how many homes can they have
@ -289,13 +308,13 @@ economy-log-enabled: false
# +------------------------------------------------------+ # # +------------------------------------------------------+ #
############################################################ ############################################################
#Show other plugins commands in help # Show other plugins commands in help
non-ess-in-help: true non-ess-in-help: true
#Hide plugins which dont give a permission # Hide plugins which dont give a permission
#You can override a true value here for a single plugin by adding a permission to a user/group. # You can override a true value here for a single plugin by adding a permission to a user/group.
#The indervidual permission is: essentials.help.<plugin>, anyone with essentials.* or '*' will see all help this setting reguardless. # The indervidual permission is: essentials.help.<plugin>, anyone with essentials.* or '*' will see all help this setting reguardless.
#You can use negitive permissions to remove access to just a single plugins help if the following is enabled. # You can use negitive permissions to remove access to just a single plugins help if the following is enabled.
hide-permissionless-help: true hide-permissionless-help: true
############################################################ ############################################################
@ -427,10 +446,10 @@ protect:
# This only has an effect if "rails" or "signs" is also enabled. # This only has an effect if "rails" or "signs" is also enabled.
block-below: true block-below: true
# Prevent placing blocks above protected rails, this is to stop a potential griefing # Prevent placing blocks above protected rails, this is to stop a potential griefing
prevent-block-on-rails: false prevent-block-on-rails: false
#Store blocks / signs in memory before writing # Store blocks / signs in memory before writing
memstore: false memstore: false
# Disable various default physics and behaviors # Disable various default physics and behaviors
@ -470,11 +489,11 @@ protect:
# Set true to disable useing for those people # Set true to disable useing for those people
use: true use: true
#Should we tell people they are not allowed to build # Should we tell people they are not allowed to build
warn-on-build-disallow: false warn-on-build-disallow: false
#disable weather options # Disable weather options
weather: weather:
storm: false storm: false
thunder: false thunder: false