TFM-4.3-Reloaded/src/main/java/me/StevenLawson/TotalFreedomMod/admin/AdminList.java

693 lines
20 KiB
Java

package me.StevenLawson.TotalFreedomMod.admin;
import com.google.common.base.Function;
import com.google.common.collect.Sets;
import me.StevenLawson.TotalFreedomMod.Log;
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod;
import me.StevenLawson.TotalFreedomMod.commands.Command_logs;
import me.StevenLawson.TotalFreedomMod.config.Configuration;
import me.StevenLawson.TotalFreedomMod.config.ConfigurationEntry;
import me.StevenLawson.TotalFreedomMod.config.MainConfig;
import me.StevenLawson.TotalFreedomMod.deprecated.twitter.TwitterHandler;
import me.StevenLawson.TotalFreedomMod.discord.sender.DiscordCommandSender;
import me.StevenLawson.TotalFreedomMod.player.PlayerRank;
import me.StevenLawson.TotalFreedomMod.player.UUIDManager;
import me.StevenLawson.TotalFreedomMod.util.Utilities;
import me.StevenLawson.TotalFreedomMod.world.AdminWorld;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
public class AdminList
{
public static final Function<Player, Boolean> SUPERADMIN_SERVICE;
private static final Map<UUID, Admin> adminList;
private static final Set<UUID> superUUIDs;
private static final Set<UUID> telnetUUIDs;
private static final Set<UUID> seniorUUIDs;
private static final Set<String> seniorConsoleNames;
private static final Set<String> superIps;
private static int cleanThreshold = 24 * 7; // 1 Week in hours
static
{
adminList = new HashMap<UUID, Admin>();
superUUIDs = new HashSet<UUID>();
telnetUUIDs = new HashSet<UUID>();
seniorUUIDs = new HashSet<UUID>();
seniorConsoleNames = new HashSet<String>();
superIps = new HashSet<String>();
SUPERADMIN_SERVICE = new Function<Player, Boolean>()
{
@Override
public Boolean apply(Player f)
{
return isSuperAdmin(f);
}
};
}
private AdminList()
{
throw new AssertionError();
}
public static Set<UUID> getSuperUUIDs()
{
return Collections.unmodifiableSet(superUUIDs);
}
public static Set<UUID> getTelnetUUIDs()
{
return Collections.unmodifiableSet(telnetUUIDs);
}
public static Set<UUID> getSeniorUUIDs()
{
return Collections.unmodifiableSet(seniorUUIDs);
}
public static Set<String> getSeniorConsoleNames()
{
return Collections.unmodifiableSet(seniorConsoleNames);
}
public static Set<String> getSuperadminIps()
{
return Collections.unmodifiableSet(superIps);
}
public static Set<Admin> getAllAdmins()
{
return Sets.newHashSet(adminList.values());
}
public static Set<String> getSuperNames()
{
final Set<String> names = new HashSet<String>();
for (Admin admin : adminList.values())
{
if (!admin.isActivated())
{
continue;
}
names.add(admin.getLastLoginName());
}
return Collections.unmodifiableSet(names);
}
public static Set<String> getLowercaseSuperNames()
{
final Set<String> names = new HashSet<String>();
for (Admin admin : adminList.values())
{
if (!admin.isActivated())
{
continue;
}
names.add(admin.getLastLoginName().toLowerCase());
}
return Collections.unmodifiableSet(names);
}
public static void setUuid(Admin admin, UUID oldUuid, UUID newUuid)
{
if (!adminList.containsKey(oldUuid))
{
Log.warning("Could not set new UUID for admin " + admin.getLastLoginName() + ", admin is not loaded!");
return;
}
if (oldUuid.equals(newUuid))
{
Log.warning("could not set new UUID for admin " + admin.getLastLoginName() + ", UUIDs match.");
return;
}
// Add new entry
final Admin newAdmin = new Admin(
newUuid,
admin.getLastLoginName(),
admin.getLastLogin(),
admin.getCustomLoginMessage(),
admin.isTelnetAdmin(),
admin.isSeniorAdmin(),
admin.isActivated());
newAdmin.addIps(admin.getIps());
adminList.put(newUuid, newAdmin);
save(newAdmin);
// Remove old entry
adminList.remove(oldUuid);
final Configuration config = new Configuration(TotalFreedomMod.plugin, TotalFreedomMod.SUPERADMIN_FILENAME, true);
config.load();
config.set("admins." + oldUuid, null);
config.save();
}
public static void load()
{
adminList.clear();
final Configuration config = new Configuration(TotalFreedomMod.plugin, TotalFreedomMod.SUPERADMIN_FILENAME, true);
config.load();
cleanThreshold = config.getInt("clean_threshold_hours", cleanThreshold);
// Parse old superadmins
if (config.isConfigurationSection("superadmins"))
{
parseOldConfig(config);
}
if (!config.isConfigurationSection("admins"))
{
Log.warning("Missing admins section in superadmin.yml.");
return;
}
final ConfigurationSection section = config.getConfigurationSection("admins");
for (String uuidString : section.getKeys(false))
{
if (!Utilities.isUniqueId(uuidString))
{
Log.warning("Invalid Unique ID: " + uuidString + " in superadmin.yml, ignoring");
continue;
}
final UUID uuid = UUID.fromString(uuidString);
final Admin superadmin = new Admin(uuid, section.getConfigurationSection(uuidString));
adminList.put(uuid, superadmin);
}
updateIndexLists();
Log.info("Loaded " + adminList.size() + " admins (" + superUUIDs.size() + " active) and " + superIps.size() + " IPs.");
}
public static void updateIndexLists()
{
superUUIDs.clear();
telnetUUIDs.clear();
seniorUUIDs.clear();
seniorConsoleNames.clear();
superIps.clear();
for (Admin admin : adminList.values())
{
if (!admin.isActivated())
{
continue;
}
final UUID uuid = admin.getUniqueId();
superUUIDs.add(uuid);
for (String ip : admin.getIps())
{
superIps.add(ip);
}
if (admin.isTelnetAdmin())
{
telnetUUIDs.add(uuid);
}
if (admin.isSeniorAdmin())
{
seniorUUIDs.add(uuid);
seniorConsoleNames.add(admin.getLastLoginName());
for (String alias : admin.getConsoleAliases())
{
seniorConsoleNames.add(alias.toLowerCase());
}
}
}
AdminWorld.getInstance().wipeAccessCache();
}
private static void parseOldConfig(Configuration config)
{
Log.info("Old superadmin configuration found, parsing...");
final ConfigurationSection section = config.getConfigurationSection("superadmins");
int counter = 0;
int errors = 0;
for (String admin : config.getConfigurationSection("superadmins").getKeys(false))
{
final UUID uuid = UUIDManager.getUniqueId(admin);
if (uuid == null)
{
errors++;
Log.warning("Could not convert admin " + admin + ", UUID could not be found!");
continue;
}
config.set("admins." + uuid + ".last_login_name", uuid);
config.set("admins." + uuid + ".is_activated", section.getBoolean(admin + ".is_activated"));
config.set("admins." + uuid + ".is_telnet_admin", section.getBoolean(admin + ".is_telnet_admin"));
config.set("admins." + uuid + ".is_senior_admin", section.getBoolean(admin + ".is_senior_admin"));
config.set("admins." + uuid + ".last_login", section.getString(admin + ".last_login"));
config.set("admins." + uuid + ".custom_login_message", section.getString(admin + ".custom_login_message"));
config.set("admins." + uuid + ".console_aliases", section.getStringList(admin + ".console_aliases"));
config.set("admins." + uuid + ".ips", section.getStringList(admin + ".ips"));
counter++;
}
config.set("superadmins", null);
config.save();
Log.info("Done! " + counter + " admins parsed, " + errors + " errors");
}
public static void saveAll()
{
final Configuration config = new Configuration(TotalFreedomMod.plugin, TotalFreedomMod.SUPERADMIN_FILENAME, true);
config.load();
config.set("clean_threshold_hours", cleanThreshold);
final Iterator<Entry<UUID, Admin>> it = adminList.entrySet().iterator();
while (it.hasNext())
{
final Entry<UUID, Admin> pair = it.next();
final UUID uuid = pair.getKey();
final Admin superadmin = pair.getValue();
config.set("admins." + uuid + ".last_login_name", superadmin.getLastLoginName());
config.set("admins." + uuid + ".is_activated", superadmin.isActivated());
config.set("admins." + uuid + ".is_telnet_admin", superadmin.isTelnetAdmin());
config.set("admins." + uuid + ".is_senior_admin", superadmin.isSeniorAdmin());
config.set("admins." + uuid + ".last_login", Utilities.dateToString(superadmin.getLastLogin()));
config.set("admins." + uuid + ".custom_login_message", superadmin.getCustomLoginMessage());
config.set("admins." + uuid + ".console_aliases", Utilities.removeDuplicates(superadmin.getConsoleAliases()));
config.set("admins." + uuid + ".ips", Utilities.removeDuplicates(superadmin.getIps()));
}
config.save();
}
public static void save(Admin admin)
{
if (!adminList.containsValue(admin))
{
Log.warning("Could not save admin " + admin.getLastLoginName() + ", admin is not loaded!");
return;
}
final Configuration config = new Configuration(TotalFreedomMod.plugin, TotalFreedomMod.SUPERADMIN_FILENAME, true);
config.load();
final UUID uuid = admin.getUniqueId();
config.set("admins." + uuid + ".last_login_name", admin.getLastLoginName());
config.set("admins." + uuid + ".is_activated", admin.isActivated());
config.set("admins." + uuid + ".is_telnet_admin", admin.isTelnetAdmin());
config.set("admins." + uuid + ".is_senior_admin", admin.isSeniorAdmin());
config.set("admins." + uuid + ".last_login", Utilities.dateToString(admin.getLastLogin()));
config.set("admins." + uuid + ".custom_login_message", admin.getCustomLoginMessage());
config.set("admins." + uuid + ".console_aliases", Utilities.removeDuplicates(admin.getConsoleAliases()));
config.set("admins." + uuid + ".ips", Utilities.removeDuplicates(admin.getIps()));
config.save();
}
public static Admin getEntry(Player player)
{
return getEntry(UUIDManager.getUniqueId(player));
}
public static Admin getEntry(UUID uuid)
{
return adminList.get(uuid);
}
@Deprecated
public static Admin getEntry(String name)
{
for (UUID uuid : adminList.keySet())
{
if (adminList.get(uuid).getLastLoginName().equalsIgnoreCase(name))
{
return adminList.get(uuid);
}
}
return null;
}
public static Admin getEntryByIp(String ip)
{
return getEntryByIp(ip, false);
}
public static Admin getEntryByIp(String needleIp, boolean fuzzy)
{
Iterator<Entry<UUID, Admin>> it = adminList.entrySet().iterator();
while (it.hasNext())
{
final Entry<UUID, Admin> pair = it.next();
final Admin superadmin = pair.getValue();
if (fuzzy)
{
for (String haystackIp : superadmin.getIps())
{
if (Utilities.fuzzyIpMatch(needleIp, haystackIp, 3))
{
return superadmin;
}
}
}
else
{
if (superadmin.getIps().contains(needleIp))
{
return superadmin;
}
}
}
return null;
}
public static void updateLastLogin(Player player)
{
final Admin admin = getEntry(player);
if (admin == null)
{
return;
}
admin.setLastLogin(new Date());
admin.setLastLoginName(player.getName());
saveAll();
}
public static boolean isSuperAdminSafe(UUID uuid, String ip)
{
if (TotalFreedomMod.server.getOnlineMode() && uuid != null)
{
return AdminList.getSuperUUIDs().contains(uuid);
}
final Admin admin = AdminList.getEntryByIp(ip);
return admin != null && admin.isActivated();
}
public static synchronized boolean isSuperAdminSync(CommandSender sender)
{
return isSuperAdmin(sender);
}
public static boolean isSuperAdmin(CommandSender sender)
{
if (!(sender instanceof Player))
{
return true;
}
final Player player = (Player) sender;
if (superIps.contains(Utilities.getIp(player)))
{
return true;
}
return Bukkit.getOnlineMode() && superUUIDs.contains(UUIDManager.getUniqueId(player));
}
public static boolean isTelnetAdmin(CommandSender sender, boolean verifySuperadmin)
{
if (verifySuperadmin)
{
if (!isSuperAdmin(sender))
{
return false;
}
}
if (!(sender instanceof Player))
{
return true;
}
final Admin entry = getEntry((Player) sender);
if (entry != null)
{
return entry.isTelnetAdmin();
}
return false;
}
public static boolean isSeniorAdmin(CommandSender sender)
{
return isSeniorAdmin(sender, false);
}
public static boolean isSeniorAdmin(CommandSender sender, boolean verifySuperadmin)
{
if (verifySuperadmin)
{
if (!isSuperAdmin(sender))
{
return false;
}
}
if (!(sender instanceof Player))
{
return seniorConsoleNames.contains(sender.getName())
|| (MainConfig.getBoolean(ConfigurationEntry.CONSOLE_IS_SENIOR) && sender.getName().equals("CONSOLE"));
}
if(sender instanceof DiscordCommandSender) {
PlayerRank rank = PlayerRank.fromSender(sender);
if(rank.equals(PlayerRank.SENIOR)) {
return true;
}
}
final Admin entry = getEntry((Player) sender);
if (entry != null)
{
return entry.isSeniorAdmin();
}
return false;
}
public static boolean isIdentityMatched(Player player)
{
if (!isSuperAdmin(player))
{
return false;
}
if (Bukkit.getOnlineMode())
{
return true;
}
final Admin entry = getEntry(player);
if (entry == null)
{
return false;
}
return entry.getUniqueId().equals(UUIDManager.getUniqueId(player));
}
@Deprecated
public static boolean checkPartialSuperadminIp(String ip, String name)
{
ip = ip.trim();
if (superIps.contains(ip))
{
return true;
}
try
{
String matchIp = null;
for (String testIp : superIps)
{
if (Utilities.fuzzyIpMatch(ip, testIp, 3))
{
matchIp = testIp;
break;
}
}
if (matchIp != null)
{
final Admin entry = getEntryByIp(matchIp);
if (entry == null)
{
return true;
}
if (entry.getLastLoginName().equalsIgnoreCase(name))
{
if (!entry.getIps().contains(ip))
{
entry.addIp(ip);
}
saveAll();
}
return true;
}
}
catch (Exception ex)
{
Log.severe(ex);
}
return false;
}
public static boolean isAdminImpostor(Player player)
{
if (superUUIDs.contains(UUIDManager.getUniqueId(player)))
{
return !isSuperAdmin(player);
}
return false;
}
public static void addSuperadmin(OfflinePlayer player)
{
final UUID uuid = UUIDManager.getUniqueId(player);
final String ip = Utilities.getIp(player);
final boolean canSuperIp = !MainConfig.getList(ConfigurationEntry.NOADMIN_IPS).contains(ip);
if (adminList.containsKey(uuid))
{
final Admin superadmin = adminList.get(uuid);
superadmin.setActivated(true);
if (player.isOnline())
{
superadmin.setLastLogin(new Date());
if (ip != null && canSuperIp)
{
superadmin.addIp(ip);
}
}
saveAll();
updateIndexLists();
return;
}
if (ip == null)
{
Log.severe("Could not add superadmin: " + Utilities.formatPlayer(player));
Log.severe("Could not retrieve IP!");
return;
}
if (!canSuperIp)
{
Log.warning("Could not add superadmin: " + Utilities.formatPlayer(player));
Log.warning("IP " + ip + " may not be supered.");
return;
}
final Admin superadmin = new Admin(
uuid,
player.getName(),
new Date(),
"",
false,
false,
true);
superadmin.addIp(ip);
adminList.put(uuid, superadmin);
saveAll();
updateIndexLists();
}
public static void removeSuperadmin(OfflinePlayer player)
{
final UUID uuid = UUIDManager.getUniqueId(player);
if (!adminList.containsKey(uuid))
{
Log.warning("Could not remove admin: " + Utilities.formatPlayer(player));
Log.warning("Player is not an admin!");
return;
}
final Admin superadmin = adminList.get(uuid);
superadmin.setActivated(false);
Command_logs.deactivateSuperadmin(superadmin);
saveAll();
updateIndexLists();
}
public static void cleanSuperadminList(boolean verbose)
{
Iterator<Entry<UUID, Admin>> it = adminList.entrySet().iterator();
while (it.hasNext())
{
final Entry<UUID, Admin> pair = it.next();
final Admin superadmin = pair.getValue();
if (!superadmin.isActivated() || superadmin.isSeniorAdmin())
{
continue;
}
final Date lastLogin = superadmin.getLastLogin();
final long lastLoginHours = TimeUnit.HOURS.convert(new Date().getTime() - lastLogin.getTime(), TimeUnit.MILLISECONDS);
if (lastLoginHours > cleanThreshold)
{
if (verbose)
{
Utilities.adminAction("TotalFreedomMod", "Deactivating superadmin " + superadmin.getLastLoginName() + ", inactive for " + lastLoginHours + " hours.", true);
}
superadmin.setActivated(false);
Command_logs.deactivateSuperadmin(superadmin);
TwitterHandler.delTwitter(superadmin.getLastLoginName());
}
}
saveAll();
updateIndexLists();
}
}