SPIGOT-522: Remove the global api cache option

This was useful when plugins first started upgrading to uuid because each
plugin would implement their own way for grabbing uuid's from mojang. Because
none of them shared the result they would quickly hit the limits on the api
causing the conversion to either fail or pause for long periods of time. The
global api cache was a (very hacky) way to force all plugins to share a cache
but caused a few issues with plugins that expected a full implementation of
the HTTPURLConnection. Due to the fact that most servers/plugins have updated
now it seems to be a good time to remove this as its usefulness mostly has
expired.
This commit is contained in:
Thinkofdeath 2015-02-06 10:08:31 +00:00
parent 00e1315f65
commit 954c898c28
17 changed files with 3 additions and 315 deletions

View File

@ -1,310 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thinkofdeath@spigotmc.org>
Date: Mon, 28 Jul 2014 11:42:11 +0100
Subject: [PATCH] Add an option for a global cache for any request on Mojang's
api to handle plugins that don't use UserCache (or any cache)
diff --git a/src/main/java/org/spigotmc/CachedMojangAPIConnection.java b/src/main/java/org/spigotmc/CachedMojangAPIConnection.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/org/spigotmc/CachedMojangAPIConnection.java
@@ -0,0 +0,0 @@
+package org.spigotmc;
+
+import com.google.common.base.Charsets;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+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;
+ }
+}
diff --git a/src/main/java/org/spigotmc/CachedStreamHandlerFactory.java b/src/main/java/org/spigotmc/CachedStreamHandlerFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/org/spigotmc/CachedStreamHandlerFactory.java
@@ -0,0 +0,0 @@
+package org.spigotmc;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+public class CachedStreamHandlerFactory implements URLStreamHandlerFactory
+{
+ public static boolean isSet = false;
+
+ @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 e )
+ {
+ e.printStackTrace();
+ } catch ( InvocationTargetException e )
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public URLConnection getDefaultConnection(URL u, Proxy p)
+ {
+ try
+ {
+ return (URLConnection) openConProxy.invoke( handler, u, p );
+ } catch ( IllegalAccessException e )
+ {
+ e.printStackTrace();
+ } catch ( InvocationTargetException e )
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -0,0 +0,0 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -0,0 +0,0 @@ public class SpigotConfig
attackDamage = getDouble( "settings.attribute.attackDamage.max", attackDamage );
( (AttributeRanged) GenericAttributes.e ).b = attackDamage;
}
+
+ private static void globalAPICache()
+ {
+ if ( getBoolean( "settings.global-api-cache", false ) && !CachedStreamHandlerFactory.isSet )
+ {
+ Bukkit.getLogger().info( "Global API cache enabled - All requests to Mojang's API will be " +
+ "handled by Spigot" );
+ CachedStreamHandlerFactory.isSet = true;
+ URL.setURLStreamHandlerFactory(new CachedStreamHandlerFactory());
+ }
+ }
}
--

View File

@ -19,8 +19,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
@@ -0,0 +0,0 @@ public class SpigotConfig
URL.setURLStreamHandlerFactory(new CachedStreamHandlerFactory());
}
attackDamage = getDouble( "settings.attribute.attackDamage.max", attackDamage );
( (AttributeRanged) GenericAttributes.e ).b = attackDamage;
}
+
+ public static boolean debug;

View File

@ -136,6 +136,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
};
@Override
--
1.9.5.msysgit.0
--