Skip to content

Instantly share code, notes, and snippets.

@arxenix
Created August 31, 2013 20:32
Show Gist options
  • Save arxenix/6400457 to your computer and use it in GitHub Desktop.
Save arxenix/6400457 to your computer and use it in GitHub Desktop.
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import lilypad.client.connect.api.Connect;
import lilypad.client.connect.api.MessageEvent;
import lilypad.client.connect.api.MessageEventListener;
import lilypad.client.connect.api.request.RequestException;
import lilypad.client.connect.api.request.impl.MessageRequest;
public class PlayerLookup implements Runnable, MessageEventListener {
private Server server;
private Connect connect;
public static Map<String, String> playersToServer = new HashMap<String, String>();
public static Map<String, List<String>> serversToPlayers = new HashMap<String, List<String>>();
private static Map<String, Long> lastServer = new HashMap<String, Long>();
private static ReentrantLock lock = new ReentrantLock();
public PlayerLookup(Server server, Connect connect) {
this.server = server;
this.connect = connect;
}
@SuppressWarnings("unchecked")
public void run() {
Player[] players = this.server.getOnlinePlayers();
String[] names = new String[players.length];
for(int i = 0; i < players.length; i++) {
names[i] = players[i].getName();
}
String namesAsString = concat(names, "\0");
try {
this.connect.request(new MessageRequest(Collections.EMPTY_LIST, "lilyessentials.playersync", namesAsString));
} catch(UnsupportedEncodingException exception) {
// ignore
} catch(RequestException exception) {
// ignore
}
}
public String concat(String[] strings, String separator){
StringBuilder b = new StringBuilder();
for(int i=0;i<strings.length;i++){
b.append(strings[i]);
if(i!=strings.length-1){
b.append(separator);
}
}
return b.toString();
}
public void onMessage(Connect connect, MessageEvent messageEvent) {
if(!messageEvent.getChannel().equals("lilyessentials.playersync")) {
return;
}
String message;
try {
message = messageEvent.getMessageAsString();
} catch(UnsupportedEncodingException exception) {
return;
}
List<String> players = new ArrayList<String>(Arrays.asList(message.split("\0")));
serversToPlayers.put(messageEvent.getSender(), players);
lastServer.put(messageEvent.getSender(), System.currentTimeMillis());
rebuild(true);
}
public static void rebuild(boolean force) {
// TODO if it is not forced, we need to keep a cache of the next time it is required to check so we don't have to iterate every time
lock.lock();
try {
boolean required = force;
Iterator<Entry<String, Long>> lastUpdates = lastServer.entrySet().iterator();
Entry<String, Long> lastUpdate;
while(lastUpdates.hasNext()) {
lastUpdate = lastUpdates.next();
if(System.currentTimeMillis() - lastUpdate.getValue() < 7500L) {
continue;
}
required = true;
lastUpdates.remove();
serversToPlayers.remove(lastUpdate.getKey());
if(serversToPlayers.isEmpty()) {
required = false;
}
}
if(required) {
playersToServer.clear();
for(Entry<String, List<String>> serverToPlayers : serversToPlayers.entrySet()) {
for(String player : serverToPlayers.getValue()) {
playersToServer.put(player, serverToPlayers.getKey());
}
}
}
} finally {
lock.unlock();
}
}
public static List<String> getPlayers(String server){
rebuild(false);
return serversToPlayers.get(server);
}
public static Set<String> getPlayers() {
rebuild(false);
return playersToServer.keySet();
}
public static Map<String, String> getPlayersToServer() {
rebuild(false);
return playersToServer;
}
public static String lookupPlayer(String player) {
Set<String> players = getPlayers();
if(players.contains(player)) {
return player;
}
String matchedPlayer = null;
for(String iterPlayer : players) {
if(!iterPlayer.toLowerCase().startsWith(player.toLowerCase())) {
continue;
}
matchedPlayer = iterPlayer;
break;
}
return matchedPlayer;
}
public static String getServerByPlayer(String player) {
return getPlayersToServer().get(player);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment