mirror of
https://github.com/AtlasMediaGroup/TotalFreedomMod.git
synced 2025-06-29 11:46:40 +00:00
Mavenized project
This commit is contained in:
260
src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java
Normal file
260
src/main/java/me/totalfreedom/totalfreedommod/banning/Ban.java
Normal file
@ -0,0 +1,260 @@
|
||||
package me.totalfreedom.totalfreedommod.banning;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
||||
import net.pravian.aero.base.ConfigLoadable;
|
||||
import net.pravian.aero.base.ConfigSavable;
|
||||
import net.pravian.aero.base.Validatable;
|
||||
import net.pravian.aero.util.Ips;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class Ban implements ConfigLoadable, ConfigSavable, Validatable
|
||||
{
|
||||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z");
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String username = null;
|
||||
@Getter
|
||||
private final List<String> ips = Lists.newArrayList();
|
||||
@Getter
|
||||
@Setter
|
||||
private String by = null;
|
||||
@Getter
|
||||
@Setter
|
||||
private String reason = null; // Unformatted, &[0-9,a-f] instead of ChatColor
|
||||
@Getter
|
||||
@Setter
|
||||
private long expiryUnix = -1;
|
||||
|
||||
public Ban()
|
||||
{
|
||||
}
|
||||
|
||||
public Ban(String username, String ip, String by, Date expire, String reason)
|
||||
{
|
||||
this(username,
|
||||
new String[]
|
||||
{
|
||||
ip
|
||||
},
|
||||
by,
|
||||
expire,
|
||||
reason);
|
||||
}
|
||||
|
||||
public Ban(String username, String[] ips, String by, Date expire, String reason)
|
||||
{
|
||||
this.username = username;
|
||||
if (ips != null)
|
||||
{
|
||||
this.ips.addAll(Arrays.asList(ips));
|
||||
}
|
||||
this.by = by;
|
||||
this.expiryUnix = FUtil.getUnixTime(expire);
|
||||
}
|
||||
|
||||
//
|
||||
// For player IP
|
||||
public static Ban forPlayerIp(Player player, CommandSender by)
|
||||
{
|
||||
return forPlayerIp(player, by, null, null);
|
||||
}
|
||||
|
||||
public static Ban forPlayerIp(Player player, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return new Ban(null, new String[]
|
||||
{
|
||||
Ips.getIp(player)
|
||||
}, by.getName(), expiry, reason);
|
||||
}
|
||||
|
||||
public static Ban forPlayerIp(String ip, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return new Ban(null, ip, by.getName(), expiry, reason);
|
||||
}
|
||||
|
||||
//
|
||||
// For player name
|
||||
public static Ban forPlayerName(Player player, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return forPlayerName(player.getName(), by, expiry, reason);
|
||||
}
|
||||
|
||||
public static Ban forPlayerName(String player, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return new Ban(player,
|
||||
(String[]) null,
|
||||
by.getName(),
|
||||
expiry,
|
||||
reason);
|
||||
}
|
||||
|
||||
//
|
||||
// For player
|
||||
public static Ban forPlayer(Player player, CommandSender by)
|
||||
{
|
||||
return forPlayerName(player, by, null, null);
|
||||
}
|
||||
|
||||
public static Ban forPlayer(Player player, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return new Ban(player.getName(),
|
||||
Ips.getIp(player),
|
||||
by.getName(),
|
||||
expiry,
|
||||
reason);
|
||||
}
|
||||
|
||||
public static Ban forPlayerFuzzy(Player player, CommandSender by, Date expiry, String reason)
|
||||
{
|
||||
return new Ban(player.getName(),
|
||||
FUtil.getFuzzyIp(Ips.getIp(player)),
|
||||
by.getName(),
|
||||
expiry,
|
||||
reason);
|
||||
}
|
||||
|
||||
public boolean hasUsername()
|
||||
{
|
||||
return username != null && !username.isEmpty();
|
||||
}
|
||||
|
||||
public boolean addIp(String ip)
|
||||
{
|
||||
return ips.add(ip);
|
||||
}
|
||||
|
||||
public boolean removeIp(String ip)
|
||||
{
|
||||
return ips.remove(ip);
|
||||
}
|
||||
|
||||
public boolean hasIps()
|
||||
{
|
||||
return !ips.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasExpiry()
|
||||
{
|
||||
return expiryUnix > 0;
|
||||
}
|
||||
|
||||
public Date getExpiryDate()
|
||||
{
|
||||
return FUtil.getUnixDate(expiryUnix);
|
||||
}
|
||||
|
||||
public boolean isExpired()
|
||||
{
|
||||
return hasExpiry() && expiryUnix < FUtil.getUnixTime();
|
||||
}
|
||||
|
||||
public String bakeKickMessage()
|
||||
{
|
||||
final StringBuilder message = new StringBuilder(ChatColor.GOLD + "You");
|
||||
|
||||
message.append(!hasUsername() ? "r IP address is" : " are").append(" temporarily banned from this server.");
|
||||
message.append("\nAppeal at ").append(ChatColor.BLUE)
|
||||
.append(ConfigEntry.SERVER_BAN_URL.getString());
|
||||
|
||||
if (reason != null)
|
||||
{
|
||||
message.append("\n").append(ChatColor.RED).append("Reason: ").append(ChatColor.GOLD)
|
||||
.append(ChatColor.translateAlternateColorCodes('&', reason));
|
||||
}
|
||||
|
||||
if (by != null)
|
||||
{
|
||||
message.append("\n").append(ChatColor.RED).append("Banned by: ").append(ChatColor.GOLD)
|
||||
.append(by);
|
||||
}
|
||||
|
||||
if (getExpiryUnix() != 0)
|
||||
{
|
||||
message.append("\n").append(ChatColor.RED).append("Expires: ").append(ChatColor.GOLD)
|
||||
.append(DATE_FORMAT.format(FUtil.getUnixDate(expiryUnix)));
|
||||
}
|
||||
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(object instanceof Ban))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Ban ban = (Ban) object;
|
||||
if (hasIps() != ban.hasIps()
|
||||
|| hasUsername() != hasUsername())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasIps() && !(getIps().equals(ban.getIps())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasUsername() && !(getUsername().equalsIgnoreCase(ban.getUsername())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 7;
|
||||
hash = 79 * hash + (this.username != null ? this.username.toLowerCase().hashCode() : 0);
|
||||
hash = 79 * hash + (this.ips != null ? this.ips.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFrom(ConfigurationSection cs)
|
||||
{
|
||||
this.username = cs.getString("username", null);
|
||||
this.ips.clear();
|
||||
this.ips.addAll(cs.getStringList("ips"));
|
||||
this.by = cs.getString("by", null);
|
||||
this.reason = cs.getString("reason", null);
|
||||
this.expiryUnix = cs.getLong("expiry_unix", -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveTo(ConfigurationSection cs)
|
||||
{
|
||||
cs.set("username", username);
|
||||
cs.set("ips", ips.isEmpty() ? null : ips);
|
||||
cs.set("by", by);
|
||||
cs.set("reason", reason);
|
||||
cs.set("expiry_unix", expiryUnix > 0 ? expiryUnix : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return username != null || !ips.isEmpty();
|
||||
}
|
||||
}
|
@ -0,0 +1,304 @@
|
||||
package me.totalfreedom.totalfreedommod.banning;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
||||
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
||||
import net.pravian.aero.component.service.AbstractService;
|
||||
import net.pravian.aero.config.YamlConfig;
|
||||
import net.pravian.aero.util.Ips;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
|
||||
public class BanManager extends AbstractService<TotalFreedomMod>
|
||||
{
|
||||
private final Set<Ban> bans = Sets.newHashSet();
|
||||
private final Map<String, Ban> ipBans = Maps.newHashMap();
|
||||
private final Map<String, Ban> nameBans = Maps.newHashMap();
|
||||
private final List<String> unbannableUsernames = Lists.newArrayList();
|
||||
//
|
||||
private final YamlConfig config;
|
||||
|
||||
public BanManager(TotalFreedomMod plugin)
|
||||
{
|
||||
super(plugin);
|
||||
this.config = new YamlConfig(TotalFreedomMod.plugin, "bans.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
saveAll();
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
config.load();
|
||||
|
||||
bans.clear();
|
||||
for (String id : config.getKeys(false))
|
||||
{
|
||||
if (!config.isConfigurationSection(id))
|
||||
{
|
||||
FLog.warning("Could not load username ban: " + id + ". Invalid format!");
|
||||
continue;
|
||||
}
|
||||
|
||||
Ban ban = new Ban();
|
||||
ban.loadFrom(config.getConfigurationSection(id));
|
||||
|
||||
if (!ban.isValid())
|
||||
{
|
||||
FLog.warning("Not adding username ban: " + id + ". Missing information.");
|
||||
continue;
|
||||
}
|
||||
|
||||
bans.add(ban);
|
||||
}
|
||||
|
||||
// Remove expired bans, repopulate ipBans and nameBans,
|
||||
updateViews();
|
||||
|
||||
FLog.info("Loaded " + ipBans.size() + " IP bans and " + nameBans.size() + " username bans");
|
||||
|
||||
// Load unbannable usernames
|
||||
unbannableUsernames.clear();
|
||||
unbannableUsernames.addAll((Collection<? extends String>) ConfigEntry.UNBANNABLE_USERNAMES.getList());
|
||||
FLog.info("Loaded " + unbannableUsernames.size() + " unbannable usernames.");
|
||||
|
||||
}
|
||||
|
||||
private void updateViews()
|
||||
{
|
||||
|
||||
// Remove expired bans
|
||||
for (Iterator<Ban> it = bans.iterator(); it.hasNext();)
|
||||
{
|
||||
if (it.next().isExpired())
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
ipBans.clear();
|
||||
nameBans.clear();
|
||||
for (Ban ban : bans)
|
||||
{
|
||||
if (ban.hasUsername())
|
||||
{
|
||||
nameBans.put(ban.getUsername().toLowerCase(), ban);
|
||||
}
|
||||
|
||||
if (ban.hasIps())
|
||||
{
|
||||
for (String ip : ban.getIps())
|
||||
{
|
||||
ipBans.put(ip, ban);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAll()
|
||||
{
|
||||
// Remove expired
|
||||
updateViews();
|
||||
|
||||
for (Ban ban : bans)
|
||||
{
|
||||
ban.saveTo(config.createSection(String.valueOf(ban.hashCode())));
|
||||
}
|
||||
|
||||
// Save config
|
||||
config.save();
|
||||
}
|
||||
|
||||
public Collection<Ban> getIpBans()
|
||||
{
|
||||
return Collections.unmodifiableCollection(ipBans.values());
|
||||
}
|
||||
|
||||
public Collection<Ban> getUsernameBans()
|
||||
{
|
||||
return Collections.unmodifiableCollection(nameBans.values());
|
||||
}
|
||||
|
||||
public Ban getByIp(String ip)
|
||||
{
|
||||
final Ban directBan = ipBans.get(ip);
|
||||
if (directBan != null && !directBan.isExpired())
|
||||
{
|
||||
return directBan;
|
||||
}
|
||||
|
||||
// Match fuzzy IP
|
||||
for (Ban loopBan : ipBans.values())
|
||||
{
|
||||
if (loopBan.isExpired())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (String loopIp : loopBan.getIps())
|
||||
{
|
||||
if (!loopIp.contains("*"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Ips.fuzzyIpMatch(ip, loopIp, 4))
|
||||
{
|
||||
return loopBan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Ban getByUsername(String username)
|
||||
{
|
||||
username = username.toLowerCase();
|
||||
final Ban directBan = nameBans.get(username);
|
||||
|
||||
if (directBan != null && !directBan.isExpired())
|
||||
{
|
||||
return directBan;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Ban unbanIp(String ip)
|
||||
{
|
||||
final Ban ban = getByIp(ip);
|
||||
|
||||
if (ban == null)
|
||||
{
|
||||
return ban;
|
||||
}
|
||||
|
||||
bans.remove(ban);
|
||||
saveAll();
|
||||
return ban;
|
||||
}
|
||||
|
||||
public Ban unbanUsername(String username)
|
||||
{
|
||||
final Ban ban = getByUsername(username);
|
||||
|
||||
if (ban == null)
|
||||
{
|
||||
return ban;
|
||||
}
|
||||
|
||||
bans.remove(ban);
|
||||
saveAll();
|
||||
return ban;
|
||||
}
|
||||
|
||||
public boolean isIpBanned(String ip)
|
||||
{
|
||||
return getByIp(ip) != null;
|
||||
}
|
||||
|
||||
public boolean isUsernameBanned(String username)
|
||||
{
|
||||
return getByUsername(username) != null;
|
||||
}
|
||||
|
||||
public boolean addBan(Ban ban)
|
||||
{
|
||||
if (bans.add(ban))
|
||||
{
|
||||
updateViews();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeBan(Ban ban)
|
||||
{
|
||||
if (bans.remove(ban))
|
||||
{
|
||||
updateViews();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void purgeIpBans()
|
||||
{
|
||||
ipBans.clear();
|
||||
saveAll();
|
||||
}
|
||||
|
||||
public void purgeNameBans()
|
||||
{
|
||||
nameBans.clear();
|
||||
saveAll();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerLogin(PlayerLoginEvent event)
|
||||
{
|
||||
final String username = event.getPlayer().getName();
|
||||
final String ip = Ips.getIp(event);
|
||||
|
||||
// Regular ban
|
||||
Ban ban = plugin.bm.getByUsername(username);
|
||||
if (ban == null)
|
||||
{
|
||||
ban = plugin.bm.getByIp(ip);
|
||||
}
|
||||
|
||||
if (ban != null)
|
||||
{
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, ban.bakeKickMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerJoin(PlayerJoinEvent event)
|
||||
{
|
||||
final Player player = event.getPlayer();
|
||||
final PlayerData data = plugin.pl.getData(player);
|
||||
|
||||
if (!plugin.al.isAdmin(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Unban admins
|
||||
for (String storedIp : data.getIps())
|
||||
{
|
||||
unbanIp(storedIp);
|
||||
unbanIp(FUtil.getFuzzyIp(storedIp));
|
||||
}
|
||||
|
||||
unbanUsername(player.getName());
|
||||
player.setOp(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package me.totalfreedom.totalfreedommod.banning;
|
||||
|
||||
import me.totalfreedom.totalfreedommod.util.FLog;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.Set;
|
||||
import lombok.Getter;
|
||||
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
||||
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
||||
import me.totalfreedom.totalfreedommod.config.FConfig;
|
||||
import me.totalfreedom.totalfreedommod.util.FUtil;
|
||||
import net.pravian.aero.component.service.AbstractService;
|
||||
import net.pravian.aero.util.Ips;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
|
||||
public class PermbanList extends AbstractService<TotalFreedomMod>
|
||||
{
|
||||
@Getter
|
||||
private final Set<String> permbannedNames = Sets.newHashSet();
|
||||
@Getter
|
||||
private final Set<String> permbannedIps = Sets.newHashSet();
|
||||
|
||||
public PermbanList(TotalFreedomMod plugin)
|
||||
{
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart()
|
||||
{
|
||||
permbannedNames.clear();
|
||||
permbannedIps.clear();
|
||||
|
||||
final FConfig config = new FConfig(TotalFreedomMod.plugin, TotalFreedomMod.PERMBAN_FILENAME, true);
|
||||
config.load();
|
||||
|
||||
for (String name : config.getKeys(false))
|
||||
{
|
||||
permbannedNames.add(name.toLowerCase().trim());
|
||||
permbannedIps.addAll(config.getStringList(name));
|
||||
}
|
||||
|
||||
FLog.info("Loaded " + permbannedNames.size() + " permanently banned usernames and " + permbannedIps.size() + " permanently banned IPs.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent event)
|
||||
{
|
||||
final String username = event.getPlayer().getName();
|
||||
final String ip = Ips.getIp(event);
|
||||
|
||||
// Permbanned IPs
|
||||
for (String testIp : getPermbannedIps())
|
||||
{
|
||||
if (FUtil.fuzzyIpMatch(testIp, ip, 4))
|
||||
{
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
|
||||
ChatColor.RED + "Your IP address is permanently banned from this server.\n"
|
||||
+ "Release procedures are available at\n"
|
||||
+ ChatColor.GOLD + ConfigEntry.SERVER_PERMBAN_URL.getString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Permbanned usernames
|
||||
for (String testPlayer : getPermbannedNames())
|
||||
{
|
||||
if (testPlayer.equalsIgnoreCase(username))
|
||||
{
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
|
||||
ChatColor.RED + "Your username is permanently banned from this server.\n"
|
||||
+ "Release procedures are available at\n"
|
||||
+ ChatColor.GOLD + ConfigEntry.SERVER_PERMBAN_URL.getString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user