[Bleeding] Started work on TFM_PlayerList

Added UUIDFetcher
This commit is contained in:
unknown 2014-04-04 16:48:39 +02:00
parent d087dc1148
commit 6365672eda
11 changed files with 506 additions and 252 deletions

View File

@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit!
#Fri Apr 04 13:44:56 CEST 2014
build.number=707
#Fri Apr 04 16:47:53 CEST 2014
build.number=708

View File

@ -0,0 +1,94 @@
package com.evilmidget38;
import com.google.common.collect.ImmutableList;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
public class UUIDFetcher implements Callable<Map<String, UUID>>
{
private static final int MAX_SEARCH = 100;
private static final String PROFILE_URL = "https://api.mojang.com/profiles/page/";
private static final String AGENT = "minecraft";
private final JSONParser jsonParser = new JSONParser();
private final List<String> names;
public UUIDFetcher(List<String> names)
{
this.names = ImmutableList.copyOf(names);
}
@Override
public Map<String, UUID> call() throws Exception
{
Map<String, UUID> uuidMap = new HashMap<String, UUID>();
String body = buildBody(names);
for (int i = 1; i < MAX_SEARCH; i++)
{
HttpURLConnection connection = createConnection(i);
writeBody(connection, body);
JSONObject jsonObject = (JSONObject) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
JSONArray array = (JSONArray) jsonObject.get("profiles");
Number count = (Number) jsonObject.get("size");
if (count.intValue() == 0)
{
break;
}
for (Object profile : array)
{
JSONObject jsonProfile = (JSONObject) profile;
String id = (String) jsonProfile.get("id");
String name = (String) jsonProfile.get("name");
UUID uuid = UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
uuidMap.put(name, uuid);
}
}
return uuidMap;
}
private static void writeBody(HttpURLConnection connection, String body) throws Exception
{
DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
writer.write(body.getBytes());
writer.flush();
writer.close();
}
private static HttpURLConnection createConnection(int page) throws Exception
{
URL url = new URL(PROFILE_URL + page);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
return connection;
}
@SuppressWarnings("unchecked")
private static String buildBody(List<String> names)
{
List<JSONObject> lookups = new ArrayList<JSONObject>();
for (String name : names)
{
JSONObject obj = new JSONObject();
obj.put("name", name);
obj.put("agent", AGENT);
lookups.add(obj);
}
return JSONValue.toJSONString(lookups);
}
}

View File

@ -1,6 +1,6 @@
package me.StevenLawson.TotalFreedomMod.Commands;
import me.StevenLawson.TotalFreedomMod.TFM_UserList;
import me.StevenLawson.TotalFreedomMod.TFM_PlayerList;
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod;
import net.minecraft.util.org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
@ -30,7 +30,7 @@ public class Command_findip extends TFM_Command
return true;
}
playerMsg("Player IPs: " + StringUtils.join(TFM_UserList.getInstance().getEntry(player).getIpAddresses(), ", "));
playerMsg("Player IPs: " + StringUtils.join(TFM_PlayerList.getInstance().getEntry(player).getIps(), ", "));
return true;
}

View File

@ -4,8 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import me.StevenLawson.TotalFreedomMod.TFM_ServerInterface;
import me.StevenLawson.TotalFreedomMod.TFM_SuperadminList;
import me.StevenLawson.TotalFreedomMod.TFM_UserList;
import me.StevenLawson.TotalFreedomMod.TFM_UserList.TFM_UserListEntry;
import me.StevenLawson.TotalFreedomMod.TFM_PlayerList;
import me.StevenLawson.TotalFreedomMod.TFM_PlayerList.PlayerEntry;
import me.StevenLawson.TotalFreedomMod.TFM_Util;
import net.minecraft.util.org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
@ -31,7 +31,7 @@ public class Command_glist extends TFM_Command
//Purge does not clear the banlist! This is not for clearing bans! This is for clearing the yaml file that stores the player/IP database!
if (TFM_SuperadminList.isSeniorAdmin(sender))
{
TFM_UserList.getInstance().purge();
TFM_PlayerList.getInstance().purgeAll();
}
else
{
@ -58,7 +58,7 @@ public class Command_glist extends TFM_Command
}
catch (PlayerNotFoundException ex)
{
TFM_UserListEntry entry = TFM_UserList.getInstance().getEntry(args[1]);
PlayerEntry entry = TFM_PlayerList.getInstance().getEntry(args[1]);
if (entry == null)
{
@ -66,8 +66,8 @@ public class Command_glist extends TFM_Command
return true;
}
username = entry.getUsername();
ip_addresses = entry.getIpAddresses();
username = entry.getLastJoinName();
ip_addresses = entry.getIps();
}
String mode = args[0].toLowerCase();

View File

@ -1,7 +1,7 @@
package me.StevenLawson.TotalFreedomMod.Commands;
import me.StevenLawson.TotalFreedomMod.TFM_RollbackManager;
import me.StevenLawson.TotalFreedomMod.TFM_UserList;
import me.StevenLawson.TotalFreedomMod.TFM_PlayerList;
import me.StevenLawson.TotalFreedomMod.TFM_Util;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -99,7 +99,7 @@ public class Command_rollback extends TFM_Command
if (playerName == null)
{
playerName = TFM_UserList.getInstance().searchByPartialName(playerNameInput);
playerName = TFM_PlayerList.getInstance().getEntry(playerNameInput).getLastJoinName();
}
return playerName;

View File

@ -685,67 +685,62 @@ public class TFM_PlayerListener implements Listener
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event)
{
try
final Player player = event.getPlayer();
final String ip = TFM_Util.getIp(player);
final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
playerdata.setSuperadminIdVerified(null);
TFM_Log.info("[JOIN] " + player.getName() + " (" + player.getUniqueId() + ") joined the game with IP address: " + ip, true);
TFM_PlayerList.getInstance().getEntry(player);
final boolean impostor = TFM_SuperadminList.isSuperadminImpostor(player);
if (impostor || TFM_SuperadminList.isUserSuperadmin(player))
{
final Player player = event.getPlayer();
final TFM_PlayerData playerdata = TFM_PlayerData.getPlayerData(player);
playerdata.setSuperadminIdVerified(null);
final String IP = player.getAddress().getAddress().getHostAddress().trim();
TFM_Util.bcastMsg(ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
TFM_Log.info("[JOIN] " + player.getName() + " (" + player.getUniqueId() + ") joined the game with IP address: " + IP, true);
TFM_UserList.getInstance().addUser(player);
final boolean impostor = TFM_SuperadminList.isSuperadminImpostor(player);
if (impostor || TFM_SuperadminList.isUserSuperadmin(player))
if (impostor)
{
TFM_Util.bcastMsg(ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
if (impostor)
player.getInventory().clear();
player.setOp(false);
player.setGameMode(GameMode.SURVIVAL);
TFM_Util.bcastMsg("Warning: " + player.getName() + " has been flagged as an impostor!", ChatColor.RED);
}
else
{
if (TFM_SuperadminList.verifyIdentity(player.getName(), TFM_Util.getIp(player)))
{
player.getInventory().clear();
player.setOp(false);
player.setGameMode(GameMode.SURVIVAL);
TFM_Util.bcastMsg("Warning: " + player.getName() + " has been flagged as an impostor!", ChatColor.RED);
playerdata.setSuperadminIdVerified(Boolean.TRUE);
TFM_SuperadminList.updateLastLogin(player);
}
else
{
if (TFM_SuperadminList.verifyIdentity(player.getName(), player.getAddress().getAddress().getHostAddress()))
{
playerdata.setSuperadminIdVerified(Boolean.TRUE);
playerdata.setSuperadminIdVerified(Boolean.FALSE);
TFM_SuperadminList.updateLastLogin(player);
}
else
{
playerdata.setSuperadminIdVerified(Boolean.FALSE);
TFM_Util.bcastMsg("Warning: " + player.getName() + " is an admin, but is using a username not registered to one of their IPs.", ChatColor.RED);
}
player.setOp(true);
TFM_Util.bcastMsg("Warning: " + player.getName() + " is an admin, but is using a username not registered to one of their IPs.", ChatColor.RED);
}
}
else if (TFM_Util.DEVELOPERS.contains(player.getName()))
{
TFM_Util.bcastMsg(ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
}
if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{
new BukkitRunnable()
{
@Override
public void run()
{
player.sendMessage(ChatColor.RED + "Server is currently closed to non-superadmins.");
}
}.runTaskLater(TotalFreedomMod.plugin, 20L * 3L);
player.setOp(true);
}
}
catch (Throwable ex)
else if (TFM_Util.DEVELOPERS.contains(player.getName()))
{
TFM_Util.bcastMsg(ChatColor.AQUA + player.getName() + " is " + TFM_PlayerRank.getLoginMessage(player));
}
if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{
new BukkitRunnable()
{
@Override
public void run()
{
player.sendMessage(ChatColor.RED + "Server is currently closed to non-superadmins.");
}
}.runTaskLater(TotalFreedomMod.plugin, 20L * 3L);
}
}

View File

@ -0,0 +1,326 @@
package me.StevenLawson.TotalFreedomMod;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.util.org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
public class TFM_PlayerList
{
private static final TFM_PlayerList INSTANCE = new TFM_PlayerList();
private static final String USERLIST_FILENAME = "playerlist.yml";
private final Map<UUID, PlayerEntry> playerList;
private final YamlConfiguration config;
private File configFile;
private TFM_PlayerList()
{
this.playerList = new HashMap<UUID, PlayerEntry>();
this.config = new YamlConfiguration();
}
public File getConfigFile()
{
return new File(TotalFreedomMod.plugin.getDataFolder(), USERLIST_FILENAME);
}
public void load()
{
playerList.clear();
configFile = new File(TotalFreedomMod.plugin.getDataFolder(), USERLIST_FILENAME);
if (configFile.exists())
{
try
{
config.load(configFile);
}
catch (Exception ex)
{
TFM_Log.warning("Could not load player config file: " + ex.getMessage());
TFM_Log.warning("Purging...");
purgeAll();
return;
}
// Load players from config
for (String uuidString : config.getKeys(false))
{
final UUID uuid;
try
{
uuid = UUID.fromString(uuidString);
}
catch (IllegalArgumentException ex)
{
TFM_Log.warning("Invalid playerlist UUID: " + uuidString + ", Skipping...");
continue;
}
final PlayerEntry entry = new PlayerEntry(uuid, config.getConfigurationSection(uuidString));
if (!entry.isComplete())
{
TFM_Log.warning("Incomplete playerlist entry: " + uuidString + ", Skipping...");
continue;
}
playerList.put(uuid, entry);
}
}
// Load online players
for (Player player : Bukkit.getOnlinePlayers())
{
getEntry(player);
}
// Save list
saveAll();
}
private void saveAll()
{
// Put entries
for (PlayerEntry entry : playerList.values())
{
entry.save();
}
}
public PlayerEntry getEntry(String player)
{
for (PlayerEntry entry : playerList.values())
{
if (entry.getLastJoinName().equalsIgnoreCase(player))
{
return entry;
}
}
return null;
}
public PlayerEntry getEntry(Player player)
{
final UUID uuid = player.getUniqueId();
PlayerEntry entry = playerList.get(uuid);
if (entry == null)
{
entry = new PlayerEntry(uuid);
entry.setFirstJoinName(player.getName());
entry.setLastJoinName(player.getName());
final long unix = TFM_Util.getUnixTime();
entry.setFirstJoinUnix(unix);
entry.setLastJoinUnix(unix);
entry.save();
playerList.put(uuid, entry);
}
return entry;
}
public void purgeAll()
{
// Clear the config entries
for (String key : config.getKeys(false))
{
config.set(key, null);
}
// Save the config
try
{
config.save(configFile);
}
catch (IOException ex)
{
TFM_Log.severe("Could not purge config file: " + ex.getMessage());
TFM_Log.severe(ex);
}
// Load online players
load();
}
/*public String searchByPartialName(String needle)
{
needle = needle.toLowerCase().trim();
Integer minEditDistance = null;
String minEditMatch = null;
Iterator<UUID> it = playerList.keySet().iterator();
while (it.hasNext())
{
String haystack = it.next();
int editDistance = StringUtils.getLevenshteinDistance(needle, haystack.toLowerCase());
if (minEditDistance == null || minEditDistance.intValue() > editDistance)
{
minEditDistance = editDistance;
minEditMatch = haystack;
}
}
return minEditMatch;
}*/
public static TFM_PlayerList getInstance()
{
return INSTANCE;
}
public final class PlayerEntry
{
private final UUID uuid;
private String firstJoinName;
private String lastJoinName;
private long firstJoinUnix;
private long lastJoinUnix;
private final List<String> ips;
protected PlayerEntry(UUID uuid, ConfigurationSection section)
{
this(uuid);
this.firstJoinName = section.getString("firstjoinname");
this.lastJoinName = section.getString("lastjoinname");
this.firstJoinUnix = section.getLong("firstjoinunix");
this.firstJoinUnix = section.getLong("lastjoinunix");
this.ips.addAll(section.getStringList("ips"));
}
protected PlayerEntry(UUID uuid)
{
this.uuid = uuid;
this.ips = new ArrayList<String>();
}
// Getters / Setters below
public UUID getUniqueId()
{
return uuid;
}
public List<String> getIps()
{
return Collections.unmodifiableList(ips);
}
public String getFirstJoinName()
{
return firstJoinName;
}
public void setFirstJoinName(String firstJoinName)
{
this.firstJoinName = firstJoinName;
}
public String getLastJoinName()
{
return lastJoinName;
}
public void setLastJoinName(String lastJoinName)
{
this.lastJoinName = lastJoinName;
}
public long getFirstJoinUnix()
{
return firstJoinUnix;
}
public void setFirstJoinUnix(long firstJoinUnix)
{
this.firstJoinUnix = firstJoinUnix;
}
public long getLastJoinUnix()
{
return lastJoinUnix;
}
public void setLastJoinUnix(long lastJoinUnix)
{
this.lastJoinUnix = lastJoinUnix;
}
public boolean addIp(String ip)
{
if (!ips.contains(ip))
{
ips.add(ip);
return true;
}
return false;
}
private boolean isComplete()
{
return firstJoinName != null
&& lastJoinName != null
&& firstJoinUnix != 0
&& lastJoinUnix != 0
&& !ips.isEmpty();
}
public void save()
{
if (!isComplete())
{
throw new IllegalStateException("Entry is not complete");
}
final ConfigurationSection section;
if (config.isConfigurationSection(uuid.toString()))
{
section = config.getConfigurationSection(uuid.toString());
}
else
{
section = config.createSection(uuid.toString());
}
section.set("firstjoinname", firstJoinName);
section.set("lastjoinname", lastJoinName);
section.set("firstjoinunix", firstJoinUnix);
section.set("lastjoinunix", lastJoinUnix);
section.set("ips", ips);
// Save config
try
{
config.save(configFile);
}
catch (IOException ex)
{
TFM_Log.severe("Could not save player entry: " + uuid.toString() + " (" + lastJoinName + ")");
TFM_Log.severe(ex);
}
}
}
}

View File

@ -495,21 +495,28 @@ public class TFM_SuperadminList
}
}
public static boolean verifyIdentity(String username, String ip) throws Exception
public static boolean verifyIdentity(String username, String ip)
{
if (Bukkit.getOnlineMode())
try
{
return true;
if (Bukkit.getOnlineMode())
{
return true;
}
TFM_Superadmin entry = getAdminEntry(username);
if (entry != null)
{
return entry.getIps().contains(ip);
}
return false;
}
catch (Exception ex)
{
TFM_Log.severe(ex);
}
TFM_Superadmin entry = getAdminEntry(username);
if (entry != null)
{
return entry.getIps().contains(ip);
}
else
{
throw new Exception();
}
return false;
}
}

View File

@ -1,178 +0,0 @@
package me.StevenLawson.TotalFreedomMod;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.minecraft.util.org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
public class TFM_UserList
{
private static final TFM_UserList INSTANCE = new TFM_UserList();
private static final String USERLIST_FILENAME = "userlist.yml";
private Map<String, TFM_UserListEntry> userlist = new HashMap<String, TFM_UserListEntry>();
private TFM_UserList()
{
}
protected void primeList()
{
try
{
userlist.clear();
FileConfiguration savedUserlist = YamlConfiguration.loadConfiguration(new File(TotalFreedomMod.plugin.getDataFolder(), USERLIST_FILENAME));
for (String username : savedUserlist.getKeys(false))
{
TFM_UserListEntry entry = new TFM_UserListEntry(username, savedUserlist.getStringList(username));
userlist.put(username, entry);
}
for (Player player : Bukkit.getOnlinePlayers())
{
addUser(player);
}
exportList();
}
catch (Exception ex)
{
TFM_Log.severe("Error loading Userlist, resetting list: " + ex.getMessage());
purge();
}
}
private void exportList()
{
final FileConfiguration newUserlist = new YamlConfiguration();
for (TFM_UserListEntry entry : userlist.values())
{
newUserlist.set(entry.getUsername(), entry.getIpAddresses());
}
try
{
newUserlist.save(new File(TotalFreedomMod.plugin.getDataFolder(), USERLIST_FILENAME));
}
catch (IOException ex)
{
TFM_Log.severe(ex);
}
}
public static TFM_UserList getInstance()
{
return INSTANCE;
}
public void addUser(Player player)
{
addUser(player.getName(), player.getAddress().getAddress().getHostAddress());
}
public void addUser(String username, String ip)
{
username = username.toLowerCase();
TFM_UserListEntry entry = userlist.get(username);
if (entry == null)
{
entry = new TFM_UserListEntry(username);
}
userlist.put(username, entry);
if (entry.addIpAddress(ip))
{
exportList();
}
}
public TFM_UserListEntry getEntry(Player player)
{
return getEntry(player.getName());
}
public TFM_UserListEntry getEntry(String username)
{
return userlist.get(username.toLowerCase());
}
public void purge()
{
userlist.clear();
for (Player player : Bukkit.getOnlinePlayers())
{
addUser(player);
}
exportList();
}
public String searchByPartialName(String needle)
{
needle = needle.toLowerCase().trim();
Integer minEditDistance = null;
String minEditMatch = null;
Iterator<String> it = userlist.keySet().iterator();
while (it.hasNext())
{
String haystack = it.next();
int editDistance = StringUtils.getLevenshteinDistance(needle, haystack.toLowerCase());
if (minEditDistance == null || minEditDistance.intValue() > editDistance)
{
minEditDistance = editDistance;
minEditMatch = haystack;
}
}
return minEditMatch;
}
public class TFM_UserListEntry
{
private String username;
private List<String> ipAddresses = new ArrayList<String>();
public TFM_UserListEntry(String username, List<String> ipAddresses)
{
this.username = username;
this.ipAddresses = ipAddresses;
}
public TFM_UserListEntry(String username)
{
this.username = username;
}
public List<String> getIpAddresses()
{
return ipAddresses;
}
public String getUsername()
{
return username;
}
public boolean addIpAddress(String ip)
{
if (!ipAddresses.contains(ip))
{
ipAddresses.add(ip);
return true;
}
return false;
}
}
}

View File

@ -125,6 +125,11 @@ public class TFM_Util
TFM_Util.bcastMsg(adminName + " - " + action, (isRed ? ChatColor.RED : ChatColor.AQUA));
}
public static String getIp(Player player)
{
return player.getAddress().getAddress().getHostAddress().trim();
}
public static String formatLocation(Location location)
{
return String.format("%s: (%d, %d, %d)",
@ -773,6 +778,11 @@ public class TFM_Util
return ChatColor.translateAlternateColorCodes('&', string);
}
public static long getUnixTime()
{
return System.currentTimeMillis() / 1000L;
}
public static class TFM_EntityWiper
{
private static final List<Class<? extends Entity>> WIPEABLES = new ArrayList<Class<? extends Entity>>();
@ -850,7 +860,7 @@ public class TFM_Util
}
}
enum EjectMethod
public static enum EjectMethod
{
STRIKE_ONE, STRIKE_TWO, STRIKE_THREE;
}

View File

@ -87,7 +87,7 @@ public class TotalFreedomMod extends JavaPlugin
loadSuperadminConfig();
loadPermbanConfig();
TFM_UserList.getInstance().primeList();
TFM_PlayerList.getInstance().load();
registerEventHandlers();