-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1c10710
Showing
6 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Eclipse stuff | ||
/.classpath | ||
/.project | ||
/.settings | ||
|
||
# netbeans | ||
/nbproject | ||
/nbactions.xml | ||
/nb-configuration.xml | ||
|
||
# we use maven! | ||
/build.xml | ||
|
||
# maven | ||
/target | ||
/dependency-reduced-pom.xml | ||
*/target | ||
*/dependency-reduced-pom.xml | ||
|
||
# vim | ||
.*.sw[a-p] | ||
|
||
# various other potential build files | ||
/build | ||
/bin | ||
/dist | ||
/manifest.mf | ||
|
||
# Mac filesystem dust | ||
/.DS_Store | ||
|
||
# intellij | ||
*.iml | ||
*.ipr | ||
*.iws | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>dank.memes</groupId> | ||
<artifactId>GlobalUUIDCache</artifactId> | ||
<version>1.0</version> | ||
<repositories> | ||
<repository> | ||
<id>spigot-repo</id> | ||
<url>https://hub.spigotmc.org/nexus/content/groups/public</url> | ||
</repository> | ||
</repositories> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>2.0.2</version> | ||
<configuration> | ||
<source>1.7</source> | ||
<target>1.7</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
<resources> | ||
<resource> | ||
<directory>src/main/resources</directory> | ||
<filtering>true</filtering> | ||
</resource> | ||
</resources> | ||
</build> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.spigotmc</groupId> | ||
<artifactId>spigot-api</artifactId> | ||
<version>1.8-R0.1-SNAPSHOT</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
120 changes: 120 additions & 0 deletions
120
src/main/java/dank/memes/uuidcache/CachedMojangAPIConnection.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package dank.memes.uuidcache; | ||
|
||
import com.google.common.base.Charsets; | ||
import com.google.common.cache.Cache; | ||
import com.google.common.cache.CacheBuilder; | ||
import com.google.gson.JsonArray; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
|
||
import java.io.*; | ||
import java.net.HttpURLConnection; | ||
import java.net.Proxy; | ||
import java.net.URL; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
public class CachedMojangAPIConnection extends HttpURLConnection { | ||
private final CachedStreamHandlerFactory.CachedStreamHandler cachedStreamHandler; | ||
private final Proxy proxy; | ||
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||
private ByteArrayInputStream inputStream; | ||
private InputStream errorStream; | ||
private boolean outClosed = false; | ||
|
||
private static final Cache<String, String> cache = CacheBuilder.newBuilder() | ||
.maximumSize(10000) | ||
.expireAfterAccess(1, TimeUnit.HOURS) | ||
.build(); | ||
|
||
public CachedMojangAPIConnection(CachedStreamHandlerFactory.CachedStreamHandler cachedStreamHandler, URL url, Proxy proxy) { | ||
super(url); | ||
this.cachedStreamHandler = cachedStreamHandler; | ||
this.proxy = proxy; | ||
} | ||
|
||
@Override | ||
public void disconnect() { | ||
|
||
} | ||
|
||
@Override | ||
public boolean usingProxy() { | ||
return proxy != null; | ||
} | ||
|
||
@Override | ||
public void connect() throws IOException { | ||
|
||
} | ||
|
||
@Override | ||
public InputStream getInputStream() throws IOException { | ||
if (inputStream == null) { | ||
outClosed = true; | ||
JsonArray users = new JsonParser().parse(new String(outputStream.toByteArray(), Charsets.UTF_8)).getAsJsonArray(); | ||
StringBuilder reply = new StringBuilder("["); | ||
StringBuilder missingUsers = new StringBuilder("["); | ||
for (JsonElement user : users) { | ||
String username = user.getAsString().toLowerCase(); | ||
String info = cache.getIfPresent(username); | ||
if (info != null) { | ||
reply.append(info).append(","); | ||
} else { | ||
missingUsers | ||
.append("\"") | ||
.append(username) | ||
.append("\"") | ||
.append(","); | ||
} | ||
} | ||
if (missingUsers.length() > 1) { | ||
missingUsers.deleteCharAt(missingUsers.length() - 1).append("]"); | ||
} | ||
if (missingUsers.length() > 2) { | ||
HttpURLConnection connection; | ||
if (proxy == null) { | ||
connection = (HttpURLConnection) cachedStreamHandler.getDefaultConnection(url); | ||
} else { | ||
connection = (HttpURLConnection) cachedStreamHandler.getDefaultConnection(url, proxy); | ||
} | ||
connection.setRequestMethod("POST"); | ||
connection.setRequestProperty("Content-Type", "application/json"); | ||
connection.setDoInput(true); | ||
connection.setDoOutput(true); | ||
OutputStream out = connection.getOutputStream(); | ||
out.write(missingUsers.toString().getBytes(Charsets.UTF_8)); | ||
out.flush(); | ||
out.close(); | ||
JsonArray newUsers = new JsonParser().parse(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8)).getAsJsonArray(); | ||
for (JsonElement user : newUsers) { | ||
JsonObject u = user.getAsJsonObject(); | ||
cache.put(u.get("name").getAsString(), u.toString()); | ||
reply.append(u.toString()).append(","); | ||
} | ||
responseCode = connection.getResponseCode(); | ||
errorStream = connection.getErrorStream(); | ||
} else { | ||
responseCode = HTTP_OK; | ||
} | ||
if (reply.length() > 1) { | ||
reply.deleteCharAt(reply.length() - 1); | ||
} | ||
inputStream = new ByteArrayInputStream(reply.append("]").toString().getBytes(Charsets.UTF_8)); | ||
} | ||
return inputStream; | ||
} | ||
|
||
@Override | ||
public InputStream getErrorStream() { | ||
return errorStream; | ||
} | ||
|
||
@Override | ||
public OutputStream getOutputStream() throws IOException { | ||
if (outClosed) { | ||
throw new RuntimeException("Write after send"); | ||
} | ||
return outputStream; | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
src/main/java/dank/memes/uuidcache/CachedStreamHandlerFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package dank.memes.uuidcache; | ||
|
||
import java.io.IOException; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.net.*; | ||
|
||
public class CachedStreamHandlerFactory implements URLStreamHandlerFactory { | ||
@Override | ||
public URLStreamHandler createURLStreamHandler(String protocol) { | ||
if (protocol.equals("http") || protocol.equals("https")) { | ||
return new CachedStreamHandler(protocol); | ||
} | ||
return null; | ||
} | ||
|
||
public class CachedStreamHandler extends URLStreamHandler { | ||
private final String protocol; | ||
private final URLStreamHandler handler; | ||
private final Method openCon; | ||
private final Method openConProxy; | ||
|
||
public CachedStreamHandler(String protocol) { | ||
this.protocol = protocol; | ||
if (protocol.equals("http")) { | ||
handler = new sun.net.www.protocol.http.Handler(); | ||
} else { | ||
handler = new sun.net.www.protocol.https.Handler(); | ||
} | ||
try { | ||
openCon = handler.getClass().getDeclaredMethod("openConnection", URL.class); | ||
openCon.setAccessible(true); | ||
openConProxy = handler.getClass().getDeclaredMethod("openConnection", URL.class, Proxy.class); | ||
openConProxy.setAccessible(true); | ||
} catch (NoSuchMethodException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
protected URLConnection openConnection(URL u) throws IOException { | ||
if (u.getHost().equals("api.mojang.com") | ||
|| u.getPath().startsWith("/profiles/minecraft")) { | ||
return cachedConnection(u); | ||
} | ||
return getDefaultConnection(u); | ||
} | ||
|
||
@Override | ||
protected URLConnection openConnection(URL u, Proxy p) throws IOException { | ||
if (u.getHost().equals("api.mojang.com") | ||
|| u.getPath().startsWith("/profiles/minecraft")) { | ||
return cachedConnection(u, p); | ||
} | ||
return getDefaultConnection(u, p); | ||
} | ||
|
||
private URLConnection cachedConnection(URL u) { | ||
return cachedConnection(u, null); | ||
} | ||
|
||
private URLConnection cachedConnection(URL u, Proxy p) { | ||
return new CachedMojangAPIConnection(this, u, p); | ||
} | ||
|
||
public URLConnection getDefaultConnection(URL u) { | ||
try { | ||
return (URLConnection) openCon.invoke(handler, u); | ||
} catch (IllegalAccessException | InvocationTargetException e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
public URLConnection getDefaultConnection(URL u, Proxy p) { | ||
try { | ||
return (URLConnection) openConProxy.invoke(handler, u, p); | ||
} catch (IllegalAccessException | InvocationTargetException e) { | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
} | ||
} | ||
|
||
|
29 changes: 29 additions & 0 deletions
29
src/main/java/dank/memes/uuidcache/GlobalUUIDCachePlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package dank.memes.uuidcache; | ||
|
||
import org.bukkit.plugin.java.JavaPlugin; | ||
|
||
import java.lang.reflect.Field; | ||
import java.net.URL; | ||
|
||
public class GlobalUUIDCachePlugin extends JavaPlugin { | ||
@Override | ||
public void onEnable() { | ||
unsetURLStreamHandlerFactory(); | ||
getLogger().info("Global API cache enabled - All requests to Mojang's API will be " + | ||
"handled by GlobalUUIDCache."); | ||
URL.setURLStreamHandlerFactory(new CachedStreamHandlerFactory()); | ||
} | ||
|
||
private static String unsetURLStreamHandlerFactory() { | ||
try { | ||
Field f = URL.class.getDeclaredField("factory"); | ||
f.setAccessible(true); | ||
Object curFac = f.get(null); | ||
f.set(null, null); | ||
URL.setURLStreamHandlerFactory(null); | ||
return curFac.getClass().getName(); | ||
} catch (Exception e) { | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
name: GlobalUUIDCache | ||
main: dank.memes.uuidcache.GlobalUUIDCachePlugin | ||
version: ${project.version} | ||
author: vemacs | ||
description: Readds global UUID cache into modern Spigot. Original source from SpigotMC. |