IdUtil MaintainedSets rework, and proper sender tab completion.
This commit is contained in:
		
							parent
							
								
									a7216b0c20
								
							
						
					
					
						commit
						eaa730ddfc
					
				@ -141,17 +141,18 @@ public class MassiveCoreEngineMain extends EngineAbstract
 | 
			
		||||
		Player watcher = event.getPlayer();
 | 
			
		||||
		if (MUtil.isntPlayer(watcher)) return;
 | 
			
		||||
		
 | 
			
		||||
		// Get the lowercased token
 | 
			
		||||
		String tokenlc = event.getLastToken().toLowerCase();
 | 
			
		||||
		// Get the lowercased token predicate
 | 
			
		||||
		Predictate<String> predictate = PredictateStartsWithIgnoreCase.get(event.getLastToken());
 | 
			
		||||
		
 | 
			
		||||
		// Create a case insensitive set to check for already added stuff
 | 
			
		||||
		Set<String> current = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
		current.addAll(event.getTabCompletions());
 | 
			
		||||
		
 | 
			
		||||
		// Add names of all online senders that match and isn't added yet. 
 | 
			
		||||
		for (String senderName : IdUtil.getOnlineNames())
 | 
			
		||||
		// Add names of all online senders that match and isn't added yet.
 | 
			
		||||
		// TODO: Should this only be players? Would a player actually want to tab-complete @console?
 | 
			
		||||
		for (String senderName : IdUtil.getNames(SenderPresence.ONLINE, SenderType.ANY))
 | 
			
		||||
		{
 | 
			
		||||
			if (!senderName.toLowerCase().startsWith(tokenlc)) continue;
 | 
			
		||||
			if (!predictate.apply(senderName)) continue;
 | 
			
		||||
			if (current.contains(senderName)) continue;
 | 
			
		||||
			if (!Mixin.canSee(watcher, senderName)) continue;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								src/com/massivecraft/massivecore/SenderPresence.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/com/massivecraft/massivecore/SenderPresence.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
package com.massivecraft.massivecore;
 | 
			
		||||
 | 
			
		||||
public enum SenderPresence
 | 
			
		||||
{
 | 
			
		||||
	// IMP NOTE: These must be sorted, with the most strict first
 | 
			
		||||
	// and the most loose at the end.
 | 
			
		||||
	LOCAL, // Online and logged in on this very server.
 | 
			
		||||
	ONLINE, // Online somewhere on the cloud. May be this server may be another server.
 | 
			
		||||
	OFFLINE, // The opposite of online.
 | 
			
		||||
	ANY, // Any. Local, Online or Offline.
 | 
			
		||||
	
 | 
			
		||||
	;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// GET FROM ONLINE VALUE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static SenderPresence fromOnline(Boolean online)
 | 
			
		||||
	{
 | 
			
		||||
		if (online == null) return null;
 | 
			
		||||
		return fromOnline(online.booleanValue());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static SenderPresence fromOnline(boolean online)
 | 
			
		||||
	{
 | 
			
		||||
		return online ? ONLINE : OFFLINE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								src/com/massivecraft/massivecore/SenderType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/com/massivecraft/massivecore/SenderType.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
package com.massivecraft.massivecore;
 | 
			
		||||
 | 
			
		||||
public enum SenderType
 | 
			
		||||
{
 | 
			
		||||
	PLAYER, // A player. Such as Notch or Dinnerbone. @console is not a player.
 | 
			
		||||
	NONPLAYER, // A sender which is not a player. Such as @console.
 | 
			
		||||
	ANY, // Anyone. Both players, and nonplayers.
 | 
			
		||||
	
 | 
			
		||||
	;
 | 
			
		||||
}
 | 
			
		||||
@ -2,6 +2,8 @@ package com.massivecraft.massivecore.cmd.arg;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
 | 
			
		||||
import com.massivecraft.massivecore.util.IdUtil;
 | 
			
		||||
 | 
			
		||||
@ -15,7 +17,7 @@ public class ARPlayer extends ARSenderIdAbstract<Player>
 | 
			
		||||
	public static ARPlayer get() { return i; }
 | 
			
		||||
	private ARPlayer()
 | 
			
		||||
	{
 | 
			
		||||
		super(SenderIdSourceMixinAllSenderIds.get(), true, true);
 | 
			
		||||
		super(SenderIdSourceMixinAllSenderIds.get(), SenderPresence.LOCAL, SenderType.PLAYER);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@ package com.massivecraft.massivecore.cmd.arg;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
 | 
			
		||||
import com.massivecraft.massivecore.util.IdUtil;
 | 
			
		||||
 | 
			
		||||
@ -15,7 +17,7 @@ public class ARSender extends ARSenderIdAbstract<CommandSender>
 | 
			
		||||
	public static ARSender get() { return i; }
 | 
			
		||||
	private ARSender()
 | 
			
		||||
	{
 | 
			
		||||
		super(SenderIdSourceMixinAllSenderIds.get(), true, false);
 | 
			
		||||
		super(SenderIdSourceMixinAllSenderIds.get(), SenderPresence.LOCAL, SenderType.ANY);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,8 @@ package com.massivecraft.massivecore.cmd.arg;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderColl;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderEntity;
 | 
			
		||||
 | 
			
		||||
@ -18,15 +20,15 @@ public class ARSenderEntity<T extends SenderEntity<T>> extends ARSenderIdAbstrac
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private ARSenderEntity(SenderColl<T> coll, boolean onlineOnly, boolean playerOnly)
 | 
			
		||||
	private ARSenderEntity(SenderColl<T> coll, SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		super(coll, onlineOnly, playerOnly);
 | 
			
		||||
		super(coll, presence, type);
 | 
			
		||||
		this.coll = coll;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private ARSenderEntity(SenderColl<T> coll, boolean onlineOnly)
 | 
			
		||||
	private ARSenderEntity(SenderColl<T> coll, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		super(coll, onlineOnly);
 | 
			
		||||
		super(coll, presence);
 | 
			
		||||
		this.coll = coll;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@ -40,8 +42,8 @@ public class ARSenderEntity<T extends SenderEntity<T>> extends ARSenderIdAbstrac
 | 
			
		||||
	// GET
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll, boolean onlineOnly, boolean playerOnly) { return new ARSenderEntity<T>(coll, onlineOnly, playerOnly); }
 | 
			
		||||
	public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll, boolean onlineOnly) { return new ARSenderEntity<T>(coll, onlineOnly); }
 | 
			
		||||
	public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll, SenderPresence presence, SenderType type) { return new ARSenderEntity<T>(coll, presence, type); }
 | 
			
		||||
	public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll, SenderPresence presence) { return new ARSenderEntity<T>(coll, presence); }
 | 
			
		||||
	public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll) { return new ARSenderEntity<T>(coll); }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
package com.massivecraft.massivecore.cmd.arg;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderIdSource;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
 | 
			
		||||
 | 
			
		||||
@ -9,14 +11,14 @@ public class ARSenderId extends ARSenderIdAbstract<String>
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private ARSenderId(SenderIdSource source, boolean onlineOnly, boolean playerOnly)
 | 
			
		||||
	private ARSenderId(SenderIdSource source, SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		super(source, onlineOnly, playerOnly);
 | 
			
		||||
		super(source, presence, type);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private ARSenderId(SenderIdSource source, boolean onlineOnly)
 | 
			
		||||
	private ARSenderId(SenderIdSource source, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		super(source, onlineOnly);
 | 
			
		||||
		super(source, presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private ARSenderId(SenderIdSource source)
 | 
			
		||||
@ -35,8 +37,8 @@ public class ARSenderId extends ARSenderIdAbstract<String>
 | 
			
		||||
	// GET
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static ARSenderId get(SenderIdSource source, boolean onlineOnly, boolean playerOnly) { return new ARSenderId(source, onlineOnly, playerOnly); }
 | 
			
		||||
	public static ARSenderId get(SenderIdSource source, boolean onlineOnly) { return new ARSenderId(source, onlineOnly); }
 | 
			
		||||
	public static ARSenderId get(SenderIdSource source, SenderPresence presence, SenderType type) { return new ARSenderId(source, presence, type); }
 | 
			
		||||
	public static ARSenderId get(SenderIdSource source, SenderPresence presence) { return new ARSenderId(source, presence); }
 | 
			
		||||
	public static ARSenderId get(SenderIdSource source) { return new ARSenderId(source); }
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
package com.massivecraft.massivecore.cmd.arg;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.MassiveException;
 | 
			
		||||
import com.massivecraft.massivecore.collections.MassiveList;
 | 
			
		||||
import com.massivecraft.massivecore.mixin.Mixin;
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.store.SenderIdSource;
 | 
			
		||||
import com.massivecraft.massivecore.util.IdUtil;
 | 
			
		||||
import com.massivecraft.massivecore.util.MUtil;
 | 
			
		||||
@ -20,28 +20,32 @@ public abstract class ARSenderIdAbstract<T> extends ARAbstract<T>
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	protected final SenderIdSource source;
 | 
			
		||||
	protected final boolean onlineOnly;
 | 
			
		||||
	protected final boolean playerOnly;
 | 
			
		||||
	protected final SenderPresence presence;
 | 
			
		||||
	protected final SenderType type;
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderIdAbstract(SenderIdSource source, boolean onlineOnly, boolean playerOnly)
 | 
			
		||||
	public ARSenderIdAbstract(SenderIdSource source, SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		if (source == null) throw new NullPointerException("source");
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		if (type == null) throw new NullPointerException("type");
 | 
			
		||||
		
 | 
			
		||||
		this.source = source;
 | 
			
		||||
		this.onlineOnly = onlineOnly;
 | 
			
		||||
		this.playerOnly = playerOnly;
 | 
			
		||||
		this.presence = presence;
 | 
			
		||||
		this.type = type;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderIdAbstract(SenderIdSource source, boolean online)
 | 
			
		||||
	public ARSenderIdAbstract(SenderIdSource source, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		this(source, online, false);
 | 
			
		||||
		this(source, presence, SenderType.ANY);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderIdAbstract(SenderIdSource source)
 | 
			
		||||
	{
 | 
			
		||||
		this(source, false);
 | 
			
		||||
		this(source, SenderPresence.ANY);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@ -57,8 +61,14 @@ public abstract class ARSenderIdAbstract<T> extends ARAbstract<T>
 | 
			
		||||
	@Override
 | 
			
		||||
	public String getTypeName()
 | 
			
		||||
	{
 | 
			
		||||
		if (onlineOnly) return "online player";
 | 
			
		||||
		else return "player";
 | 
			
		||||
		switch (presence)
 | 
			
		||||
		{
 | 
			
		||||
			case LOCAL:
 | 
			
		||||
			case ONLINE: return "online player";
 | 
			
		||||
			case OFFLINE: return "offline player";
 | 
			
		||||
			case ANY: return "player";
 | 
			
		||||
		}
 | 
			
		||||
		throw new UnsupportedOperationException("Unknown SenderPresence: " + presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
@ -93,34 +103,29 @@ public abstract class ARSenderIdAbstract<T> extends ARAbstract<T>
 | 
			
		||||
		if (MUtil.isUuid(arg)) return true;
 | 
			
		||||
		
 | 
			
		||||
		// Check data presence. This handles specials like "@console".
 | 
			
		||||
		if (IdUtil.getIdToData().containsKey(arg)) return true;
 | 
			
		||||
		if (IdUtil.getNameToData().containsKey(arg)) return true;
 | 
			
		||||
		if (IdUtil.getRegistryIdToSender().containsKey(arg)) return true;
 | 
			
		||||
		
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public Collection<String> getTabList(CommandSender sender, String arg)
 | 
			
		||||
	{
 | 
			
		||||
		Set<String> names;
 | 
			
		||||
		if (onlineOnly)
 | 
			
		||||
		{
 | 
			
		||||
			names = playerOnly ? IdUtil.getOnlinePlayerNames() : IdUtil.getOnlineNames();
 | 
			
		||||
			
 | 
			
		||||
			List<String> ret = new MassiveList<String>();
 | 
			
		||||
			for (String name : names)
 | 
			
		||||
			{
 | 
			
		||||
				if ( ! Mixin.canSee(sender, name)) continue;
 | 
			
		||||
				ret.add(name);
 | 
			
		||||
			}
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			names = playerOnly ? IdUtil.getAllPlayerNames() : IdUtil.getAllNames();
 | 
			
		||||
			
 | 
			
		||||
			return names;
 | 
			
		||||
		}
 | 
			
		||||
	{	
 | 
			
		||||
		// Step 1: Calculate presence.
 | 
			
		||||
		SenderPresence presence = this.presence;
 | 
			
		||||
		if (presence == SenderPresence.ANY) presence = SenderPresence.ONLINE;
 | 
			
		||||
		
 | 
			
		||||
		// Special step: We don't tab complete offline players.
 | 
			
		||||
		if (presence == SenderPresence.OFFLINE) return Collections.emptySet();
 | 
			
		||||
 | 
			
		||||
		// Step 2: Calculate type.
 | 
			
		||||
		SenderType type = this.type;
 | 
			
		||||
		
 | 
			
		||||
		// Step 3: Create the ret.
 | 
			
		||||
		Set<String> ret = IdUtil.getNames(presence, type);
 | 
			
		||||
		
 | 
			
		||||
		// Step 4: Return the ret.
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@ -135,14 +140,13 @@ public abstract class ARSenderIdAbstract<T> extends ARAbstract<T>
 | 
			
		||||
		String senderId = arg.toLowerCase();
 | 
			
		||||
		String betterId = IdUtil.getId(senderId);
 | 
			
		||||
		if (betterId != null) senderId = betterId;
 | 
			
		||||
		
 | 
			
		||||
		for (Collection<String> coll : this.source.getSenderIdCollections())
 | 
			
		||||
		{
 | 
			
		||||
			// If the senderId exists ...
 | 
			
		||||
			if ( ! coll.contains(senderId)) continue;
 | 
			
		||||
			
 | 
			
		||||
			// ... and the online check passes ...
 | 
			
		||||
			if (this.onlineOnly && !Mixin.isOnline(senderId)) continue;
 | 
			
		||||
			// ... and the presence check passes ...
 | 
			
		||||
			if (IdUtil.getMaintainedIds().contains(senderId, presence, type) || IdUtil.getMaintainedNames().contains(senderId, presence, type)) continue;
 | 
			
		||||
			
 | 
			
		||||
			// ... and the result is non null ...
 | 
			
		||||
			T result = this.getResultForSenderId(senderId);
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ public class MessageMixinDefault extends MessageMixinAbstract
 | 
			
		||||
	public boolean messageAll(Collection<String> messages)
 | 
			
		||||
	{
 | 
			
		||||
		if (messages == null) return false;
 | 
			
		||||
		for (CommandSender sender : IdUtil.getOnlineSenders())
 | 
			
		||||
		for (CommandSender sender : IdUtil.getLocalSenders())
 | 
			
		||||
		{
 | 
			
		||||
			this.messageOne(sender, messages);
 | 
			
		||||
		}
 | 
			
		||||
@ -39,7 +39,7 @@ public class MessageMixinDefault extends MessageMixinAbstract
 | 
			
		||||
	{
 | 
			
		||||
		if (predictate == null) return false;
 | 
			
		||||
		if (messages == null) return false;
 | 
			
		||||
		for (CommandSender sender : IdUtil.getOnlineSenders())
 | 
			
		||||
		for (CommandSender sender : IdUtil.getLocalSenders())
 | 
			
		||||
		{
 | 
			
		||||
			if (!predictate.apply(sender)) continue;
 | 
			
		||||
			this.messageOne(sender, messages);
 | 
			
		||||
@ -62,7 +62,7 @@ public class MessageMixinDefault extends MessageMixinAbstract
 | 
			
		||||
	public boolean messageRawAll(Collection<Mson> msons)
 | 
			
		||||
	{
 | 
			
		||||
		if (msons == null) return false;
 | 
			
		||||
		for (CommandSender sender : IdUtil.getOnlineSenders())
 | 
			
		||||
		for (CommandSender sender : IdUtil.getLocalSenders())
 | 
			
		||||
		{
 | 
			
		||||
			this.messageRawOne(sender, msons);
 | 
			
		||||
		}
 | 
			
		||||
@ -74,7 +74,7 @@ public class MessageMixinDefault extends MessageMixinAbstract
 | 
			
		||||
	{
 | 
			
		||||
		if (predictate == null) return false;
 | 
			
		||||
		if (msons == null) return false;
 | 
			
		||||
		for (CommandSender sender : IdUtil.getOnlineSenders())
 | 
			
		||||
		for (CommandSender sender : IdUtil.getLocalSenders())
 | 
			
		||||
		{
 | 
			
		||||
			if ( ! predictate.apply(sender)) continue;
 | 
			
		||||
			this.messageRawOne(sender, msons);
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.Predictate;
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.cmd.arg.ARSenderEntity;
 | 
			
		||||
import com.massivecraft.massivecore.cmd.arg.ARSenderId;
 | 
			
		||||
import com.massivecraft.massivecore.util.IdUtil;
 | 
			
		||||
@ -114,7 +116,7 @@ public class SenderColl<E extends SenderEntity<E>> extends Coll<E> implements Se
 | 
			
		||||
		// You could say the corresponding entities latently exist in the collection because it's creative.
 | 
			
		||||
		if (this.isCreative())
 | 
			
		||||
		{
 | 
			
		||||
			ret.add(IdUtil.getAllIds());
 | 
			
		||||
			ret.add(IdUtil.getIds(SenderPresence.ANY, SenderType.ANY));
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return ret;
 | 
			
		||||
@ -129,9 +131,9 @@ public class SenderColl<E extends SenderEntity<E>> extends Coll<E> implements Se
 | 
			
		||||
		return ARSenderEntity.get(this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderEntity<E> getAREntity(boolean online)
 | 
			
		||||
	public ARSenderEntity<E> getAREntity(SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		return ARSenderEntity.get(this, online);
 | 
			
		||||
		return ARSenderEntity.get(this, presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderId getARId()
 | 
			
		||||
@ -139,9 +141,9 @@ public class SenderColl<E extends SenderEntity<E>> extends Coll<E> implements Se
 | 
			
		||||
		return ARSenderId.get(this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public ARSenderId getARId(boolean online)
 | 
			
		||||
	public ARSenderId getARId(SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		return ARSenderId.get(this, online);
 | 
			
		||||
		return ARSenderId.get(this, presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,8 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.util.IdUtil;
 | 
			
		||||
 | 
			
		||||
public class SenderIdSourceMixinAllSenderIds implements SenderIdSource
 | 
			
		||||
@ -23,7 +25,7 @@ public class SenderIdSourceMixinAllSenderIds implements SenderIdSource
 | 
			
		||||
	public Collection<Collection<String>> getSenderIdCollections()
 | 
			
		||||
	{
 | 
			
		||||
		List<Collection<String>> ret = new ArrayList<Collection<String>>();
 | 
			
		||||
		ret.add(IdUtil.getAllIds());
 | 
			
		||||
		ret.add(IdUtil.getIds(SenderPresence.ANY, SenderType.ANY));
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
@ -5,12 +5,12 @@ import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentSkipListMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentSkipListSet;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
@ -24,6 +24,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
 | 
			
		||||
import org.bukkit.event.player.PlayerLoginEvent;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.MassiveCore;
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
 | 
			
		||||
import com.massivecraft.massivecore.event.EventMassiveCoreSenderRegister;
 | 
			
		||||
import com.massivecraft.massivecore.event.EventMassiveCoreSenderUnregister;
 | 
			
		||||
@ -105,25 +107,20 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	// MAINTAINED SETS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// Used for chat tab completion, argument readers, etc.
 | 
			
		||||
 | 
			
		||||
	private static SenderMap maintainedIds = new SenderMap();
 | 
			
		||||
	public static SenderMap getMaintainedIds() { return maintainedIds; }
 | 
			
		||||
	public static Set<String> getIds(SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		return maintainedIds.getValues(presence, type);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> onlineIds = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getOnlineIds() { return Collections.unmodifiableSet(onlineIds); }
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> onlineNames = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getOnlineNames() { return Collections.unmodifiableSet(onlineNames); }
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> onlinePlayerNames = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getOnlinePlayerNames() { return Collections.unmodifiableSet(onlinePlayerNames); }
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> allIds = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getAllIds() { return Collections.unmodifiableSet(allIds); }
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> allNames = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getAllNames() { return Collections.unmodifiableSet(allNames); }
 | 
			
		||||
	
 | 
			
		||||
	private static Set<String> allPlayerNames = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
	public static Set<String> getAllPlayerNames() { return Collections.unmodifiableSet(allPlayerNames); }
 | 
			
		||||
	private static SenderMap maintainedNames = new SenderMap();
 | 
			
		||||
	public static SenderMap getMaintainedNames() { return maintainedNames; }
 | 
			
		||||
	public static Set<String> getNames(SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		return maintainedNames.getValues(presence, type);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// REGISTRY
 | 
			
		||||
@ -132,7 +129,10 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	// It's assumed that the getName() returns the name which is also the id.
 | 
			
		||||
	
 | 
			
		||||
	private static Map<String, CommandSender> registryIdToSender = new ConcurrentHashMap<String, CommandSender>();
 | 
			
		||||
	public static Map<String, CommandSender> getRegistryIdToSender() { return Collections.unmodifiableMap(registryIdToSender); }
 | 
			
		||||
	
 | 
			
		||||
	private static Map<CommandSender, String> registrySenderToId = new ConcurrentHashMap<CommandSender, String>();
 | 
			
		||||
	public static Map<CommandSender, String> getRegistrySenderToId() { return Collections.unmodifiableMap(registrySenderToId); }
 | 
			
		||||
	
 | 
			
		||||
	public static void register(CommandSender sender)
 | 
			
		||||
	{
 | 
			
		||||
@ -145,7 +145,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		registrySenderToId.put(sender, id);
 | 
			
		||||
		
 | 
			
		||||
		// Update data before the event is ran so that data is available.
 | 
			
		||||
		update(id, name, true);
 | 
			
		||||
		update(id, name, SenderPresence.LOCAL);
 | 
			
		||||
		
 | 
			
		||||
		EventMassiveCoreSenderRegister event = new EventMassiveCoreSenderRegister(sender, data);
 | 
			
		||||
		event.run();
 | 
			
		||||
@ -163,7 +163,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		if (removed == null) return;
 | 
			
		||||
		
 | 
			
		||||
		// Update data before the event is ran so that data is available.
 | 
			
		||||
		update(id, name, false);
 | 
			
		||||
		update(id, name, SenderPresence.OFFLINE);
 | 
			
		||||
		
 | 
			
		||||
		EventMassiveCoreSenderUnregister event = new EventMassiveCoreSenderUnregister(sender, data);
 | 
			
		||||
		event.run();
 | 
			
		||||
@ -174,7 +174,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// Used for retrieving the full set of senders currently present on this server.
 | 
			
		||||
	
 | 
			
		||||
	public static Set<CommandSender> getOnlineSenders()
 | 
			
		||||
	public static Set<CommandSender> getLocalSenders()
 | 
			
		||||
	{
 | 
			
		||||
		Set<CommandSender> ret = new LinkedHashSet<CommandSender>();
 | 
			
		||||
		
 | 
			
		||||
@ -199,8 +199,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	{
 | 
			
		||||
		if (id == null) throw new NullPointerException("id");
 | 
			
		||||
		
 | 
			
		||||
		onlineIds.remove(id);
 | 
			
		||||
		allIds.remove(id);
 | 
			
		||||
		maintainedIds.removeValueCompletely(id);
 | 
			
		||||
		
 | 
			
		||||
		IdData data = idToData.remove(id);
 | 
			
		||||
		if (data == null) return null;
 | 
			
		||||
@ -213,10 +212,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	{
 | 
			
		||||
		if (name == null) throw new NullPointerException("name");
 | 
			
		||||
		
 | 
			
		||||
		onlineNames.remove(name);
 | 
			
		||||
		onlinePlayerNames.remove(name);
 | 
			
		||||
		allNames.remove(name);
 | 
			
		||||
		allPlayerNames.remove(name);
 | 
			
		||||
		maintainedNames.removeValueCompletely(name);
 | 
			
		||||
		
 | 
			
		||||
		IdData data = nameToData.remove(name);
 | 
			
		||||
		if (data == null) return null;
 | 
			
		||||
@ -224,9 +220,11 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		return data.getId();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static void addData(IdData data, boolean online)
 | 
			
		||||
	private static void addData(IdData data, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		if (data == null) throw new NullPointerException("data");
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		
 | 
			
		||||
		String id = data.getId();
 | 
			
		||||
		String name = data.getName();
 | 
			
		||||
		
 | 
			
		||||
@ -244,18 +242,12 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		
 | 
			
		||||
		if (id != null && name != null)
 | 
			
		||||
		{
 | 
			
		||||
			boolean player = MUtil.isValidPlayerName(name);
 | 
			
		||||
			
 | 
			
		||||
			if (online) onlineIds.add(id);
 | 
			
		||||
			allIds.add(id);
 | 
			
		||||
			
 | 
			
		||||
			if (online && player) onlinePlayerNames.add(name);
 | 
			
		||||
			if (online) onlineNames.add(name);
 | 
			
		||||
			if (player) allPlayerNames.add(name);
 | 
			
		||||
			allNames.add(name);
 | 
			
		||||
			List<SenderPresence> presences = SenderMap.getPresences(presence);
 | 
			
		||||
			maintainedIds.addValue(id, presences);
 | 
			
		||||
			maintainedNames.addValue(name, presences);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public static void update(String id, String name)
 | 
			
		||||
	{
 | 
			
		||||
		update(id, name, null);
 | 
			
		||||
@ -265,13 +257,13 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	{
 | 
			
		||||
		update(id, name, millis, null);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void update(final String id, final String name, Boolean online)
 | 
			
		||||
 | 
			
		||||
	public static void update(final String id, final String name, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		update(id, name, System.currentTimeMillis(), online);
 | 
			
		||||
		update(id, name, System.currentTimeMillis(), presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void update(final String id, final String name, final long millis, Boolean online)
 | 
			
		||||
	public static void update(final String id, final String name, final long millis, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		// First Null Check
 | 
			
		||||
		if (id == null && name == null) throw new NullPointerException("Either id or name must be set. They can't both be null.");
 | 
			
		||||
@ -292,35 +284,47 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		// The previousMillis is now null or the lowest of the two.
 | 
			
		||||
		if (previousMillis != null && previousMillis > millis) return;
 | 
			
		||||
		
 | 
			
		||||
		// Online Fix
 | 
			
		||||
		if (online == null)
 | 
			
		||||
		// Presence Fix
 | 
			
		||||
		if (presence == null)
 | 
			
		||||
		{
 | 
			
		||||
			if (id != null)
 | 
			
		||||
			{
 | 
			
		||||
				online = onlineIds.contains(id);
 | 
			
		||||
				presence = maintainedIds.getPresence(id);
 | 
			
		||||
			}
 | 
			
		||||
			else if (name != null)
 | 
			
		||||
			{
 | 
			
		||||
				online = onlineNames.contains(name);
 | 
			
		||||
				presence = maintainedNames.getPresence(name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Removal of previous data
 | 
			
		||||
		// TODO: This is not optimal but will do for now. It only "uproots" one step.
 | 
			
		||||
		String otherId = null;
 | 
			
		||||
		String otherName = null;
 | 
			
		||||
		
 | 
			
		||||
		if (id != null) otherName = removeId(id);
 | 
			
		||||
		if (name != null) otherId = removeName(name);
 | 
			
		||||
		
 | 
			
		||||
		if (otherId != null && !otherId.equals(id)) removeId(otherId);
 | 
			
		||||
		if (otherName != null && !otherName.equals(name)) removeName(otherName);
 | 
			
		||||
		removeIdAndNameRecurse(id, name);
 | 
			
		||||
		
 | 
			
		||||
		// Adding new data
 | 
			
		||||
		IdData data = new IdData(id, name, millis);
 | 
			
		||||
		addData(data, online);
 | 
			
		||||
		addData(data, presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private static void removeIdAndNameRecurse(String id, String name)
 | 
			
		||||
	{
 | 
			
		||||
		String otherId = null;
 | 
			
		||||
		String otherName = null;
 | 
			
		||||
		
 | 
			
		||||
		// Remove first
 | 
			
		||||
		if (id != null) otherName = removeId(id);
 | 
			
		||||
		if (name != null) otherId = removeName(name);
 | 
			
		||||
		
 | 
			
		||||
		// If equal, then null. We shouldn't perform the same operation twice.
 | 
			
		||||
		if (otherId != null && otherId.equals(id)) otherId = null;
 | 
			
		||||
		if (otherName != null && otherName.equals(name)) otherName = null;
 | 
			
		||||
		
 | 
			
		||||
		// If any isn't null. Repeat
 | 
			
		||||
		if (otherId != null || otherName != null)
 | 
			
		||||
		{
 | 
			
		||||
			removeIdAndNameRecurse(otherId, otherName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// SETUP
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@ -339,13 +343,9 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		idToData.clear();
 | 
			
		||||
		nameToData.clear();
 | 
			
		||||
		
 | 
			
		||||
		onlineIds.clear();
 | 
			
		||||
		onlineNames.clear();
 | 
			
		||||
		onlinePlayerNames.clear();
 | 
			
		||||
		
 | 
			
		||||
		allIds.clear();
 | 
			
		||||
		allNames.clear();
 | 
			
		||||
		allPlayerNames.clear();
 | 
			
		||||
		maintainedIds.clear();
 | 
			
		||||
		maintainedNames.clear();
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
		// Load Datas
 | 
			
		||||
		loadDatas();
 | 
			
		||||
@ -394,9 +394,11 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		String name = player.getName();
 | 
			
		||||
		
 | 
			
		||||
		// Declaring Existence? Sure, whatever you were before!
 | 
			
		||||
		// It can definitely not be local at this point.
 | 
			
		||||
		// But online or offline is fine.
 | 
			
		||||
		boolean online = Mixin.isOnline(player);
 | 
			
		||||
		
 | 
			
		||||
		update(id, name, online);
 | 
			
		||||
		update(id, name, SenderPresence.fromOnline(online));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Can't be cancelled
 | 
			
		||||
@ -410,10 +412,8 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		String id = uuid.toString();
 | 
			
		||||
		String name = player.getName();
 | 
			
		||||
		
 | 
			
		||||
		// Joining? Sure, the player is online!
 | 
			
		||||
		boolean online = true;
 | 
			
		||||
		
 | 
			
		||||
		update(id, name, online);
 | 
			
		||||
		// Joining? The player must be local at this point.
 | 
			
		||||
		update(id, name, SenderPresence.LOCAL);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Can't be cancelled
 | 
			
		||||
@ -428,9 +428,21 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		String name = player.getName();
 | 
			
		||||
		
 | 
			
		||||
		// Leaving? Is it an actuall leave?
 | 
			
		||||
		boolean online = !Mixin.isActualLeave(event);
 | 
			
		||||
		SenderPresence presence;
 | 
			
		||||
		if (Mixin.isActualLeave(event))
 | 
			
		||||
		{
 | 
			
		||||
			// They actually left.
 | 
			
		||||
			// They are offline.
 | 
			
		||||
			presence = SenderPresence.OFFLINE;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// They didn't actually leave.
 | 
			
		||||
			// They are online, but not local.
 | 
			
		||||
			presence = SenderPresence.ONLINE;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		update(id, name, online);
 | 
			
		||||
		update(id, name, presence);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
@ -462,10 +474,16 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		
 | 
			
		||||
		// Player
 | 
			
		||||
		// CommandSender
 | 
			
		||||
		// UUID
 | 
			
		||||
		if (senderObject instanceof CommandSender || senderObject instanceof UUID)
 | 
			
		||||
		if (senderObject instanceof CommandSender)
 | 
			
		||||
		{
 | 
			
		||||
			String id = getId(senderObject);
 | 
			
		||||
			String id = getIdFromSender((CommandSender) senderObject);
 | 
			
		||||
			return getIdToData().get(id);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// UUID
 | 
			
		||||
		if (senderObject instanceof UUID)
 | 
			
		||||
		{
 | 
			
		||||
			String id = getIdFromUuid((UUID) senderObject);
 | 
			
		||||
			return getIdToData().get(id);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
@ -620,8 +638,8 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		// Already Done
 | 
			
		||||
		if (senderObject instanceof String && MUtil.isUuid((String)senderObject)) return (String)senderObject;
 | 
			
		||||
		
 | 
			
		||||
		// Console Type
 | 
			
		||||
		if (senderObject instanceof ConsoleCommandSender) return CONSOLE_ID;
 | 
			
		||||
		// Console
 | 
			
		||||
		// Handled at "Command Sender"
 | 
			
		||||
		
 | 
			
		||||
		// Console Id/Name
 | 
			
		||||
		if (CONSOLE_ID.equals(senderObject)) return CONSOLE_ID;
 | 
			
		||||
@ -634,13 +652,13 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Player
 | 
			
		||||
		if (senderObject instanceof Player) return ((Player)senderObject).getUniqueId().toString();
 | 
			
		||||
		// Handled at "Command Sender"
 | 
			
		||||
		
 | 
			
		||||
		// CommandSender
 | 
			
		||||
		if (senderObject instanceof CommandSender) return ((CommandSender)senderObject).getName().toLowerCase();
 | 
			
		||||
		// Command Sender
 | 
			
		||||
		if (senderObject instanceof CommandSender) return getIdFromSender((CommandSender) senderObject);
 | 
			
		||||
		
 | 
			
		||||
		// UUID
 | 
			
		||||
		if (senderObject instanceof UUID) return ((UUID)senderObject).toString();
 | 
			
		||||
		if (senderObject instanceof UUID) return getIdFromUuid((UUID) senderObject);
 | 
			
		||||
		
 | 
			
		||||
		// String
 | 
			
		||||
		// Handled at "Data"
 | 
			
		||||
@ -655,6 +673,18 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		// Return Null
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String getIdFromSender(CommandSender sender)
 | 
			
		||||
	{
 | 
			
		||||
		if (sender instanceof Player) return ((Player) sender).getUniqueId().toString();
 | 
			
		||||
		if (sender instanceof ConsoleCommandSender) return CONSOLE_ID;
 | 
			
		||||
		return sender.getName().toLowerCase();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String getIdFromUuid(UUID uuid)
 | 
			
		||||
	{
 | 
			
		||||
		return uuid.toString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static String getName(Object senderObject)
 | 
			
		||||
	{
 | 
			
		||||
@ -664,8 +694,8 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		// Already Done
 | 
			
		||||
		// Handled at "Data" (not applicable - names can look differently)
 | 
			
		||||
		
 | 
			
		||||
		// Console Type
 | 
			
		||||
		if (senderObject instanceof ConsoleCommandSender) return CONSOLE_ID;
 | 
			
		||||
		// Console
 | 
			
		||||
		// Handled at "Command Sender"
 | 
			
		||||
		
 | 
			
		||||
		// Console Id/Name
 | 
			
		||||
		if (CONSOLE_ID.equals(senderObject)) return CONSOLE_ID;
 | 
			
		||||
@ -678,10 +708,10 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Player
 | 
			
		||||
		// Handled at "CommandSender"
 | 
			
		||||
		
 | 
			
		||||
		// Handled at "Command Sender"
 | 
			
		||||
 | 
			
		||||
		// CommandSender
 | 
			
		||||
		if (senderObject instanceof CommandSender) return ((CommandSender)senderObject).getName();
 | 
			
		||||
		if (senderObject instanceof CommandSender) return getNameFromSender((CommandSender)senderObject);
 | 
			
		||||
		
 | 
			
		||||
		// UUID
 | 
			
		||||
		// Handled at "Data".
 | 
			
		||||
@ -705,10 +735,15 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static String getNameFromSender(CommandSender sender)
 | 
			
		||||
	{
 | 
			
		||||
		if (sender instanceof ConsoleCommandSender) return CONSOLE_ID;
 | 
			
		||||
		return sender.getName();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isOnline(Object senderObject)
 | 
			
		||||
	{
 | 
			
		||||
		// Fix the id ...
 | 
			
		||||
		if (senderObject == null) return false;
 | 
			
		||||
		String id = getId(senderObject);
 | 
			
		||||
		if (id == null) return false;
 | 
			
		||||
		
 | 
			
		||||
@ -717,7 +752,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		if (CONSOLE_ID.equals(id)) return true;
 | 
			
		||||
		
 | 
			
		||||
		// ... return by (case insensitive) set contains.
 | 
			
		||||
		return getOnlineIds().contains(id);
 | 
			
		||||
		return IdUtil.getIds(SenderPresence.ONLINE, SenderType.ANY).contains(id);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static Long getMillis(Object senderObject)
 | 
			
		||||
@ -733,7 +768,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isPlayerId(String string)
 | 
			
		||||
	{
 | 
			
		||||
		// NOTE: Assuming all custom ids look like "@shite".
 | 
			
		||||
		// NOTE: Assuming all custom ids isn't a valid player name or id.
 | 
			
		||||
		return MUtil.isValidPlayerName(string) || MUtil.isUuid(string);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@ -805,20 +840,20 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
		MassiveCore.get().log(Txt.parse("<i>Loading Cachefile datas..."));
 | 
			
		||||
		for (IdData data : getCachefileDatas())
 | 
			
		||||
		{
 | 
			
		||||
			update(data.getId(), data.getName(), data.getMillis(), false);
 | 
			
		||||
			update(data.getId(), data.getName(), data.getMillis(), SenderPresence.OFFLINE);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		MassiveCore.get().log(Txt.parse("<i>Loading Onlineplayer datas..."));
 | 
			
		||||
		for (IdData data : getOnlineplayerDatas())
 | 
			
		||||
		for (IdData data : getLocalPlayerDatas())
 | 
			
		||||
		{
 | 
			
		||||
			update(data.getId(), data.getName(), data.getMillis(), true);
 | 
			
		||||
			update(data.getId(), data.getName(), data.getMillis(), SenderPresence.LOCAL);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		MassiveCore.get().log(Txt.parse("<i>Loading Registry datas..."));
 | 
			
		||||
		for (String id : registryIdToSender.keySet())
 | 
			
		||||
		{
 | 
			
		||||
			String name = id;
 | 
			
		||||
			update(id, name, true);
 | 
			
		||||
			update(id, name, SenderPresence.LOCAL);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		MassiveCore.get().log(Txt.parse("<i>Saving Cachefile..."));
 | 
			
		||||
@ -867,7 +902,7 @@ public class IdUtil implements Listener, Runnable
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// This data source is simply based on the players currently online
 | 
			
		||||
	
 | 
			
		||||
	public static Set<IdData> getOnlineplayerDatas()
 | 
			
		||||
	public static Set<IdData> getLocalPlayerDatas()
 | 
			
		||||
	{
 | 
			
		||||
		Set<IdData> ret = new LinkedHashSet<IdData>();
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										206
									
								
								src/com/massivecraft/massivecore/util/SenderMap.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								src/com/massivecraft/massivecore/util/SenderMap.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,206 @@
 | 
			
		||||
package com.massivecraft.massivecore.util;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.ConcurrentSkipListSet;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
 | 
			
		||||
public final class SenderMap
 | 
			
		||||
{
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// FIELDS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	private final Map<SenderPresence, Map<SenderType, Set<String>>> innerMap;
 | 
			
		||||
	
 | 
			
		||||
	public Map<SenderPresence, Map<SenderType, Set<String>>> getInnerMap()
 | 
			
		||||
	{
 | 
			
		||||
		return innerMap;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONSTRUCT
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public SenderMap()
 | 
			
		||||
	{
 | 
			
		||||
		innerMap = new EnumMap<SenderPresence, Map<SenderType, Set<String>>>(SenderPresence.class);
 | 
			
		||||
		for (SenderPresence presence : SenderPresence.values())
 | 
			
		||||
		{
 | 
			
		||||
			Map<SenderType, Set<String>> map = new EnumMap<SenderType, Set<String>>(SenderType.class);
 | 
			
		||||
			for (SenderType type : SenderType.values())
 | 
			
		||||
			{
 | 
			
		||||
				Set<String> set = new ConcurrentSkipListSet<String>(String.CASE_INSENSITIVE_ORDER);
 | 
			
		||||
				map.put(type, set);
 | 
			
		||||
			}
 | 
			
		||||
			innerMap.put(presence, map);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// GET
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public Set<String> getValues(SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		if (type == null) throw new NullPointerException("type");
 | 
			
		||||
	
 | 
			
		||||
		return Collections.unmodifiableSet(getRawValues(presence, type));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private Set<String> getRawValues(SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		return innerMap.get(presence).get(type);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public SenderPresence getPresence(String value)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		return getPresence(value, SenderType.ANY);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public SenderPresence getPresence(String value, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (type == null) throw new NullPointerException("type");
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
		for (SenderPresence presence : SenderPresence.values())
 | 
			
		||||
		{
 | 
			
		||||
			if (contains(value, presence, type)) return presence;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CONTAINS
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public boolean contains(String value, SenderPresence presence, SenderType type)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		if (type == null) throw new NullPointerException("type");
 | 
			
		||||
		
 | 
			
		||||
		return getRawValues(presence, type).contains(value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// CLEAR
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public void clear()
 | 
			
		||||
	{
 | 
			
		||||
		for (Map<SenderType, Set<String>> map : innerMap.values())
 | 
			
		||||
		{
 | 
			
		||||
			for (Set<String> set : map.values())
 | 
			
		||||
			{
 | 
			
		||||
				set.clear();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// ADD
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public void addValue(String value, SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		
 | 
			
		||||
		addValue(value, getPresences(presence));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addValue(String value, List<SenderPresence> presences)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (presences == null) throw new NullPointerException("presences");
 | 
			
		||||
		
 | 
			
		||||
		addValue(value, presences, getSenderTypes(value));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void addValue(String value, List<SenderPresence> presences, List<SenderType> types)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (presences == null) throw new NullPointerException("presences");
 | 
			
		||||
		if (types == null) throw new NullPointerException("types");
 | 
			
		||||
		
 | 
			
		||||
		for (SenderPresence presence : presences)
 | 
			
		||||
		{
 | 
			
		||||
			Map<SenderType, Set<String>> map = innerMap.get(presence);
 | 
			
		||||
			for (SenderType type : types)
 | 
			
		||||
			{
 | 
			
		||||
				Set<String> set = map.get(type);
 | 
			
		||||
				set.add(value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// REMOVE
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public boolean removeValueCompletely(String value)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
 | 
			
		||||
		boolean ret = false;
 | 
			
		||||
		for (Map<SenderType, Set<String>> map : innerMap.values())
 | 
			
		||||
		{
 | 
			
		||||
			for (Set<String> set : map.values())
 | 
			
		||||
			{
 | 
			
		||||
				ret |= set.remove(value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	// UTIL
 | 
			
		||||
	// -------------------------------------------- //
 | 
			
		||||
	
 | 
			
		||||
	public static final List<SenderPresence> LOCAL_PRESENCES = ImmutableList.of(SenderPresence.LOCAL, SenderPresence.ONLINE, SenderPresence.ANY);
 | 
			
		||||
	public static final List<SenderPresence> ONLINE_PRESENCES = ImmutableList.of(SenderPresence.ONLINE, SenderPresence.ANY);
 | 
			
		||||
	public static final List<SenderPresence> OFFLINE_PRESENCES = ImmutableList.of(SenderPresence.OFFLINE, SenderPresence.ANY);
 | 
			
		||||
	
 | 
			
		||||
	// This accepts the most strict presence,
 | 
			
		||||
	// and returns all other which also match.
 | 
			
		||||
	public static List<SenderPresence> getPresences(SenderPresence presence)
 | 
			
		||||
	{
 | 
			
		||||
		if (presence == null) throw new NullPointerException("presence");
 | 
			
		||||
		switch (presence)
 | 
			
		||||
		{
 | 
			
		||||
			case LOCAL : return LOCAL_PRESENCES;
 | 
			
		||||
			case ONLINE : return ONLINE_PRESENCES;
 | 
			
		||||
			case OFFLINE : return OFFLINE_PRESENCES;
 | 
			
		||||
			case ANY : throw new UnsupportedOperationException("SenderPresence.ANY is not supported. You must know wether it is online or offline.");
 | 
			
		||||
		}
 | 
			
		||||
		throw new UnsupportedOperationException("Unknown SenderPresence: " + null);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static final List<SenderType> PLAYER_TYPES = ImmutableList.of(SenderType.PLAYER, SenderType.ANY);
 | 
			
		||||
	public static final List<SenderType> NONPLAYER_TYPES = ImmutableList.of(SenderType.NONPLAYER, SenderType.ANY);
 | 
			
		||||
	
 | 
			
		||||
	public static List<SenderType> getSenderTypes(String value)
 | 
			
		||||
	{
 | 
			
		||||
		if (value == null) throw new NullPointerException("value");
 | 
			
		||||
		if (isPlayerValue(value)) return PLAYER_TYPES;
 | 
			
		||||
		else return NONPLAYER_TYPES;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean isPlayerValue(String value)
 | 
			
		||||
	{
 | 
			
		||||
		return IdUtil.isPlayerId(value);
 | 
			
		||||
		//return MUtil.isValidPlayerName(value) || MUtil.isUuid(value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								src/com/massivecraft/massivecore/util/SenderMapTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/com/massivecraft/massivecore/util/SenderMapTest.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
package com.massivecraft.massivecore.util;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import com.massivecraft.massivecore.SenderPresence;
 | 
			
		||||
import com.massivecraft.massivecore.SenderType;
 | 
			
		||||
 | 
			
		||||
class SenderMapTest
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	static SenderMap map = new SenderMap();
 | 
			
		||||
	public static void main(String[] args) 
 | 
			
		||||
	{
 | 
			
		||||
		map.addValue("Madus", SenderPresence.LOCAL); // Satisfying
 | 
			
		||||
		//printMap();
 | 
			
		||||
		
 | 
			
		||||
		map.removeValueCompletely("Madus"); // Satisfying
 | 
			
		||||
		//printMap();
 | 
			
		||||
		
 | 
			
		||||
		map.addValue("Madus", SenderPresence.LOCAL); // Satisfying
 | 
			
		||||
		map.addValue("Cayorion", SenderPresence.ONLINE); // Satisfying
 | 
			
		||||
		//printMap();
 | 
			
		||||
		
 | 
			
		||||
		map.removeValueCompletely("madus"); // Satisfying (case insensitive)
 | 
			
		||||
		//printMap();
 | 
			
		||||
		
 | 
			
		||||
		map.addValue("@console", SenderPresence.OFFLINE); // Satisfying
 | 
			
		||||
		//printMap();
 | 
			
		||||
		
 | 
			
		||||
		System.out.println(map.getPresence("@console")); // Satisfying (OFFLINE)
 | 
			
		||||
		System.out.println(map.getPresence("caYorioN")); // Satisfying (ONLINE)
 | 
			
		||||
		System.out.println(map.getPresence("MaDus")); // Satisfying (null)
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void printMap()
 | 
			
		||||
	{
 | 
			
		||||
		printMap(map);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static void printMap(SenderMap map)
 | 
			
		||||
	{
 | 
			
		||||
		for (Entry<SenderPresence, Map<SenderType, Set<String>>> entry1 : map.getInnerMap().entrySet())
 | 
			
		||||
		{
 | 
			
		||||
			System.out.println(entry1.getKey());
 | 
			
		||||
			for (Entry<SenderType, Set<String>> entry2 : entry1.getValue().entrySet())
 | 
			
		||||
			{
 | 
			
		||||
				System.out.println("	" + entry2.getKey() + ": " + entry2.getValue());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user