Skip to content
This repository has been archived by the owner on Jun 27, 2022. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDevMinerTV committed Jun 15, 2021
2 parents 4e56843 + 31d9e3c commit 0bdaf36
Show file tree
Hide file tree
Showing 66 changed files with 2,062 additions and 365 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

BungeeCord for 1.7/1.8/1.9/1.10/1.11/1.12/1.13/1.14/1.15/1.16
BungeeCord for 1.7/1.8/1.9/1.10/1.11/1.12/1.13/1.14/1.15/1.16/1.17
==========

**Fork:** [BungeeCord](https://github.com/SpigotMC/BungeeCord) >> [HexaCord](https://github.com/HexagonMC/BungeeCord) >> [KettleCord](https://github.com/UeberallGebannt/KettleCord/)
Expand Down
27 changes: 24 additions & 3 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<parent>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-parent</artifactId>
<version>1.16-R0.5-SNAPSHOT</version>
<version>1.17-R0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.16-R0.5-SNAPSHOT</version>
<version>1.17-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>BungeeCord-API</name>
Expand Down Expand Up @@ -49,10 +49,31 @@
<version>${netty.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-resolver-provider</artifactId>
<version>3.8.1</version>
<!-- not part of the API proper -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
<version>1.7.0</version>
<!-- not part of the API proper -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-http</artifactId>
<version>1.7.0</version>
<!-- not part of the API proper -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.26</version>
<version>1.28</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ public enum MainHand
String getDisplayName();

/**
* Sets this players display name to be used as their nametag and tab list
* name.
* Sets this players display name to be used by bungeecord commands and plugins.
*
* @param name the name to set
*/
Expand Down
123 changes: 123 additions & 0 deletions api/src/main/java/net/md_5/bungee/api/plugin/LibraryLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package net.md_5.bungee.api.plugin;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transport.http.HttpTransporterFactory;

class LibraryLoader
{

private final Logger logger;
private final RepositorySystem repository;
private final DefaultRepositorySystemSession session;
private final List<RemoteRepository> repositories;

public LibraryLoader(Logger logger)
{
this.logger = logger;

DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
locator.addService( TransporterFactory.class, HttpTransporterFactory.class );

this.repository = locator.getService( RepositorySystem.class );
this.session = MavenRepositorySystemUtils.newSession();

session.setChecksumPolicy( RepositoryPolicy.CHECKSUM_POLICY_FAIL );
session.setLocalRepositoryManager( repository.newLocalRepositoryManager( session, new LocalRepository( "libraries" ) ) );
session.setTransferListener( new AbstractTransferListener()
{
@Override
public void transferStarted(TransferEvent event) throws TransferCancelledException
{
logger.log( Level.INFO, "Downloading {0}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
}
} );
session.setReadOnly();

this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) );
}

public ClassLoader createLoader(PluginDescription desc)
{
if ( desc.getLibraries().isEmpty() )
{
return null;
}
logger.log( Level.INFO, "[{0}] Loading {1} libraries... please wait", new Object[]
{
desc.getName(), desc.getLibraries().size()
} );

List<Dependency> dependencies = new ArrayList<>();
for ( String library : desc.getLibraries() )
{
Artifact artifact = new DefaultArtifact( library );
Dependency dependency = new Dependency( artifact, null );

dependencies.add( dependency );
}

DependencyResult result;
try
{
result = repository.resolveDependencies( session, new DependencyRequest( new CollectRequest( (Dependency) null, dependencies, repositories ), null ) );
} catch ( DependencyResolutionException ex )
{
throw new RuntimeException( "Error resolving libraries", ex );
}

List<URL> jarFiles = new ArrayList<>();
for ( ArtifactResult artifact : result.getArtifactResults() )
{
File file = artifact.getArtifact().getFile();

URL url;
try
{
url = file.toURI().toURL();
} catch ( MalformedURLException ex )
{
throw new AssertionError( ex );
}

jarFiles.add( url );
logger.log( Level.INFO, "[{0}] Loaded library {1}", new Object[]
{
desc.getName(), file
} );
}

URLClassLoader loader = new URLClassLoader( jarFiles.toArray( new URL[ 0 ] ) );

return loader;
}
}
108 changes: 103 additions & 5 deletions api/src/main/java/net/md_5/bungee/api/plugin/PluginClassloader.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
package net.md_5.bungee.api.plugin;

import com.google.common.base.Preconditions;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import lombok.ToString;
import net.md_5.bungee.api.ProxyServer;

@ToString(of = "desc")
final class PluginClassloader extends URLClassLoader
{

private static final Set<PluginClassloader> allLoaders = new CopyOnWriteArraySet<>();
//
private final ProxyServer proxy;
private final PluginDescription desc;
private final JarFile jar;
private final Manifest manifest;
private final URL url;
private final ClassLoader libraryLoader;
//
private Plugin plugin;

Expand All @@ -22,29 +37,47 @@ final class PluginClassloader extends URLClassLoader
ClassLoader.registerAsParallelCapable();
}

public PluginClassloader(ProxyServer proxy, PluginDescription desc, URL[] urls)
public PluginClassloader(ProxyServer proxy, PluginDescription desc, File file, ClassLoader libraryLoader) throws IOException
{
super( urls );
super( new URL[]
{
file.toURI().toURL()
} );
this.proxy = proxy;
this.desc = desc;
this.jar = new JarFile( file );
this.manifest = jar.getManifest();
this.url = file.toURI().toURL();
this.libraryLoader = libraryLoader;

allLoaders.add( this );
}

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
return loadClass0( name, resolve, true );
return loadClass0( name, resolve, true, true );
}

private Class<?> loadClass0(String name, boolean resolve, boolean checkOther) throws ClassNotFoundException
private Class<?> loadClass0(String name, boolean resolve, boolean checkOther, boolean checkLibraries) throws ClassNotFoundException
{
try
{
return super.loadClass( name, resolve );
} catch ( ClassNotFoundException ex )
{
}

if ( checkLibraries && libraryLoader != null )
{
try
{
return libraryLoader.loadClass( name );
} catch ( ClassNotFoundException ex )
{
}
}

if ( checkOther )
{
for ( PluginClassloader loader : allLoaders )
Expand All @@ -53,16 +86,81 @@ private Class<?> loadClass0(String name, boolean resolve, boolean checkOther) th
{
try
{
return loader.loadClass0( name, resolve, false );
return loader.loadClass0( name, resolve, false, proxy.getPluginManager().isTransitiveDepend( desc, loader.desc ) );
} catch ( ClassNotFoundException ex )
{
}
}
}
}

throw new ClassNotFoundException( name );
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException
{
String path = name.replace( '.', '/' ).concat( ".class" );
JarEntry entry = jar.getJarEntry( path );

if ( entry != null )
{
byte[] classBytes;

try ( InputStream is = jar.getInputStream( entry ) )
{
classBytes = ByteStreams.toByteArray( is );
} catch ( IOException ex )
{
throw new ClassNotFoundException( name, ex );
}

int dot = name.lastIndexOf( '.' );
if ( dot != -1 )
{
String pkgName = name.substring( 0, dot );
if ( getPackage( pkgName ) == null )
{
try
{
if ( manifest != null )
{
definePackage( pkgName, manifest, url );
} else
{
definePackage( pkgName, null, null, null, null, null, null, null );
}
} catch ( IllegalArgumentException ex )
{
if ( getPackage( pkgName ) == null )
{
throw new IllegalStateException( "Cannot find package " + pkgName );
}
}
}
}

CodeSigner[] signers = entry.getCodeSigners();
CodeSource source = new CodeSource( url, signers );

return defineClass( name, classBytes, 0, classBytes.length, source );
}

return super.findClass( name );
}

@Override
public void close() throws IOException
{
try
{
super.close();
} finally
{
jar.close();
}
}

void init(Plugin plugin)
{
Preconditions.checkArgument( plugin != null, "plugin" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.File;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
Expand Down Expand Up @@ -48,4 +50,8 @@ public class PluginDescription
* Optional description.
*/
private String description = null;
/**
* Optional libraries.
*/
private List<String> libraries = new LinkedList<>();
}
Loading

0 comments on commit 0bdaf36

Please sign in to comment.